Merge from trunk 16122-16307
authorIan Thompson <quornian@googlemail.com>
Sat, 30 Aug 2008 14:32:16 +0000 (14:32 +0000)
committerIan Thompson <quornian@googlemail.com>
Sat, 30 Aug 2008 14:32:16 +0000 (14:32 +0000)
229 files changed:
CMake/macros.cmake
CMakeLists.txt
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
intern/guardedalloc/BLO_sys_types.h [new file with mode: 0644]
intern/guardedalloc/intern/mallocn.c
intern/guardedalloc/intern/mmap_win.c
intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj
intern/guardedalloc/mmap_win.h
intern/opennl/make/msvc_7_0/opennl.vcproj
intern/opennl/superlu/BLO_sys_types.h [new file with mode: 0644]
intern/opennl/superlu/smemory.c
projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
projectfiles_vc7/kernel/system/SYS_system.vcproj
release/datafiles/datatoc.c
release/scripts/flt_dofedit.py [new file with mode: 0644]
release/scripts/flt_lodedit.py [new file with mode: 0644]
release/scripts/flt_properties.py
release/text/copyright.txt
source/Makefile
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_collision.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_deform.h
source/blender/blenkernel/BKE_effect.h
source/blender/blenkernel/BKE_endian.h
source/blender/blenkernel/BKE_shrinkwrap.h [new file with mode: 0644]
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/bvhutils.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/icons.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/sca.c
source/blender/blenkernel/intern/shrinkwrap.c [new file with mode: 0644]
source/blender/blenlib/BLI_editVert.h
source/blender/blenlib/BLI_rand.h
source/blender/blenlib/BLI_winstuff.h
source/blender/blenlib/intern/BLI_ghash.c
source/blender/blenlib/intern/BLI_kdopbvh.c
source/blender/blenlib/intern/fileops.c
source/blender/blenlib/intern/psfont.c
source/blender/blenlib/intern/rand.c
source/blender/blenlib/intern/util.c
source/blender/blenloader/BLO_sys_types.h
source/blender/blenloader/intern/genfile.c
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/blenpluginapi/intern/pluginapi.c
source/blender/imbuf/intern/cineon/cineonlib.c
source/blender/imbuf/intern/cineon/dpxlib.c
source/blender/imbuf/intern/cineon/logImageCore.h
source/blender/imbuf/intern/cineon/logmemfile.c
source/blender/imbuf/intern/cineon/logmemfile.h
source/blender/imbuf/intern/scaling.c
source/blender/include/BDR_gpencil.h
source/blender/include/BIF_drawgpencil.h
source/blender/include/BIF_editarmature.h
source/blender/include/BIF_editview.h
source/blender/include/BIF_meshtools.h
source/blender/include/BIF_resources.h
source/blender/include/BSE_drawipo.h
source/blender/include/transform.h
source/blender/makesdna/DNA_actuator_types.h
source/blender/makesdna/DNA_gpencil_types.h
source/blender/makesdna/DNA_ipo_types.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/DNA_particle_types.h
source/blender/makesdna/DNA_sensor_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/python/api2_2x/Draw.c
source/blender/python/api2_2x/Material.c
source/blender/python/api2_2x/Mesh.c
source/blender/python/api2_2x/Object.c
source/blender/python/api2_2x/Particle.c
source/blender/python/api2_2x/Text3d.c
source/blender/python/api2_2x/doc/Material.py
source/blender/python/api2_2x/doc/Mathutils.py
source/blender/python/api2_2x/doc/Object.py
source/blender/python/api2_2x/doc/Text3d.py
source/blender/python/api2_2x/vector.c
source/blender/python/api2_2x/vector.h
source/blender/radiosity/CMakeLists.txt
source/blender/radiosity/SConscript
source/blender/radiosity/intern/source/Makefile
source/blender/radiosity/intern/source/radnode.c
source/blender/radiosity/intern/source/radpreprocess.c
source/blender/render/CMakeLists.txt
source/blender/render/SConscript
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/occlusion.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/strand.c
source/blender/render/intern/source/zbuf.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_logic.c
source/blender/src/buttons_object.c
source/blender/src/buttons_scene.c
source/blender/src/drawgpencil.c
source/blender/src/drawipo.c
source/blender/src/drawmesh.c
source/blender/src/drawobject.c
source/blender/src/editarmature.c
source/blender/src/editipo.c
source/blender/src/editipo_lib.c
source/blender/src/editkey.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c
source/blender/src/editnode.c
source/blender/src/editobject.c
source/blender/src/editview.c
source/blender/src/gpencil.c
source/blender/src/header_info.c
source/blender/src/header_script.c
source/blender/src/header_view3d.c
source/blender/src/interface.c
source/blender/src/meshlaplacian.c
source/blender/src/meshtools.c
source/blender/src/parametrizer.c
source/blender/src/parametrizer.h
source/blender/src/parametrizer_intern.h
source/blender/src/renderwin.c
source/blender/src/resources.c
source/blender/src/space.c
source/blender/src/toolbox.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/blender/src/transform_numinput.c
source/blender/src/usiblender.c
source/blender/yafray/intern/export_Plugin.cpp
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Converter/KX_ConvertSensors.cpp
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/GameLogic/SCA_DelaySensor.cpp [new file with mode: 0644]
source/gameengine/GameLogic/SCA_DelaySensor.h [new file with mode: 0644]
source/gameengine/GameLogic/SCA_IController.cpp
source/gameengine/GameLogic/SCA_ISensor.cpp
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
source/gameengine/GameLogic/SCA_LogicManager.cpp
source/gameengine/GameLogic/SCA_LogicManager.h
source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GameLogic/SCA_PythonController.h
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.h
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.h
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_ConstraintActuator.cpp
source/gameengine/Ketsji/KX_ConstraintActuator.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_IPO_SGController.cpp
source/gameengine/Ketsji/KX_MaterialIpoController.cpp
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_MeshProxy.h
source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
source/gameengine/Ketsji/KX_MouseFocusSensor.h
source/gameengine/Ketsji/KX_PolyProxy.cpp [new file with mode: 0644]
source/gameengine/Ketsji/KX_PolyProxy.h [new file with mode: 0644]
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_RayCast.cpp
source/gameengine/Ketsji/KX_RayCast.h
source/gameengine/Ketsji/KX_RaySensor.cpp
source/gameengine/Ketsji/KX_RaySensor.h
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/Ketsji/Makefile
source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp
source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
source/gameengine/Physics/Bullet/CMakeLists.txt
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/Bullet/Makefile
source/gameengine/Physics/Bullet/SConscript
source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_DynamicTypes.h
source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
source/gameengine/PyDoc/GameKeys.py
source/gameengine/PyDoc/GameLogic.py
source/gameengine/PyDoc/KX_GameObject.py
source/gameengine/PyDoc/KX_MeshProxy.py
source/gameengine/PyDoc/KX_PolyProxy.py [new file with mode: 0644]
source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
source/gameengine/PyDoc/SCA_DelaySensor.py [new file with mode: 0644]
source/gameengine/PyDoc/SCA_ISensor.py
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/kernel/CMakeLists.txt
source/kernel/SConscript
source/kernel/gen_system/GEN_HashedPtr.cpp
source/kernel/gen_system/Makefile
source/nan_definitions.mk

index 6b6837d25f0526667e29a74f7552f814335cdd95..e3dd46eb5ea11a8daf77ca045c7c98a0702db37a 100644 (file)
@@ -38,6 +38,8 @@ MACRO(BLENDERLIB
 ENDMACRO(BLENDERLIB)
 
 MACRO(SETUP_LIBDIRS)
+  # see "cmake --help-policy CMP0003"
+  CMAKE_POLICY(SET CMP0003 NEW)
   LINK_DIRECTORIES(${PYTHON_LIBPATH} ${SDL_LIBPATH} ${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${ICONV_LIBPATH} ${OPENEXR_LIBPATH} ${QUICKTIME_LIBPATH} ${FFMPEG_LIBPATH})
   IF(WITH_INTERNATIONAL)
     LINK_DIRECTORIES(${GETTEXT_LIBPATH})
index 0ea26750ec1c75aa03c40b02972b068cdbfaaeb0..5b86ca8f21e5a81e2f52d4f9ded2f9eb74a55bcb 100644 (file)
@@ -63,7 +63,6 @@ OPTION(WITH_QUICKTIME         "Enable Quicktime Support"                              OFF)
 OPTION(WITH_OPENEXR            "Enable OpenEXR Support (http://www.openexr.com)"       ON)
 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_OPENMP             "Enable OpenMP (has to be supported by the compiler)"   OFF)
 
 IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
index b49036a5b50322b12b27e726b9024ebb0241d3b7..7dc7d8d2f68e1483707fa1e278983e24eb87d2ab 100644 (file)
@@ -181,7 +181,9 @@ void        btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
                                          btCollisionObject* collisionObject,
                                          const btCollisionShape* collisionShape,
                                          const btTransform& colObjWorldTransform,
-                                         RayResultCallback& resultCallback,short int collisionFilterMask)
+                                         RayResultCallback& resultCallback,
+                                         short int collisionFilterMask,
+                                         bool faceNormal)
 {
        
        btSphereShape pointShape(btScalar(0.0));
@@ -191,14 +193,16 @@ void      btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
                                          collisionObject,
                                          collisionShape,
                                          colObjWorldTransform,
-                                         resultCallback,collisionFilterMask);
+                                         resultCallback,collisionFilterMask,faceNormal);
 }
 
 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)
+                                         RayResultCallback& resultCallback,
+                                         short int collisionFilterMask,
+                                         bool faceNormal)
 {
        
 
@@ -257,9 +261,9 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                        btCollisionObject*      m_collisionObject;
                                                        btTriangleMeshShape*    m_triangleMesh;
 
-                                                       BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
-                                                               btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*    triangleMesh):
-                                                               btTriangleRaycastCallback(from,to),
+                                                       BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,bool faceNormal,
+                                                               btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
+                                                               btTriangleRaycastCallback(from,to,faceNormal),
                                                                        m_resultCallback(resultCallback),
                                                                        m_collisionObject(collisionObject),
                                                                        m_triangleMesh(triangleMesh)
@@ -272,6 +276,7 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                                btCollisionWorld::LocalShapeInfo        shapeInfo;
                                                                shapeInfo.m_shapePart = partId;
                                                                shapeInfo.m_triangleIndex = triangleIndex;
+                                                               shapeInfo.m_triangleShape = m_triangleMesh;
                                                                
                                                                btCollisionWorld::LocalRayResult rayResult
                                                                (m_collisionObject, 
@@ -287,7 +292,7 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                };
 
 
-                                               BridgeTriangleRaycastCallback   rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
+                                               BridgeTriangleRaycastCallback   rcb(rayFromLocal,rayToLocal,faceNormal,&resultCallback,collisionObject,triangleMesh);
                                                rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 
                                                btVector3 rayAabbMinLocal = rayFromLocal;
@@ -313,7 +318,7 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                                                                        collisionObject,
                                                                        childCollisionShape,
                                                                        childWorldTrans,
-                                                                       resultCallback, collisionFilterMask);
+                                                                       resultCallback, collisionFilterMask, faceNormal);
 
                                                        }
 
@@ -323,7 +328,7 @@ void        btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
                        }
 }
 
-void   btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask)
+void   btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask, bool faceNormal)
 {
 
        
@@ -350,11 +355,17 @@ void      btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& r
                        btVector3 hitNormal;
                        if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
                        {
-                               rayTestSingle(rayFromTrans,rayToTrans,
-                                       collisionObject,
-                                               collisionObject->getCollisionShape(),
-                                               collisionObject->getWorldTransform(),
-                                               resultCallback);
+                               // before testing this object, verify that it is not filtered out
+                               if (resultCallback.NeedRayCast(collisionObject))
+                               {
+                                       rayTestSingle(rayFromTrans,rayToTrans,
+                                               collisionObject,
+                                                       collisionObject->getCollisionShape(),
+                                                       collisionObject->getWorldTransform(),
+                                                       resultCallback,
+                                                       collisionFilterMask,
+                                                       faceNormal);
+                               }
                        }       
                }
        }
index b6d80233ab7acbd927774aed8dc188e5e90f5e92..ed41232ece3fe091158e658bcb55ff2c5f9629ac 100644 (file)
@@ -125,8 +125,8 @@ public:
        {
                int     m_shapePart;
                int     m_triangleIndex;
-               
-               //const btCollisionShape*       m_shapeTemp;
+               // needed in case of compound shape
+               const btCollisionShape* m_triangleShape;
                //const btTransform*    m_shapeLocalTransform;
        };
 
@@ -166,6 +166,10 @@ public:
                        :m_closestHitFraction(btScalar(1.))
                {
                }
+               virtual bool        NeedRayCast(btCollisionObject* object)
+               {
+                       return true;
+               }
                virtual btScalar        AddSingleResult(LocalRayResult& rayResult) = 0;
        };
 
@@ -209,7 +213,7 @@ public:
 
        /// 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);
+       void    rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1, bool faceNormal=false);
 
        /// 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.
@@ -218,14 +222,18 @@ public:
                                          btCollisionObject* collisionObject,
                                          const btCollisionShape* collisionShape,
                                          const btTransform& colObjWorldTransform,
-                                         RayResultCallback& resultCallback, short int collisionFilterMask=-1);
+                                         RayResultCallback& resultCallback, 
+                                         short int collisionFilterMask=-1,
+                                         bool faceNormal=false);
 
        /// 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);
+                                         RayResultCallback& resultCallback, 
+                                         short int collisionFilterMask=-1,
+                                         bool faceNormal=false);
 
        void    addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1);
 
index 31b914677777ed643da4ff85a41f93080b2c4c52..68ac93ec3cca5e204550ab344441927ac5e63508 100644 (file)
@@ -16,10 +16,11 @@ subject to the following restrictions:
 
 #include "btRaycastCallback.h"
 
-btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to)
+btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to,bool faceNormal)
        :
        m_from(from),
        m_to(to),
+       m_faceNormal(faceNormal),
        m_hitFraction(btScalar(1.))
 {
 
@@ -84,8 +85,7 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId,
                                        
                                        if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) 
                                        {
-
-                                               if ( dist_a > 0 )
+                                               if (m_faceNormal || dist_a > 0)
                                                {
                                                        m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);
                                                }
index a0bbc9f8fe95f45f7dc128a8f14d7f88e9fc7675..71ed9fead49fd3c3cd1a2da849b5d31f80ab4f53 100644 (file)
@@ -27,10 +27,11 @@ public:
                //input
        btVector3 m_from;
        btVector3 m_to;
+       bool m_faceNormal;
 
        btScalar        m_hitFraction;
 
-       btTriangleRaycastCallback(const btVector3& from,const btVector3& to);
+       btTriangleRaycastCallback(const btVector3& from,const btVector3& to,bool faceNormal);
        
        virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
 
index 29719ec9a3ec3becfc9d39d3aaf966f435913df3..1017c8af6eafb5f47360e954886d0e6d413cc00d 100644 (file)
@@ -856,10 +856,26 @@ 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);
+                               // insert here Bullet 2.69 that fixes representation of cone
+                               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);
+
+                               // buggy code that does not take into account the direction of the cone
+                               //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;
 
                        }
diff --git a/intern/guardedalloc/BLO_sys_types.h b/intern/guardedalloc/BLO_sys_types.h
new file mode 100644 (file)
index 0000000..5ed3117
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+ * $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 *****
+ * A platform-independent definition of [u]intXX_t
+ * Plus the accompanying header include for htonl/ntohl
+ *
+ * This file includes <sys/types.h> to define [u]intXX_t types, where
+ * XX can be 8, 16, 32 or 64. Unfortunately, not all systems have this
+ * file.
+ * - Windows uses __intXX compiler-builtin types. These are signed,
+ *   so we have to flip the signs.
+ * For these rogue platforms, we make the typedefs ourselves.
+ *
+ */
+
+/* 
+// DG: original BLO_sys_types.h is in source/blender/blenkernel 
+// but is not allowed be accessed here because of bad-level-call
+*/
+
+#ifndef BLO_SYS_TYPES_H
+#define BLO_SYS_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if defined(_WIN32) && !defined(FREE_WINDOWS)
+
+/* The __intXX are built-in types of the visual complier! So we don't
+ * need to include anything else here. */
+
+typedef signed __int8  int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+typedef signed __int64 int64_t;
+
+typedef unsigned __int8  uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#ifndef _INTPTR_T_DEFINED
+#ifdef _WIN64
+typedef __int64 intptr_t;
+#else
+typedef long intptr_t;
+#endif
+#define _INTPTR_T_DEFINED
+#endif
+
+#ifndef _UINTPTR_T_DEFINED
+#ifdef _WIN64
+typedef unsigned __int64 uintptr_t;
+#else
+typedef unsigned long uintptr_t;
+#endif
+#define _UINTPTR_T_DEFINED
+#endif
+
+#elif defined(__linux__)
+
+       /* Linux-i386, Linux-Alpha, Linux-ppc */
+#include <stdint.h>
+
+#elif defined (__APPLE__)
+
+#include <inttypes.h>
+
+#elif defined(FREE_WINDOWS)
+
+#include <stdint.h>
+
+#else
+
+       /* FreeBSD, Irix, Solaris */
+#include <sys/types.h>
+
+#endif /* ifdef platform for types */
+
+#ifdef _WIN32
+#ifndef htonl
+#define htonl(x) correctByteOrder(x)
+#endif
+#ifndef ntohl
+#define ntohl(x) correctByteOrder(x)
+#endif
+#elif defined (__FreeBSD__) || defined (__OpenBSD__) 
+#include <sys/param.h>
+#elif defined (__APPLE__)
+#include <sys/types.h>
+#else  /* irix sun linux */
+#include <netinet/in.h>
+#endif /* ifdef platform for htonl/ntohl */
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif /* eof */
+
index 25f2fd8d26903ef1d7c78bf23eb0a49d865f47de..a36549d0cc75eb779c61f025d4e78d46f7a89ee2 100644 (file)
@@ -49,6 +49,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLO_sys_types.h" // needed for intptr_t
+
 /* --------------------------------------------------------------------- */
 /* Data definition                                                       */
 /* --------------------------------------------------------------------- */
@@ -112,7 +114,7 @@ static const char *check_memlist(MemHead *memh);
        
 
 volatile int totblock= 0;
-volatile unsigned long mem_in_use= 0, mmap_in_use= 0;
+volatile uintptr_t mem_in_use= 0, mmap_in_use= 0;
 
 static volatile struct localListBase _membase;
 static volatile struct localListBase *membase = &_membase;
@@ -335,7 +337,7 @@ void *MEM_mapallocN(unsigned int len, const char *str)
 /* Memory statistics print */
 typedef struct MemPrintBlock {
        const char *name;
-       unsigned long len;
+       uintptr_t len;
        int items;
 } MemPrintBlock;
 
@@ -485,14 +487,14 @@ short MEM_freeN(void *vmemh)              /* anders compileertie niet meer */
                return(-1);
        }
 
-       if(sizeof(long)==8) {
-               if (((long) memh) & 0x7) {
+       if(sizeof(intptr_t)==8) {
+               if (((intptr_t) memh) & 0x7) {
                        MemorY_ErroR("free","attempt to free illegal pointer");
                        return(-1);
                }
        }
        else {
-               if (((long) memh) & 0x3) {
+               if (((intptr_t) memh) & 0x3) {
                        MemorY_ErroR("free","attempt to free illegal pointer");
                        return(-1);
                }
index 436c99344a7c97de8f03216eb4ff943df0c34503..642cc16296ef147e2dbd43638cc034f87bb575b0 100644 (file)
@@ -151,7 +151,7 @@ void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset)
 }
 
 /* munmap for windows */
-long munmap(void *ptr, long size)
+intptr_t munmap(void *ptr, intptr_t size)
 {
        MemMap *mm = mmap_findlink(mmapbase, ptr);
        if (!mm) {
index 40e88511d5dbf95d06bfdc3aa68df8d98aabb00e..974acef4e7058ee98cd500e723c79c17f10c4fca 100644 (file)
@@ -261,6 +261,9 @@ ECHO Done
                        <Filter
                                Name="extern"
                                Filter="">
+                               <File
+                                       RelativePath="..\..\BLO_sys_types.h">
+                               </File>
                                <File
                                        RelativePath="..\..\MEM_guardedalloc.h">
                                </File>
index f83a2d64b18b775f33f0d188f58e87b800cc5f69..443c3b6f4ceb69eebfe527cc927079a61547a06a 100644 (file)
 
 #define MAP_FAILED ((void *)-1)
 
+#include "BLO_sys_types.h" // needed for intptr_t
+
 void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset);
-long munmap(void *ptr, long size);
+intptr_t munmap(void *ptr, intptr_t size);
 
 #endif
 
index ec999b0c25234638d0620485caeea8e184e03ee7..d302a2508aba81537fe1678221883f969bc8242b 100644 (file)
@@ -715,6 +715,9 @@ ECHO Done
                        <Filter
                                Name="superlu"
                                Filter="">
+                               <File
+                                       RelativePath="..\..\superlu\BLO_sys_types.h">
+                               </File>
                                <File
                                        RelativePath="..\..\superlu\Cnames.h">
                                </File>
diff --git a/intern/opennl/superlu/BLO_sys_types.h b/intern/opennl/superlu/BLO_sys_types.h
new file mode 100644 (file)
index 0000000..5ed3117
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+ * $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 *****
+ * A platform-independent definition of [u]intXX_t
+ * Plus the accompanying header include for htonl/ntohl
+ *
+ * This file includes <sys/types.h> to define [u]intXX_t types, where
+ * XX can be 8, 16, 32 or 64. Unfortunately, not all systems have this
+ * file.
+ * - Windows uses __intXX compiler-builtin types. These are signed,
+ *   so we have to flip the signs.
+ * For these rogue platforms, we make the typedefs ourselves.
+ *
+ */
+
+/* 
+// DG: original BLO_sys_types.h is in source/blender/blenkernel 
+// but is not allowed be accessed here because of bad-level-call
+*/
+
+#ifndef BLO_SYS_TYPES_H
+#define BLO_SYS_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if defined(_WIN32) && !defined(FREE_WINDOWS)
+
+/* The __intXX are built-in types of the visual complier! So we don't
+ * need to include anything else here. */
+
+typedef signed __int8  int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+typedef signed __int64 int64_t;
+
+typedef unsigned __int8  uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#ifndef _INTPTR_T_DEFINED
+#ifdef _WIN64
+typedef __int64 intptr_t;
+#else
+typedef long intptr_t;
+#endif
+#define _INTPTR_T_DEFINED
+#endif
+
+#ifndef _UINTPTR_T_DEFINED
+#ifdef _WIN64
+typedef unsigned __int64 uintptr_t;
+#else
+typedef unsigned long uintptr_t;
+#endif
+#define _UINTPTR_T_DEFINED
+#endif
+
+#elif defined(__linux__)
+
+       /* Linux-i386, Linux-Alpha, Linux-ppc */
+#include <stdint.h>
+
+#elif defined (__APPLE__)
+
+#include <inttypes.h>
+
+#elif defined(FREE_WINDOWS)
+
+#include <stdint.h>
+
+#else
+
+       /* FreeBSD, Irix, Solaris */
+#include <sys/types.h>
+
+#endif /* ifdef platform for types */
+
+#ifdef _WIN32
+#ifndef htonl
+#define htonl(x) correctByteOrder(x)
+#endif
+#ifndef ntohl
+#define ntohl(x) correctByteOrder(x)
+#endif
+#elif defined (__FreeBSD__) || defined (__OpenBSD__) 
+#include <sys/param.h>
+#elif defined (__APPLE__)
+#include <sys/types.h>
+#else  /* irix sun linux */
+#include <netinet/in.h>
+#endif /* ifdef platform for htonl/ntohl */
+
+#ifdef __cplusplus 
+}
+#endif
+
+#endif /* eof */
+
index 79da748671a6f8184bcc75ad4a149fe2b8756198..7eefb9006730b9d68e446277c81fa0a4d5db9099 100644 (file)
@@ -8,6 +8,8 @@
  */
 #include "ssp_defs.h"
 
+#include "BLO_sys_types.h" // needed for intptr_t
+
 /* Constants */
 #define NO_MEMTYPE  4      /* 0: lusup;
                              1: ucol;
@@ -49,8 +51,8 @@ static int no_expand;
 
 /* Macros to manipulate stack */
 #define StackFull(x)         ( x + stack.used >= stack.size )
-#define NotDoubleAlign(addr) ( (long int)addr & 7 )
-#define DoubleAlign(addr)    ( ((long int)addr + 7) & ~7L )
+#define NotDoubleAlign(addr) ( (intptr_t)addr & 7 )
+#define DoubleAlign(addr)    ( ((intptr_t)addr + 7) & ~7L )
 #define TempSpace(m, w)      ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \
                              (w + 1) * m * sizeof(float) )
 #define Reduce(alpha)        ((alpha + 1) / 2)  /* i.e. (alpha-1)/2 + 1 */
@@ -611,8 +613,8 @@ sStackCompress(GlobalLU_t *Glu)
     
     last = (char*)usub + xusub[ndim] * iword;
     fragment = (char*) (((char*)stack.array + stack.top1) - last);
-    stack.used -= (long int) fragment;
-    stack.top1 -= (long int) fragment;
+    stack.used -= (intptr_t) fragment;
+    stack.top1 -= (intptr_t) fragment;
 
     Glu->ucol = ucol;
     Glu->lsub = lsub;
index 0ea3503a289f2cd6a2ac849dd40b91dea88faf81..42dcc843091592263c3db2e00ec4e6974d388159 100644 (file)
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\intern\script.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\blenkernel\intern\shrinkwrap.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\intern\softbody.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\BKE_script.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\blenkernel\BKE_shrinkwrap.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\blenkernel\BKE_softbody.h">
                        </File>
index 7e2db4f564fbd99f9abfa38a84ad80f83a0c026f..5f14b5a09a1c0108ed6b8f881a5869b64cd8baa2 100644 (file)
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ANDController.cpp">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_DelaySensor.cpp">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_EventManager.cpp">
                        </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ANDController.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_DelaySensor.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_EventManager.h">
                        </File>
index c046d434cb34c14a93134a7e54ad05f1dfb8fad8..4e362faed69edcf3631ec2314e1a80dd92b07fb6 100644 (file)
                        <File
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_PolygonMaterial.cpp">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\Ketsji\KX_PolyProxy.cpp">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_PyConstraintBinding.cpp">
                        </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_PolygonMaterial.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\Ketsji\KX_PolyProxy.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\Ketsji\KX_PyConstraintBinding.h">
                        </File>
index 9a807f2d39a692558ae7de61fed8a296a7b8e64a..76fde7612e3e6b964b8398a90df180a7c387be66 100644 (file)
@@ -19,7 +19,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\gameengine\Rasterizer"
                                PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
                                MinimalRebuild="FALSE"
                                BasicRuntimeChecks="3"
@@ -64,7 +64,7 @@
                        CharacterSet="2">
                        <Tool
                                Name="VCCLCompilerTool"
-                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\gameengine\Rasterizer"
                                PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
                                RuntimeLibrary="0"
                                UsePrecompiledHeader="2"
                        CharacterSet="2">
                        <Tool
                                Name="VCCLCompilerTool"
-                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\gameengine\Rasterizer"
                                PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
                                RuntimeLibrary="0"
                                UsePrecompiledHeader="2"
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet"
+                               AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\kernel\gen_system"
                                PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
                                MinimalRebuild="FALSE"
                                BasicRuntimeChecks="3"
index 50ffc1fbb99d3d308e8ad28a21afc11d2b31104c..3b239d9088b1c519d117b753161ffff1d6518188 100644 (file)
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include"
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include"
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include"
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include"
+                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include"
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
index 2e24a0f92efa83f99c714f424141305b17d43074..46b935c7fd6bfe43bcf5ee681d286e1a4be5cca2 100644 (file)
@@ -35,7 +35,7 @@ int main(int argc, char**argv) {
        FILE *fpin,  *fpout;
        char cname[256];
        char sizest[256];
-       long size;
+       size_t size;
        int i;
        
        if (argc<1) {
diff --git a/release/scripts/flt_dofedit.py b/release/scripts/flt_dofedit.py
new file mode 100644 (file)
index 0000000..36e8e4d
--- /dev/null
@@ -0,0 +1,835 @@
+#!BPY
+
+"""
+Name: 'FLT DOF Editor'
+Blender: 240
+Group: 'Misc'
+Tooltip: 'Degree of Freedom editor for FLT nodes'
+"""
+
+__author__ = "Geoffrey Bantle"
+__version__ = "1.0 11/21/07"
+__email__ = ('scripts', 'Author, ')
+__url__ = ('blender', 'blenderartists.org')
+
+__bpydoc__ ="""\
+This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a
+registered trademark of MultiGen-Paradigm, Inc.
+
+Feature overview and more availible at:
+http://wiki.blender.org/index.php/Scripts/Manual/FLTools
+"""
+
+# --------------------------------------------------------------------------
+# flt_palettemanager.py version 0.1 2005/04/08
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Copyright (C) 2007: Blender Foundation
+#
+# 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 *****
+# --------------------------------------------------------------------------
+
+import Blender.Draw as Draw
+from Blender.BGL import *
+import Blender
+import flt_properties
+reload(flt_properties)
+from flt_properties import *
+
+#event codes
+evcode = {
+       "DOF_MAKE" : 100,
+       "DOF_UPDATE" : 138,
+       "DOF_DELETE" : 101,
+       "DOF_TRANSX" : 102,
+       "DOF_TRANSY" : 103,
+       "DOF_TRANSZ" : 104,
+       "DOF_ROTX" : 105,
+       "DOF_ROTY" : 106,
+       "DOF_ROTZ" : 107,
+       "DOF_SCALEX" : 108,
+       "DOF_SCALEY" : 109,
+       "DOF_SCALEZ" : 110,
+       "DOF_MIN_TRANSX" : 111,
+       "DOF_MIN_TRANSY" : 112,
+       "DOF_MIN_TRANSZ" : 113,
+       "DOF_MIN_ROTX" : 114,
+       "DOF_MIN_ROTY" : 115,
+       "DOF_MIN_ROTZ" : 116,
+       "DOF_MIN_SCALEX" : 117,
+       "DOF_MIN_SCALEY" : 118,
+       "DOF_MIN_SCALEZ" : 119,
+       "DOF_MAX_TRANSX" : 120,
+       "DOF_MAX_TRANSY" : 121,
+       "DOF_MAX_TRANSZ" : 122,
+       "DOF_MAX_ROTX" : 123,
+       "DOF_MAX_ROTY" : 124,
+       "DOF_MAX_ROTZ" : 125,
+       "DOF_MAX_SCALEX" : 126,
+       "DOF_MAX_SCALEY" : 127,
+       "DOF_MAX_SCALEZ" : 128,
+       "DOF_STEP_TRANSX" : 129,
+       "DOF_STEP_TRANSY" : 130,
+       "DOF_STEP_TRANSZ" : 131,
+       "DOF_STEP_ROTX" : 132,
+       "DOF_STEP_ROTY" : 133,
+       "DOF_STEP_ROTZ" : 134,
+       "DOF_STEP_SCALEX" : 135,
+       "DOF_STEP_SCALEY" : 136,
+       "DOF_STEP_SCALEZ" : 137
+}
+
+#system
+DOF_MAKE = None
+DOF_UPDATE = None
+DOF_DELETE = None
+
+#toggle buttons
+DOF_TRANSX = None
+DOF_TRANSY = None
+DOF_TRANSZ = None
+DOF_ROTX = None
+DOF_ROTY = None
+DOF_ROTZ = None
+DOF_SCALEX = None
+DOF_SCALEY = None
+DOF_SCALEZ = None
+
+#Minimums
+DOF_MIN_TRANSX = None
+DOF_MIN_TRANSY = None
+DOF_MIN_TRANSZ = None
+DOF_MIN_ROTX = None
+DOF_MIN_ROTY = None
+DOF_MIN_ROTZ = None
+DOF_MIN_SCALEX = None
+DOF_MIN_SCALEY = None
+DOF_MIN_SCALEZ = None
+
+#maximums
+DOF_MAX_TRANSX = None
+DOF_MAX_TRANSY = None
+DOF_MAX_TRANSZ = None
+DOF_MAX_ROTX = None
+DOF_MAX_ROTY = None
+DOF_MAX_ROTZ = None
+DOF_MAX_SCALEX = None
+DOF_MAX_SCALEY = None
+DOF_MAX_SCALEZ = None
+
+#step
+DOF_STEP_TRANSX = None
+DOF_STEP_TRANSY = None
+DOF_STEP_TRANSZ = None
+DOF_STEP_ROTX = None
+DOF_STEP_ROTY = None
+DOF_STEP_ROTZ = None
+DOF_STEP_SCALEX = None
+DOF_STEP_SCALEY = None
+DOF_STEP_SCALEZ = None
+
+#labels
+DOF_ROTSTRING = None
+DOF_TRANSTRING = None
+DOF_SCALESTRING = None
+DOF_EDITLABEL = None
+
+#make ID props easier/morereadable
+zmin = '14d!ZMIN'
+zmax = '15d!ZMAX'
+zcur = '16d!ZCUR'
+zstep = '17d!ZSTEP'
+ymin = '18d!YMIN'
+ymax = '19d!YMAX'
+ycur = '20d!YCUR'
+ystep = '21d!YSTEP'
+xmin = '22d!XMIN'
+xmax = '23d!XMAX'
+xcur = '24d!XCUR'
+xstep = '25d!XSTEP'
+pitchmin = '26d!PITCH-MIN'
+pitchmax = '27d!PITCH-MAX'
+pitchcur = '28d!PITCH-CUR'
+pitchstep = '29d!PITCH-STEP'
+rollmin = '30d!ROLL-MIN'
+rollmax = '31d!ROLL-MAX'
+rollcur = '32d!ROLL-CUR'
+rollstep = '33d!ROLL-STEP'
+yawmin = '34d!YAW-MIN'
+yawmax = '35d!YAW-MAX'
+yawcur = '36d!YAW-CUR'
+yawstep = '37d!YAW-STEP'
+zscalemin = '38d!ZSIZE-MIN'
+zscalemax = '39d!ZSIZE-MAX'
+zscalecur = '40d!ZSIZE-CUR'
+zscalestep = '41d!ZSIZE-STEP'
+yscalemin = '42d!YSIZE-MIN'
+yscalemax = '43d!YSIZE-MAX'
+yscalecur = '44d!YSIZE-CUR'
+yscalestep = '45d!YSIZE-STEP'
+xscalemin = '46d!XSIZE-MIN'
+xscalemax = '47d!XSIZE-MAX'
+xscalecur = '48d!XSIZE-CUR'
+xscalestep = '49d!XSIZE-STEP'
+
+
+
+def update_state():
+       state = dict()
+       state["activeScene"] = Blender.Scene.GetCurrent()
+       state["activeObject"] = state["activeScene"].objects.active
+       if state["activeObject"] and not state["activeObject"].sel:
+               state["activeObject"] = None
+       state["activeMesh"] = None
+       if state["activeObject"] and state["activeObject"].type == 'Mesh':
+               state["activeMesh"] = state["activeObject"].getData(mesh=True)
+       
+
+       state["activeFace"] = None
+       if state["activeMesh"]:
+               if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
+                       state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
+               
+               
+       #update editmode
+       state["editmode"]       = Blender.Window.EditMode()
+
+       return state
+       
+def idprops_append(object, typecode, props):
+       object.properties["FLT"] = dict()
+       object.properties["FLT"]['type'] = typecode 
+       for prop in props:
+               object.properties["FLT"][prop] = props[prop]
+       object.properties["FLT"]['3t8!id'] = object.name
+
+def idprops_kill():
+       state = update_state()
+       if state["activeObject"] and state["activeObject"].properties.has_key('FLT'):
+               state["activeObject"].properties.pop('FLT')
+
+def idprops_copy(source):
+       state = update_state()
+       if source.properties.has_key('FLT'):
+               for object in state["activeScene"].objects:
+                       if object.sel and object != source and (state["activeScene"].Layers & object.Layers):
+                               idprops_kill(object)
+                               object.properties['FLT'] = dict()
+                               for key in source.properties['FLT']:
+                                       object.properties['FLT'][key] = source.properties['FLT'][key]
+
+def select_by_typecode(typecode):
+       state = update_state()
+       
+       for object in state["activeScene"].objects:
+               if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers:
+                               object.select(1)
+
+def DOF_get_frame():
+       state = update_state()
+       
+       if not state["activeObject"] and not id_props_type(state["activeObject"], 14):
+               return
+       
+       #Warning! assumes 1 BU == 10 meters.
+       #do origin
+       state["activeObject"].properties['FLT']['5d!ORIGX'] = state["activeObject"].getLocation('worldspace')[0]*10.0
+       state["activeObject"].properties['FLT']['6d!ORIGY'] = state["activeObject"].getLocation('worldspace')[1]*10.0
+       state["activeObject"].properties['FLT']['7d!ORIGZ'] = state["activeObject"].getLocation('worldspace')[2]*10.0
+       #do X axis
+       x = Blender.Mathutils.Vector(1.0,0.0,0.0)
+       x = x * state["activeObject"].getMatrix('worldspace')
+       x = x * 10.0
+       state["activeObject"].properties['FLT']['8d!XAXIS-X'] = x[0]
+       state["activeObject"].properties['FLT']['9d!XAXIS-Y'] = x[1]
+       state["activeObject"].properties['FLT']['10d!XAXIS-Z'] = x[2]
+       #do X/Y plane
+       x = Blender.Mathutils.Vector(0.0,1.0,0.0)
+       x.normalize()
+       x = x * state["activeObject"].getMatrix('worldspace')
+       x = x * 10.0
+       state["activeObject"].properties['FLT']['11d!XYPLANE-X'] = x[0]
+       state["activeObject"].properties['FLT']['12d!XYPLANE-Y'] = x[1]
+       state["activeObject"].properties['FLT']['13d!XZPLANE-Z'] = x[2]
+
+def idprops_type(object, typecode):
+       if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode:
+               return True
+       return False
+
+#ui type code
+def get_prop(typecode, prop):
+       
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], typecode):
+               props = state["activeObject"].properties['FLT']
+       else:
+               props =  flt_properties.FLTDOF
+               
+       return props[prop]      
+
+def set_prop(typecode, prop, value):
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"],typecode):
+               state["activeObject"].properties['FLT'][prop] = value           
+
+lockxtrans = (1 << 31)
+lockytrans = (1 << 30)
+lockztrans = (1 << 29)
+lockxrot = (1 << 28)
+lockyrot = (1 << 27)
+lockzrot = (1 << 26)
+lockxscale = (1 << 25)
+lockyscale = (1 << 24)
+lockzscale = (1 << 23)
+
+def get_lockmask(mask):        
+       state = update_state()
+       if state["activeObject"]:
+               flag = get_prop(14,'50I!FLAG')
+               if flag & mask:
+                       return True
+       return False    
+
+def set_lockmask(mask):
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], 14):
+               oldvalue = state["activeObject"].properties['FLT']['50I!FLAG']
+               oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
+               oldvalue |= mask
+               state["activeObject"].properties['FLT']['50I!FLAG'] = struct.unpack('>i', struct.pack(">I", oldvalue))[0]
+
+def clear_lockmask(mask):
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], 14):
+               oldvalue = state["activeObject"].properties['FLT']['50I!FLAG']
+               oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
+               oldvalue &= ~mask
+               state["activeObject"].properties['FLT']['50I!FLAG'] = struct.unpack('>i',struct.pack('>I',oldvalue))[0] 
+
+       
+def create_dof():
+       state = update_state()
+       actobj = state["activeObject"]
+       if actobj and not idprops_type(actobj, 14):
+               idprops_kill()
+               idprops_append(actobj,14, flt_properties.FLTDOF)
+               DOF_get_frame()
+       
+               
+def event(evt,val):
+       if evt == Draw.ESCKEY:
+               Draw.Exit()
+               
+def but_event(evt):
+       global DOF_MAKE
+       global DOF_UPDATE
+       global DOF_DELETE
+
+       global DOF_TRANSX
+       global DOF_TRANSY
+       global DOF_TRANSZ
+       global DOF_ROTX
+       global DOF_ROTY
+       global DOF_ROTZ
+       global DOF_SCALEX
+       global DOF_SCALEY
+       global DOF_SCALEZ
+
+       global DOF_MIN_TRANSX
+       global DOF_MIN_TRANSY
+       global DOF_MIN_TRANSZ
+       global DOF_MIN_ROTX
+       global DOF_MIN_ROTY
+       global DOF_MIN_ROTZ
+       global DOF_MIN_SCALEX
+       global DOF_MIN_SCALEY
+       global DOF_MIN_SCALEZ
+
+       global DOF_MAX_TRANSX
+       global DOF_MAX_TRANSY
+       global DOF_MAX_TRANSZ
+       global DOF_MAX_ROTX
+       global DOF_MAX_ROTY
+       global DOF_MAX_ROTZ
+       global DOF_MAX_SCALEX
+       global DOF_MAX_SCALEY
+       global DOF_MAX_SCALEZ
+
+       global DOF_STEP_TRANSX
+       global DOF_STEP_TRANSY
+       global DOF_STEP_TRANSZ
+       global DOF_STEP_ROTX
+       global DOF_STEP_ROTY
+       global DOF_STEP_ROTZ
+       global DOF_STEP_SCALEX
+       global DOF_STEP_SCALEY
+       global DOF_STEP_SCALEZ
+       
+       #labels
+       global DOF_ROTSTRING
+       global DOF_TRANSTRING
+       global DOF_SCALESTRING
+       
+       
+       #masks
+       global lockxtrans
+       global lockytrans
+       global lockztrans
+       global lockxrot
+       global lockyrot
+       global lockzrot
+       global lockxscale
+       global lockyscale
+       global lockzscale
+
+       global zmin
+       global zmax
+       global zcur
+       global zstep
+       global ymin
+       global ymax
+       global ycur
+       global ystep
+       global xmin
+       global xmax
+       global xcur
+       global xstep
+       global pitchmin
+       global pitchmax
+       global pitchcur
+       global pitchstep
+       global rollmin
+       global rollmax
+       global rollcur
+       global rollstep
+       global yawmin
+       global yawmax
+       global yawcur
+       global yawstep
+       global zscalemin
+       global zscalemax
+       global zscalecur
+       global zscalestep
+       global yscalemin
+       global yscalemax
+       global yscalecur
+       global yscalestep
+       global xscalemin
+       global xscalemax
+       global xscalecur
+       global xscalestep       
+
+       
+       
+       #do "system" events
+       if evt == evcode["DOF_MAKE"]:
+               create_dof()
+
+       if evt == evcode["DOF_UPDATE"]:
+               DOF_get_frame()
+       
+       if evt == evcode["DOF_DELETE"]:
+               idprops_kill()
+       #do translation lock events
+       if evt == evcode["DOF_TRANSX"]:
+               if DOF_TRANSX.val == True:
+                       set_lockmask(lockxtrans)
+               else:
+                       clear_lockmask(lockxtrans)
+
+       if evt == evcode["DOF_TRANSY"]:
+               if DOF_TRANSY.val == True:
+                       set_lockmask(lockytrans)
+               else:
+                       clear_lockmask(lockytrans)
+
+       if evt == evcode["DOF_TRANSZ"]:
+               if DOF_TRANSZ.val == True:
+                       set_lockmask(lockztrans)
+               else:
+                       clear_lockmask(lockztrans)
+
+
+       #do rotation lock events
+       if evt == evcode["DOF_ROTX"]:
+               if DOF_ROTX.val == True:
+                       set_lockmask(lockxrot)
+               else:
+                       clear_lockmask(lockxrot)
+
+       if evt == evcode["DOF_ROTY"]:
+               if DOF_ROTY.val == True:
+                       set_lockmask(lockyrot)
+               else:
+                       clear_lockmask(lockyrot)
+
+       if evt == evcode["DOF_ROTZ"]:
+               if DOF_ROTZ.val == True:
+                       set_lockmask(lockzrot)
+               else:
+                       clear_lockmask(lockzrot)
+
+       #do scale lock events
+       if evt == evcode["DOF_SCALEX"]:
+               if DOF_SCALEX.val == True:
+                       set_lockmask(lockxscale)
+               else:
+                       clear_lockmask(lockxscale)
+
+       if evt == evcode["DOF_SCALEY"]:
+               if DOF_SCALEY.val == True:
+                       set_lockmask(lockyscale)
+               else:
+                       clear_lockmask(lockyscale)
+
+       if evt == evcode["DOF_SCALEZ"]:
+               if DOF_SCALEZ.val == True:
+                       set_lockmask(lockzscale)
+               else:
+                       clear_lockmask(lockzscale)
+                       
+       
+       #do translation buttons
+       if evt == evcode["DOF_MIN_TRANSX"]:
+               set_prop(14, xmin, DOF_MIN_TRANSX.val)
+       if evt == evcode["DOF_MAX_TRANSX"]:
+               set_prop(14,xmax, DOF_MAX_TRANSX.val)
+       if evt == evcode["DOF_STEP_TRANSX"]:
+               set_prop(14,xstep, DOF_STEP_TRANSX.val)
+               
+       if evt == evcode["DOF_MIN_TRANSY"]:
+               set_prop(14, ymin, DOF_MIN_TRANSY.val)
+       if evt == evcode["DOF_MAX_TRANSY"]:
+               set_prop(14,ymax, DOF_MAX_TRANSY.val)
+       if evt == evcode["DOF_STEP_TRANSY"]:
+               set_prop(14,ystep, DOF_STEP_TRANSY.val)
+               
+       if evt == evcode["DOF_MIN_TRANSZ"]:
+               set_prop(14, zmin, DOF_MIN_TRANSZ.val)
+       if evt == evcode["DOF_MAX_TRANSZ"]:
+               set_prop(14, zmax, DOF_MAX_TRANSZ.val)
+       if evt == evcode["DOF_STEP_TRANSZ"]:
+               set_prop(14, zstep, DOF_STEP_TRANSZ.val)
+
+       #do rotation buttons
+       if evt == evcode["DOF_MIN_ROTX"]:
+               set_prop(14, pitchmin, DOF_MIN_ROTX.val)
+       if evt == evcode["DOF_MAX_ROTX"]:
+               set_prop(14, pitchmax, DOF_MAX_ROTX.val)
+       if evt == evcode["DOF_STEP_ROTX"]:
+               set_prop(14, pitchstep, DOF_STEP_ROTX.val)
+
+       if evt == evcode["DOF_MIN_ROTY"]:
+               set_prop(14, rollmin, DOF_MIN_ROTY.val)
+       if evt == evcode["DOF_MAX_ROTY"]:
+               set_prop(14, rollmax, DOF_MAX_ROTY.val)
+       if evt == evcode["DOF_STEP_ROTY"]:
+               set_prop(14, rollstep, DOF_STEP_ROTY.val)       
+
+       if evt == evcode["DOF_MIN_ROTZ"]:
+               set_prop(14, yawmin, DOF_MIN_ROTZ.val)
+       if evt == evcode["DOF_MAX_ROTZ"]:
+               set_prop(14, yawmax, DOF_MAX_ROTZ.val)
+       if evt == evcode["DOF_STEP_ROTZ"]:
+               set_prop(14, yawstep, DOF_STEP_ROTZ.val)        
+               
+       #do scale buttons
+       if evt == evcode["DOF_MIN_SCALEX"]:
+               set_prop(14, xscalemin, DOF_MIN_SCALEX.val)
+       if evt == evcode["DOF_MAX_SCALEX"]:
+               set_prop(14, xscalemax, DOF_MAX_SCALEX.val)
+       if evt == evcode["DOF_STEP_SCALEX"]:
+               set_prop(14, xscalestep, DOF_STEP_SCALEX.val)
+       
+       if evt == evcode["DOF_MIN_SCALEY"]:
+               set_prop(14, yscalemin, DOF_MIN_SCALEY.val)
+       if evt == evcode["DOF_MAX_SCALEY"]:
+               set_prop(14, yscalemax, DOF_MAX_SCALEY.val)
+       if evt == evcode["DOF_STEP_SCALEY"]:
+               set_prop(14, yscalestep, DOF_STEP_SCALEY.val)   
+
+       if evt == evcode["DOF_MIN_SCALEZ"]:
+               set_prop(14, zscalemin, DOF_MIN_SCALEZ.val)
+       if evt == evcode["DOF_MAX_SCALEZ"]:
+               set_prop(14, zscalemax, DOF_MAX_SCALEZ.val)
+       if evt == evcode["DOF_STEP_SCALEZ"]:
+               set_prop(14, zscalestep, DOF_STEP_SCALEZ.val)
+
+
+       Draw.Redraw(1)
+       Blender.Window.RedrawAll()
+
+def draw_propsheet(x,y):
+       #UI buttons
+       global DOF_MAKE
+       global DOF_UPDATE
+       global DOF_DELETE
+
+       global DOF_TRANSX
+       global DOF_TRANSY
+       global DOF_TRANSZ
+       global DOF_ROTX
+       global DOF_ROTY
+       global DOF_ROTZ
+       global DOF_SCALEX
+       global DOF_SCALEY
+       global DOF_SCALEZ
+
+       global DOF_MIN_TRANSX
+       global DOF_MIN_TRANSY
+       global DOF_MIN_TRANSZ
+       global DOF_MIN_ROTX
+       global DOF_MIN_ROTY
+       global DOF_MIN_ROTZ
+       global DOF_MIN_SCALEX
+       global DOF_MIN_SCALEY
+       global DOF_MIN_SCALEZ
+
+       global DOF_MAX_TRANSX
+       global DOF_MAX_TRANSY
+       global DOF_MAX_TRANSZ
+       global DOF_MAX_ROTX
+       global DOF_MAX_ROTY
+       global DOF_MAX_ROTZ
+       global DOF_MAX_SCALEX
+       global DOF_MAX_SCALEY
+       global DOF_MAX_SCALEZ
+
+       global DOF_STEP_TRANSX
+       global DOF_STEP_TRANSY
+       global DOF_STEP_TRANSZ
+       global DOF_STEP_ROTX
+       global DOF_STEP_ROTY
+       global DOF_STEP_ROTZ
+       global DOF_STEP_SCALEX
+       global DOF_STEP_SCALEY
+       global DOF_STEP_SCALEZ
+
+       #labels
+       global DOF_ROTSTRING
+       global DOF_TRANSTRING
+       global DOF_SCALESTRING  
+       global DOF_EDITLABEL
+       
+       #masks
+       global lockxtrans
+       global lockytrans
+       global lockztrans
+       global lockxrot
+       global lockyrot
+       global lockzrot
+       global lockxscale
+       global lockyscale
+       global lockzscale
+       
+       global zmin
+       global zmax
+       global zcur
+       global zstep
+       global ymin
+       global ymax
+       global ycur
+       global ystep
+       global xmin
+       global xmax
+       global xcur
+       global xstep
+       global pitchmin
+       global pitchmax
+       global pitchcur
+       global pitchstep
+       global rollmin
+       global rollmax
+       global rollcur
+       global rollstep
+       global yawmin
+       global yawmax
+       global yawcur
+       global yawstep
+       global zscalemin
+       global zscalemax
+       global zscalecur
+       global zscalestep
+       global yscalemin
+       global yscalemax
+       global yscalecur
+       global yscalestep
+       global xscalemin
+       global xscalemax
+       global xscalecur
+       global xscalestep       
+
+       
+       global evcode
+       
+       state = update_state()
+       
+       row_height = 20
+       toggle_width = 50
+       input_width = 100
+       pad = 10
+       origx = x
+       origy = (row_height * 15) + (pad * 15)
+
+
+       #editor label
+       x = origx
+       y = origy
+       #y = y - (row_height + pad)
+       DOF_EDITLABEL = Blender.Draw.Label("FLT Degree of Freedom Editor", x, y, 200, row_height)
+
+
+       #draw Translation limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_TRANSTRING = Blender.Draw.Label("Translation Limits", x, y, input_width, row_height)
+
+
+       #X limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_TRANSX = Blender.Draw.Toggle("LimX", evcode["DOF_TRANSX"], x, y, toggle_width, row_height, get_lockmask(lockxtrans), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_TRANSX = Blender.Draw.Number("MinX", evcode["DOF_MIN_TRANSX"], x, y, input_width, row_height,get_prop(14,xmin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_TRANSX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_TRANSX"], x, y, input_width, row_height,get_prop(14,xmax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_TRANSX = Blender.Draw.Number("StepX", evcode["DOF_STEP_TRANSX"], x, y, input_width, row_height,get_prop(14,xstep), -1000000.0, 1000000.0, "")
+       
+       #Y limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_TRANSY = Blender.Draw.Toggle("LimY", evcode["DOF_TRANSY"], x, y, toggle_width, row_height, get_lockmask(lockytrans), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_TRANSY = Blender.Draw.Number("MinY", evcode["DOF_MIN_TRANSY"], x, y, input_width, row_height, get_prop(14,ymin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_TRANSY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_TRANSY"], x, y, input_width, row_height, get_prop(14,ymax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_TRANSY = Blender.Draw.Number("StepY", evcode["DOF_STEP_TRANSY"], x, y, input_width, row_height, get_prop(14,ystep), -1000000.0, 1000000.0, "") 
+       
+       #Z limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_TRANSZ = Blender.Draw.Toggle("LimZ", evcode["DOF_TRANSZ"], x, y, toggle_width, row_height, get_lockmask(lockztrans), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_TRANSZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_TRANSZ"], x, y, input_width, row_height, get_prop(14,zmin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_TRANSZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_TRANSZ"], x, y, input_width, row_height, get_prop(14,zmax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_TRANSZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_TRANSZ"], x, y, input_width, row_height, get_prop(14,zstep), -1000000.0, 1000000.0, "")
+       
+       #draw Rotation limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_ROTSTRING = Blender.Draw.Label("Rotation Limits", x, y, input_width, row_height)
+
+       #draw Rotation limits
+       #X limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_ROTX = Blender.Draw.Toggle("LimX", evcode["DOF_ROTX"], x, y, toggle_width, row_height, get_lockmask(lockxrot), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_ROTX = Blender.Draw.Number("MinX", evcode["DOF_MIN_ROTX"], x, y, input_width, row_height, get_prop(14,pitchmin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_ROTX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_ROTX"], x, y, input_width, row_height, get_prop(14,pitchmax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_ROTX = Blender.Draw.Number("StepX", evcode["DOF_STEP_ROTX"], x, y, input_width, row_height, get_prop(14,pitchstep), -1000000.0, 1000000.0, "")
+               
+       #Y limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_ROTY = Blender.Draw.Toggle("LimY", evcode["DOF_ROTY"], x, y, toggle_width, row_height, get_lockmask(lockyrot), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_ROTY = Blender.Draw.Number("MinY", evcode["DOF_MIN_ROTY"], x, y, input_width, row_height, get_prop(14,rollmin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_ROTY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_ROTY"], x, y, input_width, row_height, get_prop(14,rollmax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_ROTY = Blender.Draw.Number("StepY", evcode["DOF_STEP_ROTY"], x, y, input_width, row_height, get_prop(14,rollstep), -1000000.0, 1000000.0, "")
+               
+       #Z limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_ROTZ = Blender.Draw.Toggle("LimZ", evcode["DOF_ROTZ"], x, y, toggle_width, row_height, get_lockmask(lockzrot), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_ROTZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_ROTZ"], x, y, input_width, row_height, get_prop(14, yawmin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_ROTZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_ROTZ"], x, y, input_width, row_height, get_prop(14, yawmax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_ROTZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_ROTZ"], x, y, input_width, row_height, get_prop(14, yawstep), -1000000.0, 1000000.0, "")
+                       
+
+       #draw Scale limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_SCALESTRING = Blender.Draw.Label("Scale Limits", x, y, input_width, row_height)
+
+       #draw Scale limits
+       #X limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_SCALEX = Blender.Draw.Toggle("LimX", evcode["DOF_SCALEX"], x, y, toggle_width, row_height, get_lockmask(lockxscale), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_SCALEX = Blender.Draw.Number("MinX", evcode["DOF_MIN_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalemin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_SCALEX = Blender.Draw.Number("MaxX", evcode["DOF_MAX_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalemax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_SCALEX = Blender.Draw.Number("StepX", evcode["DOF_STEP_SCALEX"], x, y, input_width, row_height, get_prop(14, xscalestep), -1000000.0, 1000000.0, "")
+               
+       #Y limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_SCALEY = Blender.Draw.Toggle("LimY", evcode["DOF_SCALEY"], x, y, toggle_width, row_height, get_lockmask(lockyscale), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_SCALEY = Blender.Draw.Number("MinY", evcode["DOF_MIN_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalemin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_SCALEY = Blender.Draw.Number("MaxY", evcode["DOF_MAX_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalemax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_SCALEY = Blender.Draw.Number("StepY", evcode["DOF_STEP_SCALEY"], x, y, input_width, row_height, get_prop(14, yscalestep), -1000000.0, 1000000.0, "")           
+
+       #Z limits
+       x = origx
+       y = y- (row_height + pad)
+       DOF_SCALEZ = Blender.Draw.Toggle("LimZ", evcode["DOF_SCALEZ"], x, y, toggle_width, row_height, get_lockmask(lockzscale), "")
+       x = x + (toggle_width + pad)
+       DOF_MIN_SCALEZ = Blender.Draw.Number("MinZ", evcode["DOF_MIN_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalemin),  -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_MAX_SCALEZ = Blender.Draw.Number("MaxZ", evcode["DOF_MAX_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalemax), -1000000.0, 1000000.0, "")
+       x = x + (input_width + pad)
+       DOF_STEP_SCALEZ = Blender.Draw.Number("StepZ", evcode["DOF_STEP_SCALEZ"], x, y, input_width, row_height, get_prop(14, zscalestep), -1000000.0, 1000000.0, "")           
+
+       #System
+       x = origx
+       y = y - (row_height + (pad)*3)
+       DOF_MAKE = Blender.Draw.PushButton("Make DOF", evcode["DOF_MAKE"], x, y, input_width, row_height, "Make a Dof Node out of Active Object")
+       x = x + (input_width + pad)
+       DOF_UPDATE = Blender.Draw.PushButton("Grab Loc/Rot", evcode["DOF_UPDATE"], x, y, input_width, row_height, "Update the Dof Node position/orientation")
+       x = x + (input_width + pad)
+       DOF_DELETE = Blender.Draw.PushButton("Delete DOF", evcode["DOF_DELETE"], x, y, input_width, row_height, "Delete the Dof Node properties")
+
+
+       
+       
+def gui():
+       #draw the propsheet/toolbox.
+       psheety = 800
+       #psheetx = psheety + 10
+       draw_propsheet(20,psheety)
+
+Draw.Register(gui,event,but_event)
+       
\ No newline at end of file
diff --git a/release/scripts/flt_lodedit.py b/release/scripts/flt_lodedit.py
new file mode 100644 (file)
index 0000000..58319b9
--- /dev/null
@@ -0,0 +1,502 @@
+#!BPY
+
+"""
+Name: 'FLT LOD Editor'
+Blender: 240
+Group: 'Misc'
+Tooltip: 'Level of Detail Edtior for FLT nodes'
+"""
+
+__author__ = "Geoffrey Bantle"
+__version__ = "1.0 11/21/07"
+__email__ = ('scripts', 'Author, ')
+__url__ = ('blender', 'blenderartists.org')
+
+__bpydoc__ ="""\
+This script provides tools for working with OpenFlight databases in Blender. OpenFlight is a
+registered trademark of MultiGen-Paradigm, Inc.
+
+Feature overview and more availible at:
+http://wiki.blender.org/index.php/Scripts/Manual/FLTools
+"""
+
+# --------------------------------------------------------------------------
+# flt_palettemanager.py version 0.1 2005/04/08
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# Copyright (C) 2007: Blender Foundation
+#
+# 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 *****
+# --------------------------------------------------------------------------
+
+import Blender.Draw as Draw
+from Blender.BGL import *
+import Blender
+import flt_properties
+reload(flt_properties)
+from flt_properties import *
+
+#event codes
+evcode = {
+       "LOD_MAKE" : 100,
+       "LOD_DELETE" : 101,
+       "LOD_CALC_CENTER" : 102,
+       "LOD_GRAB_CENTER" : 103,
+       "LOD_X" : 104,
+       "LOD_Y" : 105,
+       "LOD_Z" : 106,
+       "LOD_FREEZE" : 107,
+       "LOD_SIG" : 108,
+       "LOD_IN" : 109,
+       "LOD_OUT" : 110,
+       "LOD_TRANS" : 111,              
+       "LOD_PREVIOUS" : 112
+}
+
+
+#system
+LOD_MAKE = None                        #PushButton
+LOD_DELETE = None              #PushButton
+LOD_CALC_CENTER = None #PushButton
+LOD_GRAB_CENTER = None #Pushbutton
+LOD_FREEZE = None              #Toggle
+LOD_PREVIOUS = None            #Toggle
+
+LOD_X = None                   #Input
+LOD_Y = None                   #Input
+LOD_Z = None                   #Input
+
+LOD_SIG = None                 #Input
+LOD_IN = None                  #Input
+LOD_OUT = None                 #Input
+LOD_TRANS = None               #Input
+
+#labels
+LOD_EDITLABEL = None
+LOD_SWITCHLABEL = None
+LOD_CENTERLABEL = None
+
+LOD_XLABEL = None
+LOD_YLABEL = None
+LOD_ZLABEL = None
+LOD_SIGLABEL = None
+LOD_INLABEL = None
+LOD_OUTLABEL = None
+LOD_TRANSLABEL = None
+
+
+#ID Props
+switch_in = '5d!switch in'
+switch_out = '6d!switch out'
+xco = '10d!X co'
+yco = '11d!Y co'
+zco = '12d!Z co'
+trans = '13d!Transition'
+sig_size = '14d!Sig Size'
+
+#Flags
+lodflag = '9I!flags'
+previous_mask = (1 << 31)
+freeze_mask = (1 << 29)
+
+def update_state():
+       state = dict()
+       state["activeScene"] = Blender.Scene.GetCurrent()
+       state["activeObject"] = state["activeScene"].objects.active
+       if state["activeObject"] and not state["activeObject"].sel:
+               state["activeObject"] = None
+       state["activeMesh"] = None
+       if state["activeObject"] and state["activeObject"].type == 'Mesh':
+               state["activeMesh"] = state["activeObject"].getData(mesh=True)
+       
+       state["activeFace"] = None
+       if state["activeMesh"]:
+               if state["activeMesh"].faceUV and state["activeMesh"].activeFace != None:
+                       state["activeFace"] = state["activeMesh"].faces[state["activeMesh"].activeFace]
+               
+               
+       #update editmode
+       state["editmode"]       = Blender.Window.EditMode()
+
+       return state
+       
+def idprops_append(object, typecode, props):
+       object.properties["FLT"] = dict()
+       object.properties["FLT"]['type'] = typecode 
+       for prop in props:
+               object.properties["FLT"][prop] = props[prop]
+       object.properties["FLT"]['3t8!id'] = object.name
+
+def idprops_kill():
+       state = update_state()
+       if state["activeObject"] and state["activeObject"].properties.has_key('FLT'):
+               state["activeObject"].properties.pop('FLT')
+
+def idprops_copy(source):
+       state = update_state()
+       if source.properties.has_key('FLT'):
+               for object in state["activeScene"].objects:
+                       if object.sel and object != source and (state["activeScene"].Layers & object.Layers):
+                               idprops_kill(object)
+                               object.properties['FLT'] = dict()
+                               for key in source.properties['FLT']:
+                                       object.properties['FLT'][key] = source.properties['FLT'][key]
+
+def select_by_typecode(typecode):
+       state = update_state()
+       
+       for object in state["activeScene"].objects:
+               if object.properties.has_key('FLT') and object.properties['FLT']['type'] == typecode and state["activeScene"].Layers & object.Layers:
+                               object.select(1)
+
+def idprops_type(object, typecode):
+       if object.properties.has_key('FLT') and object.properties['FLT'].has_key('type') and object.properties['FLT']['type'] == typecode:
+               return True
+       return False
+
+#ui type code
+def get_prop(typecode, prop):
+       
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], typecode):
+               props = state["activeObject"].properties['FLT']
+       else:
+               props =  flt_properties.FLTLOD
+               
+       return props[prop]      
+
+def set_prop(typecode, prop, value):
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"],typecode):
+               state["activeObject"].properties['FLT'][prop] = value           
+
+
+
+def get_lockmask(mask):
+       global lodflag
+       state = update_state()
+       if state["activeObject"]:
+               flag = get_prop(73,lodflag)
+               if flag & mask:
+                       return True
+       return False    
+
+def set_lockmask(mask):
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], 73):
+               oldvalue = state["activeObject"].properties['FLT'][lodflag]
+               oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
+               oldvalue |= mask
+               state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i', struct.pack(">I", oldvalue))[0]
+
+def clear_lockmask(mask):
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], 73):
+               oldvalue = state["activeObject"].properties['FLT'][lodflag]
+               oldvalue = struct.unpack('>I', struct.pack('>i', oldvalue))[0]
+               oldvalue &= ~mask
+               state["activeObject"].properties['FLT'][lodflag] = struct.unpack('>i',struct.pack('>I',oldvalue))[0]    
+
+def findchildren(object):
+       state = update_state()
+       children = list()
+       for candidate in state["activeScene"].objects:
+               if candidate.parent == object:
+                       children.append(candidate)
+       retlist = list(children)
+       for child in children:
+               retlist = retlist + findchildren(child)
+       return retlist
+
+def get_object_center(object):
+       bbox = object.getBoundBox(1)
+       average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
+       
+       for point in bbox:
+               average[0] += point[0]
+               average[1] += point[1]
+               average[2] += point[2]
+       
+       average[0] = average[0] / 8.0
+       average[1] = average[1] / 8.0
+       average[2] = average[2] / 8.0
+       
+       return average
+       
+
+def calc_center():
+       
+       global xco
+       global yco
+       global zco
+       
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], 73):
+               average = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
+               children = findchildren(state["activeObject"]) #get children objects    
+               if children:
+                       for child in children:
+                               center = get_object_center(child)
+                               average[0] += center[0]
+                               average[1] += center[1]
+                               average[2] += center[2]
+                       
+                       average[0] = average[0] / len(children)
+                       average[1] = average[1] / len(children)
+                       average[2] = average[2] / len(children)
+                       
+               set_prop(73, xco, average[0])
+               set_prop(73, yco, average[1])
+               set_prop(73, zco, average[2])
+               
+
+def grab_center():
+       
+       global xco
+       global yco
+       global zco
+       
+       state = update_state()
+       if state["activeObject"] and idprops_type(state["activeObject"], 73):
+               center = Blender.Window.GetCursorPos()
+               
+               set_prop(73, xco, center[0])
+               set_prop(73, yco, center[1])
+               set_prop(73, zco, center[2])    
+
+
+def create_lod():
+       state = update_state()
+       actobj = state["activeObject"]
+       if actobj and not idprops_type(actobj, 73):
+               idprops_kill()
+               idprops_append(actobj,73, flt_properties.FLTLOD)
+               calc_center()
+
+       
+               
+def event(evt,val):
+       if evt == Draw.ESCKEY:
+               Draw.Exit()
+               
+def but_event(evt):
+
+       global LOD_MAKE
+       global LOD_DELETE
+       global LOD_CALC_CENTER
+       global LOD_GRAB_CENTER
+       global LOD_FREEZE
+       global LOD_PREVIOUS
+       global LOD_X
+       global LOD_Y
+       global LOD_Z
+       global LOD_SIG
+       global LOD_IN
+       global LOD_OUT
+       global LOD_TRANS
+       
+       global switch_in
+       global switch_out
+       global xco
+       global yco
+       global zco
+       global trans
+       global sig_size
+       
+       global lodflag
+       global previous_mask
+       global freeze_mask
+       
+       global evcode
+       
+       #do "system" events
+       if evt == evcode["LOD_MAKE"]:
+               create_lod()
+
+       if evt == evcode["LOD_CALC_CENTER"]:
+               calc_center()
+       
+       if evt == evcode["LOD_DELETE"]:
+               idprops_kill()
+       
+       if evt == evcode["LOD_GRAB_CENTER"]:
+               grab_center()
+
+       #do mask events
+       if evt == evcode["LOD_FREEZE"]:
+               if LOD_FREEZE.val == True:
+                       set_lockmask(freeze_mask)
+               else:
+                       clear_lockmask(freeze_mask)
+                       
+       if evt == evcode["LOD_PREVIOUS"]:
+               if LOD_PREVIOUS.val == True:
+                       set_lockmask(previous_mask)
+               else:
+                       clear_lockmask(previous_mask)
+                       
+       #do input events
+       if evt == evcode["LOD_X"]:
+               set_prop(73, xco, LOD_X.val)
+       if evt == evcode["LOD_Y"]:
+               set_prop(73, yco, LOD_Y.val)
+       if evt == evcode["LOD_Z"]:
+               set_prop(73, zco, LOD_Z.val)
+       if evt == evcode["LOD_SIG"]:
+               set_prop(73, sig_size, LOD_SIG.val)
+       if evt == evcode["LOD_IN"]:
+               set_prop(73, switch_in, LOD_IN.val)
+       if evt == evcode["LOD_OUT"]:
+               set_prop(73, switch_out, LOD_OUT.val)
+       if evt == evcode["LOD_TRANS"]:
+               set_prop(73, trans, LOD_TRANS.val)      
+                               
+
+       Draw.Redraw(1)
+       Blender.Window.RedrawAll()
+
+def draw_propsheet(x,y):
+
+       global LOD_MAKE
+       global LOD_DELETE
+       global LOD_CALC_CENTER
+       global LOD_GRAB_CENTER
+       global LOD_FREEZE
+       global LOD_PREVIOUS
+       global LOD_X
+       global LOD_Y
+       global LOD_Z
+       global LOD_SIG
+       global LOD_IN
+       global LOD_OUT
+       global LOD_TRANS
+
+       #labels
+       global LOD_EDITLABEL
+       global LOD_SWITCHLABEL
+       global LOD_CENTERLABEL
+       global LOD_XLABEL
+       global LOD_YLABEL
+       global LOD_ZLABEL
+       global LOD_SIGLABEL
+       global LOD_INLABEL
+       global LOD_OUTLABEL
+       global LOD_TRANSLABEL
+       
+       
+       global switch_in
+       global switch_out
+       global xco
+       global yco
+       global zco
+       global trans
+       global sig_size
+       
+       global lodflag
+       global previous_mask
+       global freeze_mask
+       
+       global evcode
+
+
+       global evcode
+       
+       state = update_state()
+
+       label_width = 100       
+       row_height = 20
+       toggle_width = 50
+       input_width = 100
+       pad = 10
+       origx = x
+       origy = (row_height * 16) + (pad * 16)
+
+
+       #editor label
+       x = origx
+       y = origy
+       LOD_EDITLABEL = Blender.Draw.Label("FLT Level of Detail Editor", x, y, 250, row_height)
+
+
+       #Center inputs
+       x = origx
+       y = y- (row_height + pad)
+       LOD_CENTERLABEL = Blender.Draw.Label("LOD center", x, y, label_width, row_height)
+       y = y- (row_height + pad)
+       LOD_XLABEL = Blender.Draw.Label("X Coordinate", x, y, label_width, row_height)
+       x = origx + (label_width + pad)
+       LOD_X = Blender.Draw.Number("", evcode["LOD_X"], x, y, input_width, row_height,get_prop(73,xco),  -1000000.0, 1000000.0, "")
+       x = origx
+       y = y- (row_height + pad)
+       LOD_YLABEL = Blender.Draw.Label("Y Coordinate", x, y, label_width, row_height)  
+       x = origx + (label_width + pad)
+       LOD_Y = Blender.Draw.Number("", evcode["LOD_Y"], x, y, input_width, row_height,get_prop(73,yco), -1000000.0,  1000000.0, "")
+       x = origx
+       y = y- (row_height + pad)
+       LOD_ZLABEL = Blender.Draw.Label("Z Coordinate", x, y, label_width, row_height)
+       x = origx + (label_width + pad)         
+       LOD_Z = Blender.Draw.Number("", evcode["LOD_Z"], x, y, input_width, row_height,get_prop(73,zco), -1000000.0, 1000000.0, "")
+
+
+       #Switch inputs
+       x = origx
+       y = y- (row_height + pad)
+       LOD_SWITCHLABEL = Blender.Draw.Label("Switch Settings", x, y, input_width, row_height)
+       y = y- (row_height + pad)
+       LOD_SIGLABEL = Blender.Draw.Label("Significant Size", x, y, label_width, row_height)
+       x = origx + (label_width + pad)
+       LOD_SIG = Blender.Draw.Number("", evcode["LOD_SIG"], x, y, input_width, row_height, get_prop(73,sig_size),  -1000000.0, 1000000.0, "")
+       x = origx
+       y = y- (row_height + pad)
+       LOD_INLABEL = Blender.Draw.Label("Switch In", x, y, label_width, row_height)
+       x = origx + (label_width + pad)
+       LOD_IN = Blender.Draw.Number("", evcode["LOD_IN"], x, y, input_width, row_height, get_prop(73,switch_in), -1000000.0, 1000000.0, "")
+       x = origx
+       y = y- (row_height + pad)
+       LOD_OUTLABEL = Blender.Draw.Label("Switch Out", x, y, label_width, row_height)  
+       x = origx + (label_width + pad)
+       LOD_OUT = Blender.Draw.Number("", evcode["LOD_OUT"], x, y, input_width, row_height, get_prop(73,switch_out), -1000000.0, 1000000.0, "")
+       x = origx
+       y = y- (row_height + pad)
+       LOD_TRANSLABEL = Blender.Draw.Label("Transition", x, y, label_width, row_height)                
+       x = origx + (label_width + pad)
+       LOD_TRANS = Blender.Draw.Number("", evcode["LOD_TRANS"], x, y, input_width, row_height, get_prop(73,trans), -1000000.0, 1000000.0, "")  
+
+
+       x = origx
+       y = y - (row_height + pad)      
+       LOD_MAKE = Blender.Draw.PushButton("Make LOD", evcode["LOD_MAKE"], x, y, input_width + label_width + pad, row_height, "Make a LOD Node out of Active Object")
+       y = y - (row_height + pad)      
+       LOD_DELETE = Blender.Draw.PushButton("Delete LOD", evcode["LOD_DELETE"], x, y, input_width + label_width + pad, row_height, "Delete the LOD Node properties")
+       y = y - (row_height + pad)
+       LOD_CALC_CENTER = Blender.Draw.PushButton("Calculate Center", evcode["LOD_CALC_CENTER"], x, y, input_width + label_width + pad, row_height, "Calculate the center of this LOD")
+       y = y - (row_height + pad)
+       LOD_GRAB_CENTER = Blender.Draw.PushButton("Grab Center", evcode["LOD_GRAB_CENTER"], x, y, input_width + label_width + pad, row_height, "Grab center from 3d cursor")
+       y = y - (row_height + pad)
+       LOD_FREEZE = Blender.Draw.Toggle("Freeze Center", evcode["LOD_FREEZE"], x, y, input_width + label_width + pad, row_height, get_lockmask(freeze_mask), "")
+       y = y - (row_height + pad)
+       LOD_PREVIOUS = Blender.Draw.Toggle("Previous Range", evcode["LOD_PREVIOUS"], x, y, input_width + label_width + pad, row_height, get_lockmask(previous_mask), "")
+
+def gui():
+       #draw the propsheet/toolbox.
+       psheety = 800
+       #psheetx = psheety + 10
+       draw_propsheet(20,psheety)
+
+Draw.Register(gui,event,but_event)
+       
\ No newline at end of file
index bc7c972ca6676fa9c549a56ab8e4db11471ba442..4c841e9c0c03b7d5b06a4e05ddd7b9b338d3979b 100644 (file)
@@ -197,7 +197,10 @@ def write_prop(fw,type,value,length):
        elif type == 'i':
                fw.write_int(value)
        elif type == 'I':
-               fw.write_uint(value)
+               #NOTE!:
+               #there is no unsigned int type in python, but we can only store signed ints in ID props
+               newvalue = struct.unpack('>I', struct.pack('>i', value))[0]
+               fw.write_uint(newvalue)
        elif type == 'd':
                fw.write_double(value)
        elif type == 'f':
@@ -267,16 +270,16 @@ FLTObjectDisplay = [10]
 FLTLOD = {
        '3t8!id' : 'L',
        '4i!reserved' : 0,
-       '5d!switch in' : 0,
-       '6d!switch out' : 0,
+       '5d!switch in' : 0.0,
+       '6d!switch out' : 0.0,
        '7s!sfx ID1' : 0,
        '8s!sfx ID2' : 0,
        '9I!flags' : 0,
-       '10d!X co' : 0,
-       '11d!Y co' : 0,
-       '12d!Z co' : 0,
-       '13d!Transition' : 0,
-       '14d!Sig Size' : 0
+       '10d!X co' : 0.0,
+       '11d!Y co' : 0.0,
+       '12d!Z co' : 0.0,
+       '13d!Transition' : 0.0,
+       '14d!Sig Size' : 0.0
 }
 FLTLODDisplay = [4]
 
index 6082af3033fb2312859b6294d9f7bb8d9feabd6a..9f49dd4587a436a35a74d6ec5d842fa6e359793e 100644 (file)
@@ -56,7 +56,7 @@
   information, claims of third parties, damages as a result of injury to
   any person, or any other loss) arising out of or in connection with the
   license granted under this License Agreement or the use of or inability
-  to use the Software, even if VF has been advised of the possibility of
+  to use the Software, even if BF has been advised of the possibility of
   such damages. 
    
   5. User warning and indemnification
index d06962cbe3f5e0f339d79ef132e08b49b0641d5f..91dd17d73dd49d211789e65b8e62dc6b26fe674e 100644 (file)
@@ -250,6 +250,7 @@ SPLIB += $(OCGDIR)/blender/readblenfile/$(DEBUG_DIR)libreadblenfile.a
 # but somehow it consistently fails to resolve these symbols... or 
 # can I just not check them? nm claims they aren't...
 SPLIB += $(OCGDIR)/blender/blenkernel/blenkernel_blc/$(DEBUG_DIR)libblenkernel_blc.a
+SPLIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a
 
 # These three need to be explicitly mentioned on the cl, because 
 # if they are offered as a lib, they are optimized away. (nzc)
index e1eb6718a3069e9d535c7b3f75ce97fe17b06555..e403fc33e068289008df363de47ddaa714b67a43 100644 (file)
@@ -41,7 +41,7 @@ struct ListBase;
 struct MemFile;
 
 #define BLENDER_VERSION                        247
-#define BLENDER_SUBVERSION             0
+#define BLENDER_SUBVERSION             1
 
 #define BLENDER_MINVERSION             245
 #define BLENDER_MINSUBVERSION  15
index 2966d932a49837151bd240eff57bc3ab123c6b25..c483148e4de4a3804ce2d01d6f965cb97a9388d9 100644 (file)
@@ -119,8 +119,10 @@ FaceCollPair;
 /////////////////////////////////////////////////
 // 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 );
@@ -133,6 +135,15 @@ void collision_move_object ( CollisionModifierData *collmd, float step, float pr
 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 );
 
+/////////////////////////////////////////////////
+// used in effect.c
+/////////////////////////////////////////////////
+CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj);
+
+/////////////////////////////////////////////////
+
+
+
 /////////////////////////////////////////////////
 
 #endif
index e84c7d309566238be4b97cc1cbcff489e67538e0..c84b690bc49d419764b5c5d46aeba2db9a1e4121 100644 (file)
 #ifndef BKE_CUSTOMDATA_H
 #define BKE_CUSTOMDATA_H
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 struct CustomData;
 struct CustomDataLayer;
-typedef long CustomDataMask;
+typedef intptr_t CustomDataMask;
 
 extern const CustomDataMask CD_MASK_BAREMESH;
 extern const CustomDataMask CD_MASK_MESH;
index a1975dd4265f03019b132d672836c0fd9e54a2bc..e982806a6cc60958e27cec47581d8e9522cc149d 100644 (file)
@@ -38,6 +38,7 @@
 struct Object;
 struct ListBase;
 struct bDeformGroup;
+struct MDeformVert;
 
 void copy_defgroups (struct ListBase *lb1, struct ListBase *lb2);
 struct bDeformGroup *copy_defgroup (struct bDeformGroup *ingroup);
@@ -46,5 +47,8 @@ int get_defgroup_num (struct Object *ob, struct bDeformGroup *dg);
 int get_named_vertexgroup_num (Object *ob, char *name);
 void unique_vertexgroup_name (struct bDeformGroup *dg, struct Object *ob);
 
+float deformvert_get_weight(const struct MDeformVert *dvert, int group_num);
+float vertexgroup_get_vertex_weight(const struct MDeformVert *dvert, int index, int group_num);
+
 #endif
 
index 3763a659f2f22b2fc40f442e1d152043ab70f771..6475f7a71ac12a5b7eb4db0f6b2d3f3e82d7ad14 100644 (file)
@@ -37,6 +37,7 @@ struct Effect;
 struct ListBase;
 struct Particle;
 struct Group;
+struct RNG;
 
 typedef struct pEffectorCache {
        struct pEffectorCache *next, *prev;
@@ -64,6 +65,11 @@ struct ListBase *pdInitEffectors(struct Object *obsrc, struct Group *group);
 void                   pdEndEffectors(struct ListBase *lb);
 void                   pdDoEffectors(struct ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags);
 
+/* required for particle_system.c */
+void do_physical_effector(Object *ob, float *opco, short type, float force_val, float distance, float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, struct RNG *rng, float noise_factor, float charge, float pa_size);
+float effector_falloff(struct PartDeflect *pd, float *eff_velocity, float *vec_to_part);
+
+
 
 
 #endif
index 1757103eaf660d7e42ac25e0af813c52fdd6352c..dc5efd5ea4694d6c67caf7040668312379ba433e 100644 (file)
 
 #define BKE_ENDIANNESS(a) {  \
        union {  \
-               long l;  \
-               char c[sizeof (long)];  \
+               intptr_t l;  \
+               char c[sizeof (intptr_t)];  \
        } u;  \
        u.l = 1;  \
-       a = (u.c[sizeof (long) - 1] == 1) ? 1 : 0;  \
+       a = (u.c[sizeof (intptr_t) - 1] == 1) ? 1 : 0;  \
 }
 
 #endif
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
new file mode 100644 (file)
index 0000000..e827623
--- /dev/null
@@ -0,0 +1,146 @@
+/**
+ * BKE_shrinkwrap.h
+ *
+ * ***** 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 *****
+ */
+#ifndef BKE_SHRINKWRAP_H
+#define BKE_SHRINKWRAP_H
+
+/* mesh util */
+//TODO: move this somewhere else
+#include "BKE_customdata.h"
+struct DerivedMesh;
+struct Object;
+struct DerivedMesh *object_get_derived_final(struct Object *ob, CustomDataMask dataMask);
+
+
+/* SpaceTransform stuff */
+/*
+ * TODO: move this somewhere else
+ *
+ * this structs encapsulates all needed data to convert between 2 coordinate spaces
+ * (where conversion can be represented by a matrix multiplication)
+ *
+ * This is used to reduce the number of arguments to pass to functions that need to perform
+ * this kind of operation and make it easier for the coder, as he/she doenst needs to recode
+ * the matrix calculation.
+ *
+ * A SpaceTransform is initialized using:
+ *   space_transform_setup( &data,  ob1, ob2 )
+ *
+ * After that the following calls can be used:
+ *   space_transform_apply (&data, co); //converts a coordinate in ob1 coords space to the corresponding ob2 coords
+ *   space_transform_invert(&data, co); //converts a coordinate in ob2 coords space to the corresponding ob1 coords
+ *
+ *     //Same Concept as space_transform_apply and space_transform_invert, but no is normalized after conversion
+ *   space_transform_apply_normal (&data, &no);
+ *   space_transform_invert_normal(&data, &no);
+ *
+ */
+struct Object;
+
+typedef struct SpaceTransform
+{
+       float local2target[4][4];
+       float target2local[4][4];
+
+} SpaceTransform;
+
+void space_transform_from_matrixs(SpaceTransform *data, float local[][4], float target[][4]);
+#define space_transform_setup(data, local, target) space_transform_from_matrixs(data, (local)->obmat, (target)->obmat)
+
+void space_transform_apply (const SpaceTransform *data, float *co);
+void space_transform_invert(const SpaceTransform *data, float *co);
+
+void space_transform_apply_normal (const SpaceTransform *data, float *no);
+void space_transform_invert_normal(const SpaceTransform *data, float *no);
+
+/* Shrinkwrap stuff */
+#include "BKE_bvhutils.h"
+
+/*
+ * Shrinkwrap is composed by a set of functions and options that define the type of shrink.
+ *
+ * 3 modes are available:
+ *    - Nearest vertex
+ *       - Nearest surface
+ *    - Normal projection
+ *
+ * ShrinkwrapCalcData encapsulates all needed data for shrinkwrap functions.
+ * (So that you dont have to pass an enormous ammount of arguments to functions)
+ */
+
+struct Object;
+struct DerivedMesh;
+struct ShrinkwrapModifierData;
+struct BVHTree;
+
+
+typedef struct ShrinkwrapCalcData
+{
+       ShrinkwrapModifierData *smd;    //shrinkwrap modifier data
+
+       struct Object *ob;                              //object we are applying shrinkwrap to
+       struct DerivedMesh *original;   //mesh before shrinkwrap
+
+       float (*vertexCos)[3];                  //vertexs being shrinkwraped
+       int numVerts;
+
+       struct DerivedMesh *target;             //mesh we are shrinking to      
+       SpaceTransform local2target;    //transform to move bettwem local and target space
+
+       float keepDist;                                 //Distance to kept from target (units are in local space)
+
+} ShrinkwrapCalcData;
+
+void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *data);
+void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *data);
+void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *data);
+
+void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts);
+
+/*
+ * This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is:
+ *
+ * if transf was configured with "space_transform_setup( &transf,  ob1, ob2 )"
+ * then the input (vert, dir, BVHTreeRayHit) must be defined in ob1 coordinates space
+ * and the BVHTree must be built in ob2 coordinate space.
+ *
+ * Thus it provides an easy way to cast the same ray across several trees (where each tree was built on its own coords space)
+ */
+int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata);
+
+/*
+ * NULL initializers to local data
+ */
+#define NULL_ShrinkwrapCalcData        {NULL, }
+#define NULL_BVHTreeFromMesh   {NULL, }
+#define NULL_BVHTreeRayHit             {NULL, }
+#define NULL_BVHTreeNearest            {0, }
+
+
+#endif
+
index a96a3e10f406652776233a432579299922085b70..f389521ffa0f0a9501be694a1105dfb3469d1d4b 100644 (file)
 
 /* Warning-free macros for storing ints in pointers. Use these _only_
  * for storing an int in a pointer, not a pointer in an int (64bit)! */
-#define SET_INT_IN_POINTER(i) ((void*)(long)(i))
-#define GET_INT_FROM_POINTER(i) ((int)(long)(i))
+#define SET_INT_IN_POINTER(i) ((void*)(intptr_t)(i))
+#define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i))
 
 #endif
 
index 9dcb6b6e7fab1392dbaaebbf07259c59b9be5623..1652b24e1e58563778d7d506c68825e3ca54bc1e 100644 (file)
@@ -7,6 +7,8 @@
 
 #include "CCGSubSurf.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /***/
 
 typedef unsigned char  byte;
@@ -35,7 +37,7 @@ typedef struct _EHash {
 #define EHASH_alloc(eh, nb)                    ((eh)->allocatorIFC.alloc((eh)->allocator, nb))
 #define EHASH_free(eh, ptr)                    ((eh)->allocatorIFC.free((eh)->allocator, ptr))
 
-#define EHASH_hash(eh, item)   (((unsigned long) (item))%((unsigned int) (eh)->curSize))
+#define EHASH_hash(eh, item)   (((uintptr_t) (item))%((unsigned int) (eh)->curSize))
 
 static EHash *_ehash_new(int estimatedNumEntries, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) {
        EHash *eh = allocatorIFC->alloc(allocator, sizeof(*eh));
index 67cf89d5ee26de6b964e499eedfd6975b05a9e83..1dabab98a6e78ec95484c0b126ca1f86bb394ec2 100644 (file)
@@ -79,6 +79,8 @@
 #include "BKE_utildefines.h"
 #include "BKE_particle.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #ifdef WITH_VERSE
 #include "BKE_verse.h"
 #endif
@@ -479,7 +481,7 @@ static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData,
                EditVert *eve;
 
                for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (long) i++;
+                       eve->tmp.l = (intptr_t) i++;
                for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
                        func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]);
        } else {
@@ -497,7 +499,7 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
                EditVert *eve;
 
                for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (long) i++;
+                       eve->tmp.l = (intptr_t) i++;
 
                glBegin(GL_LINES);
                for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
@@ -532,7 +534,7 @@ static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(vo
                EditVert *eve;
 
                for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (long) i++;
+                       eve->tmp.l = (intptr_t) i++;
 
                glBegin(GL_LINES);
                for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
@@ -619,7 +621,7 @@ static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *use
 
        if (emdm->vertexCos) {
                for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (long) i++;
+                       eve->tmp.l = (intptr_t) i++;
        }
 
        for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
@@ -637,7 +639,7 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
                EditVert *eve;
 
                for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (long) i++;
+                       eve->tmp.l = (intptr_t) i++;
 
                for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
                        int drawSmooth = (efa->flag & ME_SMOOTH);
@@ -733,7 +735,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
                EditVert *eve;
 
                for (i=0,eve=em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (long) i++;
+                       eve->tmp.l = (intptr_t) i++;
 
                for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
                        MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
@@ -1053,7 +1055,7 @@ void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
 
        /* store vertex indices in tmp union */
        for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
-               ev->tmp.l = (long) i;
+               ev->tmp.l = (intptr_t) i;
 
        for( ; ee; ee = ee->next, ++edge_r) {
                edge_r->crease = (unsigned char) (ee->crease*255.0f);
@@ -1081,7 +1083,7 @@ void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
 
        /* store vertexes indices in tmp union */
        for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
-               ev->tmp.l = (long) i;
+               ev->tmp.l = (intptr_t) i;
 
        for( ; ef; ef = ef->next, ++face_r) {
                face_r->mat_nr = ef->mat_nr;
@@ -1168,7 +1170,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
                int i;
 
                for (i=0,eve=em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (long) i++;
+                       eve->tmp.l = (intptr_t) i++;
 
                emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
                emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
index 042e2afad53925c7bcd824cbcb319558a5e526fe..ae449843d2a7f668660e46a2e1ee07c48cf59099 100644 (file)
@@ -81,7 +81,7 @@ static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, con
  * Function adapted from David Eberly's distance tools (LGPL)
  * http://www.geometrictools.com/LibFoundation/Distance/Distance.html
  */
-static float nearest_point_in_tri_surface(const float *v0,const float *v1,const float *v2,const float *p, int *v, int *e, float *d, float *nearest )
+static float nearest_point_in_tri_surface(const float *v0,const float *v1,const float *v2,const float *p, int *v, int *e, float *nearest )
 {
        float diff[3];
        float e0[3];
@@ -386,7 +386,7 @@ static float nearest_point_in_tri_surface(const float *v0,const float *v1,const
                VecMulf(y, T);
                VECADD(z, w, x);
                VECADD(z, z, y);
-               VECSUB(d, p, z);
+               //VECSUB(d, p, z);
                VECCOPY(nearest, z);
                // d = p - ( v0 + S * e0 + T * e1 );
        }
@@ -418,16 +418,16 @@ static void mesh_faces_nearest_point(void *userdata, int index, const float *co,
        
        do
        {       
-               float nearest_tmp[3], col_normal[3], dist;
+               float nearest_tmp[3], dist;
                int vertex, edge;
                
-               dist = nearest_point_in_tri_surface(t0, t1, t2, co, &vertex, &edge, col_normal, nearest_tmp);
+               dist = nearest_point_in_tri_surface(t0, t1, t2, co, &vertex, &edge, nearest_tmp);
                if(dist < nearest->dist)
                {
                        nearest->index = index;
                        nearest->dist = dist;
                        VECCOPY(nearest->co, nearest_tmp);
-                       VECCOPY(nearest->no, col_normal);
+                       CalcNormFloat(t0, t1, t2, nearest->no);
                }
 
                t1 = t2;
index c7817b017ef454bfe4dd5dbb5b5193a9ad3a5d18..dbc94571cad9b885950321d22a3ca16f9d8c16a3 100644 (file)
@@ -155,7 +155,7 @@ void cloth_init ( ClothModifierData *clmd )
 
 BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
 {
-       int i;
+       unsigned int i;
        BVHTree *bvhtree;
        Cloth *cloth = clmd->clothObject;
        ClothVertex *verts;
@@ -196,7 +196,7 @@ BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float epsilon)
 
 BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon)
 {
-       int i;
+       unsigned int i;
        BVHTree *bvhtree;
        Cloth *cloth = clmd->clothObject;
        ClothVertex *verts;
@@ -782,11 +782,11 @@ 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 )
 {
-       unsigned int i = 0;
-       unsigned int j = 0;
+       int i = 0;
+       int j = 0;
        MDeformVert *dvert = NULL;
        Cloth *clothObj = NULL;
-       unsigned int numverts = dm->getNumVerts ( dm );
+       int numverts = dm->getNumVerts ( dm );
        float goalfac = 0;
        ClothVertex *verts = NULL;
 
@@ -857,7 +857,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
 
 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first)
 {
-       unsigned int i = 0;
+       int i = 0;
        MVert *mvert = NULL;
        ClothVertex *verts = NULL;
        float tnull[3] = {0,0,0};
@@ -1082,13 +1082,13 @@ 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;
-       unsigned int numverts = dm->getNumVerts ( dm );
-       unsigned int numedges = dm->getNumEdges ( dm );
-       unsigned int numfaces = dm->getNumFaces ( dm );
+       int i = 0;
+       int numverts = dm->getNumVerts ( dm );
+       int numedges = dm->getNumEdges ( dm );
+       int numfaces = dm->getNumFaces ( dm );
        MEdge *medge = CDDM_get_edges ( dm );
        MFace *mface = CDDM_get_faces ( dm );
-       unsigned int index2 = 0; // our second vertex index
+       int index2 = 0; // our second vertex index
        LinkNode **edgelist = NULL;
        EdgeHash *edgehash = NULL;
        LinkNode *search = NULL, *search2 = NULL;
index cfcab54058d02885b118712453ab23baec49c7c2..b5e09d551f038f371d2a6e180e9beef136cf1112 100644 (file)
 
 #include "BKE_cloth.h"
 
-#include "DNA_group_types.h"
-#include "DNA_object_types.h"
 #include "DNA_cloth_types.h"
+#include "DNA_group_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
 #include "DNA_scene_types.h"
 
 #include "BKE_DerivedMesh.h"
@@ -1307,9 +1308,34 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
        for ( base = G.scene->base.first; base; base = base->next )
        {
                coll_ob = base->object;
-               collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
-       
-               if ( !collmd )
+               
+               if(coll_ob->pd && coll_ob->pd->deflect)
+               {
+                       collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+               }
+               
+               if ( collmd )
+               {
+                       if(coll_ob == self)
+                               continue;
+                       
+                       if(numobj >= maxobj)
+                       {
+                               // realloc
+                               int oldmax = maxobj;
+                               CollisionModifierData **tmp;
+                               maxobj *= 2;
+                               tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+                               memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+                               MEM_freeN(objs);
+                               objs = tmp;
+                               
+                       }
+                       
+                       objs[numobj] = collmd;
+                       numobj++;
+               }
+               else
                {
                        if ( coll_ob->dup_group )
                        {
@@ -1319,8 +1345,12 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
                                for ( go= group->gobject.first; go; go= go->next )
                                {
                                        coll_ob = go->ob;
-
-                                       collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+                                       collmd = NULL;
+                                       
+                                       if(coll_ob->pd && coll_ob->pd->deflect)
+                                       {
+                                               collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+                                       }
 
                                        if ( !collmd )
                                                continue;
@@ -1347,27 +1377,6 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
                                        numobj++;
                                }
                        }
-               }
-               else
-               {
-                       if(coll_ob == self)
-                               continue;
-                       
-                       if(numobj >= maxobj)
-                       {
-                               // realloc
-                               int oldmax = maxobj;
-                               CollisionModifierData **tmp;
-                               maxobj *= 2;
-                               tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
-                               memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
-                               MEM_freeN(objs);
-                               objs = tmp;
-                               
-                       }
-                       
-                       objs[numobj] = collmd;
-                       numobj++;
                }       
        }
        *numcollobj = numobj;
@@ -1484,6 +1493,9 @@ int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, f
                        BVHTreeOverlap *overlap = NULL;
                        int result = 0;
                        
+                       if(!collmd->bvhtree)
+                               continue;
+                       
                        /* move object to position (step) in time */
                        collision_move_object ( collmd, step + dt, step );
                        
index ab53571b62d338b17c19b9db3d848defef411f24..3143c5e4df2328e80647f9e73c9d13171756c28c 100644 (file)
@@ -220,3 +220,31 @@ void unique_vertexgroup_name (bDeformGroup *dg, Object *ob)
                }
        }       
 }
+
+float deformvert_get_weight(const struct MDeformVert *dvert, int group_num)
+{
+       if(dvert)
+       {
+               const MDeformWeight *dw = dvert->dw;
+               int i;
+
+               for(i=dvert->totweight; i>0; i--, dw++)
+                       if(dw->def_nr == group_num)
+                               return dw->weight;
+       }
+
+       /* Not found */
+       return 0.0;
+}
+
+float vertexgroup_get_vertex_weight(const struct MDeformVert *dvert, int index, int group_num)
+{
+       if(group_num == -1)
+               return 1.0;
+
+       if(dvert == 0)
+               return 0.0;
+
+       return deformvert_get_weight(dvert+index, group_num);
+}
+
index 298e4b81d5bae9b9f4742f914967151f530a0427..3b79f6689c09dcf4e01cc2a6a95e0eaa98bb27ef 100644 (file)
@@ -88,6 +88,8 @@
 #include "RE_pipeline.h"
 #include "RE_shader_ext.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 
 static void boundbox_displist(Object *ob);
 
@@ -986,9 +988,9 @@ void filldisplist(ListBase *dispbase, ListBase *to)
                                efa= fillfacebase.first;
                                index= dlnew->index;
                                while(efa) {
-                                       index[0]= (long)efa->v1->tmp.l;
-                                       index[1]= (long)efa->v2->tmp.l;
-                                       index[2]= (long)efa->v3->tmp.l;
+                                       index[0]= (intptr_t)efa->v1->tmp.l;
+                                       index[1]= (intptr_t)efa->v2->tmp.l;
+                                       index[2]= (intptr_t)efa->v3->tmp.l;
                                        
                                        index+= 3;
                                        efa= efa->next;
index 4588ef800e1f55c9a4497586a9274ecc1c9d1d6e..72f70cf17ff520ca5b69b95d8b38840f6d11c1db 100644 (file)
@@ -59,6 +59,7 @@
 #include "BKE_armature.h"
 #include "BKE_bad_level_calls.h"
 #include "BKE_blender.h"
+#include "BKE_collision.h"
 #include "BKE_constraint.h"
 #include "BKE_deform.h"
 #include "BKE_depsgraph.h"
@@ -157,6 +158,13 @@ static void add_to_effectorcache(ListBase *lb, Object *ob, Object *obsrc)
                }
        }
        else if(pd->forcefield) {
+               
+               if(pd->forcefield == PFIELD_WIND)
+               {
+                       pd->rng = rng_new(1);
+                       rng_srandom(pd->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
+               }
+       
                ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
                ec->ob= ob;
                BLI_addtail(lb, ec);
@@ -205,13 +213,288 @@ void pdEndEffectors(ListBase *lb)
                pEffectorCache *ec;
                /* restore full copy */
                for(ec= lb->first; ec; ec= ec->next)
+               {
+                       if(ec->ob->pd && (ec->ob->pd->forcefield == PFIELD_WIND))
+                               rng_free(ec->ob->pd->rng);
+                       
                        *(ec->ob)= ec->obcopy;
+               }
 
                BLI_freelistN(lb);
        }
 }
 
 
+/************************************************/
+/*                     Effectors               */
+/************************************************/
+
+// triangle - ray callback function
+static void eff_tri_ray_hit(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{      
+       // whenever we hit a bounding box, we don't check further
+       hit->dist = -1;
+       hit->index = 1;
+}
+
+// get visibility of a wind ray
+static float eff_calc_visibility(Object *ob, float *co, float *dir)
+{
+       CollisionModifierData **collobjs = NULL;
+       int numcollobj = 0, i;
+       float norm[3], len = 0.0;
+       float visibility = 1.0;
+       
+       collobjs = get_collisionobjects(ob, &numcollobj);
+       
+       if(!collobjs)
+               return 0;
+       
+       VECCOPY(norm, dir);
+       VecMulf(norm, -1.0);
+       len = Normalize(norm);
+       
+       // check all collision objects
+       for(i = 0; i < numcollobj; i++)
+       {
+               CollisionModifierData *collmd = collobjs[i];
+               
+               if(collmd->bvhtree)
+               {
+                       BVHTreeRayHit hit;
+                       
+                       hit.index = -1;
+                       hit.dist = len + FLT_EPSILON;
+                       
+                       // check if the way is blocked
+                       if(BLI_bvhtree_ray_cast(collmd->bvhtree, co, norm, &hit, eff_tri_ray_hit, NULL)>=0)
+                       {
+                               // visibility is only between 0 and 1, calculated from 1-absorption
+                               visibility *= MAX2(0.0, MIN2(1.0, (1.0-((float)collmd->absorption)*0.01)));
+                               
+                               if(visibility <= 0.0f)
+                                       break;
+                       }
+               }
+       }
+       
+       MEM_freeN(collobjs);
+       
+       return visibility;
+}
+
+// noise function for wind e.g.
+static float wind_func(struct RNG *rng, float strength)
+{
+       int random = (rng_getInt(rng)+1) % 65535; // max 2357
+       float force = rng_getFloat(rng) + 1.0f;
+       float ret;
+       float sign = 0;
+       
+       sign = (random > 32000.0) ? 1.0: -1.0; // dividing by 2 is not giving equal sign distribution
+       
+       ret = sign*((float)random / force)*strength/65535.0f;
+       
+       return ret;
+}
+
+
+static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
+{
+       if(!usemin)
+               mindist= 0.0f;
+
+       if(fac < mindist) {
+               return 1.0f;
+       }
+       else if(usemax) {
+               if(fac>maxdist || (maxdist-mindist)<=0.0f)
+                       return 0.0f;
+
+               fac= (fac-mindist)/(maxdist-mindist);
+               return 1.0f - (float)pow((double)fac, (double)power);
+       }
+       else
+               return pow((double)1.0f+fac-mindist, (double)-power);
+}
+
+static float falloff_func_dist(PartDeflect *pd, float fac)
+{
+       return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
+}
+
+static float falloff_func_rad(PartDeflect *pd, float fac)
+{
+       return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
+}
+
+float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
+{
+       float eff_dir[3], temp[3];
+       float falloff=1.0, fac, r_fac;
+
+       if(pd->forcefield==PFIELD_LENNARDJ)
+               return falloff; /* Lennard-Jones field has it's own falloff built in */
+
+       VecCopyf(eff_dir,eff_velocity);
+       Normalize(eff_dir);
+
+       if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
+               falloff=0.0f;
+       else switch(pd->falloff){
+               case PFIELD_FALL_SPHERE:
+                       fac=VecLength(vec_to_part);
+                       falloff= falloff_func_dist(pd, fac);
+                       break;
+
+               case PFIELD_FALL_TUBE:
+                       fac=Inpf(vec_to_part,eff_dir);
+                       falloff= falloff_func_dist(pd, ABS(fac));
+                       if(falloff == 0.0f)
+                               break;
+
+                       VECADDFAC(temp,vec_to_part,eff_dir,-fac);
+                       r_fac=VecLength(temp);
+                       falloff*= falloff_func_rad(pd, r_fac);
+                       break;
+               case PFIELD_FALL_CONE:
+                       fac=Inpf(vec_to_part,eff_dir);
+                       falloff= falloff_func_dist(pd, ABS(fac));
+                       if(falloff == 0.0f)
+                               break;
+
+                       r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
+                       falloff*= falloff_func_rad(pd, r_fac);
+
+                       break;
+       }
+
+       return falloff;
+}
+
+void do_physical_effector(Object *ob, float *opco, short type, float force_val, float distance, float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, struct RNG *rng, float noise_factor, float charge, float pa_size)
+{
+       float mag_vec[3]={0,0,0};
+       float temp[3], temp2[3];
+       float eff_vel[3];
+       float noise = 0, visibility;
+       
+       // calculate visibility
+       visibility = eff_calc_visibility(ob, opco, vec_to_part);
+       if(visibility <= 0.0)
+               return;
+       falloff *= visibility;
+
+       VecCopyf(eff_vel,eff_velocity);
+       Normalize(eff_vel);
+
+       switch(type){
+               case PFIELD_WIND:
+                       VECCOPY(mag_vec,eff_vel);
+                       
+                       // add wind noise here, only if we have wind
+                       if((noise_factor > 0.0f) && (force_val > FLT_EPSILON))
+                               noise = wind_func(rng, noise_factor);
+                       
+                       VecMulf(mag_vec,(force_val+noise)*falloff);
+                       VecAddf(field,field,mag_vec);
+                       break;
+
+               case PFIELD_FORCE:
+                       if(planar)
+                               Projf(mag_vec,vec_to_part,eff_vel);
+                       else
+                               VecCopyf(mag_vec,vec_to_part);
+
+                       Normalize(mag_vec);
+
+                       VecMulf(mag_vec,force_val*falloff);
+                       VecAddf(field,field,mag_vec);
+                       break;
+
+               case PFIELD_VORTEX:
+                       Crossf(mag_vec,eff_vel,vec_to_part);
+
+                       Normalize(mag_vec);
+
+                       VecMulf(mag_vec,force_val*distance*falloff);
+                       VecAddf(field,field,mag_vec);
+
+                       break;
+               case PFIELD_MAGNET:
+                       if(planar)
+                               VecCopyf(temp,eff_vel);
+                       else
+                               /* magnetic field of a moving charge */
+                               Crossf(temp,eff_vel,vec_to_part);
+
+                       Normalize(temp);
+
+                       Crossf(temp2,velocity,temp);
+                       VecAddf(mag_vec,mag_vec,temp2);
+
+                       VecMulf(mag_vec,force_val*falloff);
+                       VecAddf(field,field,mag_vec);
+                       break;
+               case PFIELD_HARMONIC:
+                       if(planar)
+                               Projf(mag_vec,vec_to_part,eff_vel);
+                       else
+                               VecCopyf(mag_vec,vec_to_part);
+
+                       Normalize(mag_vec);
+
+                       VecMulf(mag_vec,force_val*falloff);
+                       VecSubf(field,field,mag_vec);
+
+                       VecCopyf(mag_vec,velocity);
+                       /* 1.9 is an experimental value to get critical damping at damp=1.0 */
+                       VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
+                       VecSubf(field,field,mag_vec);
+                       break;
+               case PFIELD_CHARGE:
+                       if(planar)
+                               Projf(mag_vec,vec_to_part,eff_vel);
+                       else
+                               VecCopyf(mag_vec,vec_to_part);
+
+                       Normalize(mag_vec);
+
+                       VecMulf(mag_vec,charge*force_val*falloff);
+                       VecAddf(field,field,mag_vec);
+                       break;
+               case PFIELD_LENNARDJ:
+               {
+                       float fac;
+
+                       if(planar) {
+                               Projf(mag_vec,vec_to_part,eff_vel);
+                               distance = VecLength(mag_vec);
+                       }
+                       else
+                               VecCopyf(mag_vec,vec_to_part);
+
+                       /* at this distance the field is 60 times weaker than maximum */
+                       if(distance > 2.22 * (size+pa_size))
+                               break;
+
+                       fac = pow((size+pa_size)/distance,6.0);
+                       
+                       fac = - fac * (1.0 - fac) / distance;
+
+                       /* limit the repulsive term drastically to avoid huge forces */
+                       fac = ((fac>2.0) ? 2.0 : fac);
+
+                       /* 0.003715 is the fac value at 2.22 times (size+pa_size),
+                          substracted to avoid discontinuity at the border
+                       */
+                       VecMulf(mag_vec, force_val * (fac-0.0037315));
+                       VecAddf(field,field,mag_vec);
+                       break;
+               }
+       }
+}
+
 /*  -------- pdDoEffectors() --------
     generic force/speed system, now used for particles and softbodies
        lb                      = listbase with objects that take part in effecting
@@ -244,13 +527,10 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float
        pEffectorCache *ec;
        PartDeflect *pd;
        float vect_to_vert[3];
-       float f_force, force_vec[3];
        float *obloc;
-       float distance, force_val, ffall_val;
-       float guidecollect[3], guidedist= 0.0f;
-       int cur_frame;
        
-       guidecollect[0]= guidecollect[1]= guidecollect[2]=0.0f;
+       float distance, vec_to_part[3];
+       float falloff;
 
        /* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
        /* Check for min distance here? (yes would be cool to add that, ton) */
@@ -261,178 +541,28 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float
                pd= ob->pd;
                        
                /* Get IPO force strength and fall off values here */
-               if (has_ipo_code(ob->ipo, OB_PD_FSTR))
-                       force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time);
-               else 
-                       force_val = pd->f_strength;
-               
-               if (has_ipo_code(ob->ipo, OB_PD_FFALL)) 
-                       ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
-               else 
-                       ffall_val = pd->f_power;
-                       
-               /* Need to set r.cfra for paths (investigate, ton) (uses ob->ctime now, ton) */
-               if(ob->ctime!=cur_time) {
-                       cur_frame = G.scene->r.cfra;
-                       G.scene->r.cfra = (int)cur_time;
-                       where_is_object_time(ob, cur_time);
-                       G.scene->r.cfra = cur_frame;
-               }
+               where_is_object_time(ob,cur_time);
                        
                /* use center of object for distance calculus */
-               obloc= ob->obmat[3];
-               VECSUB(vect_to_vert, obloc, opco);
-               distance = VecLength(vect_to_vert);
-                       
-               if((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist && pd->forcefield != PFIELD_GUIDE)
-                       ;       /* don't do anything */
-               else if((pd->flag & PFIELD_USEMIN) && distance<pd->mindist && pd->forcefield != PFIELD_GUIDE)
+               VecSubf(vec_to_part, opco, ob->obmat[3]);
+               distance = VecLength(vec_to_part);
+
+               falloff=effector_falloff(pd,ob->obmat[2],vec_to_part);          
+               
+               if(falloff<=0.0f)
                        ;       /* don't do anything */
-               else if(pd->forcefield == PFIELD_WIND) {
-                       VECCOPY(force_vec, ob->obmat[2]);
-                       
-                       /* wind works harder perpendicular to normal, would be nice for softbody later (ton) */
-                       
-                       /* Limit minimum distance to vertex so that */
-                       /* the force is not too big */
-                       if (distance < 0.001) distance = 0.001f;
-                       f_force = (force_val)*(1/(1000 * (float)pow((double)distance, (double)ffall_val)));
-                       /* this option for softbody only */
-                       if(flags && PE_WIND_AS_SPEED){
-                               speed[0] -= (force_vec[0] * f_force );
-                               speed[1] -= (force_vec[1] * f_force );
-                               speed[2] -= (force_vec[2] * f_force );
-                       }
-                       else{
-                               force[0] += force_vec[0]*f_force;
-                               force[1] += force_vec[1]*f_force;
-                               force[2] += force_vec[2]*f_force;
-                       }
-               }
-               else if(pd->forcefield == PFIELD_FORCE) {
-                       
-                       /* only use center of object */
-                       obloc= ob->obmat[3];
-
-                       /* Now calculate the gravitational force */
-                       VECSUB(vect_to_vert, obloc, opco);
-                       distance = VecLength(vect_to_vert);
-
-                       /* Limit minimum distance to vertex so that */
-                       /* the force is not too big */
-                       if (distance < 0.001) distance = 0.001f;
-                       f_force = (force_val)*(1.0/(1000.0 * (float)pow((double)distance, (double)ffall_val)));
-                       force[0] += (vect_to_vert[0] * f_force );
-                       force[1] += (vect_to_vert[1] * f_force );
-                       force[2] += (vect_to_vert[2] * f_force );
-               }
-               else if(pd->forcefield == PFIELD_VORTEX) {
-                       float vortexvec[3];
+               else {
+                       float field[3]={0,0,0}, tmp[3];
+                       VECCOPY(field, force);
+                       do_physical_effector(ob, opco, pd->forcefield,pd->f_strength,distance,
+                                                               falloff,pd->f_dist,pd->f_damp,ob->obmat[2],vec_to_part,
+                                                               speed,force,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise, 0.0f, 0.0f);
                        
-                       /* only use center of object */
-                       obloc= ob->obmat[3];
-
-                       /* Now calculate the vortex force */
-                       VECSUB(vect_to_vert, obloc, opco);
-                       distance = VecLength(vect_to_vert);
-
-                       Crossf(force_vec, ob->obmat[2], vect_to_vert);
-                       Normalize(force_vec);
-
-                       /* Limit minimum distance to vertex so that */
-                       /* the force is not too big */
-                       if (distance < 0.001) distance = 0.001f;
-                       f_force = (force_val)*(1.0/(100.0 * (float)pow((double)distance, (double)ffall_val)));
-                       vortexvec[0]= -(force_vec[0] * f_force );
-                       vortexvec[1]= -(force_vec[1] * f_force );
-                       vortexvec[2]= -(force_vec[2] * f_force );
-                       
-                       /* this option for softbody only */
-                       if(flags &&PE_WIND_AS_SPEED) {
-                               speed[0]+= vortexvec[0];
-                               speed[1]+= vortexvec[1];
-                               speed[2]+= vortexvec[2];
-                       }
-                       else {
-                               /* since vortex alters the speed, we have to correct for the previous vortex result */
-                               speed[0]+= vortexvec[0] - ec->oldspeed[0];
-                               speed[1]+= vortexvec[1] - ec->oldspeed[1];
-                               speed[2]+= vortexvec[2] - ec->oldspeed[2];
-                               
-                               VECCOPY(ec->oldspeed, vortexvec);
+                       // for softbody backward compatibility
+                       if(flags & PE_WIND_AS_SPEED){
+                               VECSUB(tmp, force, field);
+                               VECSUB(speed, speed, tmp);
                        }
                }
-               else if(pd->forcefield == PFIELD_GUIDE) {
-                       float guidevec[4], guidedir[3];
-                       float mindist= force_val; /* force_val is actually mindist in the UI */
-                       
-                       distance= ec->guide_dist;
-                       
-                       /* WARNING: bails out with continue here */
-                       if((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist) continue;
-                       
-                       /* calculate contribution factor for this guide */
-                       if(distance<=mindist) f_force= 1.0f;
-                       else if(pd->flag & PFIELD_USEMAX) {
-                               if(distance>pd->maxdist || mindist>=pd->maxdist) f_force= 0.0f;
-                               else {
-                                       f_force= 1.0f - (distance-mindist)/(pd->maxdist - mindist);
-                                       if(ffall_val!=0.0f)
-                                               f_force = (float)pow(f_force, ffall_val+1.0);
-                               }
-                       }
-                       else {
-                               f_force= 1.0f/(1.0f + distance-mindist);
-                               if(ffall_val!=0.0f)
-                                       f_force = (float)pow(f_force, ffall_val+1.0);
-                       }
-                       
-                       /* now derive path point from loc_time */
-                       if(pd->flag & PFIELD_GUIDE_PATH_ADD)
-                               where_on_path(ob, f_force*loc_time*ec->time_scale, guidevec, guidedir);
-                       else
-                               where_on_path(ob, loc_time*ec->time_scale, guidevec, guidedir);
-                       
-                       VECSUB(guidedir, guidevec, ec->oldloc);
-                       VECCOPY(ec->oldloc, guidevec);
-                       
-                       Mat4Mul3Vecfl(ob->obmat, guidedir);
-                       VecMulf(guidedir, ec->scale);   /* correction for lifetime and speed */
-                       
-                       /* we subtract the speed we gave it previous step */
-                       VECCOPY(guidevec, guidedir);
-                       VECSUB(guidedir, guidedir, ec->oldspeed);
-                       VECCOPY(ec->oldspeed, guidevec);
-                       
-                       /* if it fully contributes, we stop */
-                       if(f_force==1.0) {
-                               VECCOPY(guidecollect, guidedir);
-                               guidedist= 1.0f;
-                               break;
-                       }
-                       else if(guidedist<1.0f) {
-                               VecMulf(guidedir, f_force);
-                               VECADD(guidecollect, guidecollect, guidedir);
-                               guidedist += f_force;
-                       }                                       
-               }
-       }
-
-       /* all guides are accumulated here */
-       if(guidedist!=0.0f) {
-               if(guidedist!=1.0f) VecMulf(guidecollect, 1.0f/guidedist);
-               VECADD(speed, speed, guidecollect);
        }
 }
-
-
-/* for paf start to end, store all matrices for objects */
-typedef struct pMatrixCache {
-       float obmat[4][4];
-       float imat[3][3];
-} pMatrixCache;
-
-/* for fluidsim win32 debug messages */
-#if defined(WIN32) && (!(defined snprintf))
-#define snprintf _snprintf
-#endif
index cab7865c1b6047d0ecfbe7c67c3ba2248e6cc396..b9e3c593ddf60aad682cdc7bddff7d8a6fcd5e07 100644 (file)
@@ -50,6 +50,8 @@
 #include "BKE_icons.h"
 #include "BKE_utildefines.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #define GS(a)  (*((short *)(a)))
 
 /* GLOBALS */
index b6c8ad59e0801a23a88af998612a72fb2b75d9fc..07537e3a81c6b4fa8cafbb6b5809e15d4021d74f 100644 (file)
@@ -86,6 +86,8 @@
 #include "blendef.h"
 #include "BSE_time.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* max int, to indicate we don't store sequences in ibuf */
 #define IMA_NO_INDEX   0x7FEFEFEF
 
@@ -630,11 +632,11 @@ void free_old_images()
        }
 }
 
-static unsigned long image_mem_size(Image *ima)
+static uintptr_t image_mem_size(Image *ima)
 {
        ImBuf *ibuf, *ibufm;
        int level;
-       unsigned long size = 0;
+       uintptr_t size = 0;
 
        size= 0;
        for(ibuf= ima->ibufs.first; ibuf; ibuf= ibuf->next) {
@@ -656,7 +658,7 @@ static unsigned long image_mem_size(Image *ima)
 void BKE_image_print_memlist(void)
 {
        Image *ima;
-       unsigned long size, totsize= 0;
+       uintptr_t size, totsize= 0;
 
        for(ima= G.main->image.first; ima; ima= ima->id.next)
                totsize += image_mem_size(ima);
index 297ac0b1530c874aa0434b6b6e7840524ab4fb7e..93e35a4db061b3906ae0070f1eb553acdaa201a9 100644 (file)
@@ -1354,25 +1354,57 @@ DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s,
        }       
 }
 
+
+static void CalcFloat( float *v1, float *v2, float *v3, float *n)
+{
+       float n1[3],n2[3];
+
+       n1[0]= v1[0]-v2[0];
+       n2[0]= v2[0]-v3[0];
+       n1[1]= v1[1]-v2[1];
+       n2[1]= v2[1]-v3[1];
+       n1[2]= v1[2]-v2[2];
+       n2[2]= v2[2]-v3[2];
+       n[0]= n1[1]*n2[2]-n1[2]*n2[1];
+       n[1]= n1[2]*n2[0]-n1[0]*n2[2];
+       n[2]= n1[0]*n2[1]-n1[1]*n2[0];
+}
+
+static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n)
+{
+       /* real cross! */
+       float n1[3],n2[3];
+
+       n1[0]= v1[0]-v3[0];
+       n1[1]= v1[1]-v3[1];
+       n1[2]= v1[2]-v3[2];
+
+       n2[0]= v2[0]-v4[0];
+       n2[1]= v2[1]-v4[1];
+       n2[2]= v2[2]-v4[2];
+
+       n[0]= n1[1]*n2[2]-n1[2]*n2[1];
+       n[1]= n1[2]*n2[0]-n1[0]*n2[2];
+       n[2]= n1[0]*n2[1]-n1[1]*n2[0];
+}
+
 float calculateVertexWindForce(float wind[3], float vertexnormal[3])  
 {
-       return fabs(INPR(wind, vertexnormal));
+       return (INPR(wind, vertexnormal));
 }
 
 void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
 {
        /* Collect forces and derivatives:  F,dFdX,dFdV */
        Cloth           *cloth          = clmd->clothObject;
-       long            i               = 0;
+       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}};
        MFace           *mfaces         = cloth->mfaces;
-       //ClothVertex   *verts          = cloth->verts;
-       float wind_normalized[3];
        unsigned int numverts = cloth->numverts;
        LinkNode *search = cloth->springs;
-
+       lfVector *winvec;
 
        VECCOPY(gravity, clmd->sim_parms->gravity);
        mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
@@ -1387,7 +1419,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        /* multiply lF with mass matrix
        // force = mass * acceleration (in this case: gravity)
        */
-       for(i = 0; i < (long)numverts; i++)
+       for(i = 0; i < numverts; i++)
        {
                float temp[3];
                VECCOPY(temp, lF[i]);
@@ -1399,70 +1431,61 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        /* handle external forces like wind */
        if(effectors)
        {       
-               for(i = 0; i < cloth->numfaces; i++)
+               // 0 = force, 1 = normalized force
+               winvec = create_lfvector(cloth->numverts);
+               
+               if(!winvec)
+                       printf("winvec: out of memory in implicit.c\n");
+               
+               // precalculate wind forces
+               for(i = 0; i < cloth->numverts; i++)
                {
-                       float vertexnormal[3]={0,0,0};
                        float speed[3] = {0.0f, 0.0f,0.0f};
-                       float force[3]= {0.0f, 0.0f, 0.0f};
                        
+                       pdDoEffectors(effectors, lX[i], winvec[i], speed, (float)G.scene->r.cfra, 0.0f, 0);
+               }
+               
+               for(i = 0; i < cloth->numfaces; i++)
+               {
+                       float trinormal[3]={0,0,0}; // normalized triangle normal
+                       float triunnormal[3]={0,0,0}; // not-normalized-triangle normal
+                       float tmp[3]={0,0,0};
+                       float factor = (mfaces[i].v4) ? 0.25 : 1.0 / 3.0;
+                       factor *= 0.02;
+                       
+                       // calculate face normal
                        if(mfaces[i].v4)
-                               CalcNormFloat4(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],lX[mfaces[i].v4],vertexnormal);
+                               CalcFloat4(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],lX[mfaces[i].v4],triunnormal);
                        else
-                               CalcNormFloat(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],vertexnormal);
+                               CalcFloat(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],triunnormal);
                        
-                       pdDoEffectors(effectors, lX[mfaces[i].v1], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
-                       VECCOPY(wind_normalized, speed);
-                       Normalize(wind_normalized);
-                       VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
+                       VECCOPY(trinormal, triunnormal);
+                       Normalize(trinormal);
                        
-                       if(mfaces[i].v4)
-                       {
-                               VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], wind_normalized, 0.25);
-                       }
-                       else
-                       {
-                               VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], wind_normalized, 1.0 / 3.0);
-                       }
+                       // add wind from v1
+                       VECCOPY(tmp, trinormal);
+                       VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v1], triunnormal));
+                       VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], tmp, factor);
                        
-                       speed[0] = speed[1] = speed[2] = 0.0;
-                       pdDoEffectors(effectors, lX[mfaces[i].v2], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
-                       VECCOPY(wind_normalized, speed);
-                       Normalize(wind_normalized);
-                       VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
-                       if(mfaces[i].v4)
-                       {
-                               VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], wind_normalized, 0.25);
-                       }
-                       else
-                       {
-                               VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], wind_normalized, 1.0 / 3.0);
-                       }
+                       // add wind from v2
+                       VECCOPY(tmp, trinormal);
+                       VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v2], triunnormal));
+                       VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], tmp, factor);
                        
-                       speed[0] = speed[1] = speed[2] = 0.0;
-                       pdDoEffectors(effectors, lX[mfaces[i].v3], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
-                       VECCOPY(wind_normalized, speed);
-                       Normalize(wind_normalized);
-                       VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
-                       if(mfaces[i].v4)
-                       {
-                               VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], wind_normalized, 0.25);
-                       }
-                       else
-                       {
-                               VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], wind_normalized, 1.0 / 3.0);
-                       }
+                       // add wind from v3
+                       VECCOPY(tmp, trinormal);
+                       VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v3], triunnormal));
+                       VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], tmp, factor);
                        
-                       speed[0] = speed[1] = speed[2] = 0.0;
+                       // add wind from v4
                        if(mfaces[i].v4)
                        {
-                               pdDoEffectors(effectors, lX[mfaces[i].v4], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
-                               VECCOPY(wind_normalized, speed);
-                               Normalize(wind_normalized);
-                               VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
-                               VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], wind_normalized, 0.25);
+                               VECCOPY(tmp, trinormal);
+                               VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v4], triunnormal));
+                               VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor);
                        }
-                       
                }
+               del_lfvector(winvec);
        }
                
        // calculate spring forces
index 59eb3837aab9b01b71292961c8b01eb615a77eed..4af25ee99e713d14c7796ec55cb579476a2f59ae 100644 (file)
@@ -182,7 +182,7 @@ int part_ar[PART_TOTIPO]= {
        PART_EMIT_FREQ, PART_EMIT_LIFE, PART_EMIT_VEL, PART_EMIT_AVE, PART_EMIT_SIZE,
        PART_AVE, PART_SIZE, PART_DRAG, PART_BROWN, PART_DAMP, PART_LENGTH, PART_CLUMP,
     PART_GRAV_X, PART_GRAV_Y, PART_GRAV_Z, PART_KINK_AMP, PART_KINK_FREQ, PART_KINK_SHAPE,
-       PART_BB_TILT
+       PART_BB_TILT, PART_PD_FSTR, PART_PD_FFALL, PART_PD_FMAXD, PART_PD2_FSTR, PART_PD2_FFALL, PART_PD2_FMAXD
 };
 
 
@@ -1608,6 +1608,18 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
                        poin= &(part->kink_shape); break;
                case PART_BB_TILT:
                        poin= &(part->bb_tilt); break;
+               case PART_PD_FSTR:
+                       poin= (part->pd?(&(part->pd->f_strength)):NULL); break;
+               case PART_PD_FFALL:
+                       poin= (part->pd?(&(part->pd->f_power)):NULL); break;
+               case PART_PD_FMAXD:
+                       poin= (part->pd?(&(part->pd->maxdist)):NULL); break;
+               case PART_PD2_FSTR:
+                       poin= (part->pd2?(&(part->pd2->f_strength)):NULL); break;
+               case PART_PD2_FFALL:
+                       poin= (part->pd2?(&(part->pd2->f_power)):NULL); break;
+               case PART_PD2_FMAXD:
+                       poin= (part->pd2?(&(part->pd2->maxdist)):NULL); break;
                }
        }
 
index 1dc76296c28783d75d5164f5ca7280fc7fd6c0f6..4c74fe1cca2c8f551cc218669bbc7793f4456de3 100644 (file)
 #include "BKE_utildefines.h"
 #include "depsgraph_private.h"
 #include "BKE_bmesh.h"
+#include "BKE_deform.h"
+#include "BKE_shrinkwrap.h"
 
 #include "LOD_DependKludge.h"
 #include "LOD_decimation.h"
@@ -5493,7 +5495,7 @@ static void collisionModifier_deformVerts(
                
                numverts = dm->getNumVerts ( dm );
                
-               if(current_time > collmd->time)
+               if((current_time > collmd->time)|| (BKE_ptcache_get_continue_physics()))
                {       
                        // check if mesh has changed
                        if(collmd->x && (numverts != collmd->numverts))
@@ -6120,22 +6122,6 @@ CustomDataMask explodeModifier_requiredDataMask(ModifierData *md)
        return dataMask;
 }
 
-/* this should really be put somewhere permanently */
-static float vert_weight(MDeformVert *dvert, int group)
-{
-       MDeformWeight *dw;
-       int i;
-       
-       if(dvert) {
-               dw= dvert->dw;
-               for(i= dvert->totweight; i>0; i--, dw++) {
-                       if(dw->def_nr == group) return dw->weight;
-                       if(i==1) break; /*otherwise dw will point to somewhere it shouldn't*/
-               }
-       }
-       return 0.0;
-}
-
 static void explodeModifier_createFacepa(ExplodeModifierData *emd,
                                         ParticleSystemModifierData *psmd,
       Object *ob, DerivedMesh *dm)
@@ -6179,7 +6165,7 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd,
                        for(i=0; i<totvert; i++){
                                val = BLI_frand();
                                val = (1.0f-emd->protect)*val + emd->protect*0.5f;
-                               if(val < vert_weight(dvert+i,emd->vgroup-1))
+                               if(val < deformvert_get_weight(dvert+i,emd->vgroup-1))
                                        vertpa[i] = -1;
                        }
                }
@@ -7236,6 +7222,126 @@ static void meshdeformModifier_deformVertsEM(
                dm->release(dm);
 }
 
+
+/* Shrinkwrap */
+
+static void shrinkwrapModifier_initData(ModifierData *md)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+       smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
+       smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
+       smd->keepDist   = 0.0f;
+
+       smd->target             = NULL;
+       smd->auxTarget  = NULL;
+}
+
+static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       ShrinkwrapModifierData *smd  = (ShrinkwrapModifierData*)md;
+       ShrinkwrapModifierData *tsmd = (ShrinkwrapModifierData*)target;
+
+       tsmd->target    = smd->target;
+       tsmd->auxTarget = smd->auxTarget;
+
+       strcpy(tsmd->vgroup_name, smd->vgroup_name);
+
+       tsmd->keepDist  = smd->keepDist;
+       tsmd->shrinkType= smd->shrinkType;
+       tsmd->shrinkOpts= smd->shrinkOpts;
+}
+
+CustomDataMask shrinkwrapModifier_requiredDataMask(ModifierData *md)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+       CustomDataMask dataMask = 0;
+
+       /* ask for vertexgroups if we need them */
+       if(smd->vgroup_name[0])
+               dataMask |= (1 << CD_MDEFORMVERT);
+
+       if(smd->shrinkType == MOD_SHRINKWRAP_PROJECT
+       && smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
+               dataMask |= (1 << CD_MVERT);
+               
+       return dataMask;
+}
+
+static int shrinkwrapModifier_isDisabled(ModifierData *md)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+       return !smd->target;
+}
+
+
+static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+       walk(userData, ob, &smd->target);
+       walk(userData, ob, &smd->auxTarget);
+}
+
+static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       DerivedMesh *dm = NULL;
+       CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md);
+
+       /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
+       if(shrinkwrapModifier_requiredDataMask(md))
+       {
+               if(derivedData) dm = CDDM_copy(derivedData);
+               else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
+               else return;
+
+               if(dataMask & CD_MVERT)
+               {
+                       CDDM_apply_vert_coords(dm, vertexCos);
+                       CDDM_calc_normals(dm);
+               }
+       }
+
+       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
+
+       if(dm)
+               dm->release(dm);
+}
+
+static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       DerivedMesh *dm = NULL;
+       CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md);
+
+       if(dataMask)
+       {
+               if(derivedData) dm = CDDM_copy(derivedData);
+               else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data);
+               else return;
+
+               if(dataMask & CD_MVERT)
+               {
+                       CDDM_apply_vert_coords(dm, vertexCos);
+                       CDDM_calc_normals(dm);
+               }
+       }
+
+       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
+
+       if(dm)
+               dm->release(dm);
+}
+
+static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+       if (smd->target)
+               dag_add_relation(forest, dag_get_node(forest, smd->target),   obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
+
+       if (smd->auxTarget)
+               dag_add_relation(forest, dag_get_node(forest, smd->auxTarget), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
+}
+
 /***/
 
 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -7557,6 +7663,21 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->requiredDataMask = explodeModifier_requiredDataMask;
                mti->applyModifier = explodeModifier_applyModifier;
 
+               mti = INIT_TYPE(Shrinkwrap);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->flags = eModifierTypeFlag_AcceptsMesh
+                               | eModifierTypeFlag_AcceptsCVs
+                               | eModifierTypeFlag_SupportsEditmode
+                               | eModifierTypeFlag_EnableInEditmode;
+               mti->initData = shrinkwrapModifier_initData;
+               mti->copyData = shrinkwrapModifier_copyData;
+               mti->requiredDataMask = shrinkwrapModifier_requiredDataMask;
+               mti->isDisabled = shrinkwrapModifier_isDisabled;
+               mti->foreachObjectLink = shrinkwrapModifier_foreachObjectLink;
+               mti->deformVerts = shrinkwrapModifier_deformVerts;
+               mti->deformVertsEM = shrinkwrapModifier_deformVertsEM;
+               mti->updateDepgraph = shrinkwrapModifier_updateDepgraph;
+
                typeArrInit = 0;
 #undef INIT_TYPE
        }
index 643f90637ad7c034d16ef5772629ecf6c702b491..15d6f71073f25272eca2359d2dacf2e84decedab 100644 (file)
@@ -320,8 +320,14 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
 /************************************************/
 void psys_free_settings(ParticleSettings *part)
 {
-       if(part->pd)
+       if(part->pd) {
                MEM_freeN(part->pd);
+               part->pd = NULL;
+       }
+       if(part->pd2) {
+               MEM_freeN(part->pd2);
+               part->pd2 = NULL;
+       }
 }
 
 void free_hair(ParticleSystem *psys, int softbody)
@@ -373,8 +379,11 @@ void psys_free_children(ParticleSystem *psys)
 }
 /* free everything */
 void psys_free(Object *ob, ParticleSystem * psys)
-{
+{      
        if(psys){
+               int nr = 0;
+               ParticleSystem * tpsys;
+               
                if(ob->particlesystem.first == NULL && G.f & G_PARTICLEEDIT)
                        G.f &= ~G_PARTICLEEDIT;
 
@@ -400,6 +409,21 @@ void psys_free(Object *ob, ParticleSystem * psys)
 
                if(psys->effectors.first)
                        psys_end_effectors(psys);
+               
+               // check if we are last non-visible particle system
+               for(tpsys=ob->particlesystem.first; tpsys; tpsys=tpsys->next){
+                       if(tpsys->part)
+                       {
+                               if(ELEM(tpsys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
+                               {
+                                       nr++;
+                                       break;
+                               }
+                       }
+               }
+               // clear do-not-draw-flag
+               if(!nr)
+                       ob->transflag &= ~OB_DUPLIPARTS;
 
                if(psys->part){
                        psys->part->id.us--;            
@@ -411,7 +435,7 @@ void psys_free(Object *ob, ParticleSystem * psys)
 
                if(psys->pointcache)
                        BKE_ptcache_free(psys->pointcache);
-
+               
                MEM_freeN(psys);
        }
 }
@@ -3015,6 +3039,7 @@ ParticleSettings *psys_copy_settings(ParticleSettings *part)
        
        partn= copy_libblock(part);
        if(partn->pd) partn->pd= MEM_dupallocN(part->pd);
+       if(partn->pd2) partn->pd2= MEM_dupallocN(part->pd2);
        
        return partn;
 }
index d1c0cdec71ddba7556b8c3abe640c2cbf876c872..92c2f27bc3171d69f3fc7f50e4ec12dd01e7dfc5 100644 (file)
@@ -60,6 +60,7 @@
 #include "BKE_bad_level_calls.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_displist.h"
+#include "BKE_effect.h"
 #include "BKE_particle.h"
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
@@ -2208,174 +2209,6 @@ static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
 /************************************************/
 /*                     Effectors                                                       */
 /************************************************/
-static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
-{
-       if(!usemin)
-               mindist= 0.0f;
-
-       if(fac < mindist) {
-               return 1.0f;
-       }
-       else if(usemax) {
-               if(fac>maxdist || (maxdist-mindist)<=0.0f)
-                       return 0.0f;
-
-               fac= (fac-mindist)/(maxdist-mindist);
-               return 1.0f - (float)pow((double)fac, (double)power);
-       }
-       else
-               return pow((double)1.0f+fac-mindist, (double)-power);
-}
-
-static float falloff_func_dist(PartDeflect *pd, float fac)
-{
-       return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
-}
-
-static float falloff_func_rad(PartDeflect *pd, float fac)
-{
-       return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
-}
-
-static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
-{
-       float eff_dir[3], temp[3];
-       float falloff=1.0, fac, r_fac;
-       
-       VecCopyf(eff_dir,eff_velocity);
-       Normalize(eff_dir);
-
-       if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
-               falloff=0.0f;
-       else switch(pd->falloff){
-               case PFIELD_FALL_SPHERE:
-                       fac=VecLength(vec_to_part);
-                       falloff= falloff_func_dist(pd, fac);
-                       break;
-
-               case PFIELD_FALL_TUBE:
-                       fac=Inpf(vec_to_part,eff_dir);
-                       falloff= falloff_func_dist(pd, ABS(fac));
-                       if(falloff == 0.0f)
-                               break;
-
-                       VECADDFAC(temp,vec_to_part,eff_dir,-fac);
-                       r_fac=VecLength(temp);
-                       falloff*= falloff_func_rad(pd, r_fac);
-                       break;
-               case PFIELD_FALL_CONE:
-                       fac=Inpf(vec_to_part,eff_dir);
-                       falloff= falloff_func_dist(pd, ABS(fac));
-                       if(falloff == 0.0f)
-                               break;
-
-                       r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
-                       falloff*= falloff_func_rad(pd, r_fac);
-
-                       break;
-//             case PFIELD_FALL_INSIDE:
-                               //for(i=0; i<totface; i++,mface++){
-                               //      VECCOPY(v1,mvert[mface->v1].co);
-                               //      VECCOPY(v2,mvert[mface->v2].co);
-                               //      VECCOPY(v3,mvert[mface->v3].co);
-
-                               //      if(AxialLineIntersectsTriangle(a,co1, co2, v2, v3, v1, &lambda)){
-                               //              if(from==PART_FROM_FACE)
-                               //                      (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
-                               //              else /* store number of intersections */
-                               //                      (pa+(int)(lambda*size[a])*a0mul)->loop++;
-                               //      }
-                               //      
-                               //      if(mface->v4){
-                               //              VECCOPY(v4,mvert[mface->v4].co);
-
-                               //              if(AxialLineIntersectsTriangle(a,co1, co2, v4, v1, v3, &lambda)){
-                               //                      if(from==PART_FROM_FACE)
-                               //                              (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
-                               //                      else
-                               //                              (pa+(int)(lambda*size[a])*a0mul)->loop++;
-                               //              }
-                               //      }
-                               //}
-
-//                     break;
-       }
-
-       return falloff;
-}
-static void do_physical_effector(short type, float force_val, float distance, float falloff, float size, float damp,
-                                                       float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar)
-{
-       float mag_vec[3]={0,0,0};
-       float temp[3], temp2[3];
-       float eff_vel[3];
-
-       VecCopyf(eff_vel,eff_velocity);
-       Normalize(eff_vel);
-
-       switch(type){
-               case PFIELD_WIND:
-                       VECCOPY(mag_vec,eff_vel);
-
-                       VecMulf(mag_vec,force_val*falloff);
-                       VecAddf(field,field,mag_vec);
-                       break;
-
-               case PFIELD_FORCE:
-                       if(planar)
-                               Projf(mag_vec,vec_to_part,eff_vel);
-                       else
-                               VecCopyf(mag_vec,vec_to_part);
-
-                       VecMulf(mag_vec,force_val*falloff);
-                       VecAddf(field,field,mag_vec);
-                       break;
-
-               case PFIELD_VORTEX:
-                       Crossf(mag_vec,eff_vel,vec_to_part);
-                       Normalize(mag_vec);
-
-                       VecMulf(mag_vec,force_val*distance*falloff);
-                       VecAddf(field,field,mag_vec);
-
-                       break;
-               case PFIELD_MAGNET:
-                       if(planar)
-                               VecCopyf(temp,eff_vel);
-                       else
-                               /* magnetic field of a moving charge */
-                               Crossf(temp,eff_vel,vec_to_part);
-
-                       Crossf(temp2,velocity,temp);
-                       VecAddf(mag_vec,mag_vec,temp2);
-
-                       VecMulf(mag_vec,force_val*falloff);
-                       VecAddf(field,field,mag_vec);
-                       break;
-               case PFIELD_HARMONIC:
-                       if(planar)
-                               Projf(mag_vec,vec_to_part,eff_vel);
-                       else
-                               VecCopyf(mag_vec,vec_to_part);
-
-                       VecMulf(mag_vec,force_val*falloff);
-                       VecSubf(field,field,mag_vec);
-
-                       VecCopyf(mag_vec,velocity);
-                       /* 1.9 is an experimental value to get critical damping at damp=1.0 */
-                       VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
-                       VecSubf(field,field,mag_vec);
-                       break;
-               case PFIELD_NUCLEAR:
-                       /*pow here is root of cosine expression below*/
-                       //rad=(float)pow(2.0,-1.0/power)*distance/size;
-                       //VECCOPY(mag_vec,vec_to_part);
-                       //Normalize(mag_vec);
-                       //VecMulf(mag_vec,(float)cos(3.0*M_PI/2.0*(1.0-1.0/(pow(rad,power)+1.0)))/(rad+0.2f));
-                       //VECADDFAC(field,field,mag_vec,force_val);
-                       break;
-       }
-}
 static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field)
 {
        TexResult result[4];
@@ -2468,7 +2301,15 @@ static void add_to_effectors(ListBase *lb, Object *ob, Object *obsrc, ParticleSy
                        }
                }
                else if(pd->forcefield)
+               {
                        type |= PSYS_EC_EFFECTOR;
+                       
+                       if(pd->forcefield == PFIELD_WIND)
+                       {
+                               pd->rng = rng_new(1);
+                               rng_srandom(pd->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
+                       }
+               }
        }
        
        if(pd && pd->deflect)
@@ -2493,10 +2334,11 @@ static void add_to_effectors(ListBase *lb, Object *ob, Object *obsrc, ParticleSy
 
                for(i=0; epsys; epsys=epsys->next,i++){
                        type=0;
-                       if(epsys!=psys){
+                       if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){
                                epart=epsys->part;
 
-                               if(epsys->part->pd && epsys->part->pd->forcefield)
+                               if((epsys->part->pd && epsys->part->pd->forcefield)
+                                       || (epsys->part->pd2 && epsys->part->pd2->forcefield))
                                        type=PSYS_EC_PARTICLE;
 
                                if(epart->type==PART_REACTOR) {
@@ -2579,6 +2421,9 @@ void psys_end_effectors(ParticleSystem *psys)
 
                        if(ec->tree)
                                BLI_kdtree_free(ec->tree);
+                       
+                       if(ec->ob->pd && (ec->ob->pd->forcefield == PFIELD_WIND))
+                               rng_free(ec->ob->pd->rng);
                }
 
                BLI_freelistN(lb);
@@ -2745,35 +2590,31 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
        ListBase *lb=&psys->effectors;
        ParticleEffectorCache *ec;
        float distance, vec_to_part[3];
-       float falloff;
+       float falloff, charge = 0.0f;
        int p;
 
        /* check all effector objects for interaction */
        if(lb->first){
+               if(psys->part->pd && psys->part->pd->forcefield==PFIELD_CHARGE){
+                       /* Only the charge of the effected particle is used for 
+                          interaction, not fall-offs. If the fall-offs aren't the      
+                          same this will be unphysical, but for animation this         
+                          could be the wanted behavior. If you want physical
+                          correctness the fall-off should be spherical 2.0 anyways.
+                        */
+                       charge = psys->part->pd->f_strength;
+               }
+               if(psys->part->pd2 && psys->part->pd2->forcefield==PFIELD_CHARGE){
+                       charge += psys->part->pd2->f_strength;
+               }
                for(ec = lb->first; ec; ec= ec->next){
                        eob= ec->ob;
                        if(ec->type & PSYS_EC_EFFECTOR){
                                pd=eob->pd;
                                if(psys->part->type!=PART_HAIR && psys->part->integrator)
                                        where_is_object_time(eob,cfra);
-                               /* Get IPO force strength and fall off values here */
-                               //if (has_ipo_code(eob->ipo, OB_PD_FSTR))
-                               //      force_val = IPO_GetFloatValue(eob->ipo, OB_PD_FSTR, cfra);
-                               //else 
-                               //      force_val = pd->f_strength;
-                               
-                               //if (has_ipo_code(eob->ipo, OB_PD_FFALL)) 
-                               //      ffall_val = IPO_GetFloatValue(eob->ipo, OB_PD_FFALL, cfra);
-                               //else 
-                               //      ffall_val = pd->f_power;
-
-                               //if (has_ipo_code(eob->ipo, OB_PD_FMAXD)) 
-                               //      maxdist = IPO_GetFloatValue(eob->ipo, OB_PD_FMAXD, cfra);
-                               //else 
-                               //      maxdist = pd->maxdist;
 
                                /* use center of object for distance calculus */
-                               //obloc= eob->obmat[3];
                                VecSubf(vec_to_part, state->co, eob->obmat[3]);
                                distance = VecLength(vec_to_part);
 
@@ -2786,22 +2627,22 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
                                                                        pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat,
                                                                        pd->f_strength, falloff, force_field);
                                } else {
-                                       do_physical_effector(pd->forcefield,pd->f_strength,distance,
-                                                                               falloff,pd->f_dist,pd->f_damp,eob->obmat[2],vec_to_part,
-                                                                               pa->state.vel,force_field,pd->flag&PFIELD_PLANAR);
+                                       do_physical_effector(eob, state->co, pd->forcefield,pd->f_strength,distance,
+                                                                               falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part,
+                                                                               pa->state.vel,force_field,pd->flag&PFIELD_PLANAR,pd->rng,pd->f_noise,charge,pa->size);
                                }
                        }
                        if(ec->type & PSYS_EC_PARTICLE){
-                               int totepart;
+                               int totepart, i;
                                epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
                                epart= epsys->part;
-                               pd= epart->pd;
+                               pd=epart->pd;
                                totepart= epsys->totpart;
                                
                                if(totepart <= 0)
                                        continue;
                                
-                               if(pd->forcefield==PFIELD_HARMONIC){
+                               if(pd && pd->forcefield==PFIELD_HARMONIC){
                                        /* every particle is mapped to only one harmonic effector particle */
                                        p= pa_no%epsys->totpart;
                                        totepart= p+1;
@@ -2813,31 +2654,27 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
                                epsys->lattice=psys_get_lattice(ob,psys);
 
                                for(; p<totepart; p++){
+                                       /* particle skips itself as effector */
+                                       if(epsys==psys && p == pa_no) continue;
+
                                        epa = epsys->particles + p;
                                        estate.time=-1.0;
                                        if(psys_get_particle_state(eob,epsys,p,&estate,0)){
                                                VECSUB(vec_to_part, state->co, estate.co);
                                                distance = VecLength(vec_to_part);
-
-                                               //if(pd->forcefield==PFIELD_HARMONIC){
-                                               //      //if(cfra < epa->time + radius){ /* radius is fade-in in ui */
-                                               //      //      eforce*=(cfra-epa->time)/radius;
-                                               //      //}
-                                               //}
-                                               //else{
-                                               //      /* Limit minimum distance to effector particle so that */
-                                               //      /* the force is not too big */
-                                               //      if (distance < 0.001) distance = 0.001f;
-                                               //}
                                                
-                                               falloff=effector_falloff(pd,estate.vel,vec_to_part);
+                                               for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) {
+                                                       if(pd==NULL || pd->forcefield==0) continue;
 
-                                               if(falloff<=0.0f)
-                                                       ;       /* don't do anything */
-                                               else
-                                                       do_physical_effector(pd->forcefield,pd->f_strength,distance,
-                                                       falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
-                                                       state->vel,force_field,0);
+                                                       falloff=effector_falloff(pd,estate.vel,vec_to_part);
+
+                                                       if(falloff<=0.0f)
+                                                               ;       /* don't do anything */
+                                                       else
+                                                               do_physical_effector(eob, state->co, pd->forcefield,pd->f_strength,distance,
+                                                               falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
+                                                               state->vel,force_field,0, pd->rng, pd->f_noise,charge,pa->size);
+                                               }
                                        }
                                        else if(pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
                                                /* first step after key release */
@@ -3948,27 +3785,44 @@ static void boid_body(BoidVecFunc *bvf, ParticleData *pa, ParticleSystem *psys,
        bvf->Addf(dvec,dvec,bvec);
        bvf->Addf(state->co,state->co,dvec);
        
-       /* air speed from wind effectors */
-       if(psys->effectors.first){
+       /* air speed from wind and vortex effectors */
+       if(psys->effectors.first) {
                ParticleEffectorCache *ec;
-               for(ec=psys->effectors.first; ec; ec=ec->next){
-                       if(ec->type & PSYS_EC_EFFECTOR){
+               for(ec=psys->effectors.first; ec; ec=ec->next) {
+                       if(ec->type & PSYS_EC_EFFECTOR) {
                                Object *eob = ec->ob;
                                PartDeflect *pd = eob->pd;
+                               float direction[3], vec_to_part[3];
+                               float falloff;
+
+                               if(pd->f_strength != 0.0f) {
+                                       VecCopyf(direction, eob->obmat[2]);
+                                       VecSubf(vec_to_part, state->co, eob->obmat[3]);
+
+                                       falloff=effector_falloff(pd, direction, vec_to_part);
+
+                                       switch(pd->forcefield) {
+                                               case PFIELD_WIND:
+                                                       if(falloff <= 0.0f)
+                                                               ;       /* don't do anything */
+                                                       else {
+                                                               Normalize(direction);
+                                                               VecMulf(direction, pd->f_strength * falloff);
+                                                               bvf->Addf(state->co, state->co, direction);
+                                                       }
+                                                       break;
+                                               case PFIELD_VORTEX:
+                                               {
+                                                       float distance, mag_vec[3];
+                                                       Crossf(mag_vec, direction, vec_to_part);
+                                                       Normalize(mag_vec);
 
-                               if(pd->forcefield==PFIELD_WIND && pd->f_strength!=0.0){
-                                       float distance, wind[3];
-                                       VecCopyf(wind,eob->obmat[2]);
-                                       distance=VecLenf(state->co,eob->obmat[3]);
-
-                                       if (distance < 0.001) distance = 0.001f;
+                                                       distance = VecLength(vec_to_part);
 
-                                       if(pd->flag&PFIELD_USEMAX && distance > pd->maxdist)
-                                               ;
-                                       else{
-                                               Normalize(wind);
-                                               VecMulf(wind,pd->f_strength/(float)pow((double)distance,(double)pd->f_power));
-                                               bvf->Addf(state->co,state->co,wind);
+                                                       VecMulf(mag_vec, pd->f_strength * distance * falloff);
+                                                       bvf->Addf(state->co, state->co, mag_vec);
+                                                       break;
+                                               }
                                        }
                                }
                        }
index fcf1c7ce311fcc3aabba5be136efe7b9e9755e41..47d11bb9d298f42e4104dba76556dac27efb0c9b 100644 (file)
@@ -153,6 +153,9 @@ void init_sensor(bSensor *sens)
        case SENS_ACTUATOR:
                sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
                break;
+       case SENS_DELAY:
+               sens->data= MEM_callocN(sizeof(bDelaySensor), "delaysens");
+               break;
        case SENS_MOUSE:
                ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
                ms->type= LEFTMOUSE;
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
new file mode 100644 (file)
index 0000000..c60535c
--- /dev/null
@@ -0,0 +1,588 @@
+/**
+ * shrinkwrap.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): AndrĂ© Pinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <memory.h>
+#include <stdio.h>
+#include <time.h>
+#include <assert.h>
+
+#include "DNA_object_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BKE_shrinkwrap.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_utildefines.h"
+#include "BKE_deform.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_displist.h"
+#include "BKE_global.h"
+#include "BKE_subsurf.h"
+
+#include "BLI_arithb.h"
+#include "BLI_kdtree.h"
+#include "BLI_kdopbvh.h"
+
+#include "RE_raytrace.h"
+#include "MEM_guardedalloc.h"
+
+
+/* Util macros */
+#define TO_STR(a)      #a
+#define JOIN(a,b)      a##b
+
+#define OUT_OF_MEMORY()        ((void)printf("Shrinkwrap: Out of memory\n"))
+
+/* Benchmark macros */
+#if !defined(_WIN32) && 0
+
+#include <sys/time.h>
+
+#define BENCH(a)       \
+       do {                    \
+               double _t1, _t2;                                \
+               struct timeval _tstart, _tend;  \
+               clock_t _clock_init = clock();  \
+               gettimeofday ( &_tstart, NULL); \
+               (a);                                                    \
+               gettimeofday ( &_tend, NULL);   \
+               _t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );    \
+               _t2 = ( double )   _tend.tv_sec + ( double )   _tend.tv_usec/ ( 1000*1000 );    \
+               printf("%s: %fs (real) %fs (cpu)\n", #a, _t2-_t1, (float)(clock()-_clock_init)/CLOCKS_PER_SEC);\
+       } while(0)
+
+#else
+
+#define BENCH(a)       (a)
+
+#endif
+
+typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *co, float *normal);
+
+/* get derived mesh */
+//TODO is anyfunction that does this? returning the derivedFinal witouth we caring if its in edit mode or not?
+DerivedMesh *object_get_derived_final(Object *ob, CustomDataMask dataMask)
+{
+       if (ob==G.obedit)
+       {
+               DerivedMesh *final = NULL;
+               editmesh_get_derived_cage_and_final(&final, dataMask);
+               return final;
+       }
+       else
+               return mesh_get_derived_final(ob, dataMask);
+}
+
+/* Space transform */
+void space_transform_from_matrixs(SpaceTransform *data, float local[4][4], float target[4][4])
+{
+       float itarget[4][4];
+       Mat4Invert(itarget, target);
+       Mat4MulSerie(data->local2target, itarget, local, 0, 0, 0, 0, 0, 0);
+       Mat4Invert(data->target2local, data->local2target);
+}
+
+void space_transform_apply(const SpaceTransform *data, float *co)
+{
+       VecMat4MulVecfl(co, ((SpaceTransform*)data)->local2target, co);
+}
+
+void space_transform_invert(const SpaceTransform *data, float *co)
+{
+       VecMat4MulVecfl(co, ((SpaceTransform*)data)->target2local, co);
+}
+
+void space_transform_apply_normal(const SpaceTransform *data, float *no)
+{
+       Mat4Mul3Vecfl( ((SpaceTransform*)data)->local2target, no);
+       Normalize(no); // TODO: could we just determine de scale value from the matrix?
+}
+
+void space_transform_invert_normal(const SpaceTransform *data, float *no)
+{
+       Mat4Mul3Vecfl(((SpaceTransform*)data)->target2local, no);
+       Normalize(no); // TODO: could we just determine de scale value from the matrix?
+}
+
+/*
+ * Returns the squared distance between two given points
+ */
+static float squared_dist(const float *a, const float *b)
+{
+       float tmp[3];
+       VECSUB(tmp, a, b);
+       return INPR(tmp, tmp);
+}
+
+/* Main shrinkwrap function */
+void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
+{
+
+       ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData;
+
+       //remove loop dependencies on derived meshs (TODO should this be done elsewhere?)
+       if(smd->target == ob) smd->target = NULL;
+       if(smd->auxTarget == ob) smd->auxTarget = NULL;
+
+
+       //Configure Shrinkwrap calc data
+       calc.smd = smd;
+       calc.ob = ob;
+       calc.original = dm;
+       calc.numVerts = numVerts;
+       calc.vertexCos = vertexCos;
+
+       if(smd->target)
+       {
+               //TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array
+               calc.target = CDDM_copy( object_get_derived_final(smd->target, CD_MASK_BAREMESH) );
+
+               //TODO there might be several "bugs" on non-uniform scales matrixs.. because it will no longer be nearest surface, not sphere projection
+               //because space has been deformed
+               space_transform_setup(&calc.local2target, ob, smd->target);
+
+               calc.keepDist = smd->keepDist;  //TODO: smd->keepDist is in global units.. must change to local
+       }
+
+
+       //Projecting target defined - lets work!
+       if(calc.target)
+       {
+               switch(smd->shrinkType)
+               {
+                       case MOD_SHRINKWRAP_NEAREST_SURFACE:
+                               BENCH(shrinkwrap_calc_nearest_surface_point(&calc));
+                       break;
+
+                       case MOD_SHRINKWRAP_PROJECT:
+                               BENCH(shrinkwrap_calc_normal_projection(&calc));
+                       break;
+
+                       case MOD_SHRINKWRAP_NEAREST_VERTEX:
+                               BENCH(shrinkwrap_calc_nearest_vertex(&calc));
+                       break;
+               }
+       }
+
+       //free memory
+       if(calc.target)
+               calc.target->release( calc.target );
+}
+
+/*
+ * Shrinkwrap to the nearest vertex
+ *
+ * it builds a kdtree of vertexs we can attach to and then
+ * for each vertex performs a nearest vertex search on the tree
+ */
+void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
+{
+       int i;
+       const int vgroup                 = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
+       MDeformVert *const dvert = calc->original ? calc->original->getVertDataArray(calc->original, CD_MDEFORMVERT) : NULL;
+
+       BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
+       BVHTreeNearest  nearest  = NULL_BVHTreeNearest;
+
+
+       BENCH(bvhtree_from_mesh_verts(&treeData, calc->target, 0.0, 2, 6));
+       if(treeData.tree == NULL) return OUT_OF_MEMORY();
+
+       //Setup nearest
+       nearest.index = -1;
+       nearest.dist = FLT_MAX;
+
+#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(treeData,calc) schedule(static)
+       for(i = 0; i<calc->numVerts; ++i)
+       {
+               float *co = calc->vertexCos[i];
+               float tmp_co[3];
+               float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
+               if(weight == 0.0f) continue;
+
+               VECCOPY(tmp_co, co);
+               space_transform_apply(&calc->local2target, tmp_co); //Convert the coordinates to the tree coordinates
+
+               //Use local proximity heuristics (to reduce the nearest search)
+               //
+               //If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex
+               //so we can initiate the "nearest.dist" with the expected value to that last hit.
+               //This will lead in prunning of the search tree.
+               if(nearest.index != -1)
+                       nearest.dist = squared_dist(tmp_co, nearest.co);
+               else
+                       nearest.dist = FLT_MAX;
+
+               BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData);
+
+
+               //Found the nearest vertex
+               if(nearest.index != -1)
+               {
+                       //Adjusting the vertex weight, so that after interpolating it keeps a certain distance from the nearest position
+                       float dist = sasqrt(nearest.dist);
+                       if(dist > FLT_EPSILON) weight *= (dist - calc->keepDist)/dist;
+
+                       //Convert the coordinates back to mesh coordinates
+                       VECCOPY(tmp_co, nearest.co);
+                       space_transform_invert(&calc->local2target, tmp_co);
+
+                       VecLerpf(co, co, tmp_co, weight);       //linear interpolation
+               }
+       }
+
+       free_bvhtree_from_mesh(&treeData);
+}
+
+/*
+ * This function raycast a single vertex and updates the hit if the "hit" is considered valid.
+ * Returns TRUE if "hit" was updated.
+ * Opts control whether an hit is valid or not
+ * Supported options are:
+ *     MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE (front faces hits are ignored)
+ *     MOD_SHRINKWRAP_CULL_TARGET_BACKFACE (back faces hits are ignored)
+ */
+int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
+{
+       float tmp_co[3], tmp_no[3];
+       const float *co, *no;
+       BVHTreeRayHit hit_tmp;
+
+       //Copy from hit (we need to convert hit rays from one space coordinates to the other
+       memcpy( &hit_tmp, hit, sizeof(hit_tmp) );
+
+       //Apply space transform (TODO readjust dist)
+       if(transf)
+       {
+               VECCOPY( tmp_co, vert );
+               space_transform_apply( transf, tmp_co );
+               co = tmp_co;
+
+               VECCOPY( tmp_no, dir );
+               space_transform_apply_normal( transf, tmp_no );
+               no = tmp_no;
+
+               hit_tmp.dist *= Mat4ToScalef( ((SpaceTransform*)transf)->local2target );
+       }
+       else
+       {
+               co = vert;
+               no = dir;
+       }
+
+       hit_tmp.index = -1;
+
+       BLI_bvhtree_ray_cast(tree, co, no, &hit_tmp, callback, userdata);
+
+       if(hit_tmp.index != -1)
+       {
+               float dot = INPR( dir, hit_tmp.no);
+
+               if(((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot <= 0.0f)
+               || ((options & MOD_SHRINKWRAP_CULL_TARGET_BACKFACE) && dot >= 0.0f))
+                       return FALSE; //Ignore hit
+
+
+               //Inverting space transform (TODO make coeherent with the initial dist readjust)
+               if(transf)
+               {
+                       space_transform_invert( transf, hit_tmp.co );
+                       space_transform_invert_normal( transf, hit_tmp.no );
+
+                       hit_tmp.dist = VecLenf( (float*)vert, hit_tmp.co );
+               }
+
+               memcpy(hit, &hit_tmp, sizeof(hit_tmp) );
+               return TRUE;
+       }
+       return FALSE;
+}
+
+
+void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
+{
+       int i;
+
+       //Options about projection direction
+       const char use_normal    = calc->smd->shrinkOpts;
+       float proj_axis[3] = {0.0f, 0.0f, 0.0f};
+       MVert *vert  = NULL; //Needed in case of vertex normal
+       DerivedMesh* ss_mesh = NULL;
+
+       //Vertex group data
+       const int vgroup                   = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
+       const MDeformVert *dvert = calc->original ? calc->original->getVertDataArray(calc->original, CD_MDEFORMVERT) : NULL;
+
+
+       //Raycast and tree stuff
+       BVHTreeRayHit hit;
+       BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;        //target
+
+       //auxiliar target
+       DerivedMesh * aux_mesh = NULL;
+       BVHTreeFromMesh auxData= NULL_BVHTreeFromMesh;
+       SpaceTransform local2aux;
+
+do
+{
+
+       //Prepare data to retrieve the direction in which we should project each vertex
+       if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
+       {
+               //No Mvert information: jump to "free memory and return" part
+               if(calc->original == NULL) break;
+
+               if(calc->smd->subsurfLevels)
+               {
+                       SubsurfModifierData smd;
+                       memset(&smd, 0, sizeof(smd));
+                       smd.subdivType = ME_CC_SUBSURF;                 //catmull clark
+                       smd.levels = calc->smd->subsurfLevels;  //levels
+
+                       ss_mesh = subsurf_make_derived_from_derived(calc->original, &smd, FALSE, NULL, 0, 0);
+
+                       if(ss_mesh)
+                       {
+                               vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT);
+                               if(vert)
+                               {
+                                       //TRICKY: this code assumes subsurface will have the transformed original vertices
+                                       //in their original order at the end of the vert array.
+                                       vert = vert
+                                                + ss_mesh->getNumVerts(ss_mesh)
+                                                - calc->original->getNumVerts(calc->original);
+                               }
+                       }
+
+                       //To make sure we are not letting any memory behind
+                       assert(smd.emCache == NULL);
+                       assert(smd.mCache == NULL);
+               }
+               else
+                       vert = calc->original->getVertDataArray(calc->original, CD_MVERT);
+
+               //Not able to get vert information: jump to "free memory and return" part
+               if(vert == NULL) break;
+       }
+       else
+       {
+               //The code supports any axis that is a combination of X,Y,Z.. altought currently UI only allows to set the 3 diferent axis
+               if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) proj_axis[0] = 1.0f;
+               if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) proj_axis[1] = 1.0f;
+               if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) proj_axis[2] = 1.0f;
+
+               Normalize(proj_axis);
+
+               //Invalid projection direction: jump to "free memory and return" part
+               if(INPR(proj_axis, proj_axis) < FLT_EPSILON) break; 
+       }
+
+       //If the user doesn't allows to project in any direction of projection axis... then theres nothing todo.
+       if((use_normal & (MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)) == 0)
+               break; //jump to "free memory and return" part
+
+
+       //Build target tree
+       BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, calc->keepDist, 4, 6));
+       if(treeData.tree == NULL)
+               break; //jump to "free memory and return" part
+
+
+       //Build auxiliar target
+       if(calc->smd->auxTarget)
+       {
+               space_transform_setup( &local2aux, calc->ob, calc->smd->auxTarget);
+
+               aux_mesh = CDDM_copy( object_get_derived_final(calc->smd->auxTarget, CD_MASK_BAREMESH) );               //TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array
+               if(aux_mesh)
+                       BENCH(bvhtree_from_mesh_faces(&auxData, aux_mesh, 0.0, 4, 6));
+               else
+                       printf("Auxiliar target finalDerived mesh is null\n");
+       }
+
+
+       //Now, everything is ready to project the vertexs!
+#pragma omp parallel for private(i,hit) schedule(static)
+       for(i = 0; i<calc->numVerts; ++i)
+       {
+               float *co = calc->vertexCos[i];
+               float tmp_co[3], tmp_no[3];
+               float lim = 10000.0f; //TODO: we should use FLT_MAX here, but sweepsphere code isnt prepared for that
+               float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
+
+               if(weight == 0.0f) continue;
+
+               if(ss_mesh)
+               {
+                       VECCOPY(tmp_co, vert[i].co);
+               }
+               else
+               {
+                       VECCOPY(tmp_co, co);
+               }
+
+
+               if(vert)
+                       NormalShortToFloat(tmp_no, vert[i].no);
+               else
+                       VECCOPY( tmp_no, proj_axis );
+
+
+               hit.index = -1;
+               hit.dist = lim;
+
+
+               //Project over positive direction of axis
+               if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR)
+               {
+
+                       if(auxData.tree)
+                               normal_projection_project_vertex(0, tmp_co, tmp_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
+
+                       normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
+               }
+
+               //Project over negative direction of axis
+               if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)
+               {
+                       float inv_no[3] = { -tmp_no[0], -tmp_no[1], -tmp_no[2] };
+
+
+                       if(auxData.tree)
+                               normal_projection_project_vertex(0, tmp_co, inv_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
+
+                       normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
+               }
+
+
+               if(hit.index != -1)
+               {
+                       VecLerpf(co, co, hit.co, weight);
+               }
+       }
+
+
+//Simple do{} while(0) structure to allow to easily jump to the "free memory and return" part
+} while(0);
+
+       //free data structures
+
+       free_bvhtree_from_mesh(&treeData);
+       free_bvhtree_from_mesh(&auxData);
+
+       if(aux_mesh)
+               aux_mesh->release(aux_mesh);
+
+       if(ss_mesh)
+               ss_mesh->release(ss_mesh);
+}
+
+/*
+ * Shrinkwrap moving vertexs to the nearest surface point on the target
+ *
+ * it builds a BVHTree from the target mesh and then performs a
+ * NN matchs for each vertex
+ */
+void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
+{
+       int i;
+
+       const int vgroup = get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
+       const MDeformVert *const dvert = calc->original ? calc->original->getVertDataArray(calc->original, CD_MDEFORMVERT) : NULL;
+
+       BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
+       BVHTreeNearest  nearest  = NULL_BVHTreeNearest;
+
+
+
+       //Create a bvh-tree of the given target
+       BENCH(bvhtree_from_mesh_faces( &treeData, calc->target, 0.0, 2, 6));
+       if(treeData.tree == NULL) return OUT_OF_MEMORY();
+
+       //Setup nearest
+       nearest.index = -1;
+       nearest.dist = FLT_MAX;
+
+
+       //Find the nearest vertex
+#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc,treeData) schedule(static)
+       for(i = 0; i<calc->numVerts; ++i)
+       {
+               float *co = calc->vertexCos[i];
+               float tmp_co[3];
+               float weight = vertexgroup_get_vertex_weight(dvert, i, vgroup);
+               if(weight == 0.0f) continue;
+
+               //Convert the vertex to tree coordinates
+               VECCOPY(tmp_co, co);
+               space_transform_apply(&calc->local2target, tmp_co);
+
+               //Use local proximity heuristics (to reduce the nearest search)
+               //
+               //If we already had an hit before.. we assume this vertex is going to have a close hit to that other vertex
+               //so we can initiate the "nearest.dist" with the expected value to that last hit.
+               //This will lead in prunning of the search tree.
+               if(nearest.index != -1)
+                       nearest.dist = squared_dist(tmp_co, nearest.co);
+               else
+                       nearest.dist = FLT_MAX;
+
+               BLI_bvhtree_find_nearest(treeData.tree, tmp_co, &nearest, treeData.nearest_callback, &treeData);
+
+               //Found the nearest vertex
+               if(nearest.index != -1)
+               {
+                       if(calc->smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE)
+                       {
+                               //Make the vertex stay on the front side of the face
+                               VECADDFAC(tmp_co, nearest.co, nearest.no, calc->keepDist);
+                       }
+                       else
+                       {
+                               //Adjusting the vertex weight, so that after interpolating it keeps a certain distance from the nearest position
+                               float dist = sasqrt( nearest.dist );
+                               if(dist > FLT_EPSILON)
+                                       VecLerpf(tmp_co, tmp_co, nearest.co, (dist - calc->keepDist)/dist);     //linear interpolation
+                               else
+                                       VECCOPY( tmp_co, nearest.co );
+                       }
+
+                       //Convert the coordinates back to mesh coordinates
+                       space_transform_invert(&calc->local2target, tmp_co);
+                       VecLerpf(co, co, tmp_co, weight);       //linear interpolation
+               }
+       }
+
+
+       free_bvhtree_from_mesh(&treeData);
+}
+
index d42663e17c783af0457ff37072d3d7e578dafd40..447f6a2a485e3ad9d3308142c229c80774c3235b 100644 (file)
@@ -38,6 +38,8 @@
 #include "DNA_customdata_types.h"
 #include "DNA_mesh_types.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 struct DerivedMesh;
 struct RetopoPaintData;
 
@@ -53,7 +55,7 @@ typedef struct EditVert
                struct EditEdge *e;
                struct EditFace *f;
                void            *p;
-               long             l;
+               intptr_t         l;
                float            fp;
        } tmp;
        float no[3]; /*vertex normal */
@@ -95,7 +97,7 @@ typedef struct EditEdge
                struct EditEdge *e;
                struct EditFace *f;
                void            *p;
-               long             l;
+               intptr_t         l;
                float                   fp;
        } tmp;
        short f1, f2;   /* short, f1 is (ab)used in subdiv */
@@ -122,7 +124,7 @@ typedef struct EditFace
                struct EditEdge *e;
                struct EditFace *f;
                void            *p;
-               long             l;
+               intptr_t         l;
                float                   fp;
        } tmp;
        float n[3], cent[3];
index 0e534783c175885d41b617672beb1ff0e2df5fc7..266aa347aff04a57ecf3e6d2a2131d1b9cae4db2 100644 (file)
@@ -44,6 +44,7 @@ struct RNG*   rng_new                 (unsigned int seed);
 void           rng_free                (struct RNG* rng);
 
 void           rng_seed                (struct RNG* rng, unsigned int seed);
+void rng_srandom(struct RNG *rng, unsigned int seed);
 int                    rng_getInt              (struct RNG* rng);
 double         rng_getDouble   (struct RNG* rng);
 float          rng_getFloat    (struct RNG* rng);
index 11150075bac763f33cf821ae51e1c96f79645212..3bb63506c9551313702292116c5c3c3cbb133cca 100644 (file)
 
        // These definitions are also in arithb for simplicity
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #ifndef M_PI
 #define M_PI           3.14159265358979323846
 #endif
@@ -116,5 +120,9 @@ int closedir (DIR *dp);
 void get_default_root(char *root);
 int check_file_chars(char *filename);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __WINSTUFF_H__ */
 
index 227cb8f5e9a5e23c95f2c446f01bbe8020691d12..e9271ca3bb57ec1978344a88f43cdb5c4440edab 100644 (file)
@@ -34,6 +34,8 @@
 #include "MEM_guardedalloc.h"
 #include "BLI_ghash.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -256,11 +258,7 @@ int BLI_ghashutil_ptrcmp(void *a, void *b) {
 }
 
 unsigned int BLI_ghashutil_inthash(void *ptr) {
-#if defined(_WIN64)
-       unsigned __int64 key = (unsigned __int64)ptr;
-#else
-       unsigned long key = (unsigned long)ptr;
-#endif
+       uintptr_t key = (uintptr_t)ptr;
 
        key += ~(key << 16);
        key ^=  (key >>  5);
index 9671551a7f10212041fd0cfb9bb59d8a82274e6f..989e516d161f6d164d25baf4df996b9f9a25ae5d 100644 (file)
@@ -46,6 +46,7 @@
 
 
 #define MAX_TREETYPE 32
+#define DEFAULT_FIND_NEAREST_HEAP_SIZE 1024
 
 typedef struct BVHNode
 {
@@ -81,7 +82,7 @@ typedef struct BVHOverlapData
 typedef struct BVHNearestData
 {
        BVHTree *tree;
-       float   *co;
+       const float     *co;
        BVHTree_NearestPointCallback callback;
        void    *userdata;
        float proj[13];                 //coordinates projection over axis
@@ -119,6 +120,72 @@ static float KDOP_AXES[13][3] =
 {0, 1.0, -1.0}
 };
 
+/*
+ * Generic push and pop heap
+ */
+#define PUSH_HEAP_BODY(HEAP_TYPE,PRIORITY,heap,heap_size)      \
+{                                                                                                      \
+       HEAP_TYPE element = heap[heap_size-1];                  \
+       int child = heap_size-1;                                                \
+       while(child != 0)                                                               \
+       {                                                                                               \
+               int parent = (child-1) / 2;                                     \
+               if(PRIORITY(element, heap[parent]))                     \
+               {                                                                                       \
+                       heap[child] = heap[parent];                             \
+                       child = parent;                                                 \
+               }                                                                                       \
+               else break;                                                                     \
+       }                                                                                               \
+       heap[child] = element;                                                  \
+}
+
+#define POP_HEAP_BODY(HEAP_TYPE, PRIORITY,heap,heap_size)      \
+{                                                                                                      \
+       HEAP_TYPE element = heap[heap_size-1];                  \
+       int parent = 0;                                                                 \
+       while(parent < (heap_size-1)/2 )                                \
+       {                                                                                               \
+               int child2 = (parent+1)*2;                                      \
+               if(PRIORITY(heap[child2-1], heap[child2]))      \
+                       --child2;                                                               \
+                                                                                                       \
+               if(PRIORITY(element, heap[child2]))                     \
+                       break;                                                                  \
+                                                                                                       \
+               heap[parent] = heap[child2];                            \
+               parent = child2;                                                        \
+       }                                                                                               \
+       heap[parent] = element;                                                 \
+}
+
+int ADJUST_MEMORY(void *local_memblock, void **memblock, int new_size, int *max_size, int size_per_item)
+{
+       int   new_max_size = *max_size * 2;
+       void *new_memblock = NULL;
+
+       if(new_size <= *max_size)
+               return TRUE;
+
+       if(*memblock == local_memblock)
+       {
+               new_memblock = malloc( size_per_item * new_max_size );
+               memcpy( new_memblock, *memblock, size_per_item * *max_size );
+       }
+       else
+               new_memblock = realloc(*memblock, size_per_item * new_max_size );
+
+       if(new_memblock)
+       {
+               *memblock = new_memblock;
+               *max_size = new_max_size;
+               return TRUE;
+       }
+       else
+               return FALSE;
+}
+
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 // Introsort 
 // with permission deriven from the following Java code:
@@ -634,6 +701,18 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array,
        BVHBuildHelper data;
        int depth;
 
+       //Most of bvhtree code relies on 1-leaf trees having at least one branch
+       //We handle that special case here
+       if(num_leafs == 1)
+       {
+               BVHNode *root = branches_array+0;
+               refit_kdop_hull(tree, root, 0, num_leafs);
+               root->main_axis = get_largest_axis(root->bv) / 2;
+               root->totnode = 1;
+               root->children[0] = leafs_array[0];             
+               return;
+       }
+
        branches_array--;       //Implicit trees use 1-based indexs
        
        build_implicit_tree_helper(tree, &data);
@@ -722,6 +801,11 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
                return NULL;
 
        tree = (BVHTree *)MEM_callocN(sizeof(BVHTree), "BVHTree");
+
+       //tree epsilon must be >= FLT_EPSILON
+       //so that tangent rays can still hit a bounding volume..
+       //this bug would show up when casting a ray aligned with a kdop-axis and with an edge of 2 faces
+       epsilon = MAX2(FLT_EPSILON, epsilon);
        
        if(tree)
        {
@@ -1114,15 +1198,18 @@ static float calc_nearest_point(BVHNearestData *data, BVHNode *node, float *near
 }
 
 
-// TODO: use a priority queue to reduce the number of nodes looked on
-static void dfs_find_nearest(BVHNearestData *data, BVHNode *node)
+typedef struct NodeDistance
 {
-       int i;
-       float nearest[3], sdist;
+       BVHNode *node;
+       float dist;
 
-       sdist = calc_nearest_point(data, node, nearest);
-       if(sdist >= data->nearest.dist) return;
+} NodeDistance;
 
+#define NodeDistance_priority(a,b)     ( (a).dist < (b).dist )
+
+// TODO: use a priority queue to reduce the number of nodes looked on
+static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node)
+{
        if(node->totnode == 0)
        {
                if(data->callback)
@@ -1130,17 +1217,129 @@ static void dfs_find_nearest(BVHNearestData *data, BVHNode *node)
                else
                {
                        data->nearest.index     = node->index;
-                       VECCOPY(data->nearest.co, nearest);
-                       data->nearest.dist      = sdist;
+                       data->nearest.dist      = calc_nearest_point(data, node, data->nearest.co);
                }
        }
        else
        {
-               for(i=0; i != node->totnode; i++)
-                       dfs_find_nearest(data, node->children[i]);
+               //Better heuristic to pick the closest node to dive on
+               int i;
+               float nearest[3];
+
+               if(data->proj[ node->main_axis ] <= node->children[0]->bv[node->main_axis*2+1])
+               {
+
+                       for(i=0; i != node->totnode; i++)
+                       {
+                               if( calc_nearest_point(data, node->children[i], nearest) >= data->nearest.dist) continue;
+                               dfs_find_nearest_dfs(data, node->children[i]);
+                       }
+               }
+               else
+               {
+                       for(i=node->totnode-1; i >= 0 ; i--)
+                       {
+                               if( calc_nearest_point(data, node->children[i], nearest) >= data->nearest.dist) continue;
+                               dfs_find_nearest_dfs(data, node->children[i]);
+                       }
+               }
        }
 }
 
+static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node)
+{
+       float nearest[3], sdist;
+       sdist = calc_nearest_point(data, node, nearest);
+       if(sdist >= data->nearest.dist) return;
+       dfs_find_nearest_dfs(data, node);
+}
+
+
+static void NodeDistance_push_heap(NodeDistance *heap, int heap_size)
+PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size)
+
+static void NodeDistance_pop_heap(NodeDistance *heap, int heap_size)
+POP_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size)
+
+//NN function that uses an heap.. this functions leads to an optimal number of min-distance
+//but for normal tri-faces and BV 6-dop.. a simple dfs with local heuristics (as implemented
+//in source/blender/blenkernel/intern/shrinkwrap.c) works faster.
+//
+//It may make sense to use this function if the callback queries are very slow.. or if its impossible
+//to get a nice heuristic
+//
+//this function uses "malloc/free" instead of the MEM_* because it intends to be openmp safe
+static void bfs_find_nearest(BVHNearestData *data, BVHNode *node)
+{
+       int i;
+       NodeDistance default_heap[DEFAULT_FIND_NEAREST_HEAP_SIZE];
+       NodeDistance *heap=default_heap, current;
+       int heap_size = 0, max_heap_size = sizeof(default_heap)/sizeof(default_heap[0]);
+       float nearest[3];
+
+       int callbacks = 0, push_heaps = 0;
+
+       if(node->totnode == 0)
+       {
+               dfs_find_nearest_dfs(data, node);
+               return;
+       }
+
+       current.node = node;
+       current.dist = calc_nearest_point(data, node, nearest);
+
+       while(current.dist < data->nearest.dist)
+       {
+//             printf("%f : %f\n", current.dist, data->nearest.dist);
+               for(i=0; i< current.node->totnode; i++)
+               {
+                       BVHNode *child = current.node->children[i];
+                       if(child->totnode == 0)
+                       {
+                               callbacks++;
+                               dfs_find_nearest_dfs(data, child);
+                       }
+                       else
+                       {
+                               //adjust heap size
+                               if(heap_size >= max_heap_size
+                               && ADJUST_MEMORY(default_heap, (void**)&heap, heap_size+1, &max_heap_size, sizeof(heap[0])) == FALSE)
+                               {
+                                       printf("WARNING: bvh_find_nearest got out of memory\n");
+
+                                       if(heap != default_heap)
+                                               free(heap);
+
+                                       return;
+                               }
+
+                               heap[heap_size].node = current.node->children[i];
+                               heap[heap_size].dist = calc_nearest_point(data, current.node->children[i], nearest);
+
+                               if(heap[heap_size].dist >= data->nearest.dist) continue;
+                               heap_size++;
+
+                               NodeDistance_push_heap(heap, heap_size);
+       //                      PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size);
+                               push_heaps++;
+                       }
+               }
+               
+               if(heap_size == 0) break;
+
+               current = heap[0];
+               NodeDistance_pop_heap(heap, heap_size);
+//             POP_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size);
+               heap_size--;
+       }
+
+//     printf("hsize=%d, callbacks=%d, pushs=%d\n", heap_size, callbacks, push_heaps);
+
+       if(heap != default_heap)
+               free(heap);
+}
+
+
 int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
 {
        int i;
@@ -1172,7 +1371,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nea
 
        //dfs search
        if(root)
-               dfs_find_nearest(&data, root);
+               dfs_find_nearest_begin(&data, root);
 
        //copy back results
        if(nearest)
@@