diff --git a/CMake/macros.cmake b/CMake/macros.cmake
index 6b6837d25f0526667e29a74f7552f814335cdd95..e3dd46eb5ea11a8daf77ca045c7c98a0702db37a 100644
--- a/CMake/macros.cmake
+++ b/CMake/macros.cmake
@@ -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})
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0ea26750ec1c75aa03c40b02972b068cdbfaaeb0..5b86ca8f21e5a81e2f52d4f9ded2f9eb74a55bcb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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)
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
index b49036a5b50322b12b27e726b9024ebb0241d3b7..7dc7d8d2f68e1483707fa1e278983e24eb87d2ab 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
@@ -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);
+				}
 			}	
 		}
 	}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
index b6d80233ab7acbd927774aed8dc188e5e90f5e92..ed41232ece3fe091158e658bcb55ff2c5f9629ac 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
@@ -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);
 
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
index 31b914677777ed643da4ff85a41f93080b2c4c52..68ac93ec3cca5e204550ab344441927ac5e63508 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
@@ -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);
 						}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
index a0bbc9f8fe95f45f7dc128a8f14d7f88e9fc7675..71ed9fead49fd3c3cd1a2da849b5d31f80ab4f53 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
@@ -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);
 
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
index 29719ec9a3ec3becfc9d39d3aaf966f435913df3..1017c8af6eafb5f47360e954886d0e6d413cc00d 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
@@ -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
index 0000000000000000000000000000000000000000..5ed3117c8906103134f4b1b3d411a20c5124bfdd
--- /dev/null
+++ b/intern/guardedalloc/BLO_sys_types.h
@@ -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 */
+
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 25f2fd8d26903ef1d7c78bf23eb0a49d865f47de..a36549d0cc75eb779c61f025d4e78d46f7a89ee2 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -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);
 		}
diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c
index 436c99344a7c97de8f03216eb4ff943df0c34503..642cc16296ef147e2dbd43638cc034f87bb575b0 100644
--- a/intern/guardedalloc/intern/mmap_win.c
+++ b/intern/guardedalloc/intern/mmap_win.c
@@ -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) {
diff --git a/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj b/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj
index 40e88511d5dbf95d06bfdc3aa68df8d98aabb00e..974acef4e7058ee98cd500e723c79c17f10c4fca 100644
--- a/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj
+++ b/intern/guardedalloc/make/msvc_7_0/guardedalloc.vcproj
@@ -261,6 +261,9 @@ ECHO Done
 			<Filter
 				Name="extern"
 				Filter="">
+				<File
+					RelativePath="..\..\BLO_sys_types.h">
+				</File>
 				<File
 					RelativePath="..\..\MEM_guardedalloc.h">
 				</File>
diff --git a/intern/guardedalloc/mmap_win.h b/intern/guardedalloc/mmap_win.h
index f83a2d64b18b775f33f0d188f58e87b800cc5f69..443c3b6f4ceb69eebfe527cc927079a61547a06a 100644
--- a/intern/guardedalloc/mmap_win.h
+++ b/intern/guardedalloc/mmap_win.h
@@ -45,8 +45,10 @@
 
 #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
 
diff --git a/intern/opennl/make/msvc_7_0/opennl.vcproj b/intern/opennl/make/msvc_7_0/opennl.vcproj
index ec999b0c25234638d0620485caeea8e184e03ee7..d302a2508aba81537fe1678221883f969bc8242b 100644
--- a/intern/opennl/make/msvc_7_0/opennl.vcproj
+++ b/intern/opennl/make/msvc_7_0/opennl.vcproj
@@ -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
index 0000000000000000000000000000000000000000..5ed3117c8906103134f4b1b3d411a20c5124bfdd
--- /dev/null
+++ b/intern/opennl/superlu/BLO_sys_types.h
@@ -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 */
+
diff --git a/intern/opennl/superlu/smemory.c b/intern/opennl/superlu/smemory.c
index 79da748671a6f8184bcc75ad4a149fe2b8756198..7eefb9006730b9d68e446277c81fa0a4d5db9099 100644
--- a/intern/opennl/superlu/smemory.c
+++ b/intern/opennl/superlu/smemory.c
@@ -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;
diff --git a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
index 0ea3503a289f2cd6a2ac849dd40b91dea88faf81..42dcc843091592263c3db2e00ec4e6974d388159 100644
--- a/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
+++ b/projectfiles_vc7/blender/blenkernel/BKE_blenkernel.vcproj
@@ -494,6 +494,9 @@
 			<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>
@@ -708,6 +711,9 @@
 			<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>
diff --git a/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj b/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
index 7e2db4f564fbd99f9abfa38a84ad80f83a0c026f..5f14b5a09a1c0108ed6b8f881a5869b64cd8baa2 100644
--- a/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
+++ b/projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
@@ -347,6 +347,9 @@
 			<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>
@@ -465,6 +468,9 @@
 			<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>
diff --git a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
index c046d434cb34c14a93134a7e54ad05f1dfb8fad8..4e362faed69edcf3631ec2314e1a80dd92b07fb6 100644
--- a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
+++ b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
@@ -394,6 +394,9 @@
 			<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>
@@ -621,6 +624,9 @@
 			<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>
diff --git a/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj b/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
index 9a807f2d39a692558ae7de61fed8a296a7b8e64a..76fde7612e3e6b964b8398a90df180a7c387be66 100644
--- a/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
+++ b/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
@@ -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"
@@ -107,7 +107,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"
@@ -151,7 +151,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\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"
diff --git a/projectfiles_vc7/kernel/system/SYS_system.vcproj b/projectfiles_vc7/kernel/system/SYS_system.vcproj
index 50ffc1fbb99d3d308e8ad28a21afc11d2b31104c..3b239d9088b1c519d117b753161ffff1d6518188 100644
--- a/projectfiles_vc7/kernel/system/SYS_system.vcproj
+++ b/projectfiles_vc7/kernel/system/SYS_system.vcproj
@@ -125,7 +125,7 @@
 			<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"
@@ -177,7 +177,7 @@
 			<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"
@@ -229,7 +229,7 @@
 			<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"
@@ -281,7 +281,7 @@
 			<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"
diff --git a/release/datafiles/datatoc.c b/release/datafiles/datatoc.c
index 2e24a0f92efa83f99c714f424141305b17d43074..46b935c7fd6bfe43bcf5ee681d286e1a4be5cca2 100644
--- a/release/datafiles/datatoc.c
+++ b/release/datafiles/datatoc.c
@@ -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
index 0000000000000000000000000000000000000000..36e8e4d250189964c1cd3ca2e9faf1cf855153c2
--- /dev/null
+++ b/release/scripts/flt_dofedit.py
@@ -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
index 0000000000000000000000000000000000000000..58319b9e5254388e95f27498095cd721a7e6502c
--- /dev/null
+++ b/release/scripts/flt_lodedit.py
@@ -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
diff --git a/release/scripts/flt_properties.py b/release/scripts/flt_properties.py
index bc7c972ca6676fa9c549a56ab8e4db11471ba442..4c841e9c0c03b7d5b06a4e05ddd7b9b338d3979b 100644
--- a/release/scripts/flt_properties.py
+++ b/release/scripts/flt_properties.py
@@ -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]
 
diff --git a/release/text/copyright.txt b/release/text/copyright.txt
index 6082af3033fb2312859b6294d9f7bb8d9feabd6a..9f49dd4587a436a35a74d6ec5d842fa6e359793e 100644
--- a/release/text/copyright.txt
+++ b/release/text/copyright.txt
@@ -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
diff --git a/source/Makefile b/source/Makefile
index d06962cbe3f5e0f339d79ef132e08b49b0641d5f..91dd17d73dd49d211789e65b8e62dc6b26fe674e 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -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)
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index e1eb6718a3069e9d535c7b3f75ce97fe17b06555..e403fc33e068289008df363de47ddaa714b67a43 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -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
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index 2966d932a49837151bd240eff57bc3ab123c6b25..c483148e4de4a3804ce2d01d6f965cb97a9388d9 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -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
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index e84c7d309566238be4b97cc1cbcff489e67538e0..c84b690bc49d419764b5c5d46aeba2db9a1e4121 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -32,9 +32,11 @@
 #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;
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index a1975dd4265f03019b132d672836c0fd9e54a2bc..e982806a6cc60958e27cec47581d8e9522cc149d 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -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
 
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 3763a659f2f22b2fc40f442e1d152043ab70f771..6475f7a71ac12a5b7eb4db0f6b2d3f3e82d7ad14 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -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
diff --git a/source/blender/blenkernel/BKE_endian.h b/source/blender/blenkernel/BKE_endian.h
index 1757103eaf660d7e42ac25e0af813c52fdd6352c..dc5efd5ea4694d6c67caf7040668312379ba433e 100644
--- a/source/blender/blenkernel/BKE_endian.h
+++ b/source/blender/blenkernel/BKE_endian.h
@@ -33,11 +33,11 @@
 
 #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
index 0000000000000000000000000000000000000000..e8276238ff220213cbdacb262ad9afb99adb847f
--- /dev/null
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -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
+
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index a96a3e10f406652776233a432579299922085b70..f389521ffa0f0a9501be694a1105dfb3469d1d4b 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -197,8 +197,8 @@
 
 /* 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
 
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 9dcb6b6e7fab1392dbaaebbf07259c59b9be5623..1652b24e1e58563778d7d506c68825e3ca54bc1e 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -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));
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 67cf89d5ee26de6b964e499eedfd6975b05a9e83..1dabab98a6e78ec95484c0b126ca1f86bb394ec2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -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");
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 042e2afad53925c7bcd824cbcb319558a5e526fe..ae449843d2a7f668660e46a2e1ee07c48cf59099 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index c7817b017ef454bfe4dd5dbb5b5193a9ad3a5d18..dbc94571cad9b885950321d22a3ca16f9d8c16a3 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index cfcab54058d02885b118712453ab23baec49c7c2..b5e09d551f038f371d2a6e180e9beef136cf1112 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -31,10 +31,11 @@
 
 #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 );
 			
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index ab53571b62d338b17c19b9db3d848defef411f24..3143c5e4df2328e80647f9e73c9d13171756c28c 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -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);
+}
+
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 298e4b81d5bae9b9f4742f914967151f530a0427..3b79f6689c09dcf4e01cc2a6a95e0eaa98bb27ef 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 4588ef800e1f55c9a4497586a9274ecc1c9d1d6e..72f70cf17ff520ca5b69b95d8b38840f6d11c1db 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -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
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index cab7865c1b6047d0ecfbe7c67c3ba2248e6cc396..b9e3c593ddf60aad682cdc7bddff7d8a6fcd5e07 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -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 */
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index b6c8ad59e0801a23a88af998612a72fb2b75d9fc..07537e3a81c6b4fa8cafbb6b5809e15d4021d74f 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -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);
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 297ac0b1530c874aa0434b6b6e7840524ab4fb7e..93e35a4db061b3906ae0070f1eb553acdaa201a9 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -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
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 59eb3837aab9b01b71292961c8b01eb615a77eed..4af25ee99e713d14c7796ec55cb579476a2f59ae 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -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;
 		}
 	}
 
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 1dc76296c28783d75d5164f5ca7280fc7fd6c0f6..4c74fe1cca2c8f551cc218669bbc7793f4456de3 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -101,6 +101,8 @@
 #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
 	}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 643f90637ad7c034d16ef5772629ecf6c702b491..15d6f71073f25272eca2359d2dacf2e84decedab 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -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;
 }
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index d1c0cdec71ddba7556b8c3abe640c2cbf876c872..92c2f27bc3171d69f3fc7f50e4ec12dd01e7dfc5 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -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;
+						}
 					}
 				}
 			}
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index fcf1c7ce311fcc3aabba5be136efe7b9e9755e41..47d11bb9d298f42e4104dba76556dac27efb0c9b 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -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
index 0000000000000000000000000000000000000000..c60535cade2511e0bf03dac736b349037023b3fc
--- /dev/null
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -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);
+}
+
diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h
index d42663e17c783af0457ff37072d3d7e578dafd40..447f6a2a485e3ad9d3308142c229c80774c3235b 100644
--- a/source/blender/blenlib/BLI_editVert.h
+++ b/source/blender/blenlib/BLI_editVert.h
@@ -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];
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index 0e534783c175885d41b617672beb1ff0e2df5fc7..266aa347aff04a57ecf3e6d2a2131d1b9cae4db2 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -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);
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 11150075bac763f33cf821ae51e1c96f79645212..3bb63506c9551313702292116c5c3c3cbb133cca 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -61,6 +61,10 @@
 
 	// 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__ */
 
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 227cb8f5e9a5e23c95f2c446f01bbe8020691d12..e9271ca3bb57ec1978344a88f43cdb5c4440edab 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -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);
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 9671551a7f10212041fd0cfb9bb59d8a82274e6f..989e516d161f6d164d25baf4df996b9f9a25ae5d 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -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)
@@ -1212,7 +1411,7 @@ static float ray_nearest_hit(BVHRayCastData *data, BVHNode *node)
 			float ll = (bv[0] - data->ray.origin[i]) / data->ray_dot_axis[i];
 			float lu = (bv[1] - data->ray.origin[i]) / data->ray_dot_axis[i];
 
-			if(data->ray_dot_axis[i] > 0)
+			if(data->ray_dot_axis[i] > 0.0f)
 			{
 				if(ll > low)   low = ll;
 				if(lu < upper) upper = lu;
@@ -1252,7 +1451,7 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
 	else
 	{
 		//pick loop direction to dive into the tree (based on ray direction and split axis)
-		if(data->ray_dot_axis[ node->main_axis ] > 0)
+		if(data->ray_dot_axis[ node->main_axis ] > 0.0f)
 		{
 			for(i=0; i != node->totnode; i++)
 			{
@@ -1289,7 +1488,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, BVHTr
 	{
 		data.ray_dot_axis[i] = INPR( data.ray.direction, KDOP_AXES[i]);
 
-		if(fabs(data.ray_dot_axis[i]) < 1e-7)
+		if(fabs(data.ray_dot_axis[i]) < FLT_EPSILON)
 			data.ray_dot_axis[i] = 0.0;
 	}
 
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 96de5e99f4fe01e272a5cc680a706c4468e9fc18..2acbbbe6712c8197c67957c7961cf5640dd718d2 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -62,6 +62,8 @@
 #include "BKE_utildefines.h"
 #include <errno.h>
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* implementations: */
 char *first_slash(char *string) {
 	char *ffslash, *fbslash;
@@ -72,7 +74,7 @@ char *first_slash(char *string) {
 	if (!ffslash) return fbslash;
 	else if (!fbslash) return ffslash;
 	
-	if ((long)ffslash < (long)fbslash) return ffslash;
+	if ((intptr_t)ffslash < (intptr_t)fbslash) return ffslash;
 	else return fbslash;
 }
 
@@ -85,7 +87,7 @@ char *BLI_last_slash(const char *string) {
 	if (!lfslash) return lbslash; 
 	else if (!lbslash) return lfslash;
 	
-	if ((long)lfslash < (long)lbslash) return lbslash;
+	if ((intptr_t)lfslash < (intptr_t)lbslash) return lbslash;
 	else return lfslash;
 }
 
diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c
index 498c87cdef96dc5df563192945d24e271586345e..216246dcdd7d2ed5f2036641bee5d016d4df9f00 100644
--- a/source/blender/blenlib/intern/psfont.c
+++ b/source/blender/blenlib/intern/psfont.c
@@ -43,6 +43,8 @@
 #include "DNA_packedFile_types.h"
 #include "DNA_curve_types.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -54,7 +56,7 @@ typedef struct chardesc {
     short llx, lly;		/* bounding box */
     short urx, ury;
     short *data;		/* char data */
-    long datalen;		
+    intptr_t datalen;		
 } chardesc;
 
 typedef struct objfnt {
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index ccc478203fe911da9d4107313f17108990279bae..c484a307393654b69f97e7037fbe09cece086a17 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -81,6 +81,16 @@ void rng_seed(RNG *rng, unsigned int seed) {
 	rng->X= (((r_uint64) seed)<<16) | LOWSEED;
 }
 
+void rng_srandom(RNG *rng, unsigned int seed) {
+	extern unsigned char hash[];	// noise.c
+	
+	rng_seed(rng, seed + hash[seed & 255]);
+	seed= rng_getInt(rng);
+	rng_seed(rng, seed + hash[seed & 255]);
+	seed= rng_getInt(rng);
+	rng_seed(rng, seed + hash[seed & 255]);
+}
+
 int rng_getInt(RNG *rng) {
 	rng->X= (MULTIPLIER*rng->X + ADDEND)&MASK;
 	return (int) (rng->X>>17);
@@ -132,13 +142,7 @@ void BLI_srand(unsigned int seed) {
 
 /* using hash table to create better seed */
 void BLI_srandom(unsigned int seed) {
-	extern unsigned char hash[];	// noise.c
-	
-	rng_seed(&theBLI_rng, seed + hash[seed & 255]);
-	seed= rng_getInt(&theBLI_rng);
-	rng_seed(&theBLI_rng, seed + hash[seed & 255]);
-	seed= rng_getInt(&theBLI_rng);
-	rng_seed(&theBLI_rng, seed + hash[seed & 255]);
+	rng_srandom(&theBLI_rng, seed);
 }
 
 int BLI_rand(void) {
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index 48ebf770e1bcd428917af994032608de33039321..a31121148e3b5d473fb33d168c5627098c55f4f3 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -1970,7 +1970,7 @@ void BLI_timestr(double _time, char *str)
 
 int BLI_int_from_pointer(void *poin)
 {
-	long lval= (long)poin;
+	intptr_t lval= (intptr_t)poin;
 	
 	return (int)(lval>>3);
 }
@@ -1978,17 +1978,17 @@ int BLI_int_from_pointer(void *poin)
 void *BLI_pointer_from_int(int val)
 {
 	static int firsttime= 1;
-	static long basevalue= 0;
+	static intptr_t basevalue= 0;
 	
 	if(firsttime) {
 		void *poin= malloc(10000);
-		basevalue= (long)poin;
+		basevalue= (intptr_t)poin;
 		basevalue &= ~PMASK;
 		printf("base: %d pointer %p\n", basevalue, poin); /* debug */
 		firsttime= 0;
 		free(poin);
 	}
-	return (void *)(basevalue | (((long)val)<<3));
+	return (void *)(basevalue | (((intptr_t)val)<<3));
 }
 
 #else
diff --git a/source/blender/blenloader/BLO_sys_types.h b/source/blender/blenloader/BLO_sys_types.h
index a1885894fe321912696cb1d37cac05ce7ec396b0..a9d29375eac6e1344112c5bae50ccdcf37105d9e 100644
--- a/source/blender/blenloader/BLO_sys_types.h
+++ b/source/blender/blenloader/BLO_sys_types.h
@@ -43,11 +43,6 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-
-#ifdef FREE_WINDOWS
-typedef unsigned char uint8_t;
-typedef unsigned int uint32_t;
-#endif
  
 #if defined(_WIN32) && !defined(FREE_WINDOWS)
 
@@ -64,6 +59,14 @@ typedef unsigned __int16 uint16_t;
 typedef unsigned __int32 uint32_t;
 typedef unsigned __int64 uint64_t;
 
+#ifdef _WIN64
+typedef __int64 intptr_t;
+typedef unsigned __int64 uintptr_t;
+#else
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+#endif
+
 #elif defined(__linux__)
 
 	/* Linux-i386, Linux-Alpha, Linux-ppc */
@@ -73,6 +76,10 @@ typedef unsigned __int64 uint64_t;
 
 #include <inttypes.h>
 
+#elif defined(FREE_WINDOWS)
+
+#include <stdint.h>
+
 #else
 
 	/* FreeBSD, Irix, Solaris */
diff --git a/source/blender/blenloader/intern/genfile.c b/source/blender/blenloader/intern/genfile.c
index 87c859de839145294d0943de8e0d630a07f46538..86338ca9e89d863be1e6564f0b74b54efae5f781 100644
--- a/source/blender/blenloader/intern/genfile.c
+++ b/source/blender/blenloader/intern/genfile.c
@@ -58,6 +58,8 @@
 
 #include "genfile.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* gcc 4.1 on mingw was complaining that __int64 was alredy defined
 actually is saw the line below as typedef long long long long... 
 Anyhow, since its alredy defined, its safe to do an ifndef here- Cambpell*/
@@ -315,7 +317,7 @@ static void init_structDNA(struct SDNA *sdna, int do_endian_swap)
 /* in sdna->data the data, now we convert that to something understandable */
 {
 	int *data, *verg;
-	long nr;
+	intptr_t nr;
 	short *sp;
 	char str[8], *cp;
 	
@@ -351,7 +353,7 @@ static void init_structDNA(struct SDNA *sdna, int do_endian_swap)
 			cp++;
 			nr++;
 		}
-		nr= (long)cp;		/* prevent BUS error */
+		nr= (intptr_t)cp;		/* prevent BUS error */
 		nr= (nr+3) & ~3;
 		cp= (char *)nr;
 		
@@ -389,7 +391,7 @@ static void init_structDNA(struct SDNA *sdna, int do_endian_swap)
 			cp++;
 			nr++;
 		}
-		nr= (long)cp;		/* prevent BUS error */
+		nr= (intptr_t)cp;		/* prevent BUS error */
 		nr= (nr+3) & ~3;
 		cp= (char *)nr;
 		
@@ -1098,7 +1100,7 @@ int dna_elem_offset(struct SDNA *sdna, char *stype, char *vartype, char *name)
 	int SDNAnr= dna_findstruct_nr(sdna, stype);
 	short *spo= sdna->structs[SDNAnr];
 	char *cp= find_elem(sdna, vartype, name, spo, NULL, NULL);
-	return (int)((long)cp);
+	return (int)((intptr_t)cp);
 }
 
 
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index f56b261efe27df6bc8a72b58dbfdf71e1211fc4c..5a75b5c8b110426dd5dcaac269dde28a6d1c51c3 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -63,6 +63,8 @@
 
 #include "BLO_readblenfile.h"
 
+#include "BLO_sys_types.h" // needed for intptr_t
+
 	/**
 	 * IDType stuff, I plan to move this
 	 * out into its own file + prefix, and
@@ -193,7 +195,7 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
 			buf[2]= buf[2]?buf[2]:' ';
 			buf[3]= buf[3]?buf[3]:' ';
 			
-			fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (long)bhead->len+sizeof(BHead));
+			fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (intptr_t)bhead->len+sizeof(BHead));
 		}
 	}
 	fprintf(fp, "]\n");
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 29fd314236b2d3d8a91c617ecc66400562c6117b..6affec0e104221ee1c1dcd36b7163e1ea729f497 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2583,6 +2583,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
 static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
 {
 	part->pd= newdataadr(fd, part->pd);
+	part->pd2= newdataadr(fd, part->pd2);
 }
 
 static void lib_link_particlesystems(FileData *fd, ID *id, ListBase *particles)
@@ -2943,11 +2944,9 @@ static void lib_link_object(FileData *fd, Main *main)
 
 			sens= ob->sensors.first;
 			while(sens) {
-				if(ob->id.lib==NULL) {	// done in expand_main
-					for(a=0; a<sens->totlinks; a++) {
-						sens->links[a]= newglobadr(fd, sens->links[a]);
-					}
-				}
+				for(a=0; a<sens->totlinks; a++)
+					sens->links[a]= newglobadr(fd, sens->links[a]);
+
 				if(sens->type==SENS_TOUCH) {
 					bTouchSensor *ts= sens->data;
 					ts->ma= newlibadr(fd, ob->id.lib, ts->ma);
@@ -2962,11 +2961,9 @@ static void lib_link_object(FileData *fd, Main *main)
 
 			cont= ob->controllers.first;
 			while(cont) {
-				if(ob->id.lib==NULL) {	// done in expand_main
-					for(a=0; a<cont->totlinks; a++) {
-						cont->links[a]= newglobadr(fd, cont->links[a]);
-					}
-				}
+				for(a=0; a<cont->totlinks; a++)
+					cont->links[a]= newglobadr(fd, cont->links[a]);
+
 				if(cont->type==CONT_PYTHON) {
 					bPythonCont *pc= cont->data;
 					pc->text= newlibadr(fd, ob->id.lib, pc->text);
@@ -3594,9 +3591,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
 		{
 			Sequence temp;
 			char *poin;
-			long offset;
+			intptr_t offset;
 			
-			offset= ((long)&(temp.seqbase)) - ((long)&temp);
+			offset= ((intptr_t)&(temp.seqbase)) - ((intptr_t)&temp);
 			
 			/* root pointer */
 			if(ed->seqbasep == old_seqbasep) {
@@ -4095,7 +4092,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
 	while(se) {
 		se->v1= newdataadr(fd, se->v1);
 		se->v2= newdataadr(fd, se->v2);
-		if( (long)se->v1 > (long)se->v2) {
+		if( (intptr_t)se->v1 > (intptr_t)se->v2) {
 			sv= se->v1;
 			se->v1= se->v2;
 			se->v2= sv;
@@ -7731,31 +7728,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 		idproperties_fix_group_lengths(main->brush);
 		idproperties_fix_group_lengths(main->particle);		
 	}
-	
-	/* only needed until old bad svn/RC1,2 files are saved with a > 17 version -dg */
-	if(main->versionfile == 245 && main->subversionfile < 17) {
-		ModifierData *md;
-		Object *ob;
-		
-		for(ob = main->object.first; ob; ob= ob->id.next) {
-			for(md=ob->modifiers.first; md; ) {
-				if(md->type==eModifierType_Cloth) {
-					ModifierData *next;
-					MEM_freeN(((ClothModifierData *)md)->sim_parms);
-					MEM_freeN(((ClothModifierData *)md)->coll_parms);
-					MEM_freeN(((ClothModifierData *)md)->point_cache);
-					((ClothModifierData *)md)->sim_parms = NULL;
-					((ClothModifierData *)md)->coll_parms = NULL;
-					((ClothModifierData *)md)->point_cache = NULL;
-					next=md->next;
-					BLI_remlink(&ob->modifiers, md);
-					md = next;
-				}
-				else
-					md = md->next;
-			}
-		}
-	}
 
 	/* sun/sky */
 	if(main->versionfile < 246) {
@@ -7782,6 +7754,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 		for(me=main->mesh.first; me; me= me->id.next)
 			alphasort_version_246(fd, lib, me);
 	}
+	
+	if(main->versionfile <= 246 && main->subversionfile < 1){
+		Object *ob;
+		for(ob = main->object.first; ob; ob= ob->id.next) {
+			if(ob->pd && (ob->pd->forcefield == PFIELD_WIND))
+				ob->pd->f_noise = 0.0;
+		}
+	}
 
 	/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
 	/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
@@ -8499,9 +8479,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
 
 	sens= ob->sensors.first;
 	while(sens) {
-		for(a=0; a<sens->totlinks; a++) {
-			sens->links[a]= newglobadr(fd, sens->links[a]);
-		}
 		if(sens->type==SENS_TOUCH) {
 			bTouchSensor *ts= sens->data;
 			expand_doit(fd, mainvar, ts->ma);
@@ -8515,9 +8492,6 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
 
 	cont= ob->controllers.first;
 	while(cont) {
-		for(a=0; a<cont->totlinks; a++) {
-			cont->links[a]= newglobadr(fd, cont->links[a]);
-		}
 		if(cont->type==CONT_PYTHON) {
 			bPythonCont *pc= cont->data;
 			expand_doit(fd, mainvar, pc->text);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 3af7d3f7c25d6fbb43bb5f064c66a36d115264c6..3bc6799d616b292c9c913460264f56d8d3f81ce6 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -535,6 +535,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
 			writestruct(wd, ID_PA, "ParticleSettings", 1, part);
 			if (part->id.properties) IDP_WriteProperty(part->id.properties, wd);
 			writestruct(wd, DATA, "PartDeflect", 1, part->pd);
+			writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
 		}
 		part= part->id.next;
 	}
@@ -608,6 +609,9 @@ static void write_sensors(WriteData *wd, ListBase *lb)
 		case SENS_ACTUATOR:
 			writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
 			break;
+		case SENS_DELAY:
+			writestruct(wd, DATA, "bDelaySensor", 1, sens->data);
+			break;
 		case SENS_COLLISION:
 			writestruct(wd, DATA, "bCollisionSensor", 1, sens->data);
 			break;
diff --git a/source/blender/blenpluginapi/intern/pluginapi.c b/source/blender/blenpluginapi/intern/pluginapi.c
index e65148a0b040b355dc590456bb8956eabc876e61..9c08a0b2f9d260622dd0e9776e494a60b106f09e 100644
--- a/source/blender/blenpluginapi/intern/pluginapi.c
+++ b/source/blender/blenpluginapi/intern/pluginapi.c
@@ -50,10 +50,12 @@
 #include "plugin.h"
 #include "MEM_guardedalloc.h"
 
+#include "BLO_sys_types.h" // needed for intptr_t
+
 #include "BLI_blenlib.h"  /* util and noise functions */
 #include "BLI_threads.h"  /* For threadsfe guardedalloc malloc/calloc/free */
 #include "IMB_imbuf.h"    /* image buffer stuff       */
-#define GET_INT_FROM_POINTER(i) ((int)(long)(i)) /* should use BKE_utildefines.h */
+#define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i)) /* should use BKE_utildefines.h */
 
 /* -------------------------------------------------------------------------- */
 /* stuff from util.h                                                          */ 
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 3b45a9de822164efb8855b384f25f3905e473a0a..ecee3c7d6c0a3ddb23cfa835072f13e44ebd5e14 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -67,12 +67,12 @@ fillCineonFileInfo(CineonFile* cineon, CineonFileInformation* fileInfo, const ch
 static void
 dumpCineonFileInfo(CineonFileInformation* fileInfo) {
 	d_printf("\n--File Information--\n");
-	d_printf("Magic: %8.8lX\n", (unsigned long)ntohl(fileInfo->magic_num));
-	d_printf("Image Offset %ld\n", (long)ntohl(fileInfo->image_offset));
-	d_printf("Generic Header size %ld\n", (long)ntohl(fileInfo->gen_hdr_size));
-	d_printf("Industry Header size %ld\n", (long)ntohl(fileInfo->ind_hdr_size));
-	d_printf("User Data size %ld\n", (long)ntohl(fileInfo->user_data_size));
-	d_printf("File size %ld\n", (long)ntohl(fileInfo->file_size));
+	d_printf("Magic: %8.8lX\n", (uintptr_t)ntohl(fileInfo->magic_num));
+	d_printf("Image Offset %ld\n", (intptr_t)ntohl(fileInfo->image_offset));
+	d_printf("Generic Header size %ld\n", (intptr_t)ntohl(fileInfo->gen_hdr_size));
+	d_printf("Industry Header size %ld\n", (intptr_t)ntohl(fileInfo->ind_hdr_size));
+	d_printf("User Data size %ld\n", (intptr_t)ntohl(fileInfo->user_data_size));
+	d_printf("File size %ld\n", (intptr_t)ntohl(fileInfo->file_size));
 	d_printf("Version \"%s\"\n", fileInfo->vers);
 	d_printf("File name \"%s\"\n", fileInfo->file_name);
 	d_printf("Creation date \"%s\"\n", fileInfo->create_date);
@@ -112,11 +112,11 @@ dumpCineonChannelInfo(CineonChannelInformation* chan) {
 		default: d_printf(" (unknown)\n"); break;
 	}
 	d_printf("	Bits per pixel %d\n", chan->bits_per_pixel);
-	d_printf("	Pixels per line %ld\n", (long)ntohl(chan->pixels_per_line));
-	d_printf("	Lines per image %ld\n", (long)ntohl(chan->lines_per_image));
-	d_printf("	Ref low data %ld\n", (long)ntohl(chan->ref_low_data));
+	d_printf("	Pixels per line %ld\n", (intptr_t)ntohl(chan->pixels_per_line));
+	d_printf("	Lines per image %ld\n", (intptr_t)ntohl(chan->lines_per_image));
+	d_printf("	Ref low data %ld\n", (intptr_t)ntohl(chan->ref_low_data));
 	d_printf("	Ref low quantity %f\n", ntohf(chan->ref_low_quantity));
-	d_printf("	Ref high data %ld\n", (long)ntohl(chan->ref_high_data));
+	d_printf("	Ref high data %ld\n", (intptr_t)ntohl(chan->ref_high_data));
 	d_printf("	Ref high quantity %f\n", ntohf(chan->ref_high_quantity));
 }
 
@@ -231,8 +231,8 @@ dumpCineonFormatInfo(CineonFormatInformation* formatInfo) {
 	} else {
 		d_printf(" positive\n");
 	}
-	d_printf("End of line padding %ld\n", (long)ntohl(formatInfo->line_padding));
-	d_printf("End of channel padding %ld\n", (long)ntohl(formatInfo->channel_padding));
+	d_printf("End of line padding %ld\n", (intptr_t)ntohl(formatInfo->line_padding));
+	d_printf("End of channel padding %ld\n", (intptr_t)ntohl(formatInfo->channel_padding));
 }
 
 static void
@@ -256,8 +256,8 @@ fillCineonOriginationInfo(CineonFile* cineon,
 static void
 dumpCineonOriginationInfo(CineonOriginationInformation* originInfo) {
 	d_printf("\n--Origination Information--\n");
-	d_printf("X offset %ld\n", (long)ntohl(originInfo->x_offset));
-	d_printf("Y offset %ld\n", (long)ntohl(originInfo->y_offset));
+	d_printf("X offset %ld\n", (intptr_t)ntohl(originInfo->x_offset));
+	d_printf("Y offset %ld\n", (intptr_t)ntohl(originInfo->y_offset));
 	d_printf("File name \"%s\"\n", originInfo->file_name);
 	d_printf("Creation date \"%s\"\n", originInfo->create_date);
 	d_printf("Creation time \"%s\"\n", originInfo->create_time);
@@ -529,7 +529,7 @@ cineonOpen(const char* filename) {
 	/* let's assume cineon files are always network order */
 	if (header.fileInfo.magic_num != ntohl(CINEON_FILE_MAGIC)) {
 		if (verbose) d_printf("Bad magic number %8.8lX in \"%s\".\n",
-			(unsigned long)ntohl(header.fileInfo.magic_num), filename);
+			(uintptr_t)ntohl(header.fileInfo.magic_num), filename);
 		cineonClose(cineon);
 		return 0;
 	}
@@ -628,7 +628,7 @@ cineonOpenFromMem(unsigned char *mem, unsigned int size) {
 
 	/* let's assume cineon files are always network order */
 	if (header.fileInfo.magic_num != ntohl(CINEON_FILE_MAGIC)) {
-		if (verbose) d_printf("Bad magic number %8.8lX in\n", (unsigned long)ntohl(header.fileInfo.magic_num));
+		if (verbose) d_printf("Bad magic number %8.8lX in\n", (uintptr_t)ntohl(header.fileInfo.magic_num));
 
 		cineonClose(cineon);
 		return 0;
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 500c09ba265d609acf5e7f18e2acedfead568083..1710cdde501fc6cd4e2d005b565cc47812734546 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -58,15 +58,15 @@ fillDpxChannelInfo(DpxFile* dpx, DpxChannelInformation* chan, int des) {
 
 static void
 dumpDpxChannelInfo(DpxChannelInformation* chan) {
-	d_printf("	Signage %ld", (long)ntohl(chan->signage));
-	d_printf("	Ref low data %ld\n", (long)ntohl(chan->ref_low_data));
+	d_printf("	Signage %ld", (intptr_t)ntohl(chan->signage));
+	d_printf("	Ref low data %ld\n", (intptr_t)ntohl(chan->ref_low_data));
 	d_printf("	Ref low quantity %f\n", ntohf(chan->ref_low_quantity));
-	d_printf("	Ref high data %ld\n", (long)ntohl(chan->ref_high_data));
+	d_printf("	Ref high data %ld\n", (intptr_t)ntohl(chan->ref_high_data));
 	d_printf("	Ref high quantity %f\n", ntohf(chan->ref_high_quantity));
 	d_printf("	Designator1: %d,", chan->designator1);
 	d_printf("	Bits per pixel %d\n", chan->bits_per_pixel);
 	d_printf("	Packing: %d,", ntohs(chan->packing));
-	d_printf("	Data Offset: %ld,", (long)ntohl(chan->data_offset));
+	d_printf("	Data Offset: %ld,", (intptr_t)ntohl(chan->data_offset));
 }
 
 static void
@@ -110,19 +110,19 @@ static void
 dumpDpxFileInfo(DpxFileInformation* fileInfo) {
 	d_printf("\n--File Information--\n");
 	d_printf("Magic: %8.8lX\n", (unsigned long)ntohl(fileInfo->magic_num));
-	d_printf("Image Offset %ld\n", (long)ntohl(fileInfo->offset));
+	d_printf("Image Offset %ld\n", (intptr_t)ntohl(fileInfo->offset));
 	d_printf("Version \"%s\"\n", fileInfo->vers);
-	d_printf("File size %ld\n", (long)ntohl(fileInfo->file_size));
-	d_printf("Ditto key %ld\n", (long)ntohl(fileInfo->ditto_key));
-	d_printf("Generic Header size %ld\n", (long)ntohl(fileInfo->gen_hdr_size));
-	d_printf("Industry Header size %ld\n", (long)ntohl(fileInfo->ind_hdr_size));
-	d_printf("User Data size %ld\n", (long)ntohl(fileInfo->user_data_size));
+	d_printf("File size %ld\n", (intptr_t)ntohl(fileInfo->file_size));
+	d_printf("Ditto key %ld\n", (intptr_t)ntohl(fileInfo->ditto_key));
+	d_printf("Generic Header size %ld\n", (intptr_t)ntohl(fileInfo->gen_hdr_size));
+	d_printf("Industry Header size %ld\n", (intptr_t)ntohl(fileInfo->ind_hdr_size));
+	d_printf("User Data size %ld\n", (intptr_t)ntohl(fileInfo->user_data_size));
 	d_printf("File name \"%s\"\n", fileInfo->file_name);
 	d_printf("Creation date \"%s\"\n", fileInfo->create_date);
 	d_printf("Creator \"%s\"\n", fileInfo->creator);
 	d_printf("Project \"%s\"\n", fileInfo->project);
 	d_printf("Copyright \"%s\"\n", fileInfo->copyright);
-	d_printf("Key %ld\n", (long)ntohl(fileInfo->key));
+	d_printf("Key %ld\n", (intptr_t)ntohl(fileInfo->key));
 }
 
 static void
@@ -150,8 +150,8 @@ dumpDpxImageInfo(DpxImageInformation* imageInfo) {
 	d_printf("Image orientation %d,", ntohs(imageInfo->orientation));
 	n = ntohs(imageInfo->channels_per_image);
 	d_printf("Channels %d\n", n);
-	d_printf("Pixels per line %ld\n", (long)ntohl(imageInfo->pixels_per_line));
-	d_printf("Lines per image %ld\n", (long)ntohl(imageInfo->lines_per_image));
+	d_printf("Pixels per line %ld\n", (intptr_t)ntohl(imageInfo->pixels_per_line));
+	d_printf("Lines per image %ld\n", (intptr_t)ntohl(imageInfo->lines_per_image));
 	for (i = 0; i < n; ++i) {
 		d_printf("	--Channel %d--\n", i);
 		dumpDpxChannelInfo(&imageInfo->channel[i]);
@@ -166,12 +166,12 @@ fillDpxOriginationInfo(
 static void
 dumpDpxOriginationInfo(DpxOriginationInformation* originInfo) {
 	d_printf("\n--Origination Information--\n");
-	d_printf("X offset %ld\n", (long)ntohl(originInfo->x_offset));
-	d_printf("Y offset %ld\n", (long)ntohl(originInfo->y_offset));
+	d_printf("X offset %ld\n", (intptr_t)ntohl(originInfo->x_offset));
+	d_printf("Y offset %ld\n", (intptr_t)ntohl(originInfo->y_offset));
 	d_printf("X centre %f\n", ntohf(originInfo->x_centre));
 	d_printf("Y centre %f\n", ntohf(originInfo->y_centre));
-	d_printf("Original X %ld\n", (long)ntohl(originInfo->x_original_size));
-	d_printf("Original Y %ld\n", (long)ntohl(originInfo->y_original_size));
+	d_printf("Original X %ld\n", (intptr_t)ntohl(originInfo->x_original_size));
+	d_printf("Original Y %ld\n", (intptr_t)ntohl(originInfo->y_original_size));
 	d_printf("File name \"%s\"\n", originInfo->file_name);
 	d_printf("Creation time \"%s\"\n", originInfo->creation_time);
 	d_printf("Input device \"%s\"\n", originInfo->input_device);
@@ -417,7 +417,7 @@ intern_dpxOpen(int mode, const char* bytestuff, int bufsize) {
 	/* let's assume dpx files are always network order */
 	if (header.fileInfo.magic_num != ntohl(DPX_FILE_MAGIC)) {
 		if (verbose) d_printf("Bad magic number %8.8lX in \"%s\".\n",
-			(unsigned long)ntohl(header.fileInfo.magic_num), filename);
+			(uintptr_t)ntohl(header.fileInfo.magic_num), filename);
 		dpxClose(dpx);
 		return 0;
 	}
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h
index 01eff8d570d5414cc6295ea392c05f02e27e69a9..2646e8b3c12c979b9815fc50c7e9de1c88fa2cac 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.h
+++ b/source/blender/imbuf/intern/cineon/logImageCore.h
@@ -34,7 +34,9 @@
 extern "C" {
 #endif
 
-
+#include "BLO_sys_types.h" // for intptr_t support
+#undef ntohl
+#undef htonl
 typedef int (GetRowFn)(LogImageFile* logImage, unsigned short* row, int lineNum);
 typedef int (SetRowFn)(LogImageFile* logImage, const unsigned short* row, int lineNum);
 typedef void (CloseFn)(LogImageFile* logImage);
@@ -80,7 +82,7 @@ struct _Log_Image_File_t_
 	CloseFn* close;
 	
 	unsigned char *membuffer;
-	unsigned long membuffersize;
+	uintptr_t membuffersize;
 	unsigned char *memcursor;
 };
 
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.c b/source/blender/imbuf/intern/cineon/logmemfile.c
index 20359335933c2a7664081a5a30a19113f15835c4..160e845371396e7f42bf61ecff88943ed2155ecf 100644
--- a/source/blender/imbuf/intern/cineon/logmemfile.c
+++ b/source/blender/imbuf/intern/cineon/logmemfile.c
@@ -24,10 +24,10 @@
 
 #include "logImageCore.h"
 
-int logimage_fseek(void* logfile, long offsett, int origin)
+int logimage_fseek(void* logfile, intptr_t offsett, int origin)
 {	
 	struct _Log_Image_File_t_ *file = (struct _Log_Image_File_t_*) logfile;
-	long offset = offsett;
+	intptr_t offset = offsett;
 	
 	if (file->file) fseek(file->file, offset, origin);
 	else { /*we're seeking in memory*/
@@ -38,7 +38,7 @@ int logimage_fseek(void* logfile, long offsett, int origin)
 			if (offset > file->membuffersize) return 1;
 			file->memcursor = (file->membuffer + file->membuffersize) - offset;
 		} else if (origin==SEEK_CUR) {
-			unsigned long pos = (unsigned long)file->membuffer - (unsigned long)file->memcursor;
+			uintptr_t pos = (uintptr_t)file->membuffer - (uintptr_t)file->memcursor;
 			if (pos + offset > file->membuffersize) return 1;
 			if (pos < 0) return 1;
 			file->memcursor += offset;
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.h b/source/blender/imbuf/intern/cineon/logmemfile.h
index 6e82cf2b1452b895ea5ec61bdb8c2c3b0ffeb03f..39e2f36dad9e119e0ebc532f829bc2986123ac80 100644
--- a/source/blender/imbuf/intern/cineon/logmemfile.h
+++ b/source/blender/imbuf/intern/cineon/logmemfile.h
@@ -22,7 +22,7 @@
 #ifndef _LOGMEMFILE_H
 #define _LOGMEMFILE_H
 
-int logimage_fseek(void* logfile, long offsett, int origin);
+int logimage_fseek(void* logfile, intptr_t offsett, int origin);
 int logimage_fwrite(void *buffer, unsigned int size, unsigned int count, void *logfile);
 int logimage_fread(void *buffer, unsigned int size, unsigned int count, void *logfile);
 
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 40c1f83c98c44e7691dcecdf79d948eadd31c5b8..8257eb4643ed70b070a4648fc7896b0f8b4d09dc 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -39,6 +39,8 @@
 #include "IMB_allocimbuf.h"
 #include "IMB_filter.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /************************************************************************/
 /*								SCALING									*/
 /************************************************************************/
@@ -490,8 +492,8 @@ static void enlarge_picture_byte(
 		/ (double) (src_width - 1.001);
 	double ratioy = (double) (dst_height - 1.0) 
 		/ (double) (src_height - 1.001);
-	unsigned long x_src, dx_src, x_dst;
-	unsigned long y_src, dy_src, y_dst;
+	uintptr_t x_src, dx_src, x_dst;
+	uintptr_t y_src, dy_src, y_dst;
 
 	dx_src = 65536.0 / ratiox;
 	dy_src = 65536.0 / ratioy;
@@ -500,8 +502,8 @@ static void enlarge_picture_byte(
 	for (y_dst = 0; y_dst < dst_height; y_dst++) {
 		unsigned char* line1 = src + (y_src >> 16) * 4 * src_width;
 		unsigned char* line2 = line1 + 4 * src_width;
-		unsigned long weight1y = 65536 - (y_src & 0xffff);
-		unsigned long weight2y = 65536 - weight1y;
+		uintptr_t weight1y = 65536 - (y_src & 0xffff);
+		uintptr_t weight2y = 65536 - weight1y;
 
 		if ((y_src >> 16) == src_height - 1) {
 			line2 = line1;
@@ -509,8 +511,8 @@ static void enlarge_picture_byte(
 
 		x_src = 0;
 		for (x_dst = 0; x_dst < dst_width; x_dst++) {
-			unsigned long weight1x = 65536 - (x_src & 0xffff);
-			unsigned long weight2x = 65536 - weight1x;
+			uintptr_t weight1x = 65536 - (x_src & 0xffff);
+			uintptr_t weight2x = 65536 - weight1x;
 
 			unsigned long x = (x_src >> 16) * 4;
 
@@ -557,12 +559,12 @@ static void enlarge_picture_byte(
 }
 
 struct scale_outpix_byte {
-	unsigned long r;
-	unsigned long g;
-	unsigned long b;
-	unsigned long a;
+	uintptr_t r;
+	uintptr_t g;
+	uintptr_t b;
+	uintptr_t a;
 
-	unsigned long weight;
+	uintptr_t weight;
 };
 
 static void shrink_picture_byte(
@@ -571,9 +573,9 @@ static void shrink_picture_byte(
 {
 	double ratiox = (double) (dst_width) / (double) (src_width);
 	double ratioy = (double) (dst_height) / (double) (src_height);
-	unsigned long x_src, dx_dst, x_dst;
-	unsigned long y_src, dy_dst, y_dst;
-	long y_counter;
+	uintptr_t x_src, dx_dst, x_dst;
+	uintptr_t y_src, dy_dst, y_dst;
+	intptr_t y_counter;
 	unsigned char * dst_begin = dst;
 
 	struct scale_outpix_byte * dst_line1 = NULL;
@@ -593,16 +595,16 @@ static void shrink_picture_byte(
 	y_counter = 65536;
 	for (y_src = 0; y_src < src_height; y_src++) {
 		unsigned char* line = src + y_src * 4 * src_width;
-		unsigned long weight1y = 65536 - (y_dst & 0xffff);
-		unsigned long weight2y = 65536 - weight1y;
+		uintptr_t weight1y = 65536 - (y_dst & 0xffff);
+		uintptr_t weight2y = 65536 - weight1y;
 		x_dst = 0;
 		for (x_src = 0; x_src < src_width; x_src++) {
-			unsigned long weight1x = 65536 - (x_dst & 0xffff);
-			unsigned long weight2x = 65536 - weight1x;
+			uintptr_t weight1x = 65536 - (x_dst & 0xffff);
+			uintptr_t weight2x = 65536 - weight1x;
 
-			unsigned long x = x_dst >> 16;
+			uintptr_t x = x_dst >> 16;
 
-			unsigned long w;
+			uintptr_t w;
 
 			w = (weight1y * weight1x) >> 16;
 
@@ -643,13 +645,13 @@ static void shrink_picture_byte(
 		y_dst += dy_dst;
 		y_counter -= dy_dst;
 		if (y_counter < 0) {
-			unsigned long x;
+			uintptr_t x;
 			struct scale_outpix_byte * temp;
 
 			y_counter += 65536;
 			
 			for (x=0; x < dst_width; x++) {
-				unsigned long f = 0x80000000UL
+				uintptr_t f = 0x80000000UL
 					/ dst_line1[x].weight;
 				*dst++ = (dst_line1[x].r * f) >> 15;
 				*dst++ = (dst_line1[x].g * f) >> 15;
@@ -664,9 +666,9 @@ static void shrink_picture_byte(
 		}
 	}
 	if (dst - dst_begin < dst_width * dst_height * 4) {
-		unsigned long x;
+		uintptr_t x;
 		for (x = 0; x < dst_width; x++) {
-			unsigned long f = 0x80000000UL / dst_line1[x].weight;
+			uintptr_t f = 0x80000000UL / dst_line1[x].weight;
 			*dst++ = (dst_line1[x].r * f) >> 15;
 			*dst++ = (dst_line1[x].g * f) >> 15;
 			*dst++ = (dst_line1[x].b * f) >> 15;
@@ -698,8 +700,8 @@ static void enlarge_picture_float(
 		/ (double) (src_width - 1.001);
 	double ratioy = (double) (dst_height - 1.0) 
 		/ (double) (src_height - 1.001);
-	unsigned long x_dst;
-	unsigned long y_dst;
+	uintptr_t x_dst;
+	uintptr_t y_dst;
 	double x_src, dx_src;
 	double y_src, dy_src;
 
@@ -727,7 +729,7 @@ static void enlarge_picture_float(
 			float w12 = weight1y * weight2x;
 			float w22 = weight2y * weight2x;
 
-			unsigned long x = ((int) x_src) * 4;
+			uintptr_t x = ((int) x_src) * 4;
 
 			*dst++ =  line1[x]     * w11	
 				+ line2[x]     * w21
@@ -770,8 +772,8 @@ static void shrink_picture_float(
 {
 	double ratiox = (double) (dst_width) / (double) (src_width);
 	double ratioy = (double) (dst_height) / (double) (src_height);
-	unsigned long x_src;
-	unsigned long y_src;
+	uintptr_t x_src;
+	uintptr_t y_src;
         float dx_dst, x_dst;
 	float dy_dst, y_dst;
 	float y_counter;
@@ -794,14 +796,14 @@ static void shrink_picture_float(
 	y_counter = 1.0;
 	for (y_src = 0; y_src < src_height; y_src++) {
 		float* line = src + y_src * 4 * src_width;
-		unsigned long weight1y = 1.0 - (y_dst - (int) y_dst);
-		unsigned long weight2y = 1.0 - weight1y;
+		uintptr_t weight1y = 1.0 - (y_dst - (int) y_dst);
+		uintptr_t weight2y = 1.0 - weight1y;
 		x_dst = 0;
 		for (x_src = 0; x_src < src_width; x_src++) {
-			unsigned long weight1x = 1.0 - (x_dst - (int) x_dst);
-			unsigned long weight2x = 1.0 - weight1x;
+			uintptr_t weight1x = 1.0 - (x_dst - (int) x_dst);
+			uintptr_t weight2x = 1.0 - weight1x;
 
-			unsigned long x = (int) x_dst;
+			uintptr_t x = (int) x_dst;
 
 			float w;
 
@@ -844,7 +846,7 @@ static void shrink_picture_float(
 		y_dst += dy_dst;
 		y_counter -= dy_dst;
 		if (y_counter < 0) {
-			unsigned long x;
+			uintptr_t x;
 			struct scale_outpix_float * temp;
 
 			y_counter += 1.0;
@@ -864,7 +866,7 @@ static void shrink_picture_float(
 		}
 	}
 	if (dst - dst_begin < dst_width * dst_height * 4) {
-		unsigned long x;
+		uintptr_t x;
 		for (x = 0; x < dst_width; x++) {
 			float f = 1.0 / dst_line1[x].weight;
 			*dst++ = dst_line1[x].r * f;
diff --git a/source/blender/include/BDR_gpencil.h b/source/blender/include/BDR_gpencil.h
index eb749cf28ec656d8953fa2c72738529b6df79ac0..9b9294b0343fab9c34db32b5cf04c0fe4661b7a7 100644
--- a/source/blender/include/BDR_gpencil.h
+++ b/source/blender/include/BDR_gpencil.h
@@ -43,7 +43,6 @@ struct bGPDframe;
 /* Temporary 'Stroke Point' data */
 typedef struct tGPspoint {
 	short x, y;				/* x and y coordinates of cursor (in relative to area) */
-	float xf, yf;			/* same as x and y, but as floats */
 	float pressure;			/* pressure of tablet at this point */
 } tGPspoint;
 
@@ -77,6 +76,9 @@ void gpencil_delete_laststroke(struct bGPdata *gpd);
 void gpencil_delete_operation(short mode);
 void gpencil_delete_menu(void);
 
+void gpencil_convert_operation(short mode);
+void gpencil_convert_menu(void);
+
 //short gpencil_paint(short mousebutton);
 short gpencil_do_paint(struct ScrArea *sa, short mousebutton);
 
diff --git a/source/blender/include/BIF_drawgpencil.h b/source/blender/include/BIF_drawgpencil.h
index 418446313dfba99d53c537726d0dbc142e45587c..eacafce058d92e5ec064372a839b314c2827fe13 100644
--- a/source/blender/include/BIF_drawgpencil.h
+++ b/source/blender/include/BIF_drawgpencil.h
@@ -28,15 +28,18 @@
 #ifndef BIF_DRAWGPENCIL_H
 #define BIF_DRAWGPENCIL_H
 
+
+struct bGPdata;
 struct ScrArea;
 struct View3D;
 struct SpaceNode;
 struct SpaceSeq;
-struct bGPdata;
 struct uiBlock;
+struct ImBuf;
 
 short draw_gpencil_panel(struct uiBlock *block, struct bGPdata *gpd, struct ScrArea *sa); 
 
+void draw_gpencil_2dimage(struct ScrArea *sa, struct ImBuf *ibuf);
 void draw_gpencil_2dview(struct ScrArea *sa, short onlyv2d);
 void draw_gpencil_3dview(struct ScrArea *sa, short only3d);
 void draw_gpencil_oglrender(struct View3D *v3d, int winx, int winy);
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index 07fc8f08b4a0a7be2e51fb366e15be1f4f10dc85..b2bdb2dad73c81daac16622e605e0e5e19833453 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -91,6 +91,7 @@ void	free_editArmature(void);
 
 int		join_armature(void);
 void 	separate_armature(void);
+void	apply_armature_pose2bones(void);
 void	load_editArmature(void);
 
 void	make_bone_parent(void);
diff --git a/source/blender/include/BIF_editview.h b/source/blender/include/BIF_editview.h
index d2c6c56d01a2da3258b2c4fbfc82e9a33d317ebd..204733a19d68d160fff82dab1dc5af47fd730320 100644
--- a/source/blender/include/BIF_editview.h
+++ b/source/blender/include/BIF_editview.h
@@ -40,6 +40,7 @@ void	arrows_move_cursor(unsigned short event);
 void 	lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves);
 int		lasso_inside(short mcords[][2], short moves, short sx, short sy);
 int 	lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1);
+int 	edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2);
 void	borderselect(void);
 void	circle_select(void);
 void	deselectall(void);
diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h
index b08c66fd16e5c3b78f472a5afd6f486e8106a3ee..d809d1f21f927258a395f231083b1de3b76f6d08 100644
--- a/source/blender/include/BIF_meshtools.h
+++ b/source/blender/include/BIF_meshtools.h
@@ -40,7 +40,7 @@ extern void objects_bake_render_menu(void);
 extern void objects_bake_render_ui(short event);
 extern void objects_bake_render(short event, char **error_msg);
 
-extern long mesh_octree_table(struct Object *ob, float *co, char mode);
+extern intptr_t mesh_octree_table(struct Object *ob, float *co, char mode);
 extern int mesh_get_x_mirror_vert(struct Object *ob, int index);
 extern struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, float *co);
 extern int *mesh_get_x_mirror_faces(struct Object *ob);
diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h
index 92f18a89a4bb6176c48201d0155826106da11c95..5099c253c7906e2baf10bce97cdc64f2969510a1 100644
--- a/source/blender/include/BIF_resources.h
+++ b/source/blender/include/BIF_resources.h
@@ -524,6 +524,10 @@ enum {
 	
 	TH_EDGE_SHARP,
 	TH_EDITMESH_ACTIVE,
+
+	TH_HANDLE_VERTEX,
+	TH_HANDLE_VERTEX_SELECT,
+	TH_HANDLE_VERTEX_SIZE,
 };
 /* XXX WARNING: previous is saved in file, so do not change order! */
 
diff --git a/source/blender/include/BSE_drawipo.h b/source/blender/include/BSE_drawipo.h
index 932f103a579b755c7ac67e967bbd99030a2682c5..b8388b2172af960bb27f2a2cb47c78a457132d0e 100644
--- a/source/blender/include/BSE_drawipo.h
+++ b/source/blender/include/BSE_drawipo.h
@@ -42,6 +42,7 @@ struct ScrArea;
 struct EditIpo;
 struct View2D;
 struct rctf;
+struct SpaceLink;
 
 void calc_ipogrid(void);
 void draw_ipogrid(void);
@@ -50,6 +51,8 @@ void areamouseco_to_ipoco	(struct View2D *v2d, short *mval, float *x, float *y);
 void ipoco_to_areaco		(struct View2D *v2d, float *vec, short *mval);
 void ipoco_to_areaco_noclip	(struct View2D *v2d, float *vec, short *mval);
 
+struct View2D *spacelink_get_view2d(struct SpaceLink *sl);
+
 void view2d_do_locks		(struct ScrArea *cursa, int flag);
 void view2d_zoom			(struct View2D *v2d, float factor, int winx, int winy);
 void view2d_getscale		(struct View2D *v2d, float *x, float *y);
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 720b856a14941e9c31a5ab7911f1960631d88c0d..51fa39ff9d6bd702c459c1d6ad32ee5cd094f241 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -466,7 +466,6 @@ int validSnappingNormal(TransInfo *t);
 /*********************** Generics ********************************/
 
 void initTrans(TransInfo *t);
-void initTransModeFlags(TransInfo *t, int mode);
 void postTrans (TransInfo *t);
 
 void drawLine(float *center, float *dir, char axis, short options);
@@ -498,6 +497,7 @@ TransInfo * BIF_GetTransInfo(void);
 
 /*********************** NumInput ********************************/
 
+void initNumInput(NumInput *n);
 void outputNumInput(NumInput *n, char *str);
 short hasNumInput(NumInput *n);
 void applyNumInput(NumInput *n, float *vec);
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 7444ce95f56a47de24e3e868b6290d48bfc805ba..59d0555b4523072e4b9389229b3698a8e2e8428a 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -81,7 +81,9 @@ typedef struct bEditObjectActuator {
 	struct Mesh *me;
 	char name[32];
 	float linVelocity[3]; /* initial lin. velocity on creation */
-	short localflag; /* flag for the lin. vel: apply locally   */
+	float angVelocity[3]; /* initial ang. velocity on creation */
+	float pad;
+	short localflag; /* flag for the lin & ang. vel: apply locally   */
 	short dyn_operation;
 } bEditObjectActuator;
 
@@ -384,6 +386,9 @@ typedef struct FreeCamera {
 #define ACT_EDOB_TRACK_TO		3
 #define ACT_EDOB_DYNAMICS		4
 
+/* editObjectActuator->localflag */
+#define ACT_EDOB_LOCAL_LINV		2
+#define ACT_EDOB_LOCAL_ANGV		4
 
 
 /* editObjectActuator->flag */
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index dca4e28688dcab1991234abc616807fa542d6a8f..cc0c99120572ca33ce3d6539e99d61537e59a82a 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -59,8 +59,10 @@ typedef struct bGPDstroke {
 #define GP_STROKE_3DSPACE		(1<<0)
 	/* stroke is in 2d-space */
 #define GP_STROKE_2DSPACE		(1<<1)
-	/* stroke is an "eraser" stroke */
-#define GP_STROKE_ERASER		(1<<2)
+	/* stroke is in 2d-space (but with special 'image' scaling) */
+#define GP_STROKE_2DIMAGE		(1<<2)
+	/* only for use with stroke-buffer (while drawing eraser) */
+#define GP_STROKE_ERASER		(1<<15)
 
 
 /* Grease-Pencil Annotations - 'Frame'
diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h
index 3954a500dc7d29004c482dcb44ada3f964a0a10f..1e30f3f7640a2b0eaebd95b184a4064667162c10 100644
--- a/source/blender/makesdna/DNA_ipo_types.h
+++ b/source/blender/makesdna/DNA_ipo_types.h
@@ -354,8 +354,8 @@ typedef short IPO_Channel;
 
 /* ******************** */
 /* particle ipos */
-#define PART_TOTIPO		19
-#define PART_TOTNAM		19
+#define PART_TOTIPO		25
+#define PART_TOTNAM		25
 
 #define PART_EMIT_FREQ	1
 #define PART_EMIT_LIFE	2
@@ -381,6 +381,14 @@ typedef short IPO_Channel;
 
 #define PART_BB_TILT	19
 
+#define PART_PD_FSTR	20
+#define PART_PD_FFALL	21
+#define PART_PD_FMAXD	22
+
+#define PART_PD2_FSTR	23
+#define PART_PD2_FFALL	24
+#define PART_PD2_FMAXD	25
+
 
 /* these are IpoCurve specific */
 /* **************** IPO ********************* */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index a44d9793062e3bc2e7ca445921593c64c0dd9f89..9599cc1d247f6008bb0c81b8be7ced066269e551 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -35,6 +35,7 @@ typedef enum ModifierType {
 	eModifierType_Cloth,
 	eModifierType_Collision,
 	eModifierType_Bevel,
+	eModifierType_Shrinkwrap,
 	NUM_MODIFIER_TYPES
 } ModifierType;
 
@@ -390,7 +391,8 @@ typedef struct CollisionModifierData {
 	
 	unsigned int numverts;
 	unsigned int numfaces;
-	int pad;
+	short absorption; /* used for forces, in % */
+	short pad;
 	float time;		/* cfra time of modifier */
 	struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */
 } CollisionModifierData;
@@ -490,4 +492,45 @@ typedef struct ExplodeModifierData {
 	float protect;
 } ExplodeModifierData;
 
+typedef struct ShrinkwrapModifierData {
+	ModifierData modifier;
+
+	struct Object *target;	/* shrink target */
+	struct Object *auxTarget; /* additional shrink target */
+	char vgroup_name[32];	/* optional vertexgroup name */
+	float keepDist;			/* distance offset to keep from mesh/projection point */
+	short shrinkType;		/* shrink type projection */
+	short shrinkOpts;		/* shrink options */
+	char projAxis;			/* axis to project over */
+
+	/*
+	 * if using projection over vertex normal this controls the
+	 * the level of subsurface that must be done before getting the
+	 * vertex coordinates and normal
+	 */
+	char subsurfLevels;
+
+	char pad[6];
+
+} ShrinkwrapModifierData;
+
+/* Shrinkwrap->shrinkType */
+#define MOD_SHRINKWRAP_NEAREST_SURFACE	0
+#define MOD_SHRINKWRAP_PROJECT			1
+#define MOD_SHRINKWRAP_NEAREST_VERTEX	2
+
+/* Shrinkwrap->shrinkOpts */
+#define MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR	(1<<0)	/* allow shrinkwrap to move the vertex in the positive direction of axis */
+#define MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR	(1<<1)	/* allow shrinkwrap to move the vertex in the negative direction of axis */
+
+#define MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE	(1<<3)	/* ignore vertex moves if a vertex ends projected on a front face of the target */
+#define MOD_SHRINKWRAP_CULL_TARGET_BACKFACE		(1<<4)	/* ignore vertex moves if a vertex ends projected on a back face of the target */
+
+#define MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE		(1<<5)	/* distance is measure to the front face of the target */
+
+#define MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS		(1<<0)
+#define MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS		(1<<1)
+#define MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS		(1<<2)
+#define MOD_SHRINKWRAP_PROJECT_OVER_NORMAL			0	/* projection over normal is used if no axis is selected */
+
 #endif
diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h
index dc6c2bcbcc0f14ac607b10e372d676f65957e729..5900e16d5e804f7a3e7420f8fac9b48e719bef6c 100644
--- a/source/blender/makesdna/DNA_object_force.h
+++ b/source/blender/makesdna/DNA_object_force.h
@@ -67,6 +67,9 @@ typedef struct PartDeflect {
 	float tex_nabla;
 	short tex_mode, kink, kink_axis, rt2;
 	struct Tex *tex;	/* Texture of the texture effector */
+	struct RNG *rng; /* random noise generator for e.g. wind */
+	float f_noise; /* noise of force (currently used for wind) */
+	int pad;
 } PartDeflect;
 
 typedef struct PointCache {
@@ -153,8 +156,8 @@ typedef struct SoftBody {
 #define PFIELD_GUIDE	5
 #define PFIELD_TEXTURE	6
 #define PFIELD_HARMONIC	7
-#define PFIELD_NUCLEAR	8
-#define PFIELD_MDIPOLE	9
+#define PFIELD_CHARGE	8
+#define PFIELD_LENNARDJ	9
 
 
 /* pd->flag: various settings */
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 4f62cd084cc9b0ca0095635d1ab4d3276ea15bb5..363f0075e23f20513446ee353d28313b418fc908 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -166,6 +166,7 @@ typedef struct ParticleSettings {
 	struct Object *bb_ob;
 	struct Ipo *ipo;
 	struct PartDeflect *pd;
+	struct PartDeflect *pd2;
 } ParticleSettings;
 
 typedef struct ParticleSystem{				/* note, make sure all (runtime) are NULL's in copy_particlesystem */
@@ -264,6 +265,8 @@ typedef struct ParticleSystem{				/* note, make sure all (runtime) are NULL's in
 #define PART_CHILD_RENDER	(1<<29)
 #define PART_CHILD_GUIDE	(1<<30)
 
+#define PART_SELF_EFFECT	(1<<22)
+
 /* part->rotfrom */
 #define PART_ROT_KEYS		0	/* interpolate directly from keys */
 #define PART_ROT_ZINCR		1	/* same as zdir but done incrementally from previous position */
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index c0306f4373067180a52405affcb19f46222d3fce..d508ff3a55292af7bfcfd7090d145abc366ce3e8 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -88,6 +88,13 @@ typedef struct bActuatorSensor {
 	char name[32];
 } bActuatorSensor;
 
+typedef struct bDelaySensor {
+    short delay;
+	short duration;
+	short flag;
+	short pad;
+} bDelaySensor;
+
 typedef struct bCollisionSensor {
 	char name[32];          /* property name */
 	char materialName[32];  /* material      */
@@ -204,6 +211,7 @@ typedef struct bJoystickSensor {
 #define SENS_MESSAGE   10
 #define SENS_JOYSTICK  11
 #define SENS_ACTUATOR  12
+#define SENS_DELAY     13
 /* sensor->flag */
 #define SENS_SHOW		1
 #define SENS_DEL		2
@@ -229,6 +237,9 @@ typedef struct bJoystickSensor {
  * */
 /*  #define SENS_COLLISION_PROPERTY 0  */
 #define SENS_COLLISION_MATERIAL 1
+/* ray specific mode */
+/* X-Ray means that the ray will traverse objects that don't have the property/material */
+#define SENS_RAY_XRAY			2
 
 /* Some stuff for the mouse sensor Type: */
 #define BL_SENS_MOUSE_LEFT_BUTTON    1
@@ -254,5 +265,7 @@ typedef struct bJoystickSensor {
 #define SENS_JOY_HAT			2
 #define SENS_JOY_HAT_DIR		0
 
+#define SENS_DELAY_REPEAT		1
+
 #endif
 
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 1e3f337ad999a388cb048feb138a56b178381638..8e849c5aa3dfe8bd7561375c49e73f2daf78d1c2 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -247,6 +247,7 @@ typedef struct SpaceImage {
 	float xof, yof;					/* user defined offset, image is centered */
 	float centx, centy;				/* storage for offset while render drawing */
 	
+	struct bGPdata *gpd;			/* grease pencil data */
 } SpaceImage;
 
 typedef struct SpaceNla {
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index cd1c047dac9a24e8b87510ea2ebe759174b6d488..856324695a9bb9cef32f825fb53ca2e06b86a011 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -101,6 +101,11 @@ typedef struct ThemeSpace {
 	char movie[4], image[4], scene[4], audio[4];		// for sequence editor
 	char effect[4], plugin[4], transition[4], meta[4];
 	char editmesh_active[4]; 
+
+	char handle_vertex[4];
+	char handle_vertex_select[4];
+	char handle_vertex_size;
+	char hpad[7];
 } ThemeSpace;
 
 
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 3818d66b39ca96ba42b0f966ada09a1a523c2c21..b4deb1f2b6065b331359c25a580d0911a6eb9d83 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -55,6 +55,8 @@
 #include "MEM_guardedalloc.h"
 #include "DNA_sdna_types.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -955,7 +957,7 @@ int make_structDNA(char *baseDirectory, FILE *file)
 		/* calculate size of datablock with strings */
 		cp= names[nr_names-1];
 		cp+= strlen(names[nr_names-1]) + 1;			/* +1: null-terminator */
-		len= (long) (cp - (char*) names[0]);
+		len= (intptr_t) (cp - (char*) names[0]);
 		len= (len+3) & ~3;
 		dna_write(file, names[0], len);
 		
@@ -968,7 +970,7 @@ int make_structDNA(char *baseDirectory, FILE *file)
 		/* calculate datablock size */
 		cp= types[nr_types-1];
 		cp+= strlen(types[nr_types-1]) + 1;		/* +1: null-terminator */
-		len= (long) (cp - (char*) types[0]);
+		len= (intptr_t) (cp - (char*) types[0]);
 		len= (len+3) & ~3;
 		
 		dna_write(file, types[0], len);
@@ -990,7 +992,7 @@ int make_structDNA(char *baseDirectory, FILE *file)
 		/* calc datablock size */
 		sp= structs[nr_structs-1];
 		sp+= 2+ 2*( sp[1] );
-		len= (long) ((char*) sp - (char*) structs[0]);
+		len= (intptr_t) ((char*) sp - (char*) structs[0]);
 		len= (len+3) & ~3;
 		
 		dna_write(file, structs[0], len);
diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c
index 047a035fb8b4c5d6ddb78e24593e21e38f900ba4..bd19a6a6a3efb2520036f921be0e47e7335d98fe 100644
--- a/source/blender/python/api2_2x/Draw.c
+++ b/source/blender/python/api2_2x/Draw.c
@@ -1554,6 +1554,12 @@ static PyObject *Method_Number( PyObject * self, PyObject * args )
 
 	UI_METHOD_ERRORCHECK;
 
+	if ( !PyNumber_Check(inio) || !PyNumber_Check(mino) ||
+			!PyNumber_Check(maxo) ) {
+		return EXPP_ReturnPyObjError( PyExc_TypeError,
+				"expected ints or floats for the initial, min and max values" );
+	}
+
 	but = newbutton(  );
 	if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
 	block = Get_uiBlock(  );
diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c
index ccd24a437b5e8edd801b5774ce8150a73673e2e9..20747a167e695b0722c1b932f8a5a5e6af5f2e6c 100644
--- a/source/blender/python/api2_2x/Material.c
+++ b/source/blender/python/api2_2x/Material.c
@@ -554,6 +554,7 @@ static int Material_setSssTexScatter( BPy_Material * self, PyObject * value );
 static int Material_setSssFront( BPy_Material * self, PyObject * value );
 static int Material_setSssBack( BPy_Material * self, PyObject * value );
 static int Material_setSssBack( BPy_Material * self, PyObject * value );
+static int Material_setTexChannel( BPy_Material * self, PyObject * value );
 
 static PyObject *Material_getColorComponent( BPy_Material * self,
 							void * closure );
@@ -633,6 +634,7 @@ static PyObject *Material_getSssBack( BPy_Material * self );
 static PyObject *Material_getFilter( BPy_Material * self );
 static PyObject *Material_getTranslucency( BPy_Material * self );
 static PyObject *Material_getTextures( BPy_Material * self );
+static PyObject *Material_getTexChannel( BPy_Material * self );
 static PyObject *Material_clearIpo( BPy_Material * self );
 
 static PyObject *Material_setTexture( BPy_Material * self, PyObject * args );
@@ -1140,7 +1142,11 @@ static PyGetSetDef BPy_Material_getseters[] = {
 	 NULL},
 	{"lightGroup",
 	 (getter)Material_getLightGroup, (setter)Material_setLightGroup,
-	 "Set the light group for this material",
+	 "The light group for this material",
+	 NULL},
+	{"enabledTextures",
+	 (getter)Material_getTexChannel, (setter)Material_setTexChannel,
+	 "Enabled texture channels for this material",
 	 NULL},
 	{"R",
 	 (getter)Material_getColorComponent, (setter)Material_setColorComponent,
@@ -1517,6 +1523,36 @@ static PyObject *Material_getLightGroup( BPy_Material * self )
 	return Group_CreatePyObject( self->material->group );
 }
 
+static PyObject *Material_getTexChannel( BPy_Material * self )
+{
+	int i;
+    short mask = 1;
+	PyObject *list = PyList_New(0);
+	if( !list )
+		return EXPP_ReturnPyObjError( PyExc_MemoryError,
+				"PyList_New() failed" );
+
+	for( i = 0, mask = 1; i < MAX_MTEX ; ++i, mask <<= 1 ) {
+		if( self->material->mtex[i] && (mask & self->material->septex) == 0 ) {
+			PyObject * val = PyInt_FromLong(i);
+			if( !val ) {
+				Py_DECREF( list );
+				return EXPP_ReturnPyObjError( PyExc_MemoryError,
+						"PyInt_FromLong() failed" );
+			}
+			if( PyList_Append( list, val ) < 0 ) {
+				Py_DECREF( val );
+				Py_DECREF( list );
+				return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+						"PyList_Append() failed" );
+			}
+			Py_DECREF( val );
+		}
+	}
+
+	return list;
+}
+
 static PyObject *Material_getHaloSize( BPy_Material * self )
 {
 	return PyFloat_FromDouble( ( double ) self->material->hasize );
@@ -1982,6 +2018,57 @@ static int Material_setLightGroup( BPy_Material * self, PyObject * value )
 	return GenericLib_assignData(value, (void **) &self->material->group, NULL, 1, ID_GR, 0);
 }
 
+static int Material_setTexChannel( BPy_Material * self, PyObject * value )
+{
+	int i, mask;
+	short septex = 0;
+	int result = 1;
+
+	/* fail if input is not a standard sequence */
+	if( !PyList_Check( value ) && !PyTuple_Check( value ) )
+		return EXPP_ReturnIntError( PyExc_TypeError,
+						"expected tuple or list of integers" );
+
+	/* get a fast sequence; in Python 2.5, this just return the original
+	 * list or tuple and INCREFs it, so we must DECREF */
+	value = PySequence_Fast( value, "" );
+
+	/* set the disable bit for each existing texture */
+	for( i= 0, mask= 1; i < MAX_MTEX; ++i, mask <<= 1 )
+		if( self->material->mtex[i] != NULL )
+			septex |= mask;
+
+	/* check the list, and build new septex value */
+	for( i= PySequence_Size(value)-1; i >= 0; --i ) {
+		long ival;
+		PyObject *item = PySequence_Fast_GET_ITEM( value, i );
+		if( !PyInt_Check( item ) ) {
+			PyErr_SetString ( PyExc_TypeError,
+					"expected tuple or list of integers" );
+			goto exit;
+		}
+		ival= PyInt_AsLong( item );
+		if(ival < 0 || ival > MAX_MTEX) {
+			PyErr_SetString( PyExc_ValueError,
+							"channel value out of range" );
+			goto exit;
+		}
+		ival&= (1<<MAX_MTEX)-1;
+		if( self->material->mtex[(int)ival] == NULL ) {
+			PyErr_SetString( PyExc_ValueError,
+							"channels must have a texture assigned" );
+			goto exit;
+		}
+		septex&= ~(1<<ival);
+	}
+	self->material->septex= septex;
+	result = 0;
+
+exit:
+	Py_DECREF(value);
+	return result;
+}
+
 static int Material_setAdd( BPy_Material * self, PyObject * value )
 {
 	return EXPP_setFloatClamped ( value, &self->material->add,
@@ -2313,9 +2400,6 @@ static int Material_setSssBack( BPy_Material * self, PyObject * value )
 								EXPP_MAT_SSS_BACK_MAX);
 }
 
-
-
-
 static PyObject *Material_setTexture( BPy_Material * self, PyObject * args )
 {
 	int texnum;
diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c
index 9f68287d658d96d91224595a84bbb9c9863f6f37..b3e8fefdb7be704cf00461797df6e4abb3fab27f 100644
--- a/source/blender/python/api2_2x/Mesh.c
+++ b/source/blender/python/api2_2x/Mesh.c
@@ -5381,11 +5381,11 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
 	if( PySequence_Size( args ) != 2 ||
 			!PyArg_ParseTuple( args, "iO", &edge_also, &args ) )
 		return EXPP_ReturnPyObjError( PyExc_TypeError,
-				"expected and int and a sequence of ints or MFaces" );
+				"expected an int and a sequence of ints or MFaces" );
 
 	if( !PyList_Check( args ) && !PyTuple_Check( args ) )
 		return EXPP_ReturnPyObjError( PyExc_TypeError,
-				"expected and int and a sequence of ints or MFaces" );
+				"expected an int and a sequence of ints or MFaces" );
 
 	/* see how many args we need to parse */
 	len = PySequence_Size( args );
diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c
index 45cce46d389688ce177117d17d7d8def42283bf0..dc70921492c73c23a886466f9acbd1a3b34234ba 100644
--- a/source/blender/python/api2_2x/Object.c
+++ b/source/blender/python/api2_2x/Object.c
@@ -204,6 +204,7 @@ enum obj_consts {
 	EXPP_OBJ_ATTR_SB_INSPRING,
 	EXPP_OBJ_ATTR_SB_INFRICT,
 
+	EXPP_OBJ_ATTR_EMPTY_DRAWTYPE
 };
 
 #define EXPP_OBJECT_DRAWSIZEMIN         0.01f
@@ -2431,6 +2432,12 @@ static int Object_setDrawType( BPy_Object * self, PyObject * value )
 			OB_BOUNDBOX, OB_TEXTURE, 'b' );
 }
 
+static int Object_setEmptyShape( BPy_Object * self, PyObject * value )
+{
+	return EXPP_setIValueRange( value, &self->object->empty_drawtype,
+			OB_ARROWS, OB_EMPTY_CONE, 'b' );
+}
+
 static int Object_setEuler( BPy_Object * self, PyObject * args )
 {
 	float rot1, rot2, rot3;
@@ -3758,6 +3765,9 @@ static PyObject *getIntAttr( BPy_Object *self, void *type )
 	case EXPP_OBJ_ATTR_DRAWTYPE:
 		param = object->dt;
 		break;
+	case EXPP_OBJ_ATTR_EMPTY_DRAWTYPE:
+		param = object->empty_drawtype;
+		break;
 	case EXPP_OBJ_ATTR_PARENT_TYPE:
 		param = object->partype;
 		break;
@@ -4938,6 +4948,10 @@ static PyGetSetDef BPy_Object_getseters[] = {
 	 (getter)getIntAttr, (setter)Object_setDrawType,
 	 "The object's drawing type",
 	 (void *)EXPP_OBJ_ATTR_DRAWTYPE},
+	{"emptyShape",
+	 (getter)getIntAttr, (setter)Object_setEmptyShape,
+	 "The empty's drawing shape",
+	 (void *)EXPP_OBJ_ATTR_EMPTY_DRAWTYPE},
 	{"parentType",
 	 (getter)getIntAttr, (setter)NULL,
 	 "The object's parent type",
@@ -5538,6 +5552,24 @@ static PyObject *M_Object_IpoKeyTypesDict( void )
 	return M;
 }
 
+static PyObject *M_Object_EmptyShapesDict( void )
+{
+	PyObject *M = PyConstant_New(  );
+
+	if( M ) {
+		BPy_constant *d = ( BPy_constant * ) M;
+		PyConstant_Insert( d, "ARROWS", PyInt_FromLong( OB_ARROWS ) );
+		PyConstant_Insert( d, "AXES", PyInt_FromLong( OB_PLAINAXES ) );
+		PyConstant_Insert( d, "CIRCLE", PyInt_FromLong( OB_CIRCLE ) );
+		PyConstant_Insert( d, "ARROW", PyInt_FromLong( OB_SINGLE_ARROW ) );
+		PyConstant_Insert( d, "CUBE", PyInt_FromLong( OB_CUBE ) );
+		PyConstant_Insert( d, "SPHERE", PyInt_FromLong( OB_EMPTY_SPHERE ) );
+		PyConstant_Insert( d, "CONE", PyInt_FromLong( OB_EMPTY_CONE ) );
+	}
+	return M;
+}
+
+
 /*****************************************************************************/
 /* Function:	 initObject						*/
 /*****************************************************************************/
@@ -5552,6 +5584,7 @@ PyObject *Object_Init( void )
 	PyObject *RBFlagsDict = M_Object_RBFlagsDict( );
 	PyObject *RBShapesDict = M_Object_RBShapeBoundDict( );
 	PyObject *IpoKeyTypesDict = M_Object_IpoKeyTypesDict( );
+	PyObject *EmptyShapesDict = M_Object_EmptyShapesDict( );
 
 	PyType_Ready( &Object_Type ) ;
 
@@ -5596,7 +5629,9 @@ PyObject *Object_Init( void )
 	if( RBShapesDict )
 		PyModule_AddObject( module, "RBShapes", RBShapesDict );
 	if( IpoKeyTypesDict )
-		PyModule_AddObject( module, "IpoKeyTypes", IpoKeyTypesDict );	
+		PyModule_AddObject( module, "IpoKeyTypes", IpoKeyTypesDict );
+	if( EmptyShapesDict )
+		PyModule_AddObject( module, "EmptyShapes", EmptyShapesDict );
 
 		/*Add SUBMODULES to the module*/
 	dict = PyModule_GetDict( module ); /*borrowed*/
diff --git a/source/blender/python/api2_2x/Particle.c b/source/blender/python/api2_2x/Particle.c
index 2c2e724129ed7a63b048e6d4e78c6a297a5eaaa9..bc65426e16c1e332fde279c4e896e7568bda2db1 100644
--- a/source/blender/python/api2_2x/Particle.c
+++ b/source/blender/python/api2_2x/Particle.c
@@ -804,7 +804,7 @@ static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args )
 {
 	ParticleSystem *psys = 0L;
 	Object *ob = 0L;
-	PyObject *partlist,*seglist;
+	PyObject *partlist,*seglist=0L;
 	ParticleCacheKey **cache,*path;
 	PyObject* loc = 0L;
 	ParticleKey state;
@@ -1107,7 +1107,7 @@ static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args )
 	ParticleSystem *psys = 0L;
 	ParticleData *data;
 	Object *ob = 0L;
-	PyObject *partlist,*tuple;
+	PyObject *partlist,*tuple=0L;
 	DerivedMesh* dm;
 	float vm[4][4],wm[4][4];
 	float size;
@@ -1217,7 +1217,7 @@ static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args )
 	ParticleSystem *psys = 0L;
 	ParticleData *data;
 	Object *ob = 0L;
-	PyObject *partlist,*tuple;
+	PyObject *partlist,*tuple=0L;
 	DerivedMesh* dm;
 	float vm[4][4],wm[4][4];
 	float life;
diff --git a/source/blender/python/api2_2x/Text3d.c b/source/blender/python/api2_2x/Text3d.c
index 5137e989b8ddbbe3a07246a13ed2170b6a6be3b0..202195cdcb4e246c57713958bdb3192b60300faf 100644
--- a/source/blender/python/api2_2x/Text3d.c
+++ b/source/blender/python/api2_2x/Text3d.c
@@ -132,9 +132,12 @@ static PyObject *Text3d_getAlignment( BPy_Text3d * self );
 static PyObject *Text3d_setAlignment( BPy_Text3d * self, PyObject * args );
 static PyObject *Text3d_getFont( BPy_Text3d * self );
 static PyObject *Text3d_setFont( BPy_Text3d * self, PyObject * args );
+static PyObject *Text3d_getMaterial( BPy_Text3d * self, PyObject * value );
+static PyObject *Text3d_setMaterial( BPy_Text3d * self, PyObject * args );
 static PyObject *Text3d_addFrame( BPy_Text3d * self );
 static PyObject *Text3d_removeFrame( BPy_Text3d * self, PyObject * args );
 
+
 /*****************************************************************************/
 /* Python BPy_Text3d methods table:                                            */
 /*****************************************************************************/
@@ -210,6 +213,10 @@ static PyMethodDef BPy_Text3d_methods[] = {
 	METH_NOARGS, "() - Gets font list for Text3d"},
  	{"setFont", ( PyCFunction ) Text3d_setFont,
  	METH_VARARGS, "() - Sets font for Text3d"},
+ 	{"getMaterial", ( PyCFunction ) Text3d_getMaterial,
+	METH_O, "() - Gets font list for Text3d"},
+ 	{"setMaterial", ( PyCFunction ) Text3d_setMaterial,
+ 	METH_VARARGS, "() - Sets font for Text3d"},	
  	{"addFrame", ( PyCFunction ) Text3d_addFrame,
  	METH_NOARGS, "() - adds a new text frame"},
  	{"removeFrame", ( PyCFunction ) Text3d_removeFrame,
@@ -1132,6 +1139,45 @@ static PyObject *Text3d_setFont( BPy_Text3d * self, PyObject * args )
 	Py_RETURN_NONE;
 }
 
+/* todo, add style access, will be almost exact copy of these 2  */
+static PyObject *Text3d_getMaterial( BPy_Text3d * self, PyObject * value )
+{
+	int index = PyInt_AsLong( value );
+	if (index == -1 && PyErr_Occurred())
+		return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a character index" );
+
+	if (index < 0)
+		index = self->curve->len + index;
+	
+	if ( index < 0 || index >= self->curve->len )
+		return EXPP_ReturnPyObjError( PyExc_IndexError, "character index out of range" );
+	
+	return PyInt_FromLong( self->curve->strinfo[index].mat_nr );
+}
+
+static PyObject *Text3d_setMaterial( BPy_Text3d * self, PyObject * args )
+{
+	int index, mat_nr;
+	if( !PyArg_ParseTuple( args, "ii",&index, &mat_nr) )
+		return NULL; /* Python error is ok */
+	
+	if (index < 0)
+		index = self->curve->len + index;
+	
+	if ( index < 0 || index >= self->curve->len )
+		return EXPP_ReturnPyObjError( PyExc_IndexError, "character index out of range" );
+
+	if (mat_nr < 0)
+		mat_nr = self->curve->totcol + mat_nr;
+	
+	if ( mat_nr < 0 || mat_nr >= self->curve->totcol )
+		return EXPP_ReturnPyObjError( PyExc_IndexError, "material index out of range" );
+	
+	self->curve->strinfo[index].mat_nr = mat_nr;
+	
+	Py_RETURN_NONE;
+}
+
 static PyObject *Text3d_addFrame( BPy_Text3d * self )
 {
 	Curve *cu = self->curve;
diff --git a/source/blender/python/api2_2x/doc/Material.py b/source/blender/python/api2_2x/doc/Material.py
index a3496164cd19b9abe5fc6894a7b1e3dfdbe84c6f..02f7edd77f533d5fdb7132670e10ed763a96cfd6 100644
--- a/source/blender/python/api2_2x/doc/Material.py
+++ b/source/blender/python/api2_2x/doc/Material.py
@@ -323,6 +323,21 @@ class Material:
 	each color a list of 5 floats [0 - 1], [r,g,b,a,pos].
 	The colorband can have between 1 and 31 colors.
 	@type colorbandSpecular:  list
+	@type enabledTextures: list of integers
+	@ivar enabledTextures: The texture channels enabled in this material.
+		The attribute returns is list of integers in the range [0, 9], each
+		number representing the respective enabled MTex entry (see
+		L{getTextures()<getTextures>}).  Enabling is done by assigning
+		a list of ints or an empty list.  Attempting to enable a channel
+		which does not have a texture assigned to it will result in a
+		ValueError exception.
+		Example::
+			mat.enabledTextures = []  # no texture channels are enabled
+			mat.enabledTextures = [0, 6] # texture channels 0 and 6 are enabled
+			ch = mat.enabledTextures
+			ch.append(4)
+			mat.enabledTextures = ch
+			print mat.enabledTextures # will print: [0, 4, 6]
 	
 	@ivar enableSSS:  If True, subsurface scattering will be rendered on this material.
 	@type enableSSS:  bool
@@ -1010,7 +1025,7 @@ class Material:
 
 	def setTexture(index, texture, texco, mapto):
 		"""
-		Assign a Blender Texture object to slot number 'number'.
+		Assign a Blender Texture object to channel number 'number'.
 		@type index: int
 		@param index: material's texture index in [0, 9].
 		@type texture: Blender Texture
@@ -1033,7 +1048,7 @@ class Material:
 		Get this Material's Texture list.
 		@rtype: list of MTex
 		@return: a list of Blender MTex objects.  None is returned for each empty
-				texture slot.
+				texture channel.
 		"""
 
 	def getScriptLinks (event):
diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py
index 8b0c41b9a690200cb03b0c5283396683660efe04..524d1fb6d4c790fe1068bd2115944bbcbb695841 100644
--- a/source/blender/python/api2_2x/doc/Mathutils.py
+++ b/source/blender/python/api2_2x/doc/Mathutils.py
@@ -521,6 +521,15 @@ class Vector:
     @return: Return a quaternion rotation from the vector and the track and up axis.
     """
 
+  def reflect(mirror):
+    """
+    Return the reflection vector from the mirror vector argument.
+    @type mirror: Vector object
+    @param mirror: This vector could be a normal from the reflecting surface.
+    @rtype: Vector object matching the size of this vector.
+    @return: The reflected vector.
+    """
+
 class Euler:
   """
   The Euler object
diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py
index 2e4850aeb14985f88959d6c455b15de7a6fa1cd1..07942d580937c46b0954fa14fd8a2f6333160812 100644
--- a/source/blender/python/api2_2x/doc/Object.py
+++ b/source/blender/python/api2_2x/doc/Object.py
@@ -117,6 +117,10 @@ Example::
 	attribute.  Only one type can be selected at a time.  Values are
 	BOX, SPHERE, CYLINDER, CONE, and POLYHEDERON
 
+@type EmptyShapes: readonly dictionary
+@var EmptyShapes: Constant dict used for with L{Object.emptyShape} attribute.
+	Only one type can be selected at a time. Values are
+	ARROW, ARROWS, AXES, CIRCLE, CONE, CUBE AND SPHERE
 """
 
 def New (type, name='type'):
@@ -347,7 +351,7 @@ class Object:
 			ob.layers = []  # object won't be visible
 			ob.layers = [1, 4] # object visible only in layers 1 and 4
 			ls = o.layers
-			ls.append([10])
+			ls.append(10)
 			o.layers = ls
 			print ob.layers # will print: [1, 4, 10]
 		B{Note}: changes will only be visible after the screen (at least
@@ -525,6 +529,8 @@ class Object:
 	@ivar drawType: The object's drawing type.
 		See L{DrawTypes} constant dict for values.
 	@type drawType: int
+	@ivar emptyShape: The empty drawing shape.
+		See L{EmptyShapes} constant dict for values.
 	@ivar parentType: The object's parent type.  Read-only.
 		See L{ParentTypes} constant dict for values.
 	@type parentType: int
diff --git a/source/blender/python/api2_2x/doc/Text3d.py b/source/blender/python/api2_2x/doc/Text3d.py
index a7d8c5850786001ba990e0c1091bfdd8f82aa961..4bd989014f41db55fdc9963bf06e60d977210e7e 100644
--- a/source/blender/python/api2_2x/doc/Text3d.py
+++ b/source/blender/python/api2_2x/doc/Text3d.py
@@ -287,6 +287,26 @@ class Text3d:
 		@param align: The new text3d's Alignment value. 
 		"""
 	
+	def getMaterial(index):
+		"""
+		get the material index of a character.
+		@rtype: int
+		@return: the material index if the character
+		@type index: int
+		@param index: the index of the character in a string
+		"""
+
+	def setMaterial(index, material_index):
+		"""
+		Set a characters material.
+		@note: after changing this youll need to update the object with object.makeDisplayList() to see the changes.
+		@rtype: None
+		@type index: int
+		@param index: the index of the character in a string
+		@type material_index: int
+		@param material_index: the material index set set the character.
+		"""
+	
 	def addFrame():
 		"""
 		Adds a text frame. maximum number of frames is 255.
diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c
index 33ca993fb494640a08f0f70d3186c0a2103b5b7d..fe28f0fac425274921be669889b7adce6005ace5 100644
--- a/source/blender/python/api2_2x/vector.c
+++ b/source/blender/python/api2_2x/vector.c
@@ -42,6 +42,7 @@ char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]";
 char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]";
 char Vector_toPoint_doc[] = "() - create a new Point Object from this vector";
 char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis";
+char Vector_reflect_doc[] = "(mirror) - return a vector reflected on the mirror normal";
 char Vector_copy_doc[] = "() - return a copy of the vector";
 /*-----------------------METHOD DEFINITIONS ----------------------*/
 struct PyMethodDef Vector_methods[] = {
@@ -53,6 +54,7 @@ struct PyMethodDef Vector_methods[] = {
 	{"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc},
 	{"toPoint", (PyCFunction) Vector_toPoint, METH_NOARGS, Vector_toPoint_doc},
 	{"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc},
+	{"reflect", ( PyCFunction ) Vector_reflect, METH_O, Vector_reflect_doc},
 	{"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc},
 	{"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc},
 	{NULL, NULL, 0, NULL}
@@ -273,7 +275,55 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
 	return newQuaternionObject(quat, Py_NEW);
 }
 
-
+/*----------------------------Vector.reflect(mirror) ----------------------
+  return a reflected vector on the mirror normal
+  ((2 * DotVecs(vec, mirror)) * mirror) - vec
+  using arithb.c would be nice here */
+PyObject *Vector_reflect( VectorObject * self, PyObject * value )
+{
+	VectorObject *mirrvec;
+	float mirror[3];
+	float vec[3];
+	float reflect[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+	float dot2;
+	
+	/* for normalizing */
+	int i;
+	float norm = 0.0f;
+	
+	if (!VectorObject_Check(value)) 
+		return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a vector argument" );
+	
+	mirrvec = (VectorObject *)value;
+	
+	mirror[0] = mirrvec->vec[0];
+	mirror[1] = mirrvec->vec[1];
+	if (mirrvec->size > 2)	mirror[2] = mirrvec->vec[2];
+	else					mirror[2] = 0.0;
+	
+	/* normalize, whos idea was it not to use arithb.c? :-/ */
+	for(i = 0; i < 3; i++) {
+		norm += mirror[i] * mirror[i];
+	}
+	norm = (float) sqrt(norm);
+	for(i = 0; i < 3; i++) {
+		mirror[i] /= norm;
+	}
+	/* done */
+	
+	vec[0] = self->vec[0];
+	vec[1] = self->vec[1];
+	if (self->size > 2)		vec[2] = self->vec[2];
+	else					vec[2] = 0.0;
+	
+	dot2 = 2 * vec[0]*mirror[0]+vec[1]*mirror[1]+vec[2]*mirror[2];
+	
+	reflect[0] = (dot2 * mirror[0]) - vec[0];
+	reflect[1] = (dot2 * mirror[1]) - vec[1];
+	reflect[2] = (dot2 * mirror[2]) - vec[2];
+	
+	return newVectorObject(reflect, self->size, Py_NEW);
+}
 
 /*----------------------------Vector.copy() --------------------------------------
   return a copy of the vector */
diff --git a/source/blender/python/api2_2x/vector.h b/source/blender/python/api2_2x/vector.h
index a86f2ddfe42ea592617139faebdadeea67ca1aa4..61b50d5f458554a4c0105d0954713731c0a3362f 100644
--- a/source/blender/python/api2_2x/vector.h
+++ b/source/blender/python/api2_2x/vector.h
@@ -52,6 +52,7 @@ PyObject *Vector_Resize3D( VectorObject * self );
 PyObject *Vector_Resize4D( VectorObject * self );
 PyObject *Vector_toPoint( VectorObject * self );
 PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args );
+PyObject *Vector_reflect( VectorObject * self, PyObject * value );
 PyObject *Vector_copy( VectorObject * self );
 PyObject *newVectorObject(float *vec, int size, int type);
 
diff --git a/source/blender/radiosity/CMakeLists.txt b/source/blender/radiosity/CMakeLists.txt
index 36e9ad197708dc25bb68b75f303960f5ea4f4792..941da41a5b28ed0aa62bc710ec7173a78c58cf61 100644
--- a/source/blender/radiosity/CMakeLists.txt
+++ b/source/blender/radiosity/CMakeLists.txt
@@ -29,7 +29,7 @@ FILE(GLOB SRC intern/source/*.c)
 SET(INC 
   extern/include ../blenlib ../blenkernel ../makesdna ../include
   ../../../intern/guardedalloc ../render/extern/include
-  ../render/intern/include
+  ../render/intern/include ../blenloader
 )
 
 BLENDERLIB_NOLIST(blender_radiosity "${SRC}" "${INC}")
diff --git a/source/blender/radiosity/SConscript b/source/blender/radiosity/SConscript
index 102f79683f9e25344176e6aa1c8992e637437bc6..a86b76bb4b1f76278ced8981dc54eabe7b7a1279 100644
--- a/source/blender/radiosity/SConscript
+++ b/source/blender/radiosity/SConscript
@@ -5,7 +5,7 @@ sources = env.Glob('intern/source/*.c')
 
 incs = 'extern/include ../blenlib ../blenkernel ../makesdna ../include'
 incs += ' #/intern/guardedalloc ../render/extern/include'
-incs += ' ../render/intern/include'
+incs += ' ../render/intern/include ../blenloader'
 
 incs += ' ' + env['BF_OPENGL_INC']
 
diff --git a/source/blender/radiosity/intern/source/Makefile b/source/blender/radiosity/intern/source/Makefile
index 19768c959c7e680bc61dfe66e43f3e7133b46f39..e5ff8c40d0823e86c508566c651b796e445afddb 100644
--- a/source/blender/radiosity/intern/source/Makefile
+++ b/source/blender/radiosity/intern/source/Makefile
@@ -44,6 +44,7 @@ CPPFLAGS += -I../../../blenlib
 CPPFLAGS += -I../../../makesdna
 CPPFLAGS += -I../../../imbuf
 CPPFLAGS += -I../../../
+CPPFLAGS += -I../../../blenloader
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
 
 # first /include is my own includes, second are the external includes
diff --git a/source/blender/radiosity/intern/source/radnode.c b/source/blender/radiosity/intern/source/radnode.c
index 5517a22eb934e41491b6c0194b8dae58c13d15b0..042fe6840fc2204fce1fe455fafb97a1866dd120 100644
--- a/source/blender/radiosity/intern/source/radnode.c
+++ b/source/blender/radiosity/intern/source/radnode.c
@@ -50,6 +50,8 @@
 
 #include "radio.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -167,14 +169,14 @@ void *calloc_fast(int size)
 void free_fast(void *poin, int size)
 {
 	MallocGroup *mg;
-	long val;
+	intptr_t val;
 
 	mg= MallocBase.last;
 	while(mg) {
 		if(mg->size==size) {
-			if( ((long)poin) >= ((long)mg->data) ) {
-				if( ((long)poin) < ((long)(mg->data+MAL_GROUPSIZE*size)) ) {
-					val= ((long)poin) - ((long)mg->data);
+			if( ((intptr_t)poin) >= ((intptr_t)mg->data) ) {
+				if( ((intptr_t)poin) < ((intptr_t)(mg->data+MAL_GROUPSIZE*size)) ) {
+					val= ((intptr_t)poin) - ((intptr_t)mg->data);
 					val/= size;
 					mg->curfree= val;
 					mg->flags[val]= 0;
diff --git a/source/blender/radiosity/intern/source/radpreprocess.c b/source/blender/radiosity/intern/source/radpreprocess.c
index 5f8a39786c149858671c5100251eaef896e7c0e0..07b933b6db963246a7c14a481c3b239c342fe662 100644
--- a/source/blender/radiosity/intern/source/radpreprocess.c
+++ b/source/blender/radiosity/intern/source/radpreprocess.c
@@ -68,6 +68,8 @@
 
 #include "radio.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -179,7 +181,7 @@ int vergedge(const void *v1,const void *v2)
 
 void addedge(float *v1, float *v2, EdSort *es)
 {
-	if( ((long)v1)<((long)v2) ) {
+	if( ((intptr_t)v1)<((intptr_t)v2) ) {
 		es->v1= v1;
 		es->v2= v2;
 	}
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index b543dff49fff91f6b79385f232027d53433c0e91..0b659554d1a8ffa1bcbf5912c008f811a6c78e7e 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -29,7 +29,7 @@ FILE(GLOB SRC intern/source/*.c)
 SET(INC 
   intern/include ../../../intern/guardedalloc ../blenlib ../makesdna
   extern/include ../blenkernel ../radiosity/extern/include ../imbuf
-  ../quicktime ../include ../../kernel/gen_messaging ../yafray
+  ../quicktime ../include ../../kernel/gen_messaging ../yafray ../blenloader
 )
 
 IF(WITH_OPENEXR)
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index b1bc9673f23310cbabd9a9de2dbe460ca5b87a29..f0d1353b0d3a8a41a6473ff62368e9f91e6d5883 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -6,7 +6,7 @@ sources = env.Glob('intern/source/*.c')
 
 incs = 'intern/include #/intern/guardedalloc ../blenlib ../makesdna'
 incs += ' extern/include ../blenkernel ../radiosity/extern/include ../imbuf'
-incs += ' ../quicktime ../include ../../kernel/gen_messaging'
+incs += ' ../quicktime ../include ../../kernel/gen_messaging ../blenloader'
 
 defs = []
 
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 2f97b19f75cfeed0b38474ceda756430d32be888..f83bbd7e8b29254eb3414f29391db024cb981fe9 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -44,6 +44,8 @@
 #include "RE_shader_ext.h"	/* TexResult, ShadeResult, ShadeInput */
 #include "sunsky.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 struct Object;
 struct MemArena;
 struct VertTableNode;
@@ -89,11 +91,11 @@ typedef struct RenderPart
 	int *rectp;						/* polygon index table */
 	int *rectz;						/* zbuffer */
 	int *rectmask;					/* negative zmask */
-	long *rectdaps;					/* delta acum buffer for pixel structs */
+	intptr_t *rectdaps;					/* delta acum buffer for pixel structs */
 	int *rectbacko;					/* object table for backside sss */
 	int *rectbackp;					/* polygon index table for backside sss */
 	int *rectbackz;					/* zbuffer for backside sss */
-	long *rectall;					/* buffer for all faces for sss */
+	intptr_t *rectall;					/* buffer for all faces for sss */
 
 	rcti disprect;					/* part coordinates within total picture */
 	int rectx, recty;				/* the size */
@@ -226,7 +228,7 @@ struct ISBData;
 
 typedef struct ShadSampleBuf {
 	struct ShadSampleBuf *next, *prev;
-	long *zbuf;
+	intptr_t *zbuf;
 	char *cbuf;
 } ShadSampleBuf;
 
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index e4a5ad676315993082f2fc8c879a5fdc0ac9bd4f..8626fb0f9d07ab3a49db8b3f0c299973abdd2524 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1565,7 +1565,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 	float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
 	float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2];
 	int i, a, k, max_k=0, totpart, totuv=0, totcol=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0;
-	int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
+	int path_possible=0, keys_possible=0, baked_keys=0, totchild=0;
 	int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
 	int totface, *origindex = 0;
 	char **uv_name=0;
@@ -1573,6 +1573,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 /* 1. check that everything is ok & updated */
 	if(psys==NULL)
 		return 0;
+	
+	totchild=psys->totchild;
 
 	part=psys->part;
 	pars=psys->particles;
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index d70c51b83bc3952680c16a68c0f6c9fd0be04d0f..15c57eb936251526924e168b82e6999282065ae6 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -1670,7 +1670,7 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp)
 	OcclusionCacheSample *sample;
 	OccFace exclude;
 	ShadeInput *shi;
-	long *rd=NULL;
+	intptr_t *rd=NULL;
 	int *ro=NULL, *rp=NULL, *rz=NULL, onlyshadow;
 	int x, y, step = CACHE_STEP;
 
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 6a0af82b4d7373e0096786f9f3a5353314d52c90..3cd7bdc67724a4f6e41a199b3bd2711f39bf3cc4 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -138,7 +138,7 @@ static void print_error(char *str) {printf("ERROR: %s\n", str);}
 
 static void stats_background(RenderStats *rs)
 {
-	extern unsigned long mem_in_use;
+	extern uintptr_t mem_in_use;
 	float megs_used_memory= mem_in_use/(1024.0*1024.0);
 	char str[400], *spos= str;
 	
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 4520e4c10bb3f6f42b9f6fb5cfddc8e483342062..4a2ad995b394b139a906cb9c4a568309558734bc 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -243,7 +243,7 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl)
 	rcti disprect= pa->disprect, testrect= pa->disprect;
 	float dist, xsq, ysq, xn, yn;
 	float col[4];
-	long *rd= NULL;
+	intptr_t *rd= NULL;
 	int a, *rz, zz, y, sample, totsample, od;
 	short minx, maxx, miny, maxy, x;
 	unsigned int lay= rl->lay;
@@ -324,7 +324,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
 	ShadeInput shi;
 	float *pass;
 	float fac, col[4];
-	long *rd= pa->rectdaps;
+	intptr_t *rd= pa->rectdaps;
 	int *rz= pa->rectz;
 	int x, y, sample, totsample, fullsample, od;
 	
@@ -767,7 +767,7 @@ static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
 {
 	RenderResult *rr= pa->result;
 	ShadeSample ssamp;
-	long *rd, *rectdaps= pa->rectdaps;
+	intptr_t *rd, *rectdaps= pa->rectdaps;
 	int samp;
 	int x, y, seed, crop=0, offs=0, od;
 	
@@ -874,7 +874,7 @@ static void freeps(ListBase *lb)
 	lb->first= lb->last= NULL;
 }
 
-static void addps(ListBase *lb, long *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
+static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
 {
 	PixStrMain *psm;
 	PixStr *ps, *last= NULL;
@@ -901,7 +901,7 @@ static void addps(ListBase *lb, long *rd, int obi, int facenr, int z, int maskz,
 	ps= psm->ps + psm->counter++;
 	
 	if(last) last->next= ps;
-	else *rd= (long)ps;
+	else *rd= (intptr_t)ps;
 	
 	ps->next= NULL;
 	ps->obi= obi;
@@ -1027,7 +1027,7 @@ static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
 
 static unsigned short *make_solid_mask(RenderPart *pa)
 { 
- 	long *rd= pa->rectdaps;
+ 	intptr_t *rd= pa->rectdaps;
  	unsigned short *solidmask, *sp;
  	int x;
  	
@@ -1092,7 +1092,7 @@ void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
 {
 	ZbufSolidData *sdata= (ZbufSolidData*)data;
 	ListBase *lb= sdata->psmlist;
-	long *rd= pa->rectdaps;
+	intptr_t *rd= pa->rectdaps;
 	int *ro= zspan->recto;
 	int *rp= zspan->rectp;
 	int *rz= zspan->rectz;
@@ -1133,7 +1133,7 @@ void zbufshadeDA_tile(RenderPart *pa)
 	
 		/* initialize pixelstructs and edge buffer */
 		addpsmain(&psmlist);
-		pa->rectdaps= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd");
+		pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd");
 		
 		if(rl->layflag & SCE_LAY_EDGE) 
 			if(R.r.mode & R_EDGE) 
@@ -1433,7 +1433,7 @@ static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
 		return;
 	
 	if(pa->rectall) {
-		long *rs= pa->rectall + pa->rectx*y + x;
+		intptr_t *rs= pa->rectall + pa->rectx*y + x;
 
 		addps(&handle->psmlist, rs, obi, facenr, z, 0, 0);
 		handle->totps++;
@@ -1569,7 +1569,7 @@ void zbufshade_sss_tile(RenderPart *pa)
 	int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
 #if 0
 	PixStr *ps;
-	long *rs;
+	intptr_t *rs;
 	int z;
 #endif
 
@@ -1581,7 +1581,7 @@ void zbufshade_sss_tile(RenderPart *pa)
 	handle.psmlist.first= handle.psmlist.last= NULL;
 	addpsmain(&handle.psmlist);
 
-	pa->rectall= MEM_callocN(sizeof(long)*pa->rectx*pa->recty+4, "rectall");
+	pa->rectall= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "rectall");
 #else
 	pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
 	pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index f3258b601de851af669f80f6d9a875e586970dde..f477df3ed8c115006d65019a698dc8df89fe13ce 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -171,7 +171,7 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
 {
 	ShadSampleBuf *shsample;
 	float dist;
-	unsigned long *ztile;
+	uintptr_t *ztile;
 	int *rz, *rz1, verg, verg1, size= shb->size;
 	int a, x, y, minx, miny, byt1, byt2;
 	char *rc, *rcline, *ctile, *zt;
@@ -179,10 +179,10 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
 	shsample= MEM_mallocN( sizeof(ShadSampleBuf), "shad sample buf");
 	BLI_addtail(&shb->buffers, shsample);
 	
-	shsample->zbuf= MEM_mallocN( sizeof(unsigned long)*(size*size)/256, "initshadbuf2");
+	shsample->zbuf= MEM_mallocN( sizeof(uintptr_t)*(size*size)/256, "initshadbuf2");
 	shsample->cbuf= MEM_callocN( (size*size)/256, "initshadbuf3");
 	
-	ztile= (unsigned long *)shsample->zbuf;
+	ztile= (uintptr_t *)shsample->zbuf;
 	ctile= shsample->cbuf;
 	
 	/* help buffer */
@@ -237,7 +237,7 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
 				}
 				if(byt1 && byt2) {	/* only store byte */
 					*ctile= 1;
-					*ztile= (unsigned long)MEM_mallocN(256+4, "tile1");
+					*ztile= (uintptr_t)MEM_mallocN(256+4, "tile1");
 					rz= (int *)*ztile;
 					*rz= *rz1;
 					
@@ -247,7 +247,7 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
 				}
 				else if(byt1) {		/* only store short */
 					*ctile= 2;
-					*ztile= (unsigned long)MEM_mallocN(2*256+4,"Tile2");
+					*ztile= (uintptr_t)MEM_mallocN(2*256+4,"Tile2");
 					rz= (int *)*ztile;
 					*rz= *rz1;
 					
@@ -260,7 +260,7 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
 				}
 				else {			/* store triple */
 					*ctile= 3;
-					*ztile= (unsigned long)MEM_mallocN(3*256,"Tile3");
+					*ztile= (uintptr_t)MEM_mallocN(3*256,"Tile3");
 
 					zt= (char *)*ztile;
 					rc= rcline;
@@ -542,7 +542,7 @@ void freeshadowbuf(LampRen *lar)
 		v= (shb->size*shb->size)/256;
 		
 		for(shsample= shb->buffers.first; shsample; shsample= shsample->next) {
-			long *ztile= shsample->zbuf;
+			intptr_t *ztile= shsample->zbuf;
 			char *ctile= shsample->cbuf;
 			
 			for(b=0; b<v; b++, ztile++, ctile++)
@@ -1752,7 +1752,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar)
 	ISBSample *samp, *samplebuf[16];	/* should be RE_MAX_OSA */
 	ISBBranch root;
 	MemArena *memarena;
-	long *rd;
+	intptr_t *rd;
 	int *recto, *rectp, x, y, sindex, sample, bsp_err=0;
 	
 	/* storage for shadow, per thread */
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 591d51a969d277f24bc4041ac94f939811d4273f..05e36160f0e66f8c5be411cd2b302eeca425f43a 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -416,7 +416,7 @@ typedef struct StrandPart {
 	int *totapixbuf;
 	int *rectz;
 	int *rectmask;
-	long *rectdaps;
+	intptr_t *rectdaps;
 	int rectx, recty;
 	int sample;
 
@@ -510,7 +510,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float
 	if(spart->rectdaps) {
 		/* find the z of the sample */
 		PixStr *ps;
-		long *rd= spart->rectdaps + offset;
+		intptr_t *rd= spart->rectdaps + offset;
 		
 		bufferz= 0x7FFFFFFF;
 		if(spart->rectmask) maskz= 0x7FFFFFFF;
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index c91c9e2f799fb42121e2b58c4cf16b72374b3069..29aa6e3be292e0b2b3b61dc216f4f67f52058b50 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2278,7 +2278,7 @@ static int hashlist_projectvert(float *v1, float winmat[][4], float *hoco)
 		return 0;
 	}
 	
-	buck= &bucket[ (((long)v1)/16) & 255 ];
+	buck= &bucket[ (((intptr_t)v1)/16) & 255 ];
 	if(buck->vert==v1) {
 		QUATCOPY(hoco, buck->hoco);
 		return buck->clip;
@@ -3263,7 +3263,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample)
 {
 	PixStr *ps;
 	int x, y, *rza, *rma;
-	long *rd;
+	intptr_t *rd;
 	
 	if(R.osa==0) {
 		memcpy(arectz, pa->rectz, sizeof(int)*pa->rectx*pa->recty);
@@ -3484,7 +3484,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, Re
 /* speed pointer NULL = sky, we clear */
 /* else if either alpha is full or no solid was filled in: copy speed */
 /* else fill in minimum speed */
-void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, long *rdrect)
+void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, intptr_t *rdrect)
 {
 	RenderPass *rpass;
 	
@@ -3958,7 +3958,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
 	ZTranspRow zrow[MAX_ZROW];
 	StrandShadeCache *sscache= NULL;
 	float sampalpha, alpha, *passrect= pass;
-	long *rdrect;
+	intptr_t *rdrect;
 	int x, y, crop=0, a, b, totface, totsample, doztra;
 	int addpassflag, offs= 0, od, addzbuf, osa = (R.osa? R.osa: 1);
 	unsigned short *ztramask= NULL, filled;
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index cb6f7e629fa42e9fd9c9bfa9982d151d8d09397c..76f244db6fc27ab7e2b2463289f2e58e4f3fe6b9 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -1826,6 +1826,16 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
 			height = 94;
 		} else if (md->type==eModifierType_Explode) {
 			height = 94;
+		} else if (md->type==eModifierType_Shrinkwrap) {
+			ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+			height = 86 + 3;
+			if (smd->shrinkType == MOD_SHRINKWRAP_PROJECT)
+			{
+				height += 19*5;
+				if(smd->projAxis == 0) height += 19;
+			}
+			else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE)
+				height += 19;
 		}
 							/* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
 		uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, ""); 
@@ -2446,6 +2456,51 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
 			uiDefButBitS(block, TOG, eExplodeFlag_Alive, B_MODIFIER_RECALC, "Alive",	lx+buttonWidth/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are alive");
 			uiDefButBitS(block, TOG, eExplodeFlag_Dead, B_MODIFIER_RECALC, "Dead",	lx+buttonWidth*2/3, cy, buttonWidth/3,19, &emd->flag, 0, 0, 0, 0, "Show mesh when particles are dead");
 			uiBlockEndAlign(block);
+		} else if (md->type==eModifierType_Shrinkwrap) {
+			ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+			char shrinktypemenu[]="Shrinkwrap type%t|nearest surface point %x0|projection %x1|nearest vertex %x2";
+
+			uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob: ",	lx, (cy-=19), buttonWidth,19, &smd->target, "Target to shrink to");
+
+			but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ",		lx, (cy-=19), buttonWidth,19, &smd->vgroup_name, 0, 31, 0, 0, "Vertex Group name");
+			uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+
+			uiDefButF(block, NUM, B_MODIFIER_RECALC, "Offset:",	lx,(cy-=19),buttonWidth,19, &smd->keepDist, 0.0f, 100.0f, 1.0f, 0, "Specify distance to keep from the target");
+
+			cy -= 3;
+			uiDefButS(block, MENU, B_MODIFIER_RECALC, shrinktypemenu, lx,(cy-=19),buttonWidth,19, &smd->shrinkType, 0, 0, 0, 0, "Selects type of shrinkwrap algorithm for target position.");
+
+			if (smd->shrinkType == MOD_SHRINKWRAP_PROJECT){
+
+
+				/* UI for projection axis */
+				uiBlockBeginAlign(block);
+				uiDefButC(block, ROW, B_MODIFIER_RECALC, "Normal"    , lx,(cy-=19),buttonWidth,19, &smd->projAxis, 18.0, MOD_SHRINKWRAP_PROJECT_OVER_NORMAL, 0, 0, "Projection over X axis");
+				if(smd->projAxis == 0)
+				{
+					uiDefButC(block, NUM, B_MODIFIER_RECALC, "SS Levels:",		lx, (cy-=19), buttonWidth,19, &smd->subsurfLevels, 0, 6, 0, 0, "This indicates the number of CCSubdivisions that must be performed before extracting vertexs positions and normals");
+				}
+
+				uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS, B_MODIFIER_RECALC, "X",	lx+buttonWidth/3*0,(cy-=19),buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over X axis");
+				uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS, B_MODIFIER_RECALC, "Y",	lx+buttonWidth/3*1,cy,buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over Y axis");
+				uiDefButBitC(block, TOG, MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS, B_MODIFIER_RECALC, "Z",	lx+buttonWidth/3*2,cy,buttonWidth/3,19, &smd->projAxis, 0, 0, 0, 0, "Projection over Z axis");
+
+
+				/* allowed directions of projection axis */
+				uiDefButBitS(block, TOG, MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR, B_MODIFIER_RECALC, "Negative",	lx,(cy-=19),buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows to move the vertex in the negative direction of axis");
+				uiDefButBitS(block, TOG, MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR, B_MODIFIER_RECALC, "Positive",	lx + buttonWidth/2,cy,buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Allows to move the vertex in the positive direction of axis");
+
+				uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE, B_MODIFIER_RECALC, "Cull frontfaces",lx,(cy-=19),buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a front face on target");
+				uiDefButBitS(block, TOG, MOD_SHRINKWRAP_CULL_TARGET_BACKFACE,  B_MODIFIER_RECALC, "Cull backfaces",	lx+buttonWidth/2,cy,buttonWidth/2,19, &smd->shrinkOpts, 0, 0, 0, 0, "Controls whether a vertex can be projected to a back face on target");
+				uiDefIDPoinBut(block, modifier_testMeshObj, ID_OB, B_CHANGEDEP, "Ob2: ",	lx, (cy-=19), buttonWidth,19, &smd->auxTarget, "Aditional mesh to project over");
+			}
+			else if (smd->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE){
+				uiDefButBitS(block, TOG, MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE, B_MODIFIER_RECALC, "Above surface",	lx,(cy-=19),buttonWidth,19, &smd->shrinkOpts, 0, 0, 0, 0, "Vertices are kept on the front side of faces");
+			}
+
+			uiBlockEndAlign(block);
+
 		}
 
 		uiBlockEndAlign(block);
@@ -4145,7 +4200,7 @@ static void validate_posebonebutton_cb(void *bonev, void *namev)
 static void armature_layer_cb(void *lay_v, void *value_v)
 {
 	short *layer= lay_v;
-	int value= (long)value_v;
+	int value= (intptr_t)value_v;
 	
 	if(*layer==0 || G.qual==0) *layer= value;
 	allqueue(REDRAWBUTSEDIT, 0);
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 8788363c19bf3abde78fb27ce7a91f4f2eb39fd5..9b41b646bc8914f54c4967a169ab53a4bdd4673b 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -683,6 +683,8 @@ static char *sensor_name(int type)
 		return "Property";
 	case SENS_ACTUATOR:
 		return "Actuator";
+	case SENS_DELAY:
+		return "Delay";
 	case SENS_MOUSE:
 		return "Mouse";
 	case SENS_COLLISION:
@@ -704,7 +706,7 @@ static char *sensor_name(int type)
 static char *sensor_pup(void)
 {
 	/* the number needs to match defines in game.h */
-	return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|"
+	return "Sensors %t|Always %x0|Delay %x13|Keyboard %x3|Mouse %x5|"
 		"Touch %x1|Collision %x6|Near %x2|Radar %x7|"
 		"Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12";
 }
@@ -1000,6 +1002,7 @@ static int get_col_sensor(int type)
 {
 	switch(type) {
 	case SENS_ALWAYS:		return TH_BUT_ACTION;
+	case SENS_DELAY:		return TH_BUT_ACTION;
 	case SENS_TOUCH:		return TH_BUT_NEUTRAL;
 	case SENS_COLLISION:	return TH_BUT_SETTING;
 	case SENS_NEAR:			return TH_BUT_SETTING1; 
@@ -1070,8 +1073,8 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
 	bRaySensor       *raySens      = NULL;
 	bMessageSensor   *mes          = NULL;
 	bJoystickSensor	 *joy		   = NULL;
-	bActuatorSensor  *as          = NULL;
-
+	bActuatorSensor  *as           = NULL;
+	bDelaySensor     *ds		   = NULL;
 	short ysize;
 	char *str;
 	
@@ -1297,6 +1300,27 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
 			yco-= ysize;
 			break;
 		}
+	case SENS_DELAY:
+		{
+			ysize= 48;
+			
+			glRects(xco, yco-ysize, xco+width, yco);
+			uiEmboss((float)xco, (float)yco-ysize,
+				(float)xco+width, (float)yco, 1);
+			
+			draw_default_sensor_header(sens, block, xco, yco, width);
+			ds = sens->data;
+			
+			uiDefButS(block, NUM, 0, "Delay",(short)(10+xco),(short)(yco-44),(short)((width-22)*0.4+10), 19,
+				&ds->delay, 0.0, 5000.0, 0, 0, "Delay in number of frames before the positive trigger");
+			uiDefButS(block, NUM, 0, "Dur",(short)(10+xco+(width-22)*0.4+10),(short)(yco-44),(short)((width-22)*0.4-10), 19,
+				&ds->duration, 0.0, 5000.0, 0, 0, "If >0, delay in number of frames before the negative trigger following the positive trigger");
+			uiDefButBitS(block, TOG, SENS_DELAY_REPEAT, 0, "REP",(short)(xco + 10 + (width-22)*0.8),(short)(yco - 44),
+				(short)(0.20 * (width-22)), 19, &ds->flag, 0.0, 0.0, 0, 0,
+				"Toggle repeat option. If selected, the sensor restarts after Delay+Dur frames");
+			yco-= ysize;
+			break;
+		}
 	case SENS_MOUSE:
 		{
 			ms= sens->data;
@@ -1366,9 +1390,14 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
 					&raySens->propname, 0, 31, 0, 0,
 					"Only look for Objects with this property");
 			}
-			
+
+			/* X-Ray option */
+			uiDefButBitS(block, TOG, SENS_RAY_XRAY, 1, "X",
+				xco + 10,yco - 68, 0.10 * (width-20), 19,
+				&raySens->mode, 0.0, 0.0, 0, 0,
+				"Toggle X-Ray option (see through objects that don't have the property)");
 			/* 2. sensing range */
-			uiDefButF(block, NUM, 1, "Range", xco+10, yco-68, 0.6 * (width-20), 19,
+			uiDefButF(block, NUM, 1, "Range", xco+10 + 0.10 * (width-20), yco-68, 0.5 * (width-20), 19,
 				&raySens->range, 0.01, 10000.0, 100, 0,
 				"Sense objects no farther than this distance");
 			
@@ -1833,7 +1862,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
 			but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, 
 				"Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, 
 				&ia->flag, 0, 0, 0, 0, 
-				"Convert Ipo to force. Force is applied in global or local coordinate according to Local flag"); 
+				"Apply Ipo as a global or local force depending on the local option (dynamic objects only)"); 
 			uiButSetFunc(but, change_ipo_actuator, but, ia);
 
 			but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, 
@@ -1998,7 +2027,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
 
 		if(eoa->type==ACT_EDOB_ADD_OBJECT) {
 			int wval; /* just a temp width */
-			ysize = 72;
+			ysize = 92;
 			glRects(xco, yco-ysize, xco+width, yco);
 			uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
 	 
@@ -2018,9 +2047,27 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
 			uiDefButF(block, NUM, 0, "",		xco+45+2*wval, yco-68, wval, 19,
 					 eoa->linVelocity+2, -100.0, 100.0, 10, 0,
 					 "Velocity upon creation, z component.");
-			uiDefButBitS(block, TOG, 2, 0, "L", xco+45+3*wval, yco-68, 15, 19,
+			uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19,
 					 &eoa->localflag, 0.0, 0.0, 0, 0,
 					 "Apply the transformation locally");
+			
+			
+			uiDefBut(block, LABEL, 0, "AngV",	xco,           yco-90,   45, 19,
+					 NULL, 0, 0, 0, 0,
+					 "Angular velocity upon creation.");
+			uiDefButF(block, NUM, 0, "",		xco+45,        yco-90, wval, 19,
+					 eoa->angVelocity, -10000.0, 10000.0, 10, 0,
+					 "Angular velocity upon creation, x component.");
+			uiDefButF(block, NUM, 0, "",		xco+45+wval,   yco-90, wval, 19,
+					 eoa->angVelocity+1, -10000.0, 10000.0, 10, 0,
+					 "Angular velocity upon creation, y component.");
+			uiDefButF(block, NUM, 0, "",		xco+45+2*wval, yco-90, wval, 19,
+					 eoa->angVelocity+2, -10000.0, 10000.0, 10, 0,
+					 "Angular velocity upon creation, z component.");
+			uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19,
+					 &eoa->localflag, 0.0, 0.0, 0, 0,
+					 "Apply the rotation locally");
+					 
 
 		}
 		else if(eoa->type==ACT_EDOB_END_OBJECT) {
@@ -3183,7 +3230,8 @@ void logic_buts(void)
 		while(cont) {
 			for (iact=0; iact<cont->totlinks; iact++) {
 				act = cont->links[iact];
-				act->flag |= ACT_LINKED;
+				if (act)
+					act->flag |= ACT_LINKED;
 			}
 			controller_state_mask |= cont->state_mask;
 			cont = cont->next;
@@ -3231,7 +3279,8 @@ void logic_buts(void)
 						/* this controller is visible, mark all its actuator */
 						for (iact=0; iact<cont->totlinks; iact++) {
 							act = cont->links[iact];
-							act->flag |= ACT_VISIBLE;
+							if (act)
+								act->flag |= ACT_VISIBLE;
 						}
 						uiBlockSetEmboss(block, UI_EMBOSSM);
 						uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,	xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
@@ -3323,8 +3372,8 @@ void logic_buts(void)
 					ycoo= yco;
 					if(sens->flag & SENS_SHOW)
 					{
-						uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),	(short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
-						but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
+						uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),	(short)(xco+22), yco, 80, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
+						but= uiDefBut(block, TEX, 1, "", (short)(xco+102), yco, (short)(width-124), 19, sens->name, 0, 31, 0, 0, "Sensor name");
 						uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
 
 						sens->otype= sens->type;
@@ -3334,9 +3383,9 @@ void logic_buts(void)
 					else {
 						set_col_sensor(sens->type, 1);
 						glRecti(xco+22, yco, xco+width-22,yco+19);
-						but= uiDefBut(block, LABEL, 0, sensor_name(sens->type),	(short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
+						but= uiDefBut(block, LABEL, 0, sensor_name(sens->type),	(short)(xco+22), yco, 80, 19, sens, 0, 0, 0, 0, "");
 						uiButSetFunc(but, sca_move_sensor, sens, NULL);
-						but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
+						but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+102), yco, (short)(width-124), 19, sens, 0, 31, 0, 0, "");
 						uiButSetFunc(but, sca_move_sensor, sens, NULL);
 					}
 
@@ -3393,8 +3442,8 @@ void logic_buts(void)
 
 					if(act->flag & ACT_SHOW) {
 						act->otype= act->type;
-						uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),	(short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type");
-						but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name");
+						uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),	(short)(xco+22), yco, 90, 19, &act->type, 0, 0, 0, 0, "Actuator type");
+						but= uiDefBut(block, TEX, 1, "", (short)(xco+112), yco, (short)(width-134), 19, act->name, 0, 31, 0, 0, "Actuator name");
 						uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
 
 						ycoo= yco;
@@ -3404,9 +3453,9 @@ void logic_buts(void)
 					else {
 						set_col_actuator(act->type, 1);
 						glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
-						but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type");
+						but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 90, 19, act, 0, 0, 0, 0, "Actuator type");
 						uiButSetFunc(but, sca_move_actuator, act, NULL);
-						but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name");
+						but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+112), yco, (short)(width-134), 19, act, 0, 0, 0, 0, "Actuator name");
 						uiButSetFunc(but, sca_move_actuator, act, NULL);
 						ycoo= yco;
 					}
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 58f3bff09c8f1bf8f2486a61e73a74c08cf9ff2e..b0d612456d22ed191a9b24c6344f7557c2d5538b 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -3279,6 +3279,8 @@ static void object_panel_collision(Object *ob)
 		uiDefBut(block, LABEL, 0, "",160,160,150,2, NULL, 0.0, 0, 0, 0, "");
 		
 		if(pd->deflect) {
+			CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType ( ob, eModifierType_Collision );
+			
 			uiDefBut(block, LABEL, 0, "Particle Interaction",			10,135,310,20, NULL, 0.0, 0, 0, 0, "");
 
 			uiBlockBeginAlign(block);
@@ -3294,12 +3296,18 @@ static void object_panel_collision(Object *ob)
 			uiDefBut(block, LABEL, 0, "Soft Body and Cloth Interaction",			10,65,310,20, NULL, 0.0, 0, 0, 0, "");
 
 			uiBlockBeginAlign(block);
-			uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:",	10,45,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during collision");
-			uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:",	10,25,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
-			uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:",	10, 5,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
+			uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:",	10,45,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
+			uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:",	160, 45,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
 			uiBlockEndAlign(block);
+			uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:",	10,25,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during collision");
 
-			uiDefButBitS(block, TOG, OB_SB_COLLFINAL, B_FIELD_CHANGE, "Ev.M.Stack", 170,45,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack (softbody only)");
+			uiDefButBitS(block, TOG, OB_SB_COLLFINAL, B_FIELD_CHANGE, "Ev.M.Stack", 160,25,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack (softbody only)");
+			
+			// collision options
+			if(collmd)
+			{
+				uiDefButS(block, NUM, B_FIELD_CHANGE, "Absorption: ",	10,0,150,20, &collmd->absorption, 0.0, 100, 1, 2, "How much of effector force gets lost during collision with this object (in percent).");
+			}
 		}
 	}
 }
@@ -3309,6 +3317,7 @@ static void object_panel_fields(Object *ob)
 	uiBut *but;
 	int particles=0;
 	static short actpsys=-1;
+	static char slot=0;
 
 	block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win);
 	if(uiNewPanel(curarea, block, "Fields", "Physics", 0, 0, 318, 204)==0) return;
@@ -3330,7 +3339,7 @@ static void object_panel_fields(Object *ob)
 		char *tipstr="Choose field type";
 
 		uiBlockBeginAlign(block);
-		
+
 		if(ob->particlesystem.first) {
 			ParticleSystem *psys;
 			char *menustr2= psys_menu_string(ob,1);
@@ -3342,8 +3351,16 @@ static void object_panel_fields(Object *ob)
 				if(psys->part->pd==NULL)
 					psys->part->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
 
-				pd= psys->part->pd;
+				if(psys->part->pd2==NULL)
+					psys->part->pd2= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
+
+				pd= ((slot==1) ? psys->part->pd2 : psys->part->pd);
 				particles=1;
+
+				uiDefButC(block, ROW, B_REDR, "",	10, 163, 14, 14, &slot, 3.0, 0, 0, 0, "Edit first particle effector slot");
+				uiDefButC(block, ROW, B_REDR, "",	24, 163, 14, 14, &slot, 3.0, 1, 0, 0, "Edit second particle effector slot");
+				uiBlockEndAlign(block);
+				uiBlockBeginAlign(block);
 			}
 			else
 				actpsys= -1; /* -1 = object */
@@ -3356,8 +3373,8 @@ static void object_panel_fields(Object *ob)
 
 		/* setup menu button */
 		if(particles){
-			sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d", 
-					PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC);
+			sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Charge%%x%d|Lennard-Jones%%x%d", 
+					PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_CHARGE, PFIELD_LENNARDJ);
 
 			if(pd->forcefield==PFIELD_FORCE) tipstr= "Particle attracts or repels particles (On shared object layers)";
 			else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of particle Z axis (On shared object layers)";
@@ -3365,11 +3382,11 @@ static void object_panel_fields(Object *ob)
 		}
 		else{
 			if(ob->type==OB_CURVE)
-				sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Curve Guide%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d", 
-						PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE);
+				sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Curve Guide%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d|Charge%%x%d|Lennard-Jones%%x%d", 
+						PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE, PFIELD_CHARGE, PFIELD_LENNARDJ);
 			else
-				sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d", 
-						PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE);
+				sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d|Charge%%x%d|Lennard-Jones%%x%d", 
+						PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE, PFIELD_CHARGE, PFIELD_LENNARDJ);
 
 			if(pd->forcefield==PFIELD_FORCE) tipstr= "Object center attracts or repels particles (On shared object layers)";
 			else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of Object Z axis (On shared object layers)";
@@ -3384,8 +3401,6 @@ static void object_panel_fields(Object *ob)
 
 		uiBlockEndAlign(block);
 		uiDefBut(block, LABEL, 0, "",160,180,150,2, NULL, 0.0, 0, 0, 0, "");
-
-		MEM_freeN(menustr);
 		
 		if(pd->forcefield) {
 			uiBlockBeginAlign(block);
@@ -3411,6 +3426,8 @@ static void object_panel_fields(Object *ob)
 				}
 				else if(pd->forcefield == PFIELD_HARMONIC) 
 					uiDefButF(block, NUM, B_FIELD_CHANGE, "Damp: ",	10,120,140,20, &pd->f_damp, 0, 10, 10, 0, "Damping of the harmonic force");	
+				else if(pd->forcefield == PFIELD_WIND) 
+					uiDefButF(block, NUM, B_FIELD_CHANGE, "Noise: ",10,120,140,20, &pd->f_noise, 0, 10, 100, 0, "Noise of the wind force");	
 			}
 			uiBlockEndAlign(block);
 			
@@ -3449,40 +3466,49 @@ static void object_panel_fields(Object *ob)
 				uiBlockEndAlign(block);
 			}
 			else{
-				uiDefButS(block, MENU, B_FIELD_DEP, "Fall-off%t|Cone%x2|Tube%x1|Sphere%x0",	160,180,140,20, &pd->falloff, 0.0, 0.0, 0, 0, "Fall-off shape");
-				if(pd->falloff==PFIELD_FALL_TUBE)
-					uiDefBut(block, LABEL, 0, "Longitudinal",		160,160,140,20, NULL, 0.0, 0, 0, 0, "");
-				uiBlockBeginAlign(block);
-				uiDefButBitS(block, TOG, PFIELD_POSZ, B_FIELD_CHANGE, "Pos",	160,140,40,20, &pd->flag, 0.0, 0, 0, 0, "Effect only in direction of positive Z axis");
-				uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",	200,140,100,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational falloff = 2)");
-				uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use",	160,120,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
-				uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",	200,120,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
-				uiDefButBitS(block, TOG, PFIELD_USEMIN, B_FIELD_CHANGE, "Use",	160,100,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum distance for the field's fall-off");
-				uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",	200,100,100,20, &pd->mindist, 0, 1000.0, 10, 0, "Minimum distance for the field's fall-off");
-				uiBlockEndAlign(block);
-
-				if(pd->falloff==PFIELD_FALL_TUBE){
-					uiDefBut(block, LABEL, 0, "Radial",		160,80,70,20, NULL, 0.0, 0, 0, 0, "");
-					uiBlockBeginAlign(block);
-					uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",	160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
-					uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use",	160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum radial distance for the field to work");
-					uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",	200,40,100,20, &pd->maxrad, 0, 1000.0, 10, 0, "Maximum radial distance for the field to work");
-					uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use",	160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum radial distance for the field's fall-off");
-					uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",	200,20,100,20, &pd->minrad, 0, 1000.0, 10, 0, "Minimum radial distance for the field's fall-off");
-					uiBlockEndAlign(block);
+				if(pd->forcefield==PFIELD_LENNARDJ) {
+					uiDefBut(block, LABEL, 0, "Fall-off determined",		160,140,140,20, NULL, 0.0, 0, 0, 0, "");
+					uiDefBut(block, LABEL, 0, "by particle sizes",		160,120,140,20, NULL, 0.0, 0, 0, 0, "");
 				}
-				else if(pd->falloff==PFIELD_FALL_CONE){
-					uiDefBut(block, LABEL, 0, "Angular",		160,80,70,20, NULL, 0.0, 0, 0, 0, "");
+				else {
+					uiDefButS(block, MENU, B_FIELD_DEP, "Fall-off%t|Cone%x2|Tube%x1|Sphere%x0",	160,180,140,20, &pd->falloff, 0.0, 0.0, 0, 0, "Fall-off shape");
+					if(pd->falloff==PFIELD_FALL_TUBE)
+						uiDefBut(block, LABEL, 0, "Longitudinal",		160,160,140,20, NULL, 0.0, 0, 0, 0, "");
 					uiBlockBeginAlign(block);
-					uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",	160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
-					uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use",	160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum angle for the field to work");
-					uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxAngle: ",	200,40,100,20, &pd->maxrad, 0, 89.0, 10, 0, "Maximum angle for the field to work (in radians)");
-					uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use",	160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum angle for the field's fall-off");
-					uiDefButF(block, NUM, B_FIELD_CHANGE, "MinAngle: ",	200,20,100,20, &pd->minrad, 0, 89.0, 10, 0, "Minimum angle for the field's fall-off (in radians)");
+					uiDefButBitS(block, TOG, PFIELD_POSZ, B_FIELD_CHANGE, "Pos",	160,140,40,20, &pd->flag, 0.0, 0, 0, 0, "Effect only in direction of positive Z axis");
+					uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",	200,140,100,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational falloff = 2)");
+					uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use",	160,120,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
+					uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",	200,120,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
+					uiDefButBitS(block, TOG, PFIELD_USEMIN, B_FIELD_CHANGE, "Use",	160,100,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum distance for the field's fall-off");
+					uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",	200,100,100,20, &pd->mindist, 0, 1000.0, 10, 0, "Minimum distance for the field's fall-off");
 					uiBlockEndAlign(block);
+
+					if(pd->falloff==PFIELD_FALL_TUBE){
+						uiDefBut(block, LABEL, 0, "Radial",		160,80,70,20, NULL, 0.0, 0, 0, 0, "");
+						uiBlockBeginAlign(block);
+						uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",	160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
+						uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use",	160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum radial distance for the field to work");
+						uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",	200,40,100,20, &pd->maxrad, 0, 1000.0, 10, 0, "Maximum radial distance for the field to work");
+						uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use",	160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum radial distance for the field's fall-off");
+						uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",	200,20,100,20, &pd->minrad, 0, 1000.0, 10, 0, "Minimum radial distance for the field's fall-off");
+						uiBlockEndAlign(block);
+					}
+					else if(pd->falloff==PFIELD_FALL_CONE){
+						uiDefBut(block, LABEL, 0, "Angular",		160,80,70,20, NULL, 0.0, 0, 0, 0, "");
+						uiBlockBeginAlign(block);
+						uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",	160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
+						uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use",	160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum angle for the field to work");
+						uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxAngle: ",	200,40,100,20, &pd->maxrad, 0, 89.0, 10, 0, "Maximum angle for the field to work (in radians)");
+						uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use",	160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum angle for the field's fall-off");
+						uiDefButF(block, NUM, B_FIELD_CHANGE, "MinAngle: ",	200,20,100,20, &pd->minrad, 0, 89.0, 10, 0, "Minimum angle for the field's fall-off (in radians)");
+						uiBlockEndAlign(block);
+					}
 				}
 			}
+
 		}	
+		
+		MEM_freeN(menustr);
 	}
 }
 
@@ -4329,6 +4355,8 @@ static void object_panel_particle_extra(Object *ob)
 		uiDefButBitI(block, TOG, PART_CHILD_EFFECT, B_PART_RECALC, "Children", butx+(butw*3)/5,buty,(butw*2)/5,buth, &part->flag, 0, 0, 0, 0, "Apply effectors to children");
 		uiBlockEndAlign(block);
 	}
+	else if(part->phystype == PART_PHYS_NEWTON)
+		uiDefButBitI(block, TOG, PART_SELF_EFFECT, B_PART_RECALC, "Self Effect",	 butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Particle effectors effect themselves");
 	else
 		buty-=buth;
 
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index fb6a7636e16591c7e2bdd7a5288bbce949427eba..5205be3e1b0dba4e79924dc3682806201c39da88 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -33,6 +33,7 @@
 #include <string.h>
 
 #include "MEM_guardedalloc.h"
+#include "BLO_sys_types.h" // for intptr_t support
 #include "DNA_node_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
@@ -3261,7 +3262,7 @@ static void layer_copy_func(void *lay_v, void *lay_p)
 static void delete_scene_layer_func(void *srl_v, void *act_i)
 {
 	if(BLI_countlist(&G.scene->r.layers)>1) {
-		long act= (long)act_i;
+		intptr_t act= (intptr_t)act_i;
 		
 		BLI_remlink(&G.scene->r.layers, srl_v);
 		MEM_freeN(srl_v);
@@ -3322,7 +3323,7 @@ static char *scene_layer_menu(void)
 static void draw_3d_layer_buttons(uiBlock *block, int type, unsigned int *poin, short xco, short yco, short dx, short dy, char *tip)
 {
 	uiBut *bt;
-	long a;
+	intptr_t a;
 	
 	uiBlockBeginAlign(block);
 	for(a=0; a<5; a++) {
@@ -3381,7 +3382,7 @@ static void render_panel_layers(void)
 	
 	uiDefButBitI(block, TOG, R_SINGLE_LAYER, B_NOP, "Single",	230,145,60,20, &G.scene->r.scemode, 0, 0, 0, 0, "Only render this layer");	
 	bt=uiDefIconBut(block, BUT, B_NOP, ICON_X,	285, 145, 25, 20, 0, 0, 0, 0, 0, "Deletes current Render Layer");
-	uiButSetFunc(bt, delete_scene_layer_func, srl, (void *)(long)G.scene->r.actlay);
+	uiButSetFunc(bt, delete_scene_layer_func, srl, (void *)(intptr_t)G.scene->r.actlay);
 	uiBlockEndAlign(block);
 
 	/* RenderLayer visible-layers */
diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c
index ee28049e2c03f54a7e59be4a120d8f03c43a88ae..15f65bfe3cf120143a05f3272c76143955119216 100644
--- a/source/blender/src/drawgpencil.c
+++ b/source/blender/src/drawgpencil.c
@@ -37,6 +37,9 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
 #include "BMF_Api.h"
 
 #include "BLI_arithb.h"
@@ -142,6 +145,13 @@ void gp_ui_delframe_cb (void *gpd, void *gpl)
 	allqueue(REDRAWACTION, 0);
 }
 
+/* convert the active layer to geometry */
+void gp_ui_convertlayer_cb (void *gpd, void *gpl)
+{
+	gpencil_layer_setactive(gpd, gpl);
+	gpencil_convert_menu();
+}
+
 /* ------- Drawing Code ------- */
 
 /* draw the controls for a given layer */
@@ -163,7 +173,7 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
 		/* rounded header */
 		if (active) uiBlockSetCol(block, TH_BUT_ACTION);
 			rb_col= (active)?-20:20;
-			uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15 , rb_col-20, ""); 
+			uiDefBut(block, ROUNDBOX, B_REDR, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15 , rb_col-20, ""); 
 		if (active) uiBlockSetCol(block, TH_AUTO);
 		
 		/* lock toggle */
@@ -174,7 +184,7 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
 	if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) {
 		char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */
 		
-		height= 26;
+		height= 0;
 		
 		/* visibility button (only if hidden but not locked!) */
 		if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED))
@@ -246,8 +256,14 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
 			
 			/* options */
 			uiBlockBeginAlign(block);
-				but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)");
-				uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl);
+				if (curarea->spacetype == SPACE_VIEW3D) {
+					but= uiDefBut(block, BUT, B_REDR, "Convert to...", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Converts this layer's strokes to geometry (Hotkey = Alt-Shift-C)");
+					uiButSetFunc(but, gp_ui_convertlayer_cb, gpd, gpl);
+				}
+				else {
+					but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)");
+					uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl);
+				}
 				
 				but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)");
 				uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
@@ -317,8 +333,12 @@ enum {
 	GP_DRAWDATA_NOSTATUS 	= (1<<0),	/* don't draw status info */
 	GP_DRAWDATA_ONLY3D		= (1<<1),	/* only draw 3d-strokes */
 	GP_DRAWDATA_ONLYV2D		= (1<<2),	/* only draw 'canvas' strokes */
+	GP_DRAWDATA_ONLYI2D		= (1<<3),	/* only draw 'image' strokes */
 };
 
+/* thickness above which we should use special drawing */
+#define GP_DRAWTHICKNESS_SPECIAL 	3
+
 /* ----- Tool Buffer Drawing ------ */
 
 /* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
@@ -343,23 +363,13 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick
 		glEnd();
 	}
 	else if (sflag & GP_STROKE_ERASER) {
-		/* draw stroke curve - just standard thickness */
-		setlinestyle(4);
-		glLineWidth(1.0f);
-		
-		glBegin(GL_LINE_STRIP);
-		for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
-			glVertex2f(pt->x, pt->y);
-		}
-		glEnd();
-		
-		setlinestyle(0);
+		/* don't draw stroke at all! */
 	}
 	else {
 		float oldpressure = 0.0f;
 		
 		/* draw stroke curve */
-		setlinestyle(2);
+		if (G.f & G_DEBUG) setlinestyle(2);
 		
 		glBegin(GL_LINE_STRIP);
 		for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
@@ -377,14 +387,14 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick
 		}
 		glEnd();
 		
-		setlinestyle(0);
+		if (G.f & G_DEBUG) setlinestyle(0);
 	}
 }
 
 /* ----- Existing Strokes Drawing (3D and Point) ------ */
 
 /* draw a given stroke - just a single dot (only one point) */
-static void gp_draw_stroke_point (bGPDspoint *points, short sflag, int winx, int winy)
+static void gp_draw_stroke_point (bGPDspoint *points, short thickness, short sflag, int winx, int winy)
 {
 	/* draw point */
 	if (sflag & GP_STROKE_3DSPACE) {
@@ -392,18 +402,38 @@ static void gp_draw_stroke_point (bGPDspoint *points, short sflag, int winx, int
 			glVertex3f(points->x, points->y, points->z);
 		glEnd();
 	}
-	else if (sflag & GP_STROKE_2DSPACE) {
-		glBegin(GL_POINTS);
-			glVertex2f(points->x, points->y);
-		glEnd();
-	}
 	else {
-		const float x= (points->x / 1000 * winx);
-		const float y= (points->y / 1000 * winy);
+		float co[2];
 		
-		glBegin(GL_POINTS);
-			glVertex2f(x, y);
-		glEnd();
+		/* get coordinates of point */
+		if (sflag & GP_STROKE_2DSPACE) {
+			co[0]= points->x;
+			co[1]= points->y;
+		}
+		else {
+			co[0]= (points->x / 1000 * winx);
+			co[1]= (points->y / 1000 * winy);
+		}
+		
+		/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple opengl point will do */
+		if (thickness < GP_DRAWTHICKNESS_SPECIAL) {
+			glBegin(GL_POINTS);
+				glVertex2fv(co);
+			glEnd();
+		}
+		else {
+			/* draw filled circle as is done in circf (but without the matrix push/pops which screwed things up) */
+			GLUquadricObj *qobj = gluNewQuadric(); 
+			
+			gluQuadricDrawStyle(qobj, GLU_FILL); 
+			
+			/* need to translate drawing position, but must reset after too! */
+			glTranslatef(co[0],  co[1], 0.); 
+			gluDisk( qobj, 0.0,  thickness, 32, 1); 
+			glTranslatef(-co[0],  -co[1], 0.);
+			
+			gluDeleteQuadric(qobj);
+		}
 	}
 }
 
@@ -445,8 +475,8 @@ static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thicknes
 /* draw a given stroke in 2d */
 static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
 {	
-	/* if thickness is less than 3, 'smooth' opengl lines look better */
-	if ((thickness < 3) || (G.rt==0)) {
+	/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better */
+	if (thickness < GP_DRAWTHICKNESS_SPECIAL) {
 		bGPDspoint *pt;
 		int i;
 		
@@ -466,18 +496,18 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
 	}
 	else { /* tesselation code: currently only enabled with rt != 0 */
 		bGPDspoint *pt1, *pt2;
-		float p0[2], p1[2], pm[2];
+		float pm[2];
 		int i;
 		
 		glShadeModel(GL_FLAT);
-		glBegin(GL_QUAD_STRIP);
+		glBegin(GL_QUADS);
 		
 		for (i=0, pt1=points, pt2=points+1; i < (totpoints-1); i++, pt1++, pt2++) {
 			float s0[2], s1[2];		/* segment 'center' points */
 			float t0[2], t1[2];		/* tesselated coordinates */
 			float m1[2], m2[2];		/* gradient and normal */
-			float pthick, dist;		/* thickness at segment point, and length of segment */
-			float sminorang;		/* minor angle between strokes */
+			float mt[2], sc[2];		/* gradient for thickness, point for end-cap */
+			float pthick;			/* thickness at segment point */
 			
 			/* get x and y coordinates from points */
 			if (sflag & GP_STROKE_2DSPACE) {
@@ -494,91 +524,123 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
 			/* calculate gradient and normal - 'angle'=(ny/nx) */
 			m1[1]= s1[1] - s0[1];		
 			m1[0]= s1[0] - s0[0];
-			dist = Vec2Lenf(s0, s1);
-			m2[1]= -(m1[0]) / dist;
-			m2[0]= m1[1] / dist;
+			Normalize2(m1);
+			m2[1]= -m1[0];
+			m2[0]= m1[1];
+			
+			/* always use pressure from first point here */
+			pthick= (pt1->pressure * thickness);
 			
-			/* if the first segment, initialise the first segment using segment's normal */
-			if (i == 0) {	
-				pthick= (pt1->pressure * thickness);
+			/* if the first segment, start of segment is segment's normal */
+			if (i == 0) {
+				/* draw start cap first 
+				 *	- make points slightly closer to center (about halfway across) 
+				 */				
+				mt[0]= m2[0] * pthick * 0.5;
+				mt[1]= m2[1] * pthick * 0.5;
+				sc[0]= s0[0] - (m1[0] * pthick * 0.75);
+				sc[1]= s0[1] - (m1[1] * pthick * 0.75);
+				
+				t0[0]= sc[0] - mt[0];
+				t0[1]= sc[1] - mt[1];
+				t1[0]= sc[0] + mt[0];
+				t1[1]= sc[1] + mt[1];
+				
+				glVertex2fv(t0);
+				glVertex2fv(t1);
 				
-				// TODO: also draw/do a round end-cap first
+				/* calculate points for start of segment */
+				mt[0]= m2[0] * pthick;
+				mt[1]= m2[1] * pthick;
 				
-				p0[0]= s0[0] - (pthick * m2[0]);
-				p0[1]= s0[1] - (pthick * m2[1]);
-				p1[0]= s1[0] + (pthick * m2[0]);
-				p1[1]= s1[1] + (pthick * m2[1]);
+				t0[0]= s0[0] - mt[0];
+				t0[1]= s0[1] - mt[1];
+				t1[0]= s0[0] + mt[0];
+				t1[1]= s0[1] + mt[1];
 				
-				Vec2Copyf(pm, m1);
+				/* draw this line twice (first to finish off start cap, then for stroke) */
+				glVertex2fv(t1);
+				glVertex2fv(t0);
+				glVertex2fv(t0);
+				glVertex2fv(t1);
 			}
-			
-			/* if the minor angle between the current segment and the previous one is less than 90 degrees */
-			if (i)
-				sminorang= NormalizedVecAngle2_2D(pm, m1);
-			else
-				sminorang= 0.0f;
-			
-			if ((IS_EQ(sminorang, 0)==0) && (abs(sminorang) < M_PI_2) ) 
-			{
-				float closep[2];
+			/* if not the first segment, use bisector of angle between segments */
+			else {
+				float mb[2]; 		/* bisector normal */
+				float athick, dfac;		/* actual thickness, difference between thicknesses */
+				
+				/* calculate gradient of bisector (as average of normals) */
+				mb[0]= (pm[0] + m2[0]) / 2;
+				mb[1]= (pm[1] + m2[1]) / 2;
+				Normalize2(mb);
 				
-				/* recalculate startpoint of segment, where the new start-line:
-				 * 	- starts a new gl-quad-strip
-				 *	- uses the vert of old startpoint closer to our endpoint
-				 *	- distance between new startpoints = distance between old startpoints
-				 *	- new startpoints occur on same gradient as old segment does (has potential for some 'minor' overlap, but ok)
+				/* calculate gradient to apply 
+				 * 	- as basis, use just pthick * bisector gradient
+				 *	- if cross-section not as thick as it should be, add extra padding to fix it
 				 */
+				mt[0]= mb[0] * pthick;
+				mt[1]= mb[1] * pthick;
+				athick= Vec2Length(mt);
+				dfac= pthick - (athick * 2);
+				if ( ((athick * 2) < pthick) && (IS_EQ(athick, pthick)==0) ) 
+				{
+					mt[0] += (mb[0] * dfac);
+					mt[1] += (mb[1] * dfac);
+				}	
 				
-				/* find the closer vertex, and distance between startpoints */
-				if (Vec2Lenf(p0, s1) > Vec2Lenf(p1, s1))
-					Vec2Copyf(closep, p1);
-				else
-					Vec2Copyf(closep, p0);
-					
-				/* determine which side this closer vertex should be on */
-				pthick= (pt1->pressure * thickness * 2);
-				if ( ((closep[0] - s0[0]) > 0) || ((closep[1] - s0[1]) > 0) ) {
-					/* assumes this is the 'second' point, (i.e. the 'plus' one), so the other is subtracting */
-					p0[0]= closep[0] - (pthick * pm[0]);
-					p0[1]= closep[1] - (pthick * pm[1]);
-					p1[0]= closep[0];
-					p1[1]= closep[1];
-				}
-				else if ( ((closep[0] - s0[0]) < 0) || ((closep[1] - s0[1]) < 0) ) {
-					/* assumes this is the 'first' point, (i.e. the 'minus' one), so the other is adding */
-					p0[0]= closep[0];
-					p0[1]= closep[1];
-					p1[0]= closep[0] + (pthick * pm[0]);
-					p1[1]= closep[1] + (pthick * pm[1]);
-				}
+				/* calculate points for start of segment */
+				t0[0]= s0[0] - mt[0];
+				t0[1]= s0[1] - mt[1];
+				t1[0]= s0[0] + mt[0];
+				t1[1]= s0[1] + mt[1];
 				
-				/* reset gl-states! */
-				glEnd();
-				glBegin(GL_QUAD_STRIP);				
+				/* draw this line twice (once for end of current segment, and once for start of next) */
+				glVertex2fv(t1);
+				glVertex2fv(t0);
+				glVertex2fv(t0);
+				glVertex2fv(t1);
 			}
 			
-			/* do the end of this segment */
-			pthick= (pt2->pressure * thickness);
-			t0[0] = s1[0] - (pthick * m2[0]);
-			t0[1] = s1[1] - (pthick * m2[1]);
-			t1[0] = s1[0] + (pthick * m2[0]);
-			t1[1] = s1[1] + (pthick * m2[1]);
-			
-			/* draw this segment */
-			glVertex2f(p0[0], p0[1]);
-			glVertex2f(p1[0], p1[1]);
-			glVertex2f(t0[0], t0[1]);
-			glVertex2f(t1[0], t1[1]);
-			
-			// TODO: draw end cap if last segment
+			/* if last segment, also draw end of segment (defined as segment's normal) */
 			if (i == totpoints-2) {
-			
+				/* for once, we use second point's pressure (otherwise it won't be drawn) */
+				pthick= (pt2->pressure * thickness);
+				
+				/* calculate points for end of segment */
+				mt[0]= m2[0] * pthick;
+				mt[1]= m2[1] * pthick;
+				
+				t0[0]= s1[0] - mt[0];
+				t0[1]= s1[1] - mt[1];
+				t1[0]= s1[0] + mt[0];
+				t1[1]= s1[1] + mt[1];
+				
+				/* draw this line twice (once for end of stroke, and once for endcap)*/
+				glVertex2fv(t1);
+				glVertex2fv(t0);
+				glVertex2fv(t0);
+				glVertex2fv(t1);
+				
+				
+				/* draw end cap as last step 
+				 *	- make points slightly closer to center (about halfway across) 
+				 */				
+				mt[0]= m2[0] * pthick * 0.5;
+				mt[1]= m2[1] * pthick * 0.5;
+				sc[0]= s1[0] + (m1[0] * pthick * 0.75);
+				sc[1]= s1[1] + (m1[1] * pthick * 0.75);
+				
+				t0[0]= sc[0] - mt[0];
+				t0[1]= sc[1] - mt[1];
+				t1[0]= sc[0] + mt[0];
+				t1[1]= sc[1] + mt[1];
+				
+				glVertex2fv(t1);
+				glVertex2fv(t0);
 			}
 			
-			/* store current points for next segment to use */
-			Vec2Copyf(p0, t0);
-			Vec2Copyf(p1, t1);
-			Vec2Copyf(pm, m1);
+			/* store stroke's 'natural' normal for next stroke to use */
+			Vec2Copyf(pm, m2);
 		}
 		
 		glEnd();
@@ -626,12 +688,16 @@ static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, shor
 			continue;
 		if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE))
 			continue;
+		if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE))
+			continue;
+		if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE))
+			continue;
 		if ((gps->points == 0) || (gps->totpoints < 1))
 			continue;
 		
 		/* check which stroke-drawer to use */
 		if (gps->totpoints == 1)
-			gp_draw_stroke_point(gps->points, gps->flag, winx, winy);
+			gp_draw_stroke_point(gps->points, lthick, gps->flag, winx, winy);
 		else if (dflag & GP_DRAWDATA_ONLY3D)
 			gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
 		else if (gps->totpoints > 1)	
@@ -796,6 +862,22 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
 
 /* ----- Grease Pencil Sketches Drawing API ------ */
 
+/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */
+void draw_gpencil_2dimage (ScrArea *sa, ImBuf *ibuf)
+{
+	bGPdata *gpd;
+	int dflag = 0;
+	
+	/* check that we have grease-pencil stuff to draw */
+	if (ELEM(NULL, sa, ibuf)) return;
+	gpd= gpencil_data_getactive(sa);
+	if (gpd == NULL) return;
+	
+	/* draw it! */
+	dflag = (GP_DRAWDATA_ONLYI2D|GP_DRAWDATA_NOSTATUS);
+	gp_draw_data(gpd, sa->winx, sa->winy, dflag);
+}
+
 /* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly 
  * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes
  */
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index 0e7476bbe8223b04cbd7fddcf00409ae5ead09d3..9b5be04eac114d11da2ea3872e57be33b7ce2e62 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -442,7 +442,7 @@ int in_ipo_buttons(void)
 	else return 1;
 }
 
-static View2D *spacelink_get_view2d(SpaceLink *sl)
+View2D *spacelink_get_view2d(SpaceLink *sl)
 {
 	if(sl->spacetype==SPACE_IPO) 
 		return &((SpaceIpo *)sl)->v2d;
@@ -1212,16 +1212,9 @@ static void draw_ipovertices(int sel)
 					/*}*/
 				} else { /* normal non bit curves */
 					if(ei->flag & IPO_EDIT) {
-						if(ei->icu->ipo==IPO_BEZ) {
-							/* Draw the editmode hendels for a bezier curve */
-							if( (bezt->f1 & SELECT) == sel)/* && G.v2d->cur.xmin < bezt->vec[0][0] < G.v2d->cur.xmax)*/
-								bglVertex3fv(bezt->vec[0]);
-							
-							if( (bezt->f3 & SELECT) == sel)/* && G.v2d->cur.xmin < bezt->vec[2][0] < G.v2d->cur.xmax)*/
-								bglVertex3fv(bezt->vec[2]);
-							
-						}
-						
+						/* Only the vertex of the line, the
+						 * handler are draw below.
+						 */
 						if( (bezt->f2 & SELECT) == sel) /* && G.v2d->cur.xmin < bezt->vec[1][0] < G.v2d->cur.xmax)*/
 							bglVertex3fv(bezt->vec[1]);
 						
@@ -1237,6 +1230,45 @@ static void draw_ipovertices(int sel)
 				bezt++;
 			}
 			bglEnd();
+
+			if (ei->flag & IPO_EDIT) {
+				/* Now draw the two vertex of the handler,
+				 * need split it because we can't call glPointSize
+				 * in the middle of a glBegin/glEnd also the
+				 * bug comment before.
+				 */
+				a= ei->icu->totvert;
+				bezt= ei->icu->bezt;
+
+				glPointSize(BIF_GetThemeValuef(TH_HANDLE_VERTEX_SIZE));
+
+				if(sel) BIF_ThemeColor(TH_HANDLE_VERTEX_SELECT);
+				else BIF_ThemeColor(TH_HANDLE_VERTEX);
+
+				bglBegin(GL_POINTS);
+
+				while(a--) {
+					if (ei->disptype!=IPO_DISPBITS) {
+						if(ei->flag & IPO_EDIT) {
+							if(ei->icu->ipo==IPO_BEZ) {
+								/* Draw the editmode hendels for a bezier curve */
+								if( (bezt->f1 & SELECT) == sel)/* && G.v2d->cur.xmin < bezt->vec[0][0] < G.v2d->cur.xmax)*/
+									bglVertex3fv(bezt->vec[0]);
+							
+								if( (bezt->f3 & SELECT) == sel)/* && G.v2d->cur.xmin < bezt->vec[2][0] < G.v2d->cur.xmax)*/
+									bglVertex3fv(bezt->vec[2]);
+							}
+						}
+					}
+					bezt++;
+				}
+				bglEnd();
+
+				/* The color are always reset (see the while)
+				 * but the point size not so we reset now.
+				 */
+				glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
+			}
 		}
 	}
 	
diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c
index dd512595ebc4da622cd52fa5187a4a65a4f81a52..09f74c01c71c75c830d5681cf7b9c5eefb088bb6 100644
--- a/source/blender/src/drawmesh.c
+++ b/source/blender/src/drawmesh.c
@@ -664,7 +664,7 @@ static int draw_tfaces3D__setHiddenOpts(void *userData, int index)
 {
 	struct { Mesh *me; EdgeHash *eh; } *data = userData;
 	MEdge *med = &data->me->medge[index];
-	unsigned long flags = (long) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
+	uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
 
 	if((G.f & G_DRAWSEAMS) && (med->flag&ME_SEAM)) {
 		return 0;
@@ -682,7 +682,7 @@ static int draw_tfaces3D__setSeamOpts(void *userData, int index)
 {
 	struct { Mesh *me; EdgeHash *eh; } *data = userData;
 	MEdge *med = &data->me->medge[index];
-	unsigned long flags = (long) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
+	uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
 
 	if (med->flag&ME_SEAM) {
 		if (G.f&G_HIDDENEDGES) {
@@ -698,7 +698,7 @@ static int draw_tfaces3D__setSelectOpts(void *userData, int index)
 {
 	struct { Mesh *me; EdgeHash *eh; } *data = userData;
 	MEdge *med = &data->me->medge[index];
-	unsigned long flags = (long) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
+	uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
 
 	return flags & eEdge_Select;
 }
@@ -706,7 +706,7 @@ static int draw_tfaces3D__setActiveOpts(void *userData, int index)
 {
 	struct { Mesh *me; EdgeHash *eh; } *data = userData;
 	MEdge *med = &data->me->medge[index];
-	unsigned long flags = (long) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
+	uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
 
 	if (flags & eEdge_Select) {
 		return 1;
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 1a469e8b3660b29e2e6b22008a13e6f6efb94ebb..213f49528f0759b97d57e2589d247048131bc46e 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -5315,7 +5315,7 @@ void draw_object_ext(Base *base)
 
 static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-	int offset = (long) userData;
+	int offset = (intptr_t) userData;
 	EditVert *eve = EM_get_vert_for_index(index);
 
 	if (eve->h==0) {
@@ -5327,7 +5327,7 @@ static int bbs_mesh_verts(DerivedMesh *dm, int offset)
 {
 	glPointSize( BIF_GetThemeValuef(TH_VERTEX_SIZE) );
 	bglBegin(GL_POINTS);
-	dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, (void*)(long) offset);
+	dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, (void*)(intptr_t) offset);
 	bglEnd();
 	glPointSize(1.0);
 
@@ -5336,7 +5336,7 @@ static int bbs_mesh_verts(DerivedMesh *dm, int offset)
 
 static int bbs_mesh_wire__setDrawOptions(void *userData, int index)
 {
-	int offset = (long) userData;
+	int offset = (intptr_t) userData;
 	EditEdge *eed = EM_get_edge_for_index(index);
 
 	if (eed->h==0) {
@@ -5348,7 +5348,7 @@ static int bbs_mesh_wire__setDrawOptions(void *userData, int index)
 }
 static int bbs_mesh_wire(DerivedMesh *dm, int offset)
 {
-	dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, (void*)(long) offset);
+	dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, (void*)(intptr_t) offset);
 
 	return offset + G.totedge;
 }		
@@ -5382,7 +5382,7 @@ static int bbs_mesh_solid_EM(DerivedMesh *dm, int facecol)
 	cpack(0);
 
 	if (facecol) {
-		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(long) 1, 0);
+		dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*)(intptr_t) 1, 0);
 
 		if( CHECK_OB_DRAWFACEDOT(G.scene, G.vd, G.obedit->dt) ) {
 			glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
@@ -5415,7 +5415,7 @@ static int bbs_mesh_wire__setDrawOpts(void *userData, int index)
 {
 	struct { Mesh *me; EdgeHash *eh; int offset; } *data = userData;
 	MEdge *med = data->me->medge + index;
-	unsigned long flags = (long)BLI_edgehash_lookup(data->eh, med->v1, med->v2);
+	uintptr_t flags = (intptr_t)BLI_edgehash_lookup(data->eh, med->v1, med->v2);
 
 	if (flags & 1) {
 		set_framebuffer_index_color(data->offset+index);
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 35986fcff4aa392ea3699a4dbad5946abd0c73b4..5e50c8117cc860ce2abcde7084539f00401ea50f 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -439,6 +439,109 @@ void docenter_armature (Object *ob, int centermode)
 	}
 }
 
+/* helper for apply_armature_pose2bones - fixes parenting of objects that are bone-parented to armature */
+static void applyarmature_fix_boneparents (Object *armob)
+{
+	Object *ob;
+	
+	/* go through all objects in database */
+	for (ob= G.main->object.first; ob; ob= ob->id.next) {
+		/* if parent is bone in this armature, apply corrections */
+		if ((ob->parent == armob) && (ob->partype == PARBONE)) {
+			/* apply current transform from parent (not yet destroyed), 
+			 * then calculate new parent inverse matrix
+			 */
+			apply_obmat(ob);
+			
+			what_does_parent(ob);
+			Mat4Invert(ob->parentinv, workob.obmat);
+		}
+	}
+}
+
+/* set the current pose as the restpose */
+void apply_armature_pose2bones(void)
+{
+	Object	*ob;
+	bArmature *arm;
+	bPose *pose;
+	bPoseChannel *pchan;
+	EditBone *curbone;
+	
+	/* don't check if editmode (should be done by caller) */
+	ob= OBACT;
+	if (ob->type!=OB_ARMATURE) return;
+	if (object_data_is_libdata(ob)) {
+		error_libdata();
+		return;
+	}
+	arm= get_armature(ob); 
+	
+	/* helpful warnings... */
+	// TODO: add warnings to be careful about actions, applying deforms first, etc.
+	
+	/* Get editbones of active armature to alter */
+	if (G.edbo.first) BLI_freelistN(&G.edbo);
+	make_boneList(&G.edbo, &arm->bonebase, NULL);
+	
+	/* get pose of active object and move it out of posemode */
+	pose= ob->pose;
+	
+	for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
+		curbone= editbone_name_exists(&G.edbo, pchan->name);
+		
+		/* simply copy the head/tail values from pchan over to curbone */
+		VECCOPY(curbone->head, pchan->pose_head);
+		VECCOPY(curbone->tail, pchan->pose_tail);
+		
+		/* fix roll:
+		 *	1. find auto-calculated roll value for this bone now
+		 *	2. remove this from the 'visual' y-rotation
+		 */
+		{
+			float premat[3][3], imat[3][3],pmat[3][3], tmat[3][3];
+			float delta[3], eul[3];
+			
+			/* obtain new auto y-rotation */
+			VecSubf(delta, curbone->tail, curbone->head);
+			vec_roll_to_mat3(delta, 0.0, premat);
+			Mat3Inv(imat, premat);
+			
+			/* get pchan 'visual' matrix */
+			Mat3CpyMat4(pmat, pchan->pose_mat);
+			
+			/* remove auto from visual and get euler rotation */
+			Mat3MulMat3(tmat, imat, pmat);
+			Mat3ToEul(tmat, eul);
+			
+			/* just use this euler-y as new roll value */
+			curbone->roll= eul[1];
+		}
+		
+		/* clear transform values for pchan */
+		pchan->loc[0]= pchan->loc[1]= pchan->loc[2]= 0;
+		pchan->quat[1]= pchan->quat[2]= pchan->quat[3]= 0;
+		pchan->quat[0]= pchan->size[0]= pchan->size[1]= pchan->size[2]= 1;
+		
+		/* set anim lock */
+		curbone->flag |= BONE_UNKEYED;
+	}
+	
+	/* convert editbones back to bones */
+	editbones_to_armature(&G.edbo, ob);
+	if (G.edbo.first) BLI_freelistN(&G.edbo);
+	
+	/* flush positions of posebones */
+	where_is_pose(ob);
+	
+	/* fix parenting of objects which are bone-parented */
+	applyarmature_fix_boneparents(ob);
+	
+	BIF_undo_push("Apply new restpose");
+	allqueue(REDRAWVIEW3D, 0);
+}
+
+
 /* Helper function for armature joining - link fixing */
 static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
 {
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 63c301658f2232e9c85db24a5a40b48f7d20434b..cd6aefdb87c72e1859b4f432bc117cd13a419364 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -462,24 +462,7 @@ static void make_part_editipo(SpaceIpo *si)
 		name = getname_part_ei(part_ar[a]);
 		strcpy(ei->name, name);
 		ei->adrcode= part_ar[a];
-		
-		//if(ei->adrcode & MA_MAP1) {
-		//	ei->adrcode-= MA_MAP1;
-		//	ei->adrcode |= texchannel_to_adrcode(si->channel);
-		//}
-		//else {
-		//	if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS;
-		//}
-		
 		ei->col= ipo_rainbow(a, PART_TOTIPO);
-		
-		//len= strlen(ei->name);
-		//if(len) {
-		//	if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF;
-		//	else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50;
-		//	else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050;
-		//}
-		
 		ei->icu= find_ipocurve(si->ipo, ei->adrcode);
 		if(ei->icu) {
 			ei->flag= ei->icu->flag;
@@ -6011,4 +5994,4 @@ void move_to_frame(void)
 		}
 	}
 	BIF_undo_push("Set frame to selected Ipo vertex");
-}
\ No newline at end of file
+}
diff --git a/source/blender/src/editipo_lib.c b/source/blender/src/editipo_lib.c
index 41044ad13d7e2e617d7b1c4ae4dee201ceab776a..e1e286e10cf706f010e1b5f72c9c3dbc1ddcd82d 100644
--- a/source/blender/src/editipo_lib.c
+++ b/source/blender/src/editipo_lib.c
@@ -103,7 +103,8 @@ char *ic_name_empty[1] ={ "" };
 char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time",  "GravX","GravY","GravZ",  "VelX","VelY","VelZ", "Active"  };
 char *part_ic_names[PART_TOTNAM] = { "E_Freq", "E_Life", "E_Speed", "E_Angular", "E_Size",
 "Angular", "Size", "Drag", "Brown", "Damp", "Length", "Clump",
-"GravX", "GravY", "GravZ", "KinkAmp", "KinkFreq", "KinkShape", "BBTilt"};
+"GravX", "GravY", "GravZ", "KinkAmp", "KinkFreq", "KinkShape", "BBTilt",
+"FStreng", "FFall", "FMaxD", "F2Streng", "F2Fall", "F2MaxD"};
 
 /* gets the appropriate icon for the given blocktype */
 int geticon_ipo_blocktype(short blocktype)
diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c
index 1f24fb076676edbe42910affb21cd78868577b6d..ce79806463232919dc7d91e3f00e0c907b7ea4d7 100644
--- a/source/blender/src/editkey.c
+++ b/source/blender/src/editkey.c
@@ -84,6 +84,8 @@
 #include "blendef.h"
 #include "mydevice.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 extern ListBase editNurb; /* in editcurve.c */
 
 /* temporary storage for slider values */
@@ -162,7 +164,7 @@ static void rvk_slider_func(void *voidob, void *voidkeynum)
 	IpoCurve  *icu=NULL;
 	BezTriple *bezt=NULL;
 	float cfra, rvkval;
-	int keynum = (long) voidkeynum;
+	int keynum = (intptr_t) voidkeynum;
 
 	cfra = frame_to_float(CFRA);
 
@@ -275,7 +277,7 @@ void make_rvk_slider(uiBlock *block, Object *ob, int keynum,
 				  x, y , w, h,
 				  meshslidervals+keynum, min, max, 10, 2, tip);
 	
-	uiButSetFunc(but, rvk_slider_func, ob, (void *)(long)keynum);
+	uiButSetFunc(but, rvk_slider_func, ob, (void *)(intptr_t)keynum);
 	// no hilite, the winmatrix is not correct later on...
 	uiButSetFlag(but, UI_NO_HILITE);
 
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index 6dfbd67720b57356b9e1d7867e221f1504fed026..c162c904776638bf8270cf49cfcbfac0241a01cd 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -109,6 +109,7 @@ editmesh_mods.c, UI level access, no geometry changes
 
 #include "editmesh.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
 
 /* ****************************** MIRROR **************** */
 
@@ -2937,7 +2938,7 @@ void select_sharp_edges(void)
 	EditFace *efa;
 	EditFace **efa1;
 	EditFace **efa2;
-	long edgecount = 0, i;
+	intptr_t edgecount = 0, i;
 	static short sharpness = 135;
 	float fsharpness;
 
@@ -3041,7 +3042,7 @@ void select_linked_flat_faces(void)
 	EditFace *efa;
 	EditFace **efa1;
 	EditFace **efa2;
-	long edgecount = 0, i, faceselcount=0, faceselcountold=0;
+	intptr_t edgecount = 0, i, faceselcount=0, faceselcountold=0;
 	static short sharpness = 135;
 	float fsharpness;
 
diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c
index f9bb14a08c619a80d2d4668b8ef40140f45361f3..2b25253dc95d18fc3e27c347bc736e30433a5f86 100644
--- a/source/blender/src/editmesh_tools.c
+++ b/source/blender/src/editmesh_tools.c
@@ -110,6 +110,8 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 
 #include "PIL_time.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* local prototypes ---------------*/
 void bevel_menu(void);
 static void free_tagged_edges_faces(EditEdge *eed, EditFace *efa);
@@ -132,7 +134,7 @@ static int vergxco(const void *v1, const void *v2)
 }
 
 struct facesort {
-	unsigned long x;
+	uintptr_t x;
 	struct EditFace *efa;
 };
 
@@ -433,8 +435,8 @@ int removedoublesflag(short flag, short automerge, float limit)		/* return amoun
 		efa= em->faces.first;
 		while(efa) {
 			if(efa->f1 & 1) {
-				if(efa->v4) vsb->x= (unsigned long) MIN4( (unsigned long)efa->v1, (unsigned long)efa->v2, (unsigned long)efa->v3, (unsigned long)efa->v4);
-				else vsb->x= (unsigned long) MIN3( (unsigned long)efa->v1, (unsigned long)efa->v2, (unsigned long)efa->v3);
+				if(efa->v4) vsb->x= (uintptr_t) MIN4( (uintptr_t)efa->v1, (uintptr_t)efa->v2, (uintptr_t)efa->v3, (uintptr_t)efa->v4);
+				else vsb->x= (uintptr_t) MIN3( (uintptr_t)efa->v1, (uintptr_t)efa->v2, (uintptr_t)efa->v3);
 
 				vsb->efa= efa;
 				vsb++;
@@ -4665,6 +4667,7 @@ int EdgeLoopDelete(void) {
 
 int EdgeSlide(short immediate, float imperc)
 {
+	NumInput num;
 	EditMesh *em = G.editMesh;
 	EditFace *efa;
 	EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
@@ -4681,6 +4684,8 @@ int EdgeSlide(short immediate, float imperc)
 	char str[128]; 
 	float labda = 0.0f;
 	
+	initNumInput(&num);
+		
 	view3d_get_object_project_mat(curarea, G.obedit, projectMat, viewMat);
 	
 	mvalo[0] = -1; mvalo[1] = -1; 
@@ -4992,17 +4997,84 @@ int EdgeSlide(short immediate, float imperc)
 		float v2[2], v3[2];
 		EditVert *centerVert, *upVert, *downVert;
 		
-		
-
 		getmouseco_areawin(mval);  
 		
 		if (!immediate && (mval[0] == mvalo[0] && mval[1] ==  mvalo[1])) {
 			PIL_sleep_ms(10);
 		} else {
+			char *p = str;;
 
 			mvalo[0] = mval[0];
 			mvalo[1] = mval[1];
 			
+
+			tempsv = BLI_ghash_lookup(vertgh,nearest);
+
+			centerVert = editedge_getSharedVert(tempsv->up, tempsv->down);
+			upVert = editedge_getOtherVert(tempsv->up, centerVert);
+			downVert = editedge_getOtherVert(tempsv->down, centerVert);
+
+			view3d_project_float(curarea, upVert->co, v2, projectMat);
+			view3d_project_float(curarea, downVert->co, v3, projectMat);
+
+			/* Determine the % on which the loop should be cut */   
+
+			rc[0]= v3[0]-v2[0];   
+			rc[1]= v3[1]-v2[1];   
+			len= rc[0]*rc[0]+ rc[1]*rc[1];
+			if (len==0) {len = 0.0001;}
+
+			if ((G.qual & LR_SHIFTKEY)==0) {
+				wasshift = 0;
+				labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len;   
+			}
+			else {
+				if (wasshift==0) {
+					wasshift = 1;
+					shiftlabda = labda;
+				}							
+				labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len / 10.0 + shiftlabda;   			
+			}
+			
+
+			if(labda<=0.0) labda=0.0;   
+			else if(labda>=1.0)labda=1.0;   
+
+			perc=((1-labda)*2)-1;		  
+			
+			if(G.qual == 0) {
+				perc *= 100;
+				perc = floor(perc);
+				perc /= 100;
+			} else if (G.qual == LR_CTRLKEY) {
+				perc *= 10;
+				perc = floor(perc);
+				perc /= 10;				   
+			}			
+			
+			if(prop == 0) {
+				len = VecLenf(upVert->co,downVert->co)*((perc+1)/2);
+				if(flip == 1) {
+					len = VecLenf(upVert->co,downVert->co) - len;
+				} 
+			}
+			
+			if (hasNumInput(&num))
+			{
+				applyNumInput(&num, &perc);
+				
+				if (prop)
+				{
+					perc = MIN2(perc, 1);
+					perc = MAX2(perc, -1);
+				}
+				else
+				{
+					len = MIN2(perc, VecLenf(upVert->co,downVert->co));
+					len = MAX2(len, 0);
+				}
+			}
+
 			//Adjust Edgeloop
 			if(immediate) {
 				perc = imperc;   
@@ -5041,13 +5113,7 @@ int EdgeSlide(short immediate, float imperc)
 
 			}
 			
-			tempsv = BLI_ghash_lookup(vertgh,nearest);
-
-			centerVert = editedge_getSharedVert(tempsv->up, tempsv->down);
-			upVert = editedge_getOtherVert(tempsv->up, centerVert);
-			downVert = editedge_getOtherVert(tempsv->down, centerVert);
 			 // Highlight the Control Edges
-	
 			scrarea_do_windraw(curarea);   
 			persp(PERSP_VIEW);   
 			glPushMatrix();   
@@ -5075,55 +5141,36 @@ int EdgeSlide(short immediate, float imperc)
 			
 			glPopMatrix();		 
 
-			view3d_project_float(curarea, upVert->co, v2, projectMat);
-			view3d_project_float(curarea, downVert->co, v3, projectMat);
-
-			/* Determine the % on which the loop should be cut */   
-
-			rc[0]= v3[0]-v2[0];   
-			rc[1]= v3[1]-v2[1];   
-			len= rc[0]*rc[0]+ rc[1]*rc[1];
-			if (len==0) {len = 0.0001;}
-
-			if ((G.qual & LR_SHIFTKEY)==0) {
-				wasshift = 0;
-				labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len;   
+			if(prop) {
+				p += sprintf(str, "(P)ercentage: ");
+			} else {
+				p += sprintf(str, "Non (P)rop Length: ");
 			}
-			else {
-				if (wasshift==0) {
-					wasshift = 1;
-					shiftlabda = labda;
-				}							
-				labda= ( rc[0]*((mval[0]-v2[0])) + rc[1]*((mval[1]-v2[1])) )/len / 10.0 + shiftlabda;   			
+			
+			if (hasNumInput(&num))
+			{
+				char num_str[20];
+				
+				outputNumInput(&num, num_str);
+				p += sprintf(p, "%s", num_str);
+			}
+			else
+			{
+				if (prop)
+				{
+					p += sprintf(p, "%f", perc);
+				}
+				else
+				{
+					p += sprintf(p, "%f", len);
+				}
 			}
 			
-
-			if(labda<=0.0) labda=0.0;   
-			else if(labda>=1.0)labda=1.0;   
-
-			perc=((1-labda)*2)-1;		  
 			
-			if(G.qual == 0) {
-				perc *= 100;
-				perc = floor(perc);
-				perc /= 100;
-			} else if (G.qual == LR_CTRLKEY) {
-				perc *= 10;
-				perc = floor(perc);
-				perc /= 10;				   
-			}			
-			if(prop) {
-				sprintf(str, "(P)ercentage: %f", perc);
-			} else {
-				len = VecLenf(upVert->co,downVert->co)*((perc+1)/2);
-				if(flip == 1) {
-					len = VecLenf(upVert->co,downVert->co) - len;
-				} 
-				sprintf(str, "Non (P)rop Length: %f, Press (F) to flip control side", len);
+			if (prop == 0) {
+				p += sprintf(p, ", Press (F) to flip control side");
 			}
 
-			
-			
 			headerprint(str);
 			screen_swapbuffers();			
 		}
@@ -5146,7 +5193,14 @@ int EdgeSlide(short immediate, float imperc)
 							perc = 0;  
 							immediate = 1;
 					} else if(event==PKEY) {
-							(prop == 1) ? (prop = 0):(prop = 1);
+							initNumInput(&num); /* reset num input */
+							if (prop) {
+								prop = 0;
+								num.flag |= NUM_NO_NEGATIVE;
+							}
+							else {
+								prop = 1;
+							}
 							mvalo[0] = -1;  
 					} else if(event==FKEY) {
 							(flip == 1) ? (flip = 0):(flip = 1); 
@@ -5184,7 +5238,13 @@ int EdgeSlide(short immediate, float imperc)
 							look = look->next;   
 						}	  
 					}
+					
+					if (handleNumInput(&num, event))
+					{
+						mvalo[0] = -1; /* NEED A BETTER WAY TO TRIGGER REDRAW */
+					}
 				}
+				
 			} 
 		} else {
 			draw = 0;
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index 98f4f1bb46f8e4c60c96375cedce37741c0c8366..eba6c5b448890526d33154630ff8171cece183c2 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -2110,6 +2110,7 @@ static void node_border_link_delete(SpaceNode *snode)
 			mval[1]= rect.ymax;
 			areamouseco_to_ipoco(&snode->v2d, mval, &rectf.xmax, &rectf.ymax);
 			
+			glLoadIdentity();
 			myortho2(rectf.xmin, rectf.xmax, rectf.ymin, rectf.ymax);
 			
 			glSelectBuffer(256, buffer); 
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index fee967bcd9ad5faf45c85c1dc8807a75d15382f9..2094074e3f3297084478d1d8111ec629447486d1 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -172,6 +172,7 @@
 #include "BDR_drawobject.h"
 #include "BDR_editcurve.h"
 #include "BDR_unwrapper.h"
+#include "BDR_gpencil.h"
 
 #include <time.h>
 #include "mydevice.h"
@@ -2827,7 +2828,7 @@ void convertmenu(void)
 	if(G.scene->id.lib) return;
 
 	obact= OBACT;
-	if(obact==0) return;
+	if (obact == NULL) return;
 	if(!obact->flag & SELECT) return;
 	if(G.obedit) return;
 	
@@ -4130,15 +4131,26 @@ void apply_object( void )
 		}
 		allqueue(REDRAWVIEW3D, 0);
 		
-	} else {
+	} 
+	else {
+		ob= OBACT;
 		
-		evt = pupmenu("Apply Object%t|Scale and Rotation to ObData|Visual Transform to Objects Loc/Scale/Rot");
+		if ((ob->pose) && (ob->flag & OB_POSEMODE))
+			evt = pupmenu("Apply Object%t|Current Pose as RestPose%x3");
+		else
+			evt = pupmenu("Apply Object%t|Scale and Rotation to ObData%x1|Visual Transform to Objects Loc/Scale/Rot%x2");
 		if (evt==-1) return;
 		
-		if (evt==1) {
-			apply_objects_locrot();
-		} else if (evt==2) {
-			apply_objects_visual_tx();
+		switch (evt) {
+			case 1:
+				apply_objects_locrot();
+				break;
+			case 2:
+				apply_objects_visual_tx();
+				break;
+			case 3:
+				apply_armature_pose2bones();
+				break;
 		}
 	}
 }
diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c
index a3fcad7885c2869386302afa93f96a53914107b1..d2e59ae676dd19ac0933737e2337b05aa6e55c82 100644
--- a/source/blender/src/editview.c
+++ b/source/blender/src/editview.c
@@ -1631,7 +1631,7 @@ void mouse_select(void)
 
 /* ------------------------------------------------------------------------- */
 
-static int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2)
+int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2)
 {
 	int radsq= rad*rad;
 	float v1[2], v2[2], v3[2];
diff --git a/source/blender/src/gpencil.c b/source/blender/src/gpencil.c
index eef21323a44c3a1d7e90351a2582f362d194037f..ed046929d2e1bc231827464b53844c2e74f46d6d 100644
--- a/source/blender/src/gpencil.c
+++ b/source/blender/src/gpencil.c
@@ -39,11 +39,16 @@
 
 #include "BMF_Api.h"
 
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
 
 #include "DNA_listBase.h"
+#include "DNA_curve_types.h"
 #include "DNA_gpencil_types.h"
+#include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
@@ -54,6 +59,7 @@
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
 #include "BKE_blender.h"
+#include "BKE_curve.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
@@ -71,6 +77,8 @@
 #include "BDR_gpencil.h"
 #include "BIF_drawgpencil.h"
 
+#include "BDR_editobject.h"
+
 #include "BSE_drawipo.h"
 #include "BSE_headerbuttons.h"
 #include "BSE_view.h"
@@ -312,11 +320,17 @@ bGPdata *gpencil_data_getactive (ScrArea *sa)
 		{
 			SpaceSeq *sseq= sa->spacedata.first;
 			
-			/* only applicable for "Image Preview" mode */
+			/* only applicable for image modes */
 			if (sseq->mainb)
 				return sseq->gpd;
 		}
 			break;
+		case SPACE_IMAGE:
+		{
+			SpaceImage *sima= sa->spacedata.first;
+			return sima->gpd;
+		}
+			break;
 	}
 	
 	/* nothing found */
@@ -379,6 +393,17 @@ short gpencil_data_setactive (ScrArea *sa, bGPdata *gpd)
 			}
 		}
 			break;
+		case SPACE_IMAGE:
+		{
+			SpaceImage *sima= sa->spacedata.first;
+			
+			if (sima->gpd)
+				free_gpencil_data(sima->gpd);
+			sima->gpd= gpd;
+			
+			return 1;
+		}
+			break;
 	}
 	
 	/* failed to add */
@@ -589,7 +614,7 @@ void gpencil_layer_delactive (bGPdata *gpd)
 }
 
 /* ************************************************** */
-/* GREASE-PENCIL EDITING MODE - Tools */
+/* GREASE-PENCIL EDITING - Tools */
 
 /* --------- Data Deletion ---------- */
 
@@ -658,6 +683,208 @@ void gpencil_delete_menu (void)
 	gpencil_delete_operation(mode);
 }
 
+/* --------- Data Conversion ---------- */
+
+/* convert the coordinates from the given stroke point into 3d-coordinates */
+static void gp_strokepoint_convertcoords (bGPDstroke *gps, bGPDspoint *pt, float p3d[3])
+{
+	if (gps->flag & GP_STROKE_3DSPACE) {
+		/* directly use 3d-coordinates */
+		// FIXME: maybe we need to counterotate this for object rotation?
+		VecCopyf(p3d, &pt->x);
+	}
+	else {
+		short mval[2], mx, my;
+		float *fp= give_cursor();
+		float dvec[3];
+		
+		/* get screen coordinate */
+		if (gps->flag & GP_STROKE_2DSPACE) {
+			View2D *v2d= spacelink_get_view2d(curarea->spacedata.first);
+			ipoco_to_areaco_noclip(v2d, &pt->x, mval);
+		}
+		else {
+			mval[0]= (pt->x / 1000 * curarea->winx);
+			mval[1]= (pt->y / 1000 * curarea->winy);
+		}
+		mx= mval[0]; 
+		my= mval[1];
+		
+		/* convert screen coordinate to 3d coordinates 
+		 *	- method taken from editview.c - mouse_cursor() 
+		 */
+		project_short_noclip(fp, mval);
+		window_to_3d(dvec, mval[0]-mx, mval[1]-my);
+		VecSubf(p3d, fp, dvec);
+	}
+}
+
+/* convert stroke to 3d path */
+static void gp_layer_to_path (bGPDlayer *gpl, bGPDstroke *gps, Curve *cu)
+{
+	bGPDspoint *pt;
+	Nurb *nu;
+	BPoint *bp;
+	int i;
+	
+	/* create new 'nurb' within the curve */
+	nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)");
+	
+	nu->pntsu= gps->totpoints;
+	nu->pntsv= 1;
+	nu->orderu= gps->totpoints;
+	nu->flagu= 2;	/* endpoint */
+	nu->resolu= 32;
+	
+	nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*gps->totpoints, "bpoints");
+	
+	/* add points */
+	for (i=0, pt=gps->points, bp=nu->bp; i < gps->totpoints; i++, pt++, bp++) {
+		float p3d[3];
+		
+		/* get coordinates to add at */
+		gp_strokepoint_convertcoords(gps, pt, p3d);
+		VecCopyf(bp->vec, p3d);
+		
+		/* set settings */
+		bp->f1= SELECT;
+		bp->radius = bp->weight = pt->pressure * gpl->thickness;
+	}
+	
+	/* add nurb to curve */
+	BLI_addtail(&cu->nurb, nu);
+}
+
+/* convert stroke to 3d bezier */
+static void gp_layer_to_bezier (bGPDlayer *gpl, bGPDstroke *gps, Curve *cu)
+{
+	bGPDspoint *pt;
+	Nurb *nu;
+	BezTriple *bezt;
+	int i;
+	
+	/* create new 'nurb' within the curve */
+	nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
+	
+	nu->pntsu= gps->totpoints;
+	nu->resolu= 12;
+	nu->resolv= 12;
+	nu->type= CU_BEZIER;
+	nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints*sizeof(BezTriple), "bezts");
+	
+	/* add points */
+	for (i=0, pt=gps->points, bezt=nu->bezt; i < gps->totpoints; i++, pt++, bezt++) {
+		float p3d[3];
+		
+		/* get coordinates to add at */
+		gp_strokepoint_convertcoords(gps, pt, p3d);
+		
+		/* TODO: maybe in future the handles shouldn't be in same place */
+		VecCopyf(bezt->vec[0], p3d);
+		VecCopyf(bezt->vec[1], p3d);
+		VecCopyf(bezt->vec[2], p3d);
+		
+		/* set settings */
+		bezt->h1= bezt->h2= HD_FREE;
+		bezt->f1= bezt->f2= bezt->f3= SELECT;
+		bezt->radius = bezt->weight = pt->pressure * gpl->thickness;
+	}
+	
+	/* must calculate handles or else we crash */
+	calchandlesNurb(nu);
+	
+	/* add nurb to curve */
+	BLI_addtail(&cu->nurb, nu);
+}
+
+/* convert a given grease-pencil layer to a 3d-curve representation (using current view if appropriate) */
+static void gp_layer_to_curve (bGPdata *gpd, bGPDlayer *gpl, short mode)
+{
+	bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0);
+	bGPDstroke *gps;
+	Object *ob;
+	Curve *cu;
+	
+	/* error checking */
+	if (ELEM3(NULL, gpd, gpl, gpf))
+		return;
+		
+	/* only convert if there are any strokes on this layer's frame to convert */
+	if (gpf->strokes.first == NULL)
+		return;
+		
+	/* initialise the curve */	
+	cu= add_curve(gpl->info, 1);
+	cu->flag |= CU_3D;
+	
+	/* init the curve object (remove rotation and assign curve data to it) */
+	add_object_draw(OB_CURVE);
+	ob= OBACT;
+	ob->loc[0]= ob->loc[1]= ob->loc[2]= 0;
+	ob->rot[0]= ob->rot[1]= ob->rot[2]= 0;
+	ob->data= cu;
+	
+	/* add points to curve */
+	for (gps= gpf->strokes.first; gps; gps= gps->next) {
+		switch (mode) {
+			case 1: 
+				gp_layer_to_path(gpl, gps, cu);
+				break;
+			case 2:
+				gp_layer_to_bezier(gpl, gps, cu);
+				break;
+		}
+	}
+}
+
+/* convert grease-pencil strokes to another representation 
+ *	mode: 	1 - Active layer to path
+ *			2 - Active layer to bezier
+ */
+void gpencil_convert_operation (short mode)
+{
+	bGPdata *gpd;	
+	float *fp= give_cursor();
+	
+	/* get datablock to work on */
+	gpd= gpencil_data_getactive(NULL);
+	if (gpd == NULL) return;
+	
+	/* initialise 3d-cursor correction globals */
+	initgrabz(fp[0], fp[1], fp[2]);
+	
+	/* handle selection modes */
+	switch (mode) {
+		case 1: /* active layer only (to path) */
+		case 2: /* active layer only (to bezier) */
+		{
+			bGPDlayer *gpl= gpencil_layer_getactive(gpd);
+			gp_layer_to_curve(gpd, gpl, mode);
+		}
+			break;
+	}
+	
+	/* redraw and undo-push */
+	BIF_undo_push("GPencil Convert");
+	allqueue(REDRAWVIEW3D, 0);
+	allqueue(REDRAWOOPS, 0);
+}
+
+/* display a menu for converting grease-pencil strokes */
+void gpencil_convert_menu (void)
+{
+	bGPdata *gpd= gpencil_data_getactive(NULL);
+	short mode;
+	
+	/* only show menu if it will be relevant */
+	if (gpd == NULL) return;
+	
+	mode= pupmenu("Grease Pencil Convert %t|Active Layer To Path%x1|Active Layer to Bezier%x2");
+	if (mode <= 0) return;
+	
+	gpencil_convert_operation(mode);
+}
+
 /* ************************************************** */
 /* GREASE-PENCIL EDITING MODE - Painting */
 
@@ -679,6 +906,7 @@ void gpencil_delete_menu (void)
 typedef struct tGPsdata {
 	ScrArea *sa;		/* area where painting originated */
 	View2D *v2d;		/* needed for GP_STROKE_2DSPACE */
+	ImBuf *ibuf;		/* needed for GP_STROKE_2DIMAGE */
 	
 	bGPdata *gpd;		/* gp-datablock layer comes from */
 	bGPDlayer *gpl;		/* layer we're working on */
@@ -686,6 +914,10 @@ typedef struct tGPsdata {
 	
 	short status;		/* current status of painting */
 	short paintmode;	/* mode for painting */
+	
+	short mval[2];		/* current mouse-position */
+	short mvalo[2];		/* previous recorded mouse-position */
+	short radius;		/* radius of influence for eraser */
 } tGPsdata;
 
 /* values for tGPsdata->status */
@@ -800,6 +1032,16 @@ static void gp_session_initpaint (tGPsdata *p)
 			}
 		}
 			break;	
+		case SPACE_IMAGE:
+		{
+			SpaceImage *sima= curarea->spacedata.first;
+			
+			/* set the current area */
+			p->sa= curarea;
+			p->v2d= &sima->v2d;
+			//p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser);
+		}
+			break;
 		/* unsupported views */
 		default:
 		{
@@ -869,6 +1111,7 @@ static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2])
 		return 1;
 	
 	/* check if the distance since the last point is significant enough */
+	// future optimisation: sqrt here may be too slow?
 	else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX)
 		return 1;
 	
@@ -884,7 +1127,7 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
 	
 	/* in 3d-space - pt->x/y/z are 3 side-by-side floats */
 	if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) {
-		short mx=mval[0], my=mval[1];
+		const short mx=mval[0], my=mval[1];
 		float *fp= give_cursor();
 		float dvec[3];
 		
@@ -904,6 +1147,26 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
 		out[1]= y;
 	}
 	
+	/* 2d - on image 'canvas' (asume that p->v2d is set) */
+	else if ( (gpd->sbuffer_sflag & GP_STROKE_2DIMAGE) && 
+			  (p->v2d) && (p->ibuf) ) 
+	{
+		ImBuf *ibuf= p->ibuf;
+		float x, y;
+		
+		/* convert to 'canvas' coordinates, then adjust for view */
+		areamouseco_to_ipoco(p->v2d, mval, &x, &y);
+		
+		if (ibuf) {
+			out[0]= x*ibuf->x;
+			out[1]= y*ibuf->y;
+		}
+		else {
+			out[0]= x;
+			out[1]= y;
+		}
+	}
+	
 	/* 2d - relative to screen (viewport area) */
 	else {
 		out[0] = (float)(mval[0]) / (float)(p->sa->winx) * 1000;
@@ -927,8 +1190,6 @@ static short gp_stroke_addpoint (tGPsdata *p, short mval[2], float pressure)
 	/* store settings */
 	pt->x= mval[0];
 	pt->y= mval[1];
-	pt->xf= (float)mval[0];
-	pt->yf= (float)mval[0];
 	pt->pressure= pressure;
 	
 	/* increment counters */
@@ -949,9 +1210,18 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
 	bGPDspoint *pt;
 	tGPspoint *ptc;
 	int i, totelem;
+
+	/* macro to test if only converting endpoints  */	
+	#define GP_BUFFER2STROKE_ENDPOINTS ((gpd->flag & GP_DATA_EDITPAINT) && (G.qual & LR_CTRLKEY))
 	
-	/* get total number of points to allocate space for */
-	totelem = gpd->sbuffer_size;
+	/* get total number of points to allocate space for:
+	 *	- in 'Draw Mode', holding the Ctrl-Modifier will only take endpoints
+	 *	- otherwise, do whole stroke
+	 */
+	if (GP_BUFFER2STROKE_ENDPOINTS)
+		totelem = (gpd->sbuffer_size >= 2) ? 2: gpd->sbuffer_size;
+	else
+		totelem = gpd->sbuffer_size;
 	
 	/* exit with error if no valid points from this stroke */
 	if (totelem == 0) {
@@ -972,45 +1242,53 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
 	gps->flag= gpd->sbuffer_sflag;
 	
 	/* copy points from the buffer to the stroke */
-	for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) {
-		/* convert screen-coordinates to appropriate coordinates (and store them) */
-		gp_stroke_convertcoords(p, &ptc->x, &pt->x);
-		
-		/* copy pressure */
-		pt->pressure= ptc->pressure;
-		
-		pt++;
+	if (GP_BUFFER2STROKE_ENDPOINTS) {
+		/* 'Draw Mode' + Ctrl-Modifier - only endpoints */
+		{
+			/* first point */
+			ptc= gpd->sbuffer;
+			
+			/* convert screen-coordinates to appropriate coordinates (and store them) */
+			gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+			
+			/* copy pressure */
+			pt->pressure= ptc->pressure;
+			
+			pt++;
+		}
+			
+		if (totelem == 2) {
+			/* last point if applicable */
+			ptc= ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1);
+			
+			/* convert screen-coordinates to appropriate coordinates (and store them) */
+			gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+			
+			/* copy pressure */
+			pt->pressure= ptc->pressure;
+		}
+	}
+	else {
+		/* convert all points (normal behaviour) */
+		for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) {
+			/* convert screen-coordinates to appropriate coordinates (and store them) */
+			gp_stroke_convertcoords(p, &ptc->x, &pt->x);
+			
+			/* copy pressure */
+			pt->pressure= ptc->pressure;
+			
+			pt++;
+		}
 	}
 	
 	/* add stroke to frame */
 	BLI_addtail(&p->gpf->strokes, gps);
+	
+	/* undefine macro to test if only converting endpoints  */	
+	#undef GP_BUFFER2STROKE_ENDPOINTS
 }
 
 /* --- 'Eraser' for 'Paint' Tool ------ */
-/* User should draw 'circles' around the parts of the sketches they wish to 
- * delete instead of drawing squiggles over existing lines. This should be 
- * easier to manage than if it was done otherwise.
- */
-
-/* convert gp-buffer stroke into mouse-coordinates array */
-static short (*gp_stroke_eraser_2mco (bGPdata *gpd))[2]
-{
-	tGPspoint *pt;
-	short (*mcoords)[2]; 
-	int i;
-	
-	/* allocate memory for coordinates array */
-	mcoords= MEM_mallocN(sizeof(*mcoords)*gpd->sbuffer_size,"gp_buf_mcords");
-	
-	/* copy coordinates */
-	for (pt=gpd->sbuffer, i=0; i < gpd->sbuffer_size; i++, pt++) {
-		mcoords[i][0]= pt->x;
-		mcoords[i][1]= pt->y;
-	}
-	
-	/* return */
-	return mcoords;
-}
 
 /* eraser tool - remove segment from stroke/split stroke (after lasso inside) */
 static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
@@ -1080,8 +1358,19 @@ static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
 	}
 }
 
+/* eraser tool - check if part of stroke occurs within last segment drawn by eraser */
+static short gp_stroke_eraser_strokeinside (short mval[], short mvalo[], short rad, short x0, short y0, short x1, short y1)
+{
+	/* simple within-radius check for now */
+	if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1))
+		return 1;
+	
+	/* not inside */
+	return 0;
+} 
+
 /* eraser tool - evaluation per stroke */
-static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
+static void gp_stroke_eraser_dostroke (tGPsdata *p, short mval[], short mvalo[], short rad, rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
 {
 	bGPDspoint *pt1, *pt2;
 	short x0=0, y0=0, x1=0, y1=0;
@@ -1097,10 +1386,9 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
 	else if (gps->totpoints == 1) {
 		/* get coordinates */
 		if (gps->flag & GP_STROKE_3DSPACE) {
-			// FIXME: this may not be the correct correction
 			project_short(&gps->points->x, xyval);
 			x0= xyval[0];
-			x1= xyval[1];
+			y0= xyval[1];
 		}
 		else if (gps->flag & GP_STROKE_2DSPACE) {			
 			ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval);
@@ -1115,7 +1403,7 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
 		/* do boundbox check first */
 		if (BLI_in_rcti(rect, x0, y0)) {
 			/* only check if point is inside */
-			if (lasso_inside(mcoords, moves, x0, y0)) {
+			if ( ((x0-mval[0])*(x0-mval[0]) + (y0-mval[1])*(y0-mval[1])) <= rad*rad ) {
 				/* free stroke */
 				MEM_freeN(gps->points);
 				BLI_freelinkN(&gpf->strokes, gps);
@@ -1133,10 +1421,13 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
 			
 			/* get coordinates */
 			if (gps->flag & GP_STROKE_3DSPACE) {
-				// FIXME: may not be correct correction
-				project_short(&gps->points->x, xyval);
+				project_short(&pt1->x, xyval);
 				x0= xyval[0];
-				x1= xyval[1];
+				y0= xyval[1];
+				
+				project_short(&pt2->x, xyval);
+				x1= xyval[0];
+				y1= xyval[1];
 			}
 			else if (gps->flag & GP_STROKE_2DSPACE) {
 				ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval);
@@ -1159,9 +1450,8 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
 				/* check if point segment of stroke had anything to do with
 				 * eraser region  (either within stroke painted, or on its lines)
 				 * 	- this assumes that linewidth is irrelevant
-				 *	- handled using the lasso-select checking code
 				 */
-				if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) {
+				if (gp_stroke_eraser_strokeinside(mval, mvalo, rad, x0, y0, x1, y1)) {
 					/* if function returns true, break this loop (as no more point to check) */
 					if (gp_stroke_eraser_splitdel(gpf, gps, i))
 						break;
@@ -1176,24 +1466,21 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
 /* erase strokes which fall under the eraser strokes */
 static void gp_stroke_doeraser (tGPsdata *p)
 {
-	bGPdata *gpd= p->gpd;
 	bGPDframe *gpf= p->gpf;
 	bGPDstroke *gps, *gpn;
-	short (*mcoords)[2];
 	rcti rect;
 	
-	/* get buffer-stroke coordinates as shorts array, and then get bounding box */
-	mcoords= gp_stroke_eraser_2mco(gpd);
-	lasso_select_boundbox(&rect, mcoords, gpd->sbuffer_size);
+	/* rect is rectangle of eraser */
+	rect.xmin= p->mval[0] - p->radius;
+	rect.ymin= p->mval[1] - p->radius;
+	rect.xmax= p->mval[0] + p->radius;
+	rect.ymax= p->mval[1] + p->radius;
 	
 	/* loop over strokes, checking segments for intersections */
 	for (gps= gpf->strokes.first; gps; gps= gpn) {
 		gpn= gps->next;
-		gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, &rect, gpf, gps);
+		gp_stroke_eraser_dostroke(p, p->mval, p->mvalo, p->radius, &rect, gpf, gps);
 	}
-	
-	/* free mcoords array */
-	MEM_freeN(mcoords);
 }
 
 /* ---------- 'Paint' Tool ------------ */
@@ -1247,6 +1534,12 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode)
 			case SPACE_SEQ:
 			{
 				/* for now, this is not applicable here... */
+				//p->gpd->sbuffer_sflag |= GP_STROKE_2DIMAGE;
+			}
+				break;
+			case SPACE_IMAGE:
+			{
+				p->gpd->sbuffer_sflag |= GP_STROKE_2DIMAGE;
 			}
 				break;
 		}
@@ -1257,11 +1550,7 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode)
 static void gp_paint_strokeend (tGPsdata *p)
 {
 	/* check if doing eraser or not */
-	if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) {
-		/* get rid of relevant sections of strokes */
-		gp_stroke_doeraser(p);
-	}
-	else {
+	if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) {
 		/* transfer stroke to frame */
 		gp_stroke_newfrombuffer(p);
 	}
@@ -1295,7 +1584,6 @@ static void gp_paint_cleanup (tGPsdata *p)
 short gpencil_paint (short mousebutton, short paintmode)
 {
 	tGPsdata p;
-	short prevmval[2], mval[2];
 	float opressure, pressure;
 	short ok = GP_STROKEADD_NORMAL;
 	
@@ -1315,31 +1603,51 @@ short gpencil_paint (short mousebutton, short paintmode)
 	setcursor_space(p.sa->spacetype, CURSOR_VPAINT);
 	
 	/* init drawing-device settings */
-	getmouseco_areawin(mval);
+	getmouseco_areawin(p.mval);
 	pressure = get_pressure();
 	
-	prevmval[0]= mval[0];
-	prevmval[1]= mval[1];
+	p.mvalo[0]= p.mval[0];
+	p.mvalo[1]= p.mval[1];
 	opressure= pressure;
 	
+	/* radius for eraser circle is thickness^2 */
+	p.radius= p.gpl->thickness * p.gpl->thickness;
+	
+	/* start drawing eraser-circle (if applicable) */
+	if (paintmode == GP_PAINTMODE_ERASER)
+		draw_sel_circle(p.mval, NULL, p.radius, p.radius, 0); // draws frontbuffer, but sets backbuf again
+	
 	/* only allow painting of single 'dots' if: 
 	 *	- pressure is not excessive (as it can be on some windows tablets)
 	 *	- draw-mode for active datablock is turned on
+	 * 	- not erasing
 	 */
-	if (!(pressure >= 0.99f) || (p.gpd->flag & GP_DATA_EDITPAINT)) { 
-		gp_stroke_addpoint(&p, mval, pressure);
+	if (paintmode != GP_PAINTMODE_ERASER) {
+		if (!(pressure >= 0.99f) || (p.gpd->flag & GP_DATA_EDITPAINT)) { 
+			gp_stroke_addpoint(&p, p.mval, pressure);
+		}
 	}
 	
 	/* paint loop */
 	do {
 		/* get current user input */
-		getmouseco_areawin(mval);
+		getmouseco_areawin(p.mval);
 		pressure = get_pressure();
 		
 		/* only add current point to buffer if mouse moved (otherwise wait until it does) */
-		if (gp_stroke_filtermval(&p, mval, prevmval)) {
+		if (paintmode == GP_PAINTMODE_ERASER) {
+			/* do 'live' erasing now */
+			gp_stroke_doeraser(&p);
+			
+			draw_sel_circle(p.mval, p.mvalo, p.radius, p.radius, 0);
+			force_draw(0);
+			
+			p.mvalo[0]= p.mval[0];
+			p.mvalo[1]= p.mval[1];
+		}
+		else if (gp_stroke_filtermval(&p, p.mval, p.mvalo)) {
 			/* try to add point */
-			ok= gp_stroke_addpoint(&p, mval, pressure);
+			ok= gp_stroke_addpoint(&p, p.mval, pressure);
 			
 			/* handle errors while adding point */
 			if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
@@ -1347,8 +1655,8 @@ short gpencil_paint (short mousebutton, short paintmode)
 				gp_paint_strokeend(&p);
 				
 				/* start a new stroke, starting from previous point */
-				gp_stroke_addpoint(&p, prevmval, opressure);
-				ok= gp_stroke_addpoint(&p, mval, pressure);
+				gp_stroke_addpoint(&p, p.mvalo, opressure);
+				ok= gp_stroke_addpoint(&p, p.mval, pressure);
 			}
 			else if (ok == GP_STROKEADD_INVALID) {
 				/* the painting operation cannot continue... */
@@ -1361,8 +1669,8 @@ short gpencil_paint (short mousebutton, short paintmode)
 			}
 			force_draw(0);
 			
-			prevmval[0]= mval[0];
-			prevmval[1]= mval[1];
+			p.mvalo[0]= p.mval[0];
+			p.mvalo[1]= p.mval[1];
 			opressure= pressure;
 		}
 		else
@@ -1380,8 +1688,10 @@ short gpencil_paint (short mousebutton, short paintmode)
 	setcursor_space(p.sa->spacetype, CURSOR_STD);
 	
 	/* check size of buffer before cleanup, to determine if anything happened here */
-	if (paintmode == GP_PAINTMODE_ERASER)
-		ok= (p.gpd->sbuffer_size > 1);
+	if (paintmode == GP_PAINTMODE_ERASER) {
+		ok= 1; // fixme
+		draw_sel_circle(NULL, p.mvalo, 0, p.radius, 0);
+	}
 	else
 		ok= p.gpd->sbuffer_size;
 	
@@ -1408,7 +1718,8 @@ short gpencil_do_paint (ScrArea *sa, short mbut)
 	
 	/* currently, we will only 'paint' if:
 	 * 	1. draw-mode on gpd is set (for accessibility reasons)
-	 *		(single 'dots' are only available via this method)
+	 *		a) single dots are only available by this method if a single click is made
+	 *		b) a straight line is drawn if ctrl-modifier is held (check is done when stroke is converted!)
 	 *	2. if shift-modifier is held + lmb -> 'quick paint'
 	 *
 	 *	OR
diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c
index a9280d9dd193cacffd3506bd4a5b4a0b87287d2d..8b8fd9ef26625d0c4d99a0a20bab075e6c1e7929 100644
--- a/source/blender/src/header_info.c
+++ b/source/blender/src/header_info.c
@@ -39,6 +39,8 @@
 #include <config.h>
 #endif
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #include "DNA_group_types.h"
 #include "DNA_ID.h"
 #include "DNA_image_types.h"
@@ -2106,7 +2108,7 @@ static void info_text(int x, int y)
 {
 	Object *ob= OBACT;
 	extern float hashvectf[];
-	extern unsigned long mem_in_use, mmap_in_use;
+	extern uintptr_t mem_in_use, mmap_in_use;
 	unsigned int swatch_color;
 	float fac1, fac2, fac3;
 	char infostr[300], memstr[64];
diff --git a/source/blender/src/header_script.c b/source/blender/src/header_script.c
index 3c96e1692bfcc3fec0af044e999577d01e96a2c5..53c4b9b59531a6134c5835be57e27e03268f08c9 100644
--- a/source/blender/src/header_script.c
+++ b/source/blender/src/header_script.c
@@ -63,12 +63,14 @@
 #include "blendef.h"
 #include "mydevice.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* ********************** SCRIPT ****************************** */
 
 /* action executed after clicking in Scripts menu */
 static void do_scripts_submenus(void *int_arg, int event)
 {
-	int menutype = (long)int_arg;
+	int menutype = (intptr_t)int_arg;
 
 	BPY_menu_do_python (menutype, event);
 
@@ -80,7 +82,7 @@ static uiBlock *script_scripts_submenus(void *int_menutype)
 	uiBlock *block;
 	short yco = 20, menuwidth = 120;
 	BPyMenu *pym;
-	int i = 0, menutype = (long)int_menutype;
+	int i = 0, menutype = (intptr_t)int_menutype;
 
 	if ((menutype < 0) || (menutype > PYMENU_SCRIPTS_MENU_TOTAL))
 		return NULL;
@@ -132,7 +134,7 @@ static uiBlock *script_scriptsmenu(void *arg_unused)
 	uiBlockSetButmFunc(block, do_script_scriptsmenu, NULL);
 
 	for (i = 0; i < PYMENU_SCRIPTS_MENU_TOTAL; i++) {
-		uiDefIconTextBlockBut(block, script_scripts_submenus, (void *)(long)i, ICON_RIGHTARROW_THIN, BPyMenu_group_itoa(i), 0, yco-=20, menuwidth, 19, "");
+		uiDefIconTextBlockBut(block, script_scripts_submenus, (void *)(intptr_t)i, ICON_RIGHTARROW_THIN, BPyMenu_group_itoa(i), 0, yco-=20, menuwidth, 19, "");
 	}
 
 	uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index fcf4caf45225c6490b104bbbe022afed40a2086a..e57a3480b524b20cae0ba39351fee9845900cb83 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -4370,6 +4370,9 @@ static void do_view3d_pose_armaturemenu(void *arg, int event)
 	case 18:
 		pose_autoside_names(event-16);
 		break;
+	case 19: /* assign pose as restpose */
+		apply_armature_pose2bones();
+		break;
 	}
 		
 	allqueue(REDRAWVIEW3D, 0);
@@ -4395,6 +4398,7 @@ static uiBlock *view3d_pose_armaturemenu(void *arg_unused)
 	uiDefBut(block, SEPR, 0, "",				0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
 	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Relax Pose|W",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Pose as Restpose|Ctrl A",		0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
 	
 	uiDefBut(block, SEPR, 0, "",				0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c
index e7b5b1769794c278f502bdd807c172baf47e7794..a2b2af05083b50232e2d74bc041e1d302dca5f1e 100644
--- a/source/blender/src/interface.c
+++ b/source/blender/src/interface.c
@@ -105,6 +105,8 @@
 #include "blendef.h"
 #include "winlay.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #define INSIDE_BLOCK		1
 #define INSIDE_PANEL_HEADER	2
 #define INSIDE_PANEL_SCALE	3
@@ -6039,7 +6041,7 @@ void autocomplete_end(AutoComplete *autocpl, char *autoname)
 /* autocomplete callback for ID buttons */
 static void autocomplete_id(char *str, void *arg_v)
 {
-	int blocktype= (long)arg_v;
+	int blocktype= (intptr_t)arg_v;
 	ListBase *listb= wich_libbase(G.main, blocktype);
 	
 	if(listb==NULL) return;
@@ -6370,7 +6372,7 @@ uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int
 	ui_check_but(but);
 	
 	if(blocktype)
-		uiButSetCompleteFunc(but, autocomplete_id, (void *)(long)blocktype);
+		uiButSetCompleteFunc(but, autocomplete_id, (void *)(intptr_t)blocktype);
 
 	return but;
 }
diff --git a/source/blender/src/meshlaplacian.c b/source/blender/src/meshlaplacian.c
index 60f569ecf0ea8ffa11c90be78db483718d164920..2de6367c9ada00600c70f4b6ad3955c2e30004aa 100644
--- a/source/blender/src/meshlaplacian.c
+++ b/source/blender/src/meshlaplacian.c
@@ -63,6 +63,8 @@
 
 #include "ONL_opennl.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /************************** Laplacian System *****************************/
 
 struct LaplacianSystem {
@@ -126,14 +128,14 @@ static void laplacian_increase_edge_count(EdgeHash *edgehash, int v1, int v2)
 	void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
 
 	if(p)
-		*p = (void*)((long)*p + (long)1);
+		*p = (void*)((intptr_t)*p + (intptr_t)1);
 	else
-		BLI_edgehash_insert(edgehash, v1, v2, (void*)(long)1);
+		BLI_edgehash_insert(edgehash, v1, v2, (void*)(intptr_t)1);
 }
 
 static int laplacian_edge_count(EdgeHash *edgehash, int v1, int v2)
 {
-	return (int)(long)BLI_edgehash_lookup(edgehash, v1, v2);
+	return (int)(intptr_t)BLI_edgehash_lookup(edgehash, v1, v2);
 }
 
 static float cotan_weight(float *v1, float *v2, float *v3)
diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c
index 0f30aef04dfc04b047672aa3240c3e89140a6872..99833625baa7db8cd45714cba7b820546de9a380 100644
--- a/source/blender/src/meshtools.c
+++ b/source/blender/src/meshtools.c
@@ -107,6 +107,8 @@ void sort_faces(void);
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* from rendercode.c */
 #define VECMUL(dest, f)                  dest[0]*= f; dest[1]*= f; dest[2]*= f
 
@@ -592,7 +594,7 @@ void sort_faces(void)
 
 typedef struct MocNode {
 	struct MocNode *next;
-	long index[MOC_NODE_RES];
+	intptr_t index[MOC_NODE_RES];
 } MocNode;
 
 static int mesh_octree_get_base_offs(float *co, float *offs, float *div)
@@ -610,7 +612,7 @@ static int mesh_octree_get_base_offs(float *co, float *offs, float *div)
 	return (vx*MOC_RES*MOC_RES) + vy*MOC_RES + vz;
 }
 
-static void mesh_octree_add_node(MocNode **bt, long index)
+static void mesh_octree_add_node(MocNode **bt, intptr_t index)
 {
 	if(*bt==NULL) {
 		*bt= MEM_callocN(sizeof(MocNode), "MocNode");
@@ -642,7 +644,7 @@ static void mesh_octree_free_node(MocNode **bt)
 /* temporal define, just to make nicer code below */
 #define MOC_ADDNODE(vx, vy, vz)	mesh_octree_add_node(basetable + ((vx)*MOC_RES*MOC_RES) + (vy)*MOC_RES + (vz), index)
 
-static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, long index)
+static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, intptr_t index)
 {
 	float fx, fy, fz;
 	int vx, vy, vz;
@@ -690,7 +692,7 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f
 	
 }
 
-static long mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mvert, float *co)
+static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mvert, float *co)
 {
 	float *vec;
 	int a;
@@ -734,7 +736,7 @@ static struct {
 
 /* mode is 's' start, or 'e' end, or 'u' use */
 /* if end, ob can be NULL */
-long mesh_octree_table(Object *ob, float *co, char mode)
+intptr_t mesh_octree_table(Object *ob, float *co, char mode)
 {
 	MocNode **bt;
 	
@@ -805,7 +807,7 @@ long mesh_octree_table(Object *ob, float *co, char mode)
 			EditVert *eve;
 
 			for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
-				mesh_octree_add_nodes(MeshOctree.table, eve->co, MeshOctree.offs, MeshOctree.div, (long)(eve));
+				mesh_octree_add_nodes(MeshOctree.table, eve->co, MeshOctree.offs, MeshOctree.div, (intptr_t)(eve));
 			}
 		}
 		else {		
@@ -863,7 +865,7 @@ int mesh_get_x_mirror_vert(Object *ob, int index)
 EditVert *editmesh_get_x_mirror_vert(Object *ob, float *co)
 {
 	float vec[3];
-	long poinval;
+	intptr_t poinval;
 	
 	/* ignore nan verts */
 	if (isnan(co[0]) || !finite(co[0]) ||
diff --git a/source/blender/src/parametrizer.c b/source/blender/src/parametrizer.c
index 096629b01ec4fb7ea195b795d9525efff63cf999..7aa27f99d777e2a160b8c2552db063aded14b121 100644
--- a/source/blender/src/parametrizer.c
+++ b/source/blender/src/parametrizer.c
@@ -22,6 +22,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #if defined(_WIN32)
 #define M_PI 3.14159265358979323846
 #endif
@@ -38,7 +40,7 @@ static int PHashSizes[] = {
 	4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459
 };
 
-#define PHASH_hash(ph, item) (((unsigned long) (item))%((unsigned int) (ph)->cursize))
+#define PHASH_hash(ph, item) (((uintptr_t) (item))%((unsigned int) (ph)->cursize))
 #define PHASH_edge(v1, v2)	 ((v1)^(v2))
 
 static PHash *phash_new(PHashLink **list, int sizehint)
diff --git a/source/blender/src/parametrizer.h b/source/blender/src/parametrizer.h
index 80fab110d5fd1747270949deffc5a9cc02e8f789..c468b8d62c557511db5c53e1bcb6416959be562a 100644
--- a/source/blender/src/parametrizer.h
+++ b/source/blender/src/parametrizer.h
@@ -5,9 +5,11 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+	
+#include "BLO_sys_types.h" // for intptr_t support
 
 typedef void ParamHandle;	/* handle to a set of charts */
-typedef long ParamKey;		/* (hash) key for identifying verts and faces */
+typedef intptr_t ParamKey;		/* (hash) key for identifying verts and faces */
 typedef enum ParamBool {
 	PARAM_TRUE = 1,
 	PARAM_FALSE = 0
diff --git a/source/blender/src/parametrizer_intern.h b/source/blender/src/parametrizer_intern.h
index f7a32816b332125fec84471aad34399441eab20f..bc38cb4bc0fabcc47e4f10de21d1c250f2c9e467 100644
--- a/source/blender/src/parametrizer_intern.h
+++ b/source/blender/src/parametrizer_intern.h
@@ -30,7 +30,7 @@ typedef enum PBool {
 
 /* Special Purpose Hash */
 
-typedef long PHashKey;
+typedef intptr_t PHashKey;
 
 typedef struct PHashLink {
 	struct PHashLink *next;
diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c
index 6c150f3d30f237dd67e19644934aa34409a5ca05..88f5f6efe1537694805be2980c3b6faeb44a98ee 100644
--- a/source/blender/src/renderwin.c
+++ b/source/blender/src/renderwin.c
@@ -50,6 +50,8 @@
 
 #endif
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #include <limits.h>
 
 #include "BLI_blenlib.h"
@@ -901,7 +903,7 @@ static void renderwin_progress_display_cb(RenderResult *rr, volatile rcti *rect)
 void make_renderinfo_string(RenderStats *rs, char *str)
 {
 	extern char info_time_str[32];	// header_info.c
-	extern unsigned long mem_in_use, mmap_in_use;
+	extern uintptr_t mem_in_use, mmap_in_use;
 	float megs_used_memory, mmap_used_memory;
 	char *spos= str;
 	
diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c
index f47f14a605cb32c300699b4a900d95bdff9bfeaf..acd14aae7a58daacf758ccfd8a75b15af96d818f 100644
--- a/source/blender/src/resources.c
+++ b/source/blender/src/resources.c
@@ -313,7 +313,15 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
 				cp= ts->transition; break;
 			case TH_SEQ_META:
 				cp= ts->meta; break;
-				
+			case TH_HANDLE_VERTEX:
+				cp= ts->handle_vertex;
+				break;
+			case TH_HANDLE_VERTEX_SELECT:
+				cp= ts->handle_vertex_select;
+				break;
+			case TH_HANDLE_VERTEX_SIZE:
+				cp= &ts->handle_vertex_size;
+				break;
 			}
 
 		}
@@ -493,6 +501,10 @@ void BIF_InitTheme(void)
 	SETCOL(btheme->tipo.hilite, 0x60, 0xc0, 0x40, 255); 
 	btheme->tipo.vertex_size= 3;
 
+	SETCOL(btheme->tipo.handle_vertex, 0xff, 0x70, 0xff, 255);
+	SETCOL(btheme->tipo.handle_vertex_select, 0xff, 0xff, 0x70, 255);
+	btheme->tipo.handle_vertex_size= 3;
+
 	/* space file */
 	/* to have something initialized */
 	btheme->tfile= btheme->tv3d;
@@ -684,7 +696,10 @@ char *BIF_ThemeColorsPup(int spacetype)
 			str += sprintf(str, "Vertex %%x%d|", TH_VERTEX);
 			str += sprintf(str, "Vertex Selected %%x%d|", TH_VERTEX_SELECT);
 			str += sprintf(str, "Vertex Size %%x%d|", TH_VERTEX_SIZE);
-			str += sprintf(str, "Current Frame %%x%d", TH_CFRAME);
+			str += sprintf(str, "Current Frame %%x%d|", TH_CFRAME);
+			str += sprintf(str, "Handle Vertex %%x%d|", TH_HANDLE_VERTEX);
+			str += sprintf(str, "Handle Vertex Selected %%x%d|", TH_HANDLE_VERTEX_SELECT);
+			str += sprintf(str, "Handle Vertex Size %%x%d", TH_HANDLE_VERTEX_SIZE);
 			break;
 		case SPACE_FILE:
 			str += sprintf(str, "Selected file %%x%d", TH_HILITE);
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 79fdb31230968a126c9a552736a5b0724b54233e..81b0efeef0d2d282b9967dadf2d8886a857366cf 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -182,6 +182,8 @@
 
 #include "SYS_System.h" /* for the user def menu ... should move elsewhere. */
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* maybe we need this defined somewhere else */
 extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);
 extern void StartKetsjiShellSimulation(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);/*rcruiz*/
@@ -460,7 +462,7 @@ static LinkNode *save_and_reset_all_scene_cfra(void)
 	Scene *sc;
 	
 	for (sc= G.main->scene.first; sc; sc= sc->id.next) {
-		BLI_linklist_prepend(&storelist, (void*) (long) sc->r.cfra);
+		BLI_linklist_prepend(&storelist, (void*) (intptr_t) sc->r.cfra);
 
 		/* why is this reset to 1 ?*/
 		/* sc->r.cfra= 1;*/
@@ -478,7 +480,7 @@ static void restore_all_scene_cfra(LinkNode *storelist) {
 	Scene *sc;
 	
 	for (sc= G.main->scene.first; sc; sc= sc->id.next) {
-		int stored_cfra= (long) sc_store->link;
+		int stored_cfra= (intptr_t) sc_store->link;
 		
 		sc->r.cfra= stored_cfra;
 		set_scene_bg(sc);
@@ -1904,6 +1906,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
 					else
 						copy_attr_menu();
 				}
+				else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) 
+					gpencil_convert_menu(); /* gpencil.c */
 				else if(G.qual==LR_ALTKEY) {
 					if(ob && (ob->flag & OB_POSEMODE))
 						pose_clear_constraints();	/* poseobject.c */
@@ -1962,7 +1966,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
 						G.vd->drawtype= pupval;
 						doredraw= 1;
 					}
-                                }
+                }
 				
 				break;
 			case EKEY:
@@ -3490,6 +3494,9 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3, sh
 		uiButSetFunc(but, set_userdef_iconfile_cb, &iconfileindex, NULL);
 									
 	}
+	else if(th_curcol==TH_HANDLE_VERTEX_SIZE) {
+		uiDefButC(block, NUMSLI, B_UPDATE_THEME,"Handle size ", 465,y3,200,20, col, 1.0, 10.0, 0, 0, "");
+	}
 	else {
 		uiBlockBeginAlign(block);
 		if ELEM9(th_curcol, TH_PANEL, TH_LAMP, TH_FACE, TH_FACE_SELECT, TH_EDITMESH_ACTIVE, TH_MENU_BACK, TH_MENU_HILITE, TH_MENU_ITEM, TH_NODE) {
diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c
index cd71e7fd8e6fdc633f0eb2f633731ca2c1545f9e..5b2120424f155399e923ad0795aee987fd1bc8a4 100644
--- a/source/blender/src/toolbox.c
+++ b/source/blender/src/toolbox.c
@@ -123,6 +123,8 @@
 #include "BPY_extern.h"
 #include "BPY_menus.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 void asciitoraw(int ch, unsigned short *event, unsigned short *qual)
 {
 	if( isupper(ch) ) {
@@ -238,7 +240,7 @@ void error_libdata(void)
 
 int saveover(char *file)
 {
-	int len= strlen(file);
+	size_t len= strlen(file);
 	
 	if(len==0) 
 		return 0;
@@ -1756,8 +1758,8 @@ static uiBlock *tb_makemenu(void *arg)
 static int tb_mainx= 1234, tb_mainy= 0;
 static void store_main(void *arg1, void *arg2)
 {
-	tb_mainx= (long)arg1;
-	tb_mainy= (long)arg2;
+	tb_mainx= (intptr_t)arg1;
+	tb_mainy= (intptr_t)arg2;
 }
 
 static void do_group_addmenu(void *arg, int event)
@@ -2185,27 +2187,27 @@ void toolbox_n(void)
 	
 		but=uiDefBlockBut(block, tb_makemenu, menu1, str1,	mval[0]-(1.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
 		uiButSetFlag(but, UI_MAKE_TOP|UI_MAKE_RIGHT);
-		uiButSetFunc(but, store_main, (void *)(long)dx, (void *)(long)-5);
+		uiButSetFunc(but, store_main, (void *)(intptr_t)dx, (void *)(intptr_t)-5);
 
 		but=uiDefBlockBut(block, tb_makemenu, menu2, str2,	mval[0]-(0.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
 		uiButSetFlag(but, UI_MAKE_TOP);
-		uiButSetFunc(but, store_main, (void *)(long)0, (void *)(long)-5);
+		uiButSetFunc(but, store_main, (void *)(intptr_t)0, (void *)(intptr_t)-5);
 
 		but=uiDefBlockBut(block, tb_makemenu, menu3, str3,	mval[0]+(0.5*dx)+tb_mainx,mval[1]+tb_mainy, dx, 19, "");
 		uiButSetFlag(but, UI_MAKE_TOP|UI_MAKE_LEFT);
-		uiButSetFunc(but, store_main, (void *)(long)-dx, (void *)(long)-5);
+		uiButSetFunc(but, store_main, (void *)(intptr_t)-dx, (void *)(intptr_t)-5);
 
 		but=uiDefBlockBut(block, tb_makemenu, menu4, str4,	mval[0]-(1.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
 		uiButSetFlag(but, UI_MAKE_DOWN|UI_MAKE_RIGHT);
-		uiButSetFunc(but, store_main, (void *)(long)dx, (void *)(long)5);
+		uiButSetFunc(but, store_main, (void *)(intptr_t)dx, (void *)(intptr_t)5);
 
 		but=uiDefBlockBut(block, tb_makemenu, menu5, str5,	mval[0]-(0.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
 		uiButSetFlag(but, UI_MAKE_DOWN);
-		uiButSetFunc(but, store_main, (void *)(long)0, (void *)(long)5);
+		uiButSetFunc(but, store_main, (void *)(intptr_t)0, (void *)(intptr_t)5);
 
 		but=uiDefBlockBut(block, tb_makemenu, menu6, str6,	mval[0]+(0.5*dx)+tb_mainx,mval[1]+tb_mainy-20, dx, 19, "");
 		uiButSetFlag(but, UI_MAKE_DOWN|UI_MAKE_LEFT);
-		uiButSetFunc(but, store_main, (void *)(long)-dx, (void *)(long)5);
+		uiButSetFunc(but, store_main, (void *)(intptr_t)-dx, (void *)(intptr_t)5);
 	} else if (tot==5 || tot==7) {
                 /* check if it fits, dubious */
 		if(mval[0]-0.25*dx+tb_mainx < 6) mval[0]= 6 + 0.25*dx -tb_mainx;
@@ -2282,7 +2284,7 @@ void toolbox_generic( TBitem *generic_menu )
 	TBitem *menu;
 	int dx=96, first=1, len;
 	short event, mval[2];
-	long ypos = -5;
+	intptr_t ypos = -5;
 	
 	tb_mainx= -32;
 	tb_mainy= -5;
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 9f2f58d0cdbcbe25f394c6f5d6b00cbeeaa4a631..efb86b59ed14e98d1022f1545b873d15d1034ae3 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -144,6 +144,8 @@ extern ListBase editelems;
 
 #include "transform.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 /* local function prototype - for Object/Bone Constraints */
 static short constraints_list_needinv(TransInfo *t, ListBase *list);
 /* local function prototype - for finding number of keyframes that are selected for editing */
@@ -1913,7 +1915,7 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
 	EditVert *eve, *prev;
 	EditFace *efa;
 	float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
-	long index= 0;
+	intptr_t index= 0;
 	
 	/* two abused locations in vertices */
 	for(eve= em->verts.first; eve; eve= eve->next, index++) {
@@ -1925,13 +1927,13 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
 	for(efa= em->faces.first; efa; efa= efa->next) {
 		
 		/* retrieve mapped coordinates */
-		v1= mappedcos + 3*(long)(efa->v1->prev);
-		v2= mappedcos + 3*(long)(efa->v2->prev);
-		v3= mappedcos + 3*(long)(efa->v3->prev);
+		v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
+		v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
+		v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
 
-		co1= (origcos)? origcos + 3*(long)(efa->v1->prev): efa->v1->co;
-		co2= (origcos)? origcos + 3*(long)(efa->v2->prev): efa->v2->co;
-		co3= (origcos)? origcos + 3*(long)(efa->v3->prev): efa->v3->co;
+		co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
+		co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
+		co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
 
 		if(efa->v2->tmp.p==NULL && efa->v2->f1) {
 			set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
@@ -1940,8 +1942,8 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
 		}
 		
 		if(efa->v4) {
-			v4= mappedcos + 3*(long)(efa->v4->prev);
-			co4= (origcos)? origcos + 3*(long)(efa->v4->prev): efa->v4->co;
+			v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
+			co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
 
 			if(efa->v1->tmp.p==NULL && efa->v1->f1) {
 				set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index c332fd723ebd7b499d66b00fbaecd81d9e2c8f30..a1440b8cbce2a2395eae9e593c87ee9dde00b885 100644
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -32,6 +32,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_constraint_types.h"
@@ -581,39 +583,6 @@ void recalcData(TransInfo *t)
 		reshadeall_displist();
 }
 
-void initTransModeFlags(TransInfo *t, int mode) 
-{
-	t->mode = mode;
-	t->num.flag = 0;
-
-	/* REMOVING RESTRICTIONS FLAGS */
-	t->flag &= ~T_ALL_RESTRICTIONS;
-	
-	switch (mode) {
-	case TFM_RESIZE:
-		t->flag |= T_NULL_ONE;
-		t->num.flag |= NUM_NULL_ONE;
-		t->num.flag |= NUM_AFFECT_ALL;
-		if (!G.obedit) {
-			t->flag |= T_NO_ZERO;
-			t->num.flag |= NUM_NO_ZERO;
-		}
-		break;
-	case TFM_TOSPHERE:
-		t->num.flag |= NUM_NULL_ONE;
-		t->num.flag |= NUM_NO_NEGATIVE;
-		t->flag |= T_NO_CONSTRAINT;
-		break;
-	case TFM_SHEAR:
-	case TFM_CREASE:
-	case TFM_BONE_ENVELOPE:
-	case TFM_CURVE_SHRINKFATTEN:
-	case TFM_BONE_ROLL:
-		t->flag |= T_NO_CONSTRAINT;
-		break;
-	}
-}
-
 void drawLine(float *center, float *dir, char axis, short options)
 {
 	extern void make_axis_color(char *col, char *col2, char axis);	// drawview.c
@@ -672,19 +641,10 @@ void initTrans (TransInfo *t)
 	t->transform		= NULL;
 	t->handleEvent		= NULL;
 
-	t->total			=
-		t->num.idx		=
-		t->num.idx_max	=
-		t->num.ctrl[0]	= 
-		t->num.ctrl[1]	= 
-		t->num.ctrl[2]	= 0;
+	t->total			= 0;
 
 	t->val = 0.0f;
 
-	t->num.val[0]		= 
-		t->num.val[1]	= 
-		t->num.val[2]	= 0.0f;
-
 	t->vec[0]			=
 		t->vec[1]		=
 		t->vec[2]		= 0.0f;
@@ -706,7 +666,8 @@ void initTrans (TransInfo *t)
 		t->around = V3D_CENTER;
 
 	setTransformViewMatrices(t);
-	initNDofInput(&(t->ndof));
+	initNumInput(&t->num);
+	initNDofInput(&t->ndof);
 }
 
 /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
diff --git a/source/blender/src/transform_numinput.c b/source/blender/src/transform_numinput.c
index 9b811595a9add4b6926a3f547fd32ba5b9112926..89a76c097e0eadbc1999c62241cda88d5cf703bd 100644
--- a/source/blender/src/transform_numinput.c
+++ b/source/blender/src/transform_numinput.c
@@ -41,6 +41,20 @@
 
 /* ************************** NUMINPUT **************************** */
 
+void initNumInput(NumInput *n)
+{
+	n->flag		=
+	n->idx		=
+	n->idx_max	=
+	n->ctrl[0]	= 
+	n->ctrl[1]	= 
+	n->ctrl[2]	= 0;
+
+	n->val[0]		= 
+	n->val[1]	= 
+	n->val[2]	= 0.0f;
+}
+
 void outputNumInput(NumInput *n, char *str)
 {
 	char cur;
diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c
index 36d982458271c0a885d53fd1d34a91ef0841793c..e757f634a459b124c6117a516bc893c226764156 100644
--- a/source/blender/src/usiblender.c
+++ b/source/blender/src/usiblender.c
@@ -479,7 +479,15 @@ static void init_userdef_file(void)
 	if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 16)) {
 		U.flag |= USER_ADD_VIEWALIGNED|USER_ADD_EDITMODE;
 	}
-	
+	if ((G.main->versionfile < 247) || (G.main->versionfile == 247 && G.main->subversionfile < 1)) {
+		bTheme *btheme;
+		for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+			SETCOL(btheme->tipo.handle_vertex, 0xff, 0x70, 0xff, 255);
+			SETCOL(btheme->tipo.handle_vertex_select, 0xff, 0xff, 0x70, 255);
+			btheme->tipo.handle_vertex_size= 3;
+		}
+	}
+
 	/* GL Texture Garbage Collection (variable abused above!) */
 	if (U.textimeout == 0) {
 		U.texcollectrate = 60;
diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp
index 6ae4a31bf505a12587a5f0c2b60301b3d9718bbe..77d53c4ed9602268e4951d36f98ef500d4ba021f 100644
--- a/source/blender/yafray/intern/export_Plugin.cpp
+++ b/source/blender/yafray/intern/export_Plugin.cpp
@@ -74,7 +74,7 @@ extern "C" { extern char bprogname[]; }
 // add drive character if not in path string, using blender executable location as reference
 static void addDrive(string &path)
 {
-	int sp = path.find_first_of(":");
+	size_t sp = path.find_first_of(":");
 	if (sp==-1) {
 		string blpath = bprogname;
 		sp = blpath.find_first_of(":");
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 7de3056e382ff16a8d328bdc8f08818ac3f5520d..16f8ae0095ad6f4abbf73740be8e8908a99797ed 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -90,33 +90,10 @@ void update_for_newframe();
 
 static BlendFileData *load_game_data(char *filename) {
 	BlendReadError error;
-	//this doesn't work anymore for relative paths, so use BLO_read_from_memory instead
-	//BlendFileData *bfd= BLO_read_from_file(filename, &error);
-	FILE* file = fopen(filename,"rb");
-	BlendFileData *bfd  = 0;
-	if (file)
-	{
-		fseek(file, 0L, SEEK_END);
-		int len= ftell(file);
-		fseek(file, 0L, SEEK_SET);	
-		char* filebuffer= new char[len];//MEM_mallocN(len, "text_buffer");
-		int sizeread = fread(filebuffer,len,1,file);
-		if (sizeread==1){
-			bfd = BLO_read_from_memory(filebuffer, len, &error);
-		} else {
-			error = BRE_UNABLE_TO_READ;
-		}
-		fclose(file);
-		// the memory is not released in BLO_read_from_memory, must do it here
-		delete filebuffer;
-	} else {
-		error = BRE_UNABLE_TO_OPEN;
-	}
-
+	BlendFileData *bfd= BLO_read_from_file(filename, &error);
 	if (!bfd) {
 		printf("Loading %s failed: %s\n", filename, BLO_bre_as_string(error));
 	}
-	
 	return bfd;
 }
 
@@ -139,7 +116,9 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
 	// Acquire Python's GIL (global interpreter lock)
 	// so we can safely run Python code and API calls
 	PyGILState_STATE gilstate = PyGILState_Ensure();
-
+	
+	PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
+	
 	bgl::InitExtensions(true);
 
 	do
@@ -333,6 +312,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
 			initRasterizer(rasterizer, canvas);
 			PyObject *gameLogic = initGameLogic(startscene);
 			PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module.
+			PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
 			initGameKeys();
 			initPythonConstraintBinding();
 			initMathutils();
@@ -407,6 +387,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
 				// which allows the scene to safely delete them :)
 				// see: (space.c)->start_game
 				PyDict_Clear(PyModule_GetDict(gameLogic));
+				PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict);
 				
 				ketsjiengine->StopEngine();
 				exitGamePythonScripting();
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index e4eff163d5b61f8dd50c4b8488024ba2fd03691b..dafc259985030e55fe13b760ad42e80dfd3fd5ac 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -131,11 +131,11 @@ void KX_BlenderRenderTools::SetClientObject(void* obj)
 	}
 }
 
-bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+bool KX_BlenderRenderTools::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
 {
 	double* const oglmatrix = (double* const) data;
-	MT_Point3 resultpoint(hit_point);
-	MT_Vector3 resultnormal(hit_normal);
+	MT_Point3 resultpoint(result->m_hitPoint);
+	MT_Vector3 resultnormal(result->m_hitNormal);
 	MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
 	MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized();
 	left = (dir.cross(resultnormal)).safe_normalized();
@@ -236,9 +236,8 @@ void KX_BlenderRenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmat
 			if (parent)
 				parent->Release();
 				
-			MT_Point3 resultpoint;
-			MT_Vector3 resultnormal;
-			if (!KX_RayCast::RayTest(physics_controller, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback<KX_BlenderRenderTools>(this, oglmatrix)))
+			KX_RayCast::Callback<KX_BlenderRenderTools> callback(this, physics_controller, oglmatrix);
+			if (!KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback))
 			{
 				// couldn't find something to cast the shadow on...
 				glMultMatrixd(oglmatrix);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
index 8abce1b8c3ec36117fe43910371760a69c9470e0..8027136aa52e7ab81cdb682b5615c95f42bfe0e4 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -37,6 +37,7 @@
 #include "RAS_IRenderTools.h"
 
 struct KX_ClientObjectInfo;
+class KX_RayCast;
 
 /**
 BlenderRenderTools are a set of tools to apply 2D/3D graphics effects, which are not
@@ -97,7 +98,8 @@ public:
 									void* clientobject,
 									void* tface);
 	
-	bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+	bool RayHit(KX_ClientObjectInfo* client, class KX_RayCast* result, void * const data);
+	bool NeedRayCast(KX_ClientObjectInfo*) { return true; }
 
 	virtual void MotionBlur(RAS_IRasterizer* rasterizer);
 
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index a6337403cd1d69baaf164352e318ce9f417c2992..edc14dabc70c9d0bb16c3f7be1bb5d0fcb4f2472 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1946,10 +1946,22 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
 				//parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
 
 				// Extract the rotation and the scaling from the basis
-				MT_Matrix3x3 inverseOrientation(parinvtrans.getRotation());
-				parentinversenode->SetLocalOrientation(inverseOrientation);
-				MT_Matrix3x3 scale(inverseOrientation.transposed()*parinvtrans.getBasis());
-				parentinversenode->SetLocalScale(MT_Vector3(scale[0][0], scale[1][1], scale[2][2]));
+				MT_Matrix3x3 ori(parinvtrans.getBasis());
+				MT_Vector3 x(ori.getColumn(0));
+				MT_Vector3 y(ori.getColumn(1));
+				MT_Vector3 z(ori.getColumn(2));
+				MT_Vector3 scale(x.length(), y.length(), z.length());
+				if (!MT_fuzzyZero(scale[0]))
+					x /= scale[0];
+				if (!MT_fuzzyZero(scale[1]))
+					y /= scale[1];
+				if (!MT_fuzzyZero(scale[2]))
+					z /= scale[2];
+				ori.setColumn(0, x);								
+				ori.setColumn(1, y);								
+				ori.setColumn(2, z);								
+				parentinversenode->SetLocalOrientation(ori);
+				parentinversenode->SetLocalScale(scale);
 				
 				parentinversenode->AddChild(gameobj->GetSGNode());
 			}
@@ -2129,7 +2141,24 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
 								float* fl = (float*) blenderobject->parentinv;
 								MT_Transform parinvtrans(fl);
 								parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
-								parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
+
+								// Extract the rotation and the scaling from the basis
+								MT_Matrix3x3 ori(parinvtrans.getBasis());
+								MT_Vector3 x(ori.getColumn(0));
+								MT_Vector3 y(ori.getColumn(1));
+								MT_Vector3 z(ori.getColumn(2));
+								MT_Vector3 scale(x.length(), y.length(), z.length());
+								if (!MT_fuzzyZero(scale[0]))
+									x /= scale[0];
+								if (!MT_fuzzyZero(scale[1]))
+									y /= scale[1];
+								if (!MT_fuzzyZero(scale[2]))
+									z /= scale[2];
+								ori.setColumn(0, x);								
+								ori.setColumn(1, y);								
+								ori.setColumn(2, z);								
+								parentinversenode->SetLocalOrientation(ori);
+								parentinversenode->SetLocalScale(scale);
 								
 								parentinversenode->AddChild(gameobj->GetSGNode());
 							}
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index cb2521de9a4301950f2d76319c2ef4378a5df62f..7e976beaf441cdd79699b5889e48577a3659d922 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -355,22 +355,26 @@ void BL_ConvertActuators(char* maggiename,
 				
 				if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF) 
 				{
-					SND_SoundObject* sndobj = NULL;
+					SND_Scene* soundscene = scene->GetSoundScene();
+					STR_String samplename = "";
+					bool sampleisloaded = false;
 					
-					if (soundact->sound)
-					{
-						SND_Scene* soundscene = scene->GetSoundScene();
-						STR_String samplename = soundact->sound->name;
+					if (soundact->sound) {
+						/* Need to convert the samplename into absolute path
+						 * before checking if its loaded */
+						char fullpath[sizeof(soundact->sound->name)];
 						
-						bool sampleisloaded = false;
+						/* dont modify soundact->sound->name, only change a copy */
+						BLI_strncpy(fullpath, soundact->sound->name, sizeof(fullpath));
+						BLI_convertstringcode(fullpath, maggiename);
+						samplename = fullpath;
 						
 						/* let's see if the sample was already loaded */
 						if (soundscene->IsSampleLoaded(samplename))
 						{
 							sampleisloaded = true;
 						}
-						else
-						{
+						else {
 							/* if not, make it so */
 							PackedFile* pf = soundact->sound->newpackedfile;
 							
@@ -383,21 +387,33 @@ void BL_ConvertActuators(char* maggiename,
 							/* or else load it from disk */
 							else
 							{
-								/* but we need to convert the samplename into absolute pathname first */
-								BLI_convertstringcode(soundact->sound->name, maggiename);
-								samplename = soundact->sound->name;
-								
-								/* and now we can load it */
-								if (soundscene->LoadSample(samplename, NULL, 0) > -1)
+								if (soundscene->LoadSample(samplename, NULL, 0) > -1) {
 									sampleisloaded = true;
+								}
+								else {
+									std::cout <<	"WARNING: Sound actuator \"" << bact->name <<
+													"\" from object \"" <<  blenderobject->id.name+2 <<
+													"\" failed to load sample." << std::endl;
+								}
 							}
 						}
-						
-						if (sampleisloaded)
-						{
-							sndobj = new SND_SoundObject();
-							sndobj->SetSampleName(samplename.Ptr());
-							sndobj->SetObjectName(bact->name);
+					} else {
+						std::cout <<	"WARNING: Sound actuator \"" << bact->name <<
+										"\" from object \"" <<  blenderobject->id.name+2 <<
+										"\" has no sound datablock." << std::endl;
+					}
+					
+					/* Note, allowing actuators for sounds that are not there was added since 2.47
+					 * This is because python may expect the actuator and raise an exception if it dosnt find it
+					 * better just to add a dummy sound actuator. */
+					SND_SoundObject* sndobj = NULL;
+					if (sampleisloaded)
+					{
+						/* setup the SND_SoundObject */
+						sndobj = new SND_SoundObject();
+						sndobj->SetSampleName(samplename.Ptr());
+						sndobj->SetObjectName(bact->name);
+						if (soundact->sound) {
 							sndobj->SetRollOffFactor(soundact->sound->attenuation);
 							sndobj->SetGain(soundact->sound->volume);
 							sndobj->SetPitch(exp((soundact->sound->pitch / 12.0) * log(2.0)));
@@ -410,8 +426,9 @@ void BL_ConvertActuators(char* maggiename,
 								else
 									sndobj->SetLoopMode(SND_LOOP_NORMAL);
 							}
-							else
+							else {
 								sndobj->SetLoopMode(SND_LOOP_OFF);
+							}
 							
 							if (soundact->sound->flags & SOUND_FLAGS_PRIORITY)
 								sndobj->SetHighPriority(true);
@@ -422,22 +439,30 @@ void BL_ConvertActuators(char* maggiename,
 								sndobj->Set3D(true);
 							else
 								sndobj->Set3D(false);
-							
-							KX_SoundActuator* tmpsoundact = 
-								new KX_SoundActuator(gameobj, 
-								sndobj,
-								scene->GetSoundScene(), // needed for replication!
-								soundActuatorType,
-								startFrame,
-								stopFrame);
-							
-							tmpsoundact->SetName(bact->name);
-							baseact = tmpsoundact;
-							soundscene->AddObject(sndobj);
-						} else {
-							std::cout << "WARNING: Sound actuator " << bact->name << " failed to load sample." << std::endl;
+						}
+						else {
+							/* dummy values for a NULL sound
+							* see editsound.c - defaults are unlikely to change soon */
+							sndobj->SetRollOffFactor(1.0);
+							sndobj->SetGain(1.0);
+							sndobj->SetPitch(1.0);
+							sndobj->SetLoopMode(SND_LOOP_OFF);
+							sndobj->SetHighPriority(false);
+							sndobj->Set3D(false);
 						}
 					}
+					KX_SoundActuator* tmpsoundact = 
+						new KX_SoundActuator(gameobj, 
+						sndobj,
+						scene->GetSoundScene(), // needed for replication!
+						soundActuatorType,
+						startFrame,
+						stopFrame);
+					
+					tmpsoundact->SetName(bact->name);
+					baseact = tmpsoundact;
+					if (sndobj)
+						soundscene->AddObject(sndobj);
 				}
 				break;
 			}
@@ -550,10 +575,16 @@ void BL_ConvertActuators(char* maggiename,
 								originalval = converter->FindGameObject(editobact->ob);
 							}
 						}
-						MT_Vector3 linvelvec ( KX_BLENDERTRUNC(editobact->linVelocity[0]),
+						MT_Vector3 linvelvec (
+							KX_BLENDERTRUNC(editobact->linVelocity[0]),
 							KX_BLENDERTRUNC(editobact->linVelocity[1]),
 							KX_BLENDERTRUNC(editobact->linVelocity[2]));
-							
+						
+						MT_Vector3 angvelvec (
+							KX_BLENDERTRUNC(editobact->angVelocity[0]),
+							KX_BLENDERTRUNC(editobact->angVelocity[1]),
+							KX_BLENDERTRUNC(editobact->angVelocity[2]));
+						
 						KX_SCA_AddObjectActuator* tmpaddact = 
 							new KX_SCA_AddObjectActuator(
 								gameobj, 
@@ -561,7 +592,9 @@ void BL_ConvertActuators(char* maggiename,
 								editobact->time,
 								scene,
 								linvelvec.getValue(),
-								editobact->localflag!=0
+								(editobact->localflag & ACT_EDOB_LOCAL_LINV)!=0,
+								angvelvec.getValue(),
+								(editobact->localflag & ACT_EDOB_LOCAL_ANGV)!=0
 								);
 								
 								//editobact->ob to gameobj
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 5e433bb821b8ece88070a937e10139e90ed4c1d1..db47dc2dd3d7416e6356b8c1be6943741eb84cff 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -65,6 +65,7 @@ probably misplaced */
 #include "SCA_JoystickSensor.h"
 #include "KX_NetworkMessageSensor.h"
 #include "SCA_ActuatorSensor.h"
+#include "SCA_DelaySensor.h"
 
 
 #include "SCA_PropertySensor.h"
@@ -281,6 +282,22 @@ void BL_ConvertSensors(struct Object* blenderobject,
 				break;
 			}
 			
+		case  SENS_DELAY:
+			{
+				// we can reuse the Always event manager for the delay sensor
+				SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
+				if (eventmgr)
+				{
+					bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
+					gamesensor = new SCA_DelaySensor(eventmgr, 
+						gameobj,
+						delaysensor->delay,
+						delaysensor->duration,
+						(delaysensor->flag & SENS_DELAY_REPEAT) != 0);
+				}
+				break;
+			}
+
 		case SENS_COLLISION:
 			{
 				SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
@@ -616,6 +633,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
 				if (eventmgr)
 				{
 					bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
+					bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
 					
 					STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
 
@@ -628,6 +646,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
 												  gameobj,
 												  checkname,
 												  bFindMaterial,
+												  bXRay,
 												  distance,
 												  axis,
 												  kxscene);
@@ -741,10 +760,24 @@ void BL_ConvertSensors(struct Object* blenderobject,
 			for (int i=0;i<sens->totlinks;i++)
 			{
 				bController* linkedcont = (bController*) sens->links[i];
-				SCA_IController* gamecont = converter->FindGameController(linkedcont);
+				if (linkedcont) {
+					SCA_IController* gamecont = converter->FindGameController(linkedcont);
 
-				if (gamecont) {
-					logicmgr->RegisterToSensor(gamecont,gamesensor);
+					if (gamecont) {
+						logicmgr->RegisterToSensor(gamecont,gamesensor);
+					} else {
+						printf(
+							"Warning, sensor \"%s\" could not find its controller "
+							"(link %d of %d) from object \"%s\"\n"
+							"\tthere has been an error converting the blender controller for the game engine,"
+							"logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
+					}
+				} else {
+					printf(
+						"Warning, sensor \"%s\" has lost a link to a controller "
+						"(link %d of %d) from object \"%s\"\n"
+						"\tpossible causes are partially appended objects or an error reading the file,"
+						"logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
 				}
 			}
 			// done with gamesensor
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index f433a08fabafe694176a7451991cb9bfc3417374..65cd4e890f73302099a7b23276513be981629976 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -102,6 +102,12 @@ static inline void Py_Fatal(char *M) {
 		return ((class_name*) self)->Py##method_name(self, args, kwds);		\
 	}; \
 
+#define KX_PYMETHOD_VARARGS(class_name, method_name)			\
+	PyObject* Py##method_name(PyObject* self, PyObject* args); \
+	static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
+		return ((class_name*) self)->Py##method_name(self, args);		\
+	}; \
+
 #define KX_PYMETHOD_NOARGS(class_name, method_name)			\
 	PyObject* Py##method_name(PyObject* self); \
 	static PyObject* sPy##method_name( PyObject* self) { \
@@ -150,6 +156,9 @@ static inline void Py_Fatal(char *M) {
 #define KX_PYMETHODTABLE(class_name, method_name) \
 	{#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS, class_name::method_name##_doc}
 
+#define KX_PYMETHODTABLE_NOARG(class_name, method_name) \
+	{#method_name , (PyCFunction) class_name::sPy##method_name, METH_NOARGS, class_name::method_name##_doc}
+
 /**
  * Function implementation macro
  */
@@ -157,6 +166,9 @@ static inline void Py_Fatal(char *M) {
 char class_name::method_name##_doc[] = doc_string; \
 PyObject* class_name::Py##method_name(PyObject*, PyObject* args, PyObject*)
 
+#define KX_PYMETHODDEF_DOC_NOARG(class_name, method_name, doc_string) \
+char class_name::method_name##_doc[] = doc_string; \
+PyObject* class_name::Py##method_name(PyObject*)
 
 /*------------------------------
  * PyObjectPlus
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4d05250e91c5c4d1ed19ca8d449256f1cc1bbb4d
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
@@ -0,0 +1,257 @@
+/**
+ * Delay trigger
+ *
+ * $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 *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )     
+#endif
+
+#include "SCA_DelaySensor.h"
+#include "SCA_LogicManager.h"
+#include "SCA_EventManager.h"
+
+/* ------------------------------------------------------------------------- */
+/* Native functions                                                          */
+/* ------------------------------------------------------------------------- */
+
+SCA_DelaySensor::SCA_DelaySensor(class SCA_EventManager* eventmgr,
+								 SCA_IObject* gameobj,
+								 int delay,
+								 int duration,
+								 bool repeat,
+								 PyTypeObject* T)
+	: SCA_ISensor(gameobj,eventmgr, T), 
+	m_delay(delay),
+	m_duration(duration),
+	m_repeat(repeat)
+{
+	Init();
+}
+
+void SCA_DelaySensor::Init()
+{
+	m_lastResult = false;
+	m_frameCount = -1;
+	m_reset = true;
+}
+
+SCA_DelaySensor::~SCA_DelaySensor()
+{
+	/* intentionally empty */
+}
+
+CValue* SCA_DelaySensor::GetReplica()
+{
+	CValue* replica = new SCA_DelaySensor(*this);
+	// this will copy properties and so on...
+	CValue::AddDataToReplica(replica);
+
+	return replica;
+}
+
+
+
+bool SCA_DelaySensor::IsPositiveTrigger()
+{ 
+	return (m_invert ? !m_lastResult : m_lastResult);
+}
+
+bool SCA_DelaySensor::Evaluate(CValue* event)
+{
+	bool trigger = false;
+	bool result;
+
+	if (m_frameCount==-1) {
+		// this is needed to ensure ON trigger in case delay==0
+		// and avoid spurious OFF trigger when duration==0
+		m_lastResult = false;
+		m_frameCount = 0;
+	}
+
+	if (m_frameCount<m_delay) {
+		m_frameCount++;
+		result = false;
+	} else if (m_duration > 0) {
+		if (m_frameCount < m_delay+m_duration) {
+			m_frameCount++;
+			result = true;
+		} else {
+			result = false;
+			if (m_repeat)
+				m_frameCount = -1;
+		}
+	} else {
+		result = true;
+		if (m_repeat)
+			m_frameCount = -1;
+	}
+	if ((m_reset && m_level) || result != m_lastResult)
+		trigger = true;
+	m_reset = false;
+	m_lastResult = result;
+	return trigger;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions                                                          */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject SCA_DelaySensor::Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"SCA_DelaySensor",
+	sizeof(SCA_DelaySensor),
+	0,
+	PyDestructor,
+	0,
+	__getattr,
+	__setattr,
+	0, //&MyPyCompare,
+	__repr,
+	0, //&cvalue_as_number,
+	0,
+	0,
+	0,
+	0
+};
+
+PyParentObject SCA_DelaySensor::Parents[] = {
+	&SCA_DelaySensor::Type,
+	&SCA_ISensor::Type,
+	&SCA_ILogicBrick::Type,
+	&CValue::Type,
+	NULL
+};
+
+PyMethodDef SCA_DelaySensor::Methods[] = {
+	/* setProperty */
+	{"setDelay", (PyCFunction) SCA_DelaySensor::sPySetDelay, METH_VARARGS, SetDelay_doc},
+	{"setDuration", (PyCFunction) SCA_DelaySensor::sPySetDuration, METH_VARARGS, SetDuration_doc},
+	{"setRepeat", (PyCFunction) SCA_DelaySensor::sPySetRepeat, METH_VARARGS, SetRepeat_doc},
+	/* getProperty */
+	{"getDelay", (PyCFunction) SCA_DelaySensor::sPyGetDelay, METH_NOARGS, GetDelay_doc},
+	{"getDuration", (PyCFunction) SCA_DelaySensor::sPyGetDuration, METH_NOARGS, GetDuration_doc},
+	{"getRepeat", (PyCFunction) SCA_DelaySensor::sPyGetRepeat, METH_NOARGS, GetRepeat_doc},
+	{NULL,NULL} //Sentinel
+};
+
+PyObject* SCA_DelaySensor::_getattr(const STR_String& attr) {
+	_getattr_up(SCA_ISensor);
+}
+
+char SCA_DelaySensor::SetDelay_doc[] = 
+"setDelay(delay)\n"
+"\t- delay: length of the initial OFF period as number of frame\n"
+"\t         0 for immediate trigger\n"
+"\tSet the initial delay before the positive trigger\n";
+PyObject* SCA_DelaySensor::PySetDelay(PyObject* self, PyObject* args, PyObject* kwds)
+{
+	int delay;
+	
+	if(!PyArg_ParseTuple(args, "i", &delay)) {
+		return NULL;
+	}
+	if (delay < 0) {
+		PyErr_SetString(PyExc_ValueError, "Delay cannot be negative");
+		return NULL;
+	}
+	m_delay = delay;
+	Py_Return;
+}
+
+char SCA_DelaySensor::SetDuration_doc[] = 
+"setDuration(duration)\n"
+"\t- duration: length of the ON period in number of frame after the initial off period\n"
+"\t            0 for no ON period\n"
+"\tSet the duration of the ON pulse after initial delay.\n"
+"\tIf > 0, a negative trigger is fired at the end of the ON pulse.\n";
+PyObject* SCA_DelaySensor::PySetDuration(PyObject* self, PyObject* args, PyObject* kwds)
+{
+	int duration;
+	
+	if(!PyArg_ParseTuple(args, "i", &duration)) {
+		return NULL;
+	}
+	if (duration < 0) {
+		PyErr_SetString(PyExc_ValueError, "Duration cannot be negative");
+		return NULL;
+	}
+	m_duration = duration;
+	Py_Return;
+}
+
+char SCA_DelaySensor::SetRepeat_doc[] = 
+"setRepeat(repeat)\n"
+"\t- repeat: 1 if the initial OFF-ON cycle should be repeated indefinately\n"
+"\t          0 if the initial OFF-ON cycle should run only once\n"
+"\tSet the sensor repeat mode\n";
+PyObject* SCA_DelaySensor::PySetRepeat(PyObject* self, PyObject* args, PyObject* kwds)
+{
+	int repeat;
+	
+	if(!PyArg_ParseTuple(args, "i", &repeat)) {
+		return NULL;
+	}
+	m_repeat = (repeat != 0);
+	Py_Return;
+}
+
+char SCA_DelaySensor::GetDelay_doc[] = 
+"getDelay()\n"
+"\tReturn the delay parameter value\n";
+PyObject* SCA_DelaySensor::PyGetDelay(PyObject* self)
+{
+	return PyInt_FromLong(m_delay);
+}
+
+char SCA_DelaySensor::GetDuration_doc[] = 
+"getDuration()\n"
+"\tReturn the duration parameter value\n";
+PyObject* SCA_DelaySensor::PyGetDuration(PyObject* self)
+{
+	return PyInt_FromLong(m_duration);
+}
+
+char SCA_DelaySensor::GetRepeat_doc[] = 
+"getRepeat()\n"
+"\tReturn the repeat parameter value\n";
+PyObject* SCA_DelaySensor::PyGetRepeat(PyObject* self)
+{
+	return BoolToPyArg(m_repeat);
+}
+
+/* eof */
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h
new file mode 100644
index 0000000000000000000000000000000000000000..a997fabe3cd49a9ae788a6493c1ce3631d42ff50
--- /dev/null
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.h
@@ -0,0 +1,77 @@
+/**
+ * SCA_DelaySensor.h
+ *
+ * $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 *****
+ */
+
+#ifndef __KX_DELAYSENSOR
+#define __KX_DELAYSENSOR
+#include "SCA_ISensor.h"
+
+class SCA_DelaySensor : public SCA_ISensor
+{
+	Py_Header;
+	bool			m_lastResult;
+	bool			m_repeat;
+	int				m_delay; 
+	int				m_duration;
+	int				m_frameCount;
+
+public:
+	SCA_DelaySensor(class SCA_EventManager* eventmgr,
+					SCA_IObject* gameobj,
+					int delay,
+					int duration,
+					bool repeat,
+					PyTypeObject* T =&Type);
+	virtual ~SCA_DelaySensor();
+	virtual CValue* GetReplica();
+	virtual bool Evaluate(CValue* event);
+	virtual bool IsPositiveTrigger();
+	virtual void Init();
+
+
+	/* --------------------------------------------------------------------- */
+	/* Python interface ---------------------------------------------------- */
+	/* --------------------------------------------------------------------- */
+	
+	virtual PyObject* _getattr(const STR_String& attr);
+
+	/* setProperty */
+	KX_PYMETHOD_DOC(SCA_DelaySensor,SetDelay);
+	KX_PYMETHOD_DOC(SCA_DelaySensor,SetDuration);
+	KX_PYMETHOD_DOC(SCA_DelaySensor,SetRepeat);
+	/* getProperty */
+	KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetDelay);
+	KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetDuration);
+	KX_PYMETHOD_DOC_NOARGS(SCA_DelaySensor,GetRepeat);
+
+};
+
+#endif //__KX_ALWAYSSENSOR
+
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index 8f156cc63e7e6d42137dfee016412f809fd8b90c..0bd20117f316e0342ade13115d7687a6a4595b1c 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -188,6 +188,8 @@ void SCA_IController::ApplyState(unsigned int state)
 			for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
 			{
 				(*sensit)->IncLink();
+				// remember that this controller just activated that sensor
+				(*sensit)->AddNewController(this);
 			}
 			SetActive(true);
 		}
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 2dc49924062e28fcbceaa5801ccf1410f365bd69..c96eb82e29ea95412ec02d82048b4f7ba7bce98a 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -32,6 +32,8 @@
 #include "SCA_ISensor.h"
 #include "SCA_EventManager.h"
 #include "SCA_LogicManager.h"
+// needed for IsTriggered()
+#include "SCA_PythonController.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -132,10 +134,8 @@ void SCA_ISensor::DecLink() {
 	}
 	if (!m_links)
 	{
-		// sensor is detached from all controllers, initialize it so that it
-		// is fresh as at startup when it is reattached again.
+		// sensor is detached from all controllers, remove it from manager
 		UnregisterToManager();
-		Init();
 	}
 }
 
@@ -168,7 +168,9 @@ PyParentObject SCA_ISensor::Parents[] = {
 };
 PyMethodDef SCA_ISensor::Methods[] = {
 	{"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive, 
-	 METH_VARARGS, IsPositive_doc},
+	 METH_NOARGS, IsPositive_doc},
+	{"isTriggered", (PyCFunction) SCA_ISensor::sPyIsTriggered, 
+	 METH_VARARGS, IsTriggered_doc},
 	{"getUsePosPulseMode", (PyCFunction) SCA_ISensor::sPyGetUsePosPulseMode, 
 	 METH_NOARGS, GetUsePosPulseMode_doc},
 	{"setUsePosPulseMode", (PyCFunction) SCA_ISensor::sPySetUsePosPulseMode, 
@@ -189,6 +191,8 @@ PyMethodDef SCA_ISensor::Methods[] = {
 	 METH_NOARGS, GetLevel_doc},
 	{"setLevel", (PyCFunction) SCA_ISensor::sPySetLevel, 
 	 METH_VARARGS, SetLevel_doc},
+	{"reset", (PyCFunction) SCA_ISensor::sPyReset, 
+	 METH_NOARGS, Reset_doc},
 	{NULL,NULL} //Sentinel
 };
 
@@ -202,6 +206,9 @@ SCA_ISensor::_getattr(const STR_String& attr)
 
 void SCA_ISensor::RegisterToManager()
 {
+	// sensor is just activated, initialize it
+	Init();
+	m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
 	m_eventmgr->RegisterSensor(this);
 }
 
@@ -247,19 +254,47 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr,	  CValue* event)
 				}
 			}
 		}
+		if (!m_newControllers.empty())
+		{
+			if (!IsActive() && m_level)
+			{
+				// This level sensor is connected to at least one controller that was just made 
+				// active but it did not generate an event yet, do it now to those controllers only 
+				for (std::vector<SCA_IController*>::iterator ci=m_newControllers.begin();
+					 ci != m_newControllers.end(); ci++)
+				{
+					logicmgr->AddTriggeredController(*ci, this);
+				}
+			}
+			// clear the list. Instead of using clear, which also release the memory,
+			// use erase, which keeps the memory available for next time.
+			m_newControllers.erase(m_newControllers.begin(), m_newControllers.end());
+		}
 	} 
 }
 
 /* Python functions: */
 char SCA_ISensor::IsPositive_doc[] = 
 "isPositive()\n"
-"\tReturns whether the sensor is registered a positive event.\n";
-PyObject* SCA_ISensor::PyIsPositive(PyObject* self, PyObject* args, PyObject* kwds)
+"\tReturns whether the sensor is in an active state.\n";
+PyObject* SCA_ISensor::PyIsPositive(PyObject* self)
 {
 	int retval = IsPositiveTrigger();
 	return PyInt_FromLong(retval);
 }
 
+char SCA_ISensor::IsTriggered_doc[] = 
+"isTriggered()\n"
+"\tReturns whether the sensor has triggered the current controller.\n";
+PyObject* SCA_ISensor::PyIsTriggered(PyObject* self)
+{
+	// check with the current controller
+	int retval = 0;
+	if (SCA_PythonController::m_sCurrentController)
+		retval = SCA_PythonController::m_sCurrentController->IsTriggered(this);
+	return PyInt_FromLong(retval);
+}
+
 /**
  * getUsePulseMode: getter for the pulse mode (KX_TRUE = on)
  */
@@ -390,4 +425,15 @@ PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyOb
 	Py_Return;
 }
 
+char SCA_ISensor::Reset_doc[] = 
+"reset()\n"
+"\tReset sensor internal state, effect depends on the type of sensor and settings.\n"
+"\tThe sensor is put in its initial state as if it was just activated.\n";
+PyObject* SCA_ISensor::PyReset(PyObject* self)
+{
+	Init();
+	Py_Return;
+}
+
+
 /* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index d5dabbce3ee9d3a5a8341d18af082ef66cfa4703..0d65270dc7b290e75b656a4ad10e08ffcd535c19 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -34,6 +34,8 @@
 
 #include "SCA_ILogicBrick.h"
 
+#include <vector>
+
 /**
  * Interface Class for all logic Sensors. Implements
  * pulsemode,pulsefrequency */
@@ -73,9 +75,9 @@ class SCA_ISensor : public SCA_ILogicBrick
 	/** number of connections to controller */
 	int m_links;
 
-	/** Pass the activation on to the logic manager.*/
-	void SignalActivation(class SCA_LogicManager* logicmgr);
-	
+	/** list of controllers that have just activated this sensor because of a state change */
+	std::vector<class SCA_IController*> m_newControllers;
+
 public:
 	SCA_ISensor(SCA_IObject* gameobj,
 				class SCA_EventManager* eventmgr,
@@ -128,6 +130,8 @@ public:
 	/** Resume sensing. */
 	void Resume();
 
+	void AddNewController(class SCA_IController* controller)
+		{ m_newControllers.push_back(controller); }
 	void ClrLink()
 		{ m_links = 0; }
 	void IncLink()
@@ -137,7 +141,8 @@ public:
 		{ return !m_links; }
 
 	/* Python functions: */
-	KX_PYMETHOD_DOC(SCA_ISensor,IsPositive);
+	KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsPositive);
+	KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsTriggered);
 	KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetUsePosPulseMode);
 	KX_PYMETHOD_DOC(SCA_ISensor,SetUsePosPulseMode);
 	KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetFrequency);
@@ -148,6 +153,7 @@ public:
 	KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
 	KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetLevel);
 	KX_PYMETHOD_DOC(SCA_ISensor,SetLevel);
+	KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,Reset);
 
 };
 
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index a7a6fa93db46f3c778f9bb7e2dff450760b805eb..fba1162993d3c1a3916701bdc4e6faa3d08d75cc 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -505,7 +505,7 @@ PyObject* SCA_KeyboardSensor::sPySetAllMode(PyObject* self,
 				       PyObject* kwds)
 {
 //	printf("sPyIsPositive\n");
-    return ((SCA_KeyboardSensor*) self)->PyIsPositive(self, args, kwds);
+    return ((SCA_KeyboardSensor*) self)->PyIsPositive(self);
 }
 
 
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index 91e66aea35941e29977fa2fb6ccd9172f533c9c6..b584b37180ff53f9f6dbb25c2756cfbb43e7aed8 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -33,6 +33,7 @@
 #include "SCA_IController.h"
 #include "SCA_IActuator.h"
 #include "SCA_EventManager.h"
+#include "SCA_PythonController.h"
 #include <set>
 
 #ifdef HAVE_CONFIG_H
@@ -232,8 +233,6 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
 	// for this frame, look up for activated sensors, and build the collection of triggered controllers
 	// int numsensors = this->m_activatedsensors.size(); /*unused*/
 
-	set<SmartControllerPtr> triggeredControllerSet;
-
 	for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin();
 	!(is==m_activatedsensors.end());is++)
 	{
@@ -244,19 +243,28 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
 		{
 				SCA_IController* contr = *c;//controllerarray->at(c);
 				if (contr->IsActive())
-					triggeredControllerSet.insert(SmartControllerPtr(contr,0));
+				{
+					m_triggeredControllerSet.insert(SmartControllerPtr(contr,0));
+					// So that the controller knows which sensor has activited it.
+					// Only needed for the python controller though.
+					if (contr->GetType() == &SCA_PythonController::Type)
+					{
+						SCA_PythonController* pythonController = (SCA_PythonController*)contr;
+						pythonController->AddTriggeredSensor(sensor);
+					}
+				}
 		}
 		//sensor->SetActive(false);
 	}
 
 	
 	// int numtriggered = triggeredControllerSet.size(); /*unused*/
-	for (set<SmartControllerPtr>::iterator tit=triggeredControllerSet.begin();
-	!(tit==triggeredControllerSet.end());tit++)
+	for (set<SmartControllerPtr>::iterator tit=m_triggeredControllerSet.begin();
+	!(tit==m_triggeredControllerSet.end());tit++)
 	{
 		(*tit)->Trigger(this);
 	}
-	triggeredControllerSet.clear();
+	m_triggeredControllerSet.clear();
 }
 
 
@@ -382,6 +390,17 @@ void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor)
 	}
 }
 
+void SCA_LogicManager::AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor)
+{
+	m_triggeredControllerSet.insert(SmartControllerPtr(controller,0));
+	// so that the controller knows which sensor has activited it
+	// only needed for python controller
+	if (controller->GetType() == &SCA_PythonController::Type)
+	{
+		SCA_PythonController* pythonController = (SCA_PythonController*)controller;
+		pythonController->AddTriggeredSensor(sensor);
+	}
+}
 
 
 void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event)
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
index e0d3d50670253d501fbf5dad8e026ccc767a859b..50383879d8f0f4ed8f79009f20b239f9b339a0e6 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.h
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -99,6 +99,7 @@ class SCA_LogicManager
 	
 	vector<class SCA_ISensor*>			m_activatedsensors;
 	set<class SmartActuatorPtr>			m_activeActuators;
+	set<class SmartControllerPtr>		m_triggeredControllerSet;
 
 	map<SCA_ISensor*,controllerlist >	m_sensorcontrollermapje;
 
@@ -127,6 +128,7 @@ public:
 	void	EndFrame();
 	void	AddActivatedSensor(SCA_ISensor* sensor);
 	void	AddActiveActuator(SCA_IActuator* sensor,class CValue* event);
+	void	AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor);
 	SCA_EventManager*	FindEventManager(int eventmgrtype);
 	
 	void	RemoveGameObject(const STR_String& gameobjname);
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index cd1b029fc34a28763c9ce7bc188fe909907dc1b5..e6f7b1dd143ac9fab349e8dcd41ad0b85d87dba6 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -35,6 +35,7 @@
 #include "SCA_IActuator.h"
 #include "compile.h"
 #include "eval.h"
+#include <algorithm>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -139,6 +140,14 @@ void SCA_PythonController::SetDictionary(PyObject*	pythondictionary)
 	m_pythondictionary = PyDict_Copy(pythondictionary); /* new reference */
 }
 
+int SCA_PythonController::IsTriggered(class SCA_ISensor* sensor)
+{
+	if (std::find(m_triggeredSensors.begin(), m_triggeredSensors.end(), sensor) != 
+		m_triggeredSensors.end())
+		return 1;
+	return 0;
+}
+
 #if 0
 static char* sPyGetCurrentController__doc__;
 #endif
@@ -248,7 +257,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
 		{
 			// didn't compile, so instead of compile, complain
 			// something is wrong, tell the user what went wrong
-			printf("PYTHON SCRIPT ERROR:\n");
+			printf("Python compile error from controller \"%s\": \n", GetName().Ptr());
 			//PyRun_SimpleString(m_scriptText.Ptr());
 			PyErr_Print();
 			return;
@@ -285,7 +294,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
 	else
 	{
 		// something is wrong, tell the user what went wrong
-		printf("PYTHON SCRIPT ERROR:\n");
+		printf("Python script error from controller \"%s\": \n", GetName().Ptr());
 		PyErr_Print();
 		//PyRun_SimpleString(m_scriptText.Ptr());
 	}
@@ -294,7 +303,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
 	// something in this dictionary and crash?
 	PyDict_Clear(excdict);
 	Py_DECREF(excdict);
-
+	m_triggeredSensors.erase(m_triggeredSensors.begin(), m_triggeredSensors.end());
 	m_sCurrentController = NULL;
 }
 
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
index 39b6c68c359b8102c07cd8c761d6e95f471e0be3..1b62e7ecb5325279f4ab24d46d8b390e81f84bfc 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.h
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -36,6 +36,8 @@
 #include "SCA_LogicManager.h"
 #include "BoolValue.h"
 
+#include <vector>
+
 class SCA_IObject;
 class SCA_PythonController : public SCA_IController
 {
@@ -47,6 +49,7 @@ class SCA_PythonController : public SCA_IController
 	STR_String				m_scriptText;
 	STR_String				m_scriptName;
 	PyObject*				m_pythondictionary;
+	std::vector<class SCA_ISensor*>		m_triggeredSensors;
 
  public: 
 	static SCA_PythonController* m_sCurrentController; // protected !!!
@@ -64,6 +67,9 @@ class SCA_PythonController : public SCA_IController
 	void	SetScriptText(const STR_String& text);
 	void	SetScriptName(const STR_String& name);
 	void	SetDictionary(PyObject*	pythondictionary);
+	void	AddTriggeredSensor(class SCA_ISensor* sensor)
+		{ m_triggeredSensors.push_back(sensor); }
+	int		IsTriggered(class SCA_ISensor* sensor);
 
 	static char* sPyGetCurrentController__doc__;
 	static PyObject* sPyGetCurrentController(PyObject* self);
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index 8b828393c67e0ea13478306f080ee8eccc003d37..a64c85f6c17d17d008194ffb39ee4515b7d1dfa4 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -470,11 +470,11 @@ void GPC_RenderTools::SetClientObject(void* obj)
 	}
 }
 
-bool GPC_RenderTools::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+bool GPC_RenderTools::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
 {
 	double* const oglmatrix = (double* const) data;
-	MT_Point3 resultpoint(hit_point);
-	MT_Vector3 resultnormal(hit_normal);
+	MT_Point3 resultpoint(result->m_hitPoint);
+	MT_Vector3 resultnormal(result->m_hitNormal);
 	MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
 	MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized();
 	left = (dir.cross(resultnormal)).safe_normalized();
@@ -563,9 +563,8 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
 			if (parent)
 				parent->Release();
 				
-			MT_Point3 resultpoint;
-			MT_Vector3 resultnormal;
-			if (!KX_RayCast::RayTest(physics_controller, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback<GPC_RenderTools>(this, oglmatrix)))
+			KX_RayCast::Callback<GPC_RenderTools> callback(this, physics_controller, oglmatrix);
+			if (!KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback))
 			{
 				// couldn't find something to cast the shadow on...
 				glMultMatrixd(oglmatrix);
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
index 8fae3d2b305880cd3268dae5cd8f9ee5964f4adb..9f70f67caf2b32ab5422d1b43f75f7356cb82518 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -41,7 +41,7 @@
 #include "BMF_Api.h"
 
 struct KX_ClientObjectInfo;
-
+class KX_RayCast;
 
 class GPC_RenderTools : public RAS_IRenderTools
 {
@@ -138,7 +138,8 @@ public:
 
 	int applyLights(int objectlayer);
 
-	bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+	bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
+	bool NeedRayCast(KX_ClientObjectInfo* client) { return true; }
 
 	virtual void MotionBlur(RAS_IRasterizer* rasterizer);
 
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 7be3b94d8aea5598f7b35fad879c5422c3ff801a..c56a6d0da237f7b7f20474e543283b472e4398de 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -97,7 +97,7 @@ extern "C"
 #include "GHOST_IEventConsumer.h"
 #include "GHOST_IWindow.h"
 #include "GHOST_Rect.h"
-
+#include "marshal.h"
 
 static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
 
@@ -125,7 +125,9 @@ GPG_Application::GPG_Application(GHOST_ISystem* system, struct Main* maggie, STR
 	  m_networkdevice(0), 
 	  m_audiodevice(0),
 	  m_blendermat(0),
-	  m_blenderglslmat(0)
+	  m_blenderglslmat(0),
+	  m_pyGlobalDictString(0),
+	  m_pyGlobalDictString_Length(0)
 {
 	fSystem = system;
 }
@@ -645,14 +647,23 @@ bool GPG_Application::startEngine(void)
 		PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest);
 		m_ketsjiengine->SetPythonDictionary(dictionaryobject);
 		initRasterizer(m_rasterizer, m_canvas);
-		PyDict_SetItemString(dictionaryobject, "GameLogic", initGameLogic(startscene)); // Same as importing the module
+		PyObject *gameLogic = initGameLogic(startscene);
+		PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module
 		initGameKeys();
 		initPythonConstraintBinding();
 		initMathutils();
 
-
-
-
+		/* Restore the dict */
+		if (m_pyGlobalDictString) {
+			PyObject* pyGlobalDict = PyMarshal_ReadObjectFromString(m_pyGlobalDictString, m_pyGlobalDictString_Length);
+			if (pyGlobalDict) {
+				PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
+			} else {
+				PyErr_Clear();
+				printf("Error could not marshall string\n");
+			}
+		}
+		
 		m_sceneconverter->ConvertScene(
 			startscenename,
 			startscene,
@@ -688,6 +699,33 @@ bool GPG_Application::startEngine(void)
 
 void GPG_Application::stopEngine()
 {
+	// get the python dict and convert to a string for future use
+	{
+		SetPyGlobalDictMarshal(NULL, 0);
+		
+		PyObject* gameLogic = PyImport_ImportModule("GameLogic");
+		if (gameLogic) {
+			PyObject* pyGlobalDict = PyDict_GetItemString(PyModule_GetDict(gameLogic), "globalDict"); // Same as importing the module
+			if (pyGlobalDict) {
+				PyObject* pyGlobalDictMarshal = PyMarshal_WriteObjectToString(	pyGlobalDict, 2); // Py_MARSHAL_VERSION == 2 as of Py2.5
+				if (pyGlobalDictMarshal) {
+					m_pyGlobalDictString_Length = PyString_Size(pyGlobalDictMarshal);
+					PyObject_Print(pyGlobalDictMarshal, stderr, 0);
+					m_pyGlobalDictString = static_cast<char *> (malloc(m_pyGlobalDictString_Length));
+					memcpy(m_pyGlobalDictString, PyString_AsString(pyGlobalDictMarshal), m_pyGlobalDictString_Length);
+				} else {
+					printf("Error, GameLogic.globalDict could not be marshal'd\n");
+				}
+				Py_DECREF(gameLogic);
+			} else {
+				printf("Error, GameLogic.globalDict was removed\n");
+			}
+		} else {
+			printf("Error, GameLogic failed to import GameLogic.globalDict will be lost\n");
+		}
+	}	
+	
+	
 	// when exiting the mainloop
 	exitGamePythonScripting();
 	m_ketsjiengine->StopEngine();
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h
index 17f5add8b192d1b803d243925fde2b7124edf528..31f5eb75e525398d8b060273d3118d1dd9e326b7 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.h
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h
@@ -72,6 +72,29 @@ public:
 			bool StartGameEngine(int stereoMode);
 			void StopGameEngine();
 
+			char*
+		GetPyGlobalDictMarshal()
+		{ 
+			return m_pyGlobalDictString;
+		};
+		
+			void
+		SetPyGlobalDictMarshal( char* pyGlobalDictString, int length )
+		{
+			if (m_pyGlobalDictString && m_pyGlobalDictString != pyGlobalDictString)
+				free(m_pyGlobalDictString);
+			
+			m_pyGlobalDictString = pyGlobalDictString;
+			m_pyGlobalDictString_Length = length;
+		};
+		
+			int
+		GetPyGlobalDictMarshalLength()
+		{ 
+			return m_pyGlobalDictString_Length;
+		};
+
+
 protected:
 	bool	handleWheel(GHOST_IEvent* event);
 	bool	handleButton(GHOST_IEvent* event, bool isDown);
@@ -142,6 +165,12 @@ protected:
 
 	bool m_blendermat;
 	bool m_blenderglslmat;
-
+	
+	/*
+	 * GameLogic.globalDict as a string so that loading new blend files can use the same dict.
+	 * Do this because python starts/stops when loading blend files.
+	 */
+	char* m_pyGlobalDictString;
+	int m_pyGlobalDictString_Length;
 };
 
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 8222e5c8bac8da78f5c7a0b14960db8aff3f4b3f..26a85128025be852f1a9c084d88caf073b3601a1 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -293,7 +293,9 @@ int main(int argc, char** argv)
 	GHOST_TUns32 fullScreenHeight= 0;
 	int fullScreenBpp = 32;
 	int fullScreenFrequency = 60;
-
+	char* pyGlobalDictString = NULL; /* store python dict data between blend file loading */
+	int pyGlobalDictString_Length = 0;
+	
 #ifdef __linux__
 #ifdef __alpha__
 	signal (SIGFPE, SIG_IGN);
@@ -625,6 +627,10 @@ int main(int argc, char** argv)
 						
 						titlename = maggie->name;
 						
+						// Set the GameLogic.globalDict from marshal'd data, so we can load new blend files
+						// abd keep data in GameLogic.globalDict
+						app.SetPyGlobalDictMarshal(pyGlobalDictString, pyGlobalDictString_Length);
+						
 						// Check whether the game should be displayed full-screen
 						if ((!fullScreenParFound) && (!windowParFound))
 						{
@@ -750,6 +756,12 @@ int main(int argc, char** argv)
 							}
 						}
 						app.StopGameEngine();
+						
+						// GameLogic.globalDict has been converted into a buffer
+						// store in pyGlobalDictString so we can restore after python has stopped and started.
+						pyGlobalDictString = app.GetPyGlobalDictMarshal();
+						pyGlobalDictString_Length = app.GetPyGlobalDictMarshalLength();
+						
 						BLO_blendfiledata_free(bfd);
 						
 #ifdef __APPLE__
@@ -772,6 +784,11 @@ int main(int argc, char** argv)
 		}
 	}
 
+	if (pyGlobalDictString) {
+		free(pyGlobalDictString);
+		pyGlobalDictString = NULL;
+	}
+	
 	return error ? -1 : 0;
 }
 
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index e00ec68ad331575dba14689d85168e0665a2d7aa..4b57b0e8c54ce0ca8eaf7ac0281e738deef6ba58 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -109,16 +109,11 @@ KX_ConstraintActuator::~KX_ConstraintActuator()
 	// there's nothing to be done here, really....
 } /* end of destructor */
 
-bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
 {
 
 	KX_GameObject* hitKXObj = client->m_gameobject;
 	
-	if (client->m_type > KX_ClientObjectInfo::ACTOR)
-	{
-		// false hit
-		return false;
-	}
 	bool bFound = false;
 
 	if (m_property[0] == 0)
@@ -139,8 +134,26 @@ bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_p
 			bFound = hitKXObj->GetProperty(m_property) != NULL;
 		}
 	}
+	// update the hit status
+	result->m_hitFound = bFound;
+	// stop looking
+	return true;
+}
 
-	return bFound;
+/* this function is used to pre-filter the object before casting the ray on them.
+   This is useful for "X-Ray" option when we want to see "through" unwanted object.
+ */
+bool KX_ConstraintActuator::NeedRayCast(KX_ClientObjectInfo* client)
+{
+	if (client->m_type > KX_ClientObjectInfo::ACTOR)
+	{
+		// Unknown type of object, skip it.
+		// Should not occur as the sensor objects are filtered in RayTest()
+		printf("Invalid client type %d found in ray casting\n", client->m_type);
+		return false;
+	}
+	// no X-Ray function yet
+	return true;
 }
 
 bool KX_ConstraintActuator::Update(double curtime, bool frame)
@@ -287,8 +300,6 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
 			direction.normalize();
 			{
 				MT_Point3 topoint = position + (m_maximumBound) * direction;
-				MT_Point3 resultpoint;
-				MT_Vector3 resultnormal;
 				PHY_IPhysicsEnvironment* pe = obj->GetPhysicsEnvironment();
 				KX_IPhysicsController *spc = obj->GetPhysicsController();
 
@@ -304,9 +315,10 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
 						parent->Release();
 					}
 				}
-				result = KX_RayCast::RayTest(spc, pe, position, topoint, resultpoint, resultnormal, KX_RayCast::Callback<KX_ConstraintActuator>(this));
-
+				KX_RayCast::Callback<KX_ConstraintActuator> callback(this,spc);
+				result = KX_RayCast::RayTest(pe, position, topoint, callback);
 				if (result)	{
+					MT_Vector3 newnormal = callback.m_hitNormal;
 					// compute new position & orientation
 					if ((m_option & (KX_ACT_CONSTRAINT_NORMAL|KX_ACT_CONSTRAINT_DISTANCE)) == 0) {
 						// if none option is set, the actuator does nothing but detect ray 
@@ -316,27 +328,27 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
 					if (m_option & KX_ACT_CONSTRAINT_NORMAL) {
 						// the new orientation must be so that the axis is parallel to normal
 						if (sign)
-							resultnormal = -resultnormal;
+							newnormal = -newnormal;
 						// apply damping on the direction
 						if (m_rotDampTime) {
 							MT_Scalar rotFilter = 1.0/(1.0+m_rotDampTime);
-							resultnormal = (-m_rotDampTime*rotFilter)*direction + rotFilter*resultnormal;
+							newnormal = (-m_rotDampTime*rotFilter)*direction + rotFilter*newnormal;
 						} else if (m_posDampTime) {
-							resultnormal = -filter*direction + (1.0-filter)*resultnormal;
+							newnormal = -filter*direction + (1.0-filter)*newnormal;
 						}
-						obj->AlignAxisToVect(resultnormal, axis);
-						direction = -resultnormal;
+						obj->AlignAxisToVect(newnormal, axis);
+						direction = -newnormal;
 					}
 					if (m_option & KX_ACT_CONSTRAINT_DISTANCE) {
 						if (m_posDampTime) {
-							newdistance = filter*(position-resultpoint).length()+(1.0-filter)*m_minimumBound;
+							newdistance = filter*(position-callback.m_hitPoint).length()+(1.0-filter)*m_minimumBound;
 						} else {
 							newdistance = m_minimumBound;
 						}
 					} else {
-						newdistance = (position-resultpoint).length();
+						newdistance = (position-callback.m_hitPoint).length();
 					}
-					newposition = resultpoint-newdistance*direction;
+					newposition = callback.m_hitPoint-newdistance*direction;
 				} else if (m_option & KX_ACT_CONSTRAINT_PERMANENT) {
 					// no contact but still keep running
 					result = true;
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
index d9f39124cac550a96b69b6e1ff287edc789925d4..6ec4de9aad96f6a73e2bca099d94d628f338126f 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.h
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -37,6 +37,8 @@
 #include "MT_Vector3.h"
 #include "KX_ClientObjectInfo.h"
 
+class KX_RayCast;
+
 class KX_ConstraintActuator : public SCA_IActuator
 {
 	Py_Header;
@@ -100,7 +102,8 @@ protected:
 		KX_ACT_CONSTRAINT_DISTANCE = 512
 	};
 	bool IsValidMode(KX_CONSTRAINTTYPE m); 
-	bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+	bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
+	bool NeedRayCast(KX_ClientObjectInfo*);
 
 	KX_ConstraintActuator(SCA_IObject* gameobj,
 						  int posDamptime,
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index e0cd5a3bc9e458431de5624a0a5c0e6bc465873d..d6997ee29a864f9af7b2b0634f6c79b4190ce3a7 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -680,188 +680,6 @@ void	KX_ConvertODEEngineObject(KX_GameObject* gameobj,
 
 
 // forward declarations
-static btCollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool polytope)
-{
-	if (!meshobj)
-		return 0;
-
-	btCollisionShape* collisionMeshShape = 0;
-	btConvexHullShape* convexHullShape = 0;
-	btTriangleMeshShape* concaveShape = 0;
-
-	btTriangleMesh* collisionMeshData = 0;
-
-	//see if there is any polygons, if not, bail out.
-
-	int numPoints = 0;
-	btVector3* points = 0;
-
-	// Mesh has no polygons!
-	int numpolys = meshobj->NumPolygons();
-	if (!numpolys)
-	{
-		return NULL;
-	}
-
-	// Count the number of collision polygons and check they all come from the same 
-	// vertex array
-	int numvalidpolys = 0;
-	int vtxarray = -1;
-	RAS_IPolyMaterial *poly_material = NULL;
-	bool reinstance = true;
-
-	for (int p=0; p<numpolys; p++)
-	{
-		RAS_Polygon* poly = meshobj->GetPolygon(p);
-
-		// only add polygons that have the collisionflag set
-		if (poly->IsCollider())
-		{
-			// check polygon is from the same vertex array
-			if (poly->GetVertexIndexBase().m_vtxarray != vtxarray)
-			{
-				if (vtxarray < 0)
-					vtxarray = poly->GetVertexIndexBase().m_vtxarray;
-				else
-				{
-					reinstance = false;
-					vtxarray = -1;
-				}
-			}
-
-			// check poly is from the same material
-			if (poly->GetMaterial()->GetPolyMaterial() != poly_material)
-			{
-				if (poly_material)
-				{
-					reinstance = false;
-					poly_material = NULL;
-				}
-				else
-					poly_material = poly->GetMaterial()->GetPolyMaterial();
-			}
-
-			// count the number of collision polys
-			numvalidpolys++;
-
-			// We have one collision poly, and we can't reinstance, so we
-			// might as well break here.
-			if (!reinstance)
-				break;
-		}
-	}
-
-	// No collision polygons
-	if (numvalidpolys < 1)
-		return NULL;
-
-
-	if (polytope)
-	{
-		convexHullShape = new btConvexHullShape(&points[0].getX(),numPoints);
-		collisionMeshShape = convexHullShape;
-	} else
-	{
-		collisionMeshData = new btTriangleMesh();
-//		concaveShape = new btTriangleMeshShape(collisionMeshData);
-		//collisionMeshShape = concaveShape;
-
-	}
-
-
-	numvalidpolys = 0;
-
-	for (int p2=0; p2<numpolys; p2++)
-	{
-		RAS_Polygon* poly = meshobj->GetPolygon(p2);
-
-		// only add polygons that have the collisionflag set
-		if (poly->IsCollider())
-		{   
-			//Bullet can raycast any shape, so
-			if (polytope)
-			{
-				for (int i=0;i<poly->VertexCount();i++)
-				{
-					const float* vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-						poly->GetVertexIndexBase().m_indexarray[i],
-						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
-					btPoint3 point(vtx[0],vtx[1],vtx[2]);
-					convexHullShape->addPoint(point);
-				}
-				if (poly->VertexCount())
-					numvalidpolys++;
-
-			} else
-			{
-				{
-					const float* vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-						poly->GetVertexIndexBase().m_indexarray[2],
-						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
-					btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
-					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-						poly->GetVertexIndexBase().m_indexarray[1],
-						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
-					btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
-					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-						poly->GetVertexIndexBase().m_indexarray[0],
-						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
-					btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
-					collisionMeshData->addTriangle(vertex0,vertex1,vertex2);
-					numvalidpolys++;
-				}
-				if (poly->VertexCount() == 4)
-				{
-					const float* vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-						poly->GetVertexIndexBase().m_indexarray[3],
-						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
-					btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
-					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-						poly->GetVertexIndexBase().m_indexarray[2],
-						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
-					btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
-					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-						poly->GetVertexIndexBase().m_indexarray[0],
-						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
-					btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
-					collisionMeshData->addTriangle(vertex0,vertex1,vertex2);
-					numvalidpolys++;
-				}
-
-			}		
-		}
-	}
-
-
-
-	if (numvalidpolys > 0)
-	{
-		
-		if (!polytope)
-		{
-			bool useQuantization = true;
-			concaveShape = new btBvhTriangleMeshShape( collisionMeshData, useQuantization );
-			//concaveShape = new btTriangleMeshShape( collisionMeshData );
-
-			concaveShape->recalcLocalAabb();
-			if (collisionMeshShape)
-				delete collisionMeshShape;
-			collisionMeshShape = concaveShape;
-
-		} 
-		
-		
-
-		return collisionMeshShape;
-	}
-	if (collisionMeshShape)
-		delete collisionMeshShape;
-	if (collisionMeshData)
-		delete collisionMeshData;
-	return NULL;
-
-}
-
 
 void	KX_ConvertBulletObject(	class	KX_GameObject* gameobj,
 	class	RAS_MeshObject* meshobj,
@@ -878,6 +696,7 @@ void	KX_ConvertBulletObject(	class	KX_GameObject* gameobj,
 	bool isbulletdyna = false;
 	CcdConstructionInfo ci;
 	class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
+	class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
 
 	
 
@@ -894,120 +713,80 @@ void	KX_ConvertBulletObject(	class	KX_GameObject* gameobj,
 	ci.m_gravity = btVector3(0,0,0);
 	ci.m_localInertiaTensor =btVector3(0,0,0);
 	ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
+	shapeInfo->m_radius = objprop->m_radius;
 	isbulletdyna = objprop->m_dyna;
 	
 	ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
 	
-	btTransform trans;
-	trans.setIdentity();
-	
 	btCollisionShape* bm = 0;
 
 	switch (objprop->m_boundclass)
 	{
 	case KX_BOUNDSPHERE:
 		{
-			float radius = objprop->m_radius;
-			btVector3 inertiaHalfExtents (
-				radius,
-				radius,
-				radius);
+			//float radius = objprop->m_radius;
+			//btVector3 inertiaHalfExtents (
+			//	radius,
+			//	radius,
+			//	radius);
 			
 			//blender doesn't support multisphere, but for testing:
 
 			//bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
-			bm = new btSphereShape(objprop->m_radius);
-			bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
+			shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
+			bm = shapeInfo->CreateBulletShape();
 			break;
 		};
 	case KX_BOUNDBOX:
 		{
-			MT_Vector3 halfExtents (
+			shapeInfo->m_halfExtend.setValue(
 				objprop->m_boundobject.box.m_extends[0],
-			objprop->m_boundobject.box.m_extends[1],
-			objprop->m_boundobject.box.m_extends[2]);
-
-			halfExtents /= 2.f;
-
-			//btVector3 he (halfExtents[0]-CONVEX_DISTANCE_MARGIN ,halfExtents[1]-CONVEX_DISTANCE_MARGIN ,halfExtents[2]-CONVEX_DISTANCE_MARGIN );
-			//he = he.absolute();
-
-			btVector3 he (halfExtents[0],halfExtents[1],halfExtents[2]);
-			he = he.absolute();
-
+				objprop->m_boundobject.box.m_extends[1],
+				objprop->m_boundobject.box.m_extends[2]);
 
-			bm = new btBoxShape(he);
-			bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
+			shapeInfo->m_halfExtend /= 2.0;
+			shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
+			shapeInfo->m_shapeType = PHY_SHAPE_BOX;
+			bm = shapeInfo->CreateBulletShape();
 			break;
 		};
 	case KX_BOUNDCYLINDER:
 		{
-			btVector3 halfExtents (
+			shapeInfo->m_halfExtend.setValue(
 				objprop->m_boundobject.c.m_radius,
 				objprop->m_boundobject.c.m_radius,
 				objprop->m_boundobject.c.m_height * 0.5f
 			);
-			bm = new btCylinderShapeZ(halfExtents);
-			bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
-
+			shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
+			bm = shapeInfo->CreateBulletShape();
 			break;
 		}
 
-		case KX_BOUNDCONE:
+	case KX_BOUNDCONE:
 		{
-				btVector3 halfExtents (objprop->m_boundobject.box.m_extends[0],
-				objprop->m_boundobject.box.m_extends[1],
-				objprop->m_boundobject.box.m_extends[2]);
-
-
-				halfExtents /= 2.f;
-
-				bm = new btConeShapeZ(objprop->m_boundobject.c.m_radius,objprop->m_boundobject.c.m_height);
-				bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
-
+			shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
+			shapeInfo->m_height = objprop->m_boundobject.c.m_height;
+			shapeInfo->m_shapeType = PHY_SHAPE_CONE;
+			bm = shapeInfo->CreateBulletShape();
 			break;
 		}
-		case KX_BOUNDPOLYTOPE:
-			{
-				bm = CreateBulletShapeFromMesh(meshobj,true);
-				if (bm)
-				{
-					bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
-				}
-				break;
-			}
-		case KX_BOUNDMESH:
-			{
-				if (!ci.m_mass)
-				{				
-					bm = CreateBulletShapeFromMesh(meshobj,false);
-					ci.m_localInertiaTensor.setValue(0.f,0.f,0.f);
-					//no moving concave meshes, so don't bother calculating inertia
-					//bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
-				}
-
-				break;
-			}
-
-	default:
-		//interpret the shape as a concave triangle-mesh
+	case KX_BOUNDPOLYTOPE:
 		{
-			if (meshobj)
-			{
-				bm = CreateBulletShapeFromMesh(meshobj,false);
-				ci.m_localInertiaTensor.setValue(0.f,0.f,0.f);
-
-			//	assert(0);
-
-					/*
-				meshobj->ScheduleCollisionPolygons();
-
-				KX_DeformableMesh* gfxmesh = new KX_DeformableMesh(meshobj);
-				gfxmesh->sendFixedMapping();
-				//trianglemesh
-				bm = new TriangleMeshInterface(gfxmesh,trans);
-				*/
+			shapeInfo->SetMesh(meshobj, true);
+			bm = shapeInfo->CreateBulletShape();
+			break;
+		}
+	case KX_BOUNDMESH:
+		{
+			if (!ci.m_mass)
+			{				
+				shapeInfo->SetMesh(meshobj, false);
+				bm = shapeInfo->CreateBulletShape();
+				//no moving concave meshes, so don't bother calculating inertia
+				//bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
 			}
+
+			break;
 		}
 	}
 
@@ -1017,44 +796,41 @@ void	KX_ConvertBulletObject(	class	KX_GameObject* gameobj,
 	if (!bm)
 	{
 		delete motionstate;
+		delete shapeInfo;
 		return;
 	}
 
 	bm->setMargin(0.06);
 
 
-
 		if (objprop->m_isCompoundChild)
 		{
 			//find parent, compound shape and add to it
 			//take relative transform into account!
 			KX_BulletPhysicsController* parentCtrl = (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController();
 			assert(parentCtrl);
+			CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
 			btRigidBody* rigidbody = parentCtrl->GetRigidBody();
 			btCollisionShape* colShape = rigidbody->getCollisionShape();
 			assert(colShape->isCompound());
 			btCompoundShape* compoundShape = (btCompoundShape*)colShape;
-			btTransform childTrans;
-			childTrans.setIdentity();
-			NodeList& children = objprop->m_dynamic_parent->GetSGNode()->GetSGChildren();
 
 			MT_Point3 childPos = gameobj->GetSGNode()->GetLocalPosition();
 			MT_Matrix3x3 childRot = gameobj->GetSGNode()->GetLocalOrientation();
 			MT_Vector3 childScale = gameobj->GetSGNode()->GetLocalScale();
 
 			bm->setLocalScaling(btVector3(childScale.x(),childScale.y(),childScale.z()));
-			childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z()));
+			shapeInfo->m_childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z()));
 			float rotval[12];
 			childRot.getValue(rotval);
 			btMatrix3x3 newRot;
 			newRot.setValue(rotval[0],rotval[1],rotval[2],rotval[4],rotval[5],rotval[6],rotval[8],rotval[9],rotval[10]);
 			newRot = newRot.transpose();
 
-			childTrans.setBasis(newRot);
-				
-
-			compoundShape->addChildShape(childTrans,bm);
-			kxscene->AddShape(bm);
+			shapeInfo->m_childTrans.setBasis(newRot);
+			parentShapeInfo->AddShape(shapeInfo);	
+			
+			compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
 			//do some recalc?
 			//recalc inertia for rigidbody
 			if (!rigidbody->isStaticOrKinematicObject())
@@ -1069,15 +845,16 @@ void	KX_ConvertBulletObject(	class	KX_GameObject* gameobj,
 
 		if (objprop->m_hasCompoundChildren)
 		{
-			//replace shape by compoundShape
+			// create a compound shape info
+			CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo();
+			compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND;
+			compoundShapeInfo->AddShape(shapeInfo);
+			// create the compound shape manually as we already have the child shape
 			btCompoundShape* compoundShape = new btCompoundShape();
-			btTransform identTrans;
-			identTrans.setIdentity();
-			compoundShape->addChildShape(identTrans,bm);
-			//note abount compoundShape: Bullet does not delete the child shapes when 
-			//the compound shape is deleted, so insert also the child shapes 
-			kxscene->AddShape(bm);
+			compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
+			// now replace the shape
 			bm = compoundShape;
+			shapeInfo = compoundShapeInfo;
 		}
 
 
@@ -1113,6 +890,7 @@ void	KX_ConvertBulletObject(	class	KX_GameObject* gameobj,
 
 
 	ci.m_collisionShape = bm;
+	ci.m_shapeInfo = shapeInfo;
 	ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
 	ci.m_restitution = smmaterial->m_restitution;
 	ci.m_physicsEnv = env;
@@ -1124,9 +902,12 @@ void	KX_ConvertBulletObject(	class	KX_GameObject* gameobj,
 	ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter);
 	ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
 	ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
+	MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
+	ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
 	KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
-	//remember that we created a shape so that we can delete it when the scene is removed (bullet will not delete it) 
-	kxscene->AddShape(bm);
+	// shapeInfo is reference counted, decrement now as we don't use it anymore
+	if (shapeInfo)
+		shapeInfo->Release();
 
 	if (objprop->m_in_active_layer)
 	{
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 700cc00e996c5e5c690e8616628c402d1eacef5b..c1b228e8d26bfdfabf33648e3b21da6a2a5e225d 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -51,6 +51,7 @@ typedef unsigned long uint_ptr;
 #include "KX_GameObject.h"
 #include "RAS_MeshObject.h"
 #include "KX_MeshProxy.h"
+#include "KX_PolyProxy.h"
 #include <stdio.h> // printf
 #include "SG_Controller.h"
 #include "KX_IPhysicsController.h"
@@ -84,6 +85,7 @@ KX_GameObject::KX_GameObject(
 	m_bVisible(true),
 	m_pPhysicsController1(NULL),
 	m_pPhysicsEnvironment(NULL),
+	m_xray(false),
 	m_pHitObject(NULL),
 	m_isDeformable(false)
 {
@@ -885,6 +887,8 @@ PyMethodDef KX_GameObject::Methods[] = {
 	{"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O},
 	{"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS},
 	{"setLinearVelocity", (PyCFunction) KX_GameObject::sPySetLinearVelocity, METH_VARARGS},
+	{"getAngularVelocity", (PyCFunction) KX_GameObject::sPyGetAngularVelocity, METH_VARARGS},
+	{"setAngularVelocity", (PyCFunction) KX_GameObject::sPySetAngularVelocity, METH_VARARGS},
 	{"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
 	{"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_NOARGS},
 	{"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_NOARGS},
@@ -1146,9 +1150,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value)	// _setattr
 }
 
 
-PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, 
-											 PyObject* args, 
-											 PyObject* kwds)
+PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, PyObject* args)
 {
 	// only can get the velocity if we have a physics object connected to us...
 	int local = 0;
@@ -1162,9 +1164,7 @@ PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self,
 	}
 }
 
-PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self, 
-											 PyObject* args, 
-											 PyObject* kwds)
+PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self, PyObject* args)
 {
 	int local = 0;
 	PyObject* pyvect;
@@ -1179,6 +1179,35 @@ PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self,
 	return NULL;
 }
 
+PyObject* KX_GameObject::PyGetAngularVelocity(PyObject* self, PyObject* args)
+{
+	// only can get the velocity if we have a physics object connected to us...
+	int local = 0;
+	if (PyArg_ParseTuple(args,"|i",&local))
+	{
+		return PyObjectFrom(GetAngularVelocity((local!=0)));
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args)
+{
+	int local = 0;
+	PyObject* pyvect;
+	
+	if (PyArg_ParseTuple(args,"O|i",&pyvect,&local)) {
+		MT_Vector3 velocity;
+		if (PyVecTo(pyvect, velocity)) {
+			setAngularVelocity(velocity, (local!=0));
+			Py_RETURN_NONE;
+		}
+	}
+	return NULL;
+}
+
 PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* value)
 {
 	int visible = PyInt_AsLong(value);
@@ -1228,9 +1257,7 @@ PyObject* KX_GameObject::PySetState(PyObject* self, PyObject* value)
 
 
 
-PyObject* KX_GameObject::PyGetVelocity(PyObject* self, 
-									   PyObject* args, 
-									   PyObject* kwds)
+PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args)
 {
 	// only can get the velocity if we have a physics object connected to us...
 	MT_Vector3 velocity(0.0,0.0,0.0);
@@ -1362,9 +1389,7 @@ PyObject* KX_GameObject::PyGetChildrenRecursive(PyObject* self)
 	return list;
 }
 
-PyObject* KX_GameObject::PyGetMesh(PyObject* self, 
-								   PyObject* args, 
-								   PyObject* kwds)
+PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args)
 {
 	int mesh = 0;
 
@@ -1404,9 +1429,7 @@ PyObject* KX_GameObject::PySetCollisionMargin(PyObject* self, PyObject* value)
 
 
 
-PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, 
-										PyObject* args, 
-										PyObject* kwds)
+PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, PyObject* args)
 {
 	PyObject* pyattach;
 	PyObject* pyimpulse;
@@ -1477,9 +1500,7 @@ PyObject* KX_GameObject::PySetOrientation(PyObject* self, PyObject* value)
 	return NULL;
 }
 
-PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, 
-										  PyObject* args, 
-										  PyObject* kwds)
+PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, PyObject* args)
 {
 	PyObject* pyvect;
 	int axis = 2; //z axis is the default
@@ -1609,25 +1630,45 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getVectTo,
 	return returnValue;
 }
 
-bool KX_GameObject::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+bool KX_GameObject::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
 {
+	KX_GameObject* hitKXObj = client->m_gameobject;
+	
+	// if X-ray option is selected, the unwnted objects were not tested, so get here only with true hit
+	// if not, all objects were tested and the front one may not be the correct one.
+	if (m_xray || m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL)
+	{
+		m_pHitObject = hitKXObj;
+		return true;
+	}
+	// return true to stop RayCast::RayTest from looping, the above test was decisive
+	// We would want to loop only if we want to get more than one hit point
+	return true;
+}
 
+/* this function is used to pre-filter the object before casting the ray on them.
+   This is useful for "X-Ray" option when we want to see "through" unwanted object.
+ */
+bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo* client)
+{
 	KX_GameObject* hitKXObj = client->m_gameobject;
 	
 	if (client->m_type > KX_ClientObjectInfo::ACTOR)
 	{
-		// false hit
+		// Unknown type of object, skip it.
+		// Should not occur as the sensor objects are filtered in RayTest()
+		printf("Invalid client type %d found in ray casting\n", client->m_type);
 		return false;
 	}
-
-	if (m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL)
+	
+	// if X-Ray option is selected, skip object that don't match the criteria as we see through them
+	// if not, test all objects because we don't know yet which one will be on front
+	if (!m_xray || m_testPropName.Length() == 0 || hitKXObj->GetProperty(m_testPropName) != NULL)
 	{
-		m_pHitObject = hitKXObj;
 		return true;
 	}
-
+	// skip the object
 	return false;
-	
 }
 
 KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
@@ -1667,8 +1708,6 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
 		toPoint = fromPoint + (dist) * toDir;
 	}
 
-	MT_Point3 resultPoint;
-	MT_Vector3 resultNormal;
 	PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment();
 	KX_IPhysicsController *spc = GetPhysicsController();
 	KX_GameObject *parent = GetParent();
@@ -1682,7 +1721,8 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
 		m_testPropName = propName;
 	else
 		m_testPropName.SetLength(0);
-	KX_RayCast::RayTest(spc, pe, fromPoint, toPoint, resultPoint, resultNormal, KX_RayCast::Callback<KX_GameObject>(this));
+	KX_RayCast::Callback<KX_GameObject> callback(this,spc);
+	KX_RayCast::RayTest(pe, fromPoint, toPoint, callback);
 
     if (m_pHitObject)
 	{
@@ -1693,13 +1733,24 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
 }
 
 KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
-				   "rayCast(to,from,dist,prop): cast a ray and return tuple (object,hit,normal) of contact point with object within dist that matches prop or (None,None,None) tuple if no hit\n"
-" prop = property name that object must have; can be omitted => detect any object\n"
-" dist = max distance to look (can be negative => look behind); 0 or omitted => detect up to to\n"
+				   "rayCast(to,from,dist,prop,face,xray,poly): cast a ray and return 3-tuple (object,hit,normal) or 4-tuple (object,hit,normal,polygon) of contact point with object within dist that matches prop.\n"
+				   " If no hit, return (None,None,None) or (None,None,None,None).\n"
+" to   = 3-tuple or object reference for destination of ray (if object, use center of object)\n"
 " from = 3-tuple or object reference for origin of ray (if object, use center of object)\n"
 "        Can be None or omitted => start from self object center\n"
-" to = 3-tuple or object reference for destination of ray (if object, use center of object)\n"
-"Note: the object on which you call this method matters: the ray will ignore it if it goes through it\n")
+" dist = max distance to look (can be negative => look behind); 0 or omitted => detect up to to\n"
+" prop = property name that object must have; can be omitted => detect any object\n"
+" face = normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin\n"
+" xray = X-ray option: 1=>skip objects that don't match prop; 0 or omitted => stop on first object\n"
+" poly = polygon option: 1=>return value is a 4-tuple and the 4th element is a KX_PolyProxy object\n"
+"                           which can be None if hit object has no mesh or if there is no hit\n"
+"        If 0 or omitted, return value is a 3-tuple\n"
+"Note: The object on which you call this method matters: the ray will ignore it.\n"
+"      prop and xray option interact as follow:\n"
+"        prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray\n"
+"        prop off, xray on : idem\n"
+"        prop on,  xray off: return closest hit if it matches prop, no hit otherwise\n"
+"        prop on,  xray on : return closest hit matching prop or no hit if there is no object matching prop on the full extend of the ray\n")
 {
 	MT_Point3 toPoint;
 	MT_Point3 fromPoint;
@@ -1708,8 +1759,9 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
 	float dist = 0.0f;
 	char *propName = NULL;
 	KX_GameObject *other;
+	int face=0, xray=0, poly=0;
 
-	if (!PyArg_ParseTuple(args,"O|Ofs", &pyto, &pyfrom, &dist, &propName)) {
+	if (!PyArg_ParseTuple(args,"O|Ofsiii", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly)) {
 		return NULL; // Python sets a simple error
 	}
 
@@ -1755,8 +1807,6 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
 		return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
 	}
 	
-	MT_Point3 resultPoint;
-	MT_Vector3 resultNormal;
 	PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment();
 	KX_IPhysicsController *spc = GetPhysicsController();
 	KX_GameObject *parent = GetParent();
@@ -1770,20 +1820,41 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
 		m_testPropName = propName;
 	else
 		m_testPropName.SetLength(0);
-	KX_RayCast::RayTest(spc, pe, fromPoint, toPoint, resultPoint, resultNormal, KX_RayCast::Callback<KX_GameObject>(this));
+	m_xray = xray;
+	// to get the hit results
+	KX_RayCast::Callback<KX_GameObject> callback(this,spc,NULL,face);
+	KX_RayCast::RayTest(pe, fromPoint, toPoint, callback);
 
-    if (m_pHitObject)
+	if (m_pHitObject)
 	{
-		PyObject* returnValue = PyTuple_New(3);
+		PyObject* returnValue = (poly) ? PyTuple_New(4) : PyTuple_New(3);
 		if (returnValue) { // unlikely this would ever fail, if it does python sets an error
 			PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->AddRef());
-			PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(resultPoint));
-			PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(resultNormal));
+			PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(callback.m_hitPoint));
+			PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(callback.m_hitNormal));
+			if (poly)
+			{
+				if (callback.m_hitMesh)
+				{
+					// if this field is set, then we can trust that m_hitPolygon is a valid polygon
+					RAS_Polygon* poly = callback.m_hitMesh->GetPolygon(callback.m_hitPolygon);
+					KX_PolyProxy* polyproxy = new KX_PolyProxy(callback.m_hitMesh, poly);
+					PyTuple_SET_ITEM(returnValue, 3, polyproxy);
+				}
+				else
+				{
+					Py_INCREF(Py_None);
+					PyTuple_SET_ITEM(returnValue, 3, Py_None);
+				}
+			}
 		}
 		return returnValue;
 	}
-	return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
-	//Py_RETURN_NONE;
+	// no hit
+	if (poly)
+		return Py_BuildValue("OOOO", Py_None, Py_None, Py_None, Py_None);
+	else
+		return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
 }
 
 /* --------------------------------------------------------------------- 
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index a7ac2d75a930b2824bd38580cb5c5d7c3f0742f3..508bc7cdfd00cdedec9e978b3f8b1c5460c6050b 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -54,6 +54,7 @@
 
 //Forward declarations.
 struct KX_ClientObjectInfo;
+class KX_RayCast;
 class RAS_MeshObject;
 class KX_IPhysicsController;
 class PHY_IPhysicsEnvironment;
@@ -88,6 +89,7 @@ protected:
 	// used for ray casting
 	PHY_IPhysicsEnvironment*			m_pPhysicsEnvironment;
 	STR_String							m_testPropName;
+	bool								m_xray;
 	KX_GameObject*						m_pHitObject;
 
 	SG_Node*							m_pSGNode;
@@ -428,7 +430,8 @@ public:
 		return (m_pSGNode && m_pSGNode->GetSGParent() && m_pSGNode->GetSGParent()->IsVertexParent());
 	}
 
-	bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+	bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
+	bool NeedRayCast(KX_ClientObjectInfo* client);
 
 
 	/**
@@ -726,9 +729,11 @@ public:
 
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition);
 	KX_PYMETHOD_O(KX_GameObject,SetPosition);
-	KX_PYMETHOD(KX_GameObject,GetLinearVelocity);
-	KX_PYMETHOD(KX_GameObject,SetLinearVelocity);
-	KX_PYMETHOD(KX_GameObject,GetVelocity);
+	KX_PYMETHOD_VARARGS(KX_GameObject,GetLinearVelocity);
+	KX_PYMETHOD_VARARGS(KX_GameObject,SetLinearVelocity);
+	KX_PYMETHOD_VARARGS(KX_GameObject,GetAngularVelocity);
+	KX_PYMETHOD_VARARGS(KX_GameObject,SetAngularVelocity);
+	KX_PYMETHOD_VARARGS(KX_GameObject,GetVelocity);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetMass);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetReactionForce);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetOrientation);
@@ -737,20 +742,20 @@ public:
 	KX_PYMETHOD_O(KX_GameObject,SetVisible);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetState);
 	KX_PYMETHOD_O(KX_GameObject,SetState);
-	KX_PYMETHOD(KX_GameObject,AlignAxisToVect);
+	KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
 	KX_PYMETHOD_O(KX_GameObject,GetAxisVect);
 	KX_PYMETHOD_NOARGS(KX_GameObject,SuspendDynamics);
 	KX_PYMETHOD_NOARGS(KX_GameObject,RestoreDynamics);
 	KX_PYMETHOD_NOARGS(KX_GameObject,EnableRigidBody);
 	KX_PYMETHOD_NOARGS(KX_GameObject,DisableRigidBody);
-	KX_PYMETHOD(KX_GameObject,ApplyImpulse);
+	KX_PYMETHOD_VARARGS(KX_GameObject,ApplyImpulse);
 	KX_PYMETHOD_O(KX_GameObject,SetCollisionMargin);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetParent);
 	KX_PYMETHOD_O(KX_GameObject,SetParent);
 	KX_PYMETHOD_NOARGS(KX_GameObject,RemoveParent);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetChildren);	
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetChildrenRecursive);
-	KX_PYMETHOD(KX_GameObject,GetMesh);
+	KX_PYMETHOD_VARARGS(KX_GameObject,GetMesh);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetPhysicsId);
 	KX_PYMETHOD_NOARGS(KX_GameObject,GetPropertyNames);
 	KX_PYMETHOD_NOARGS(KX_GameObject,EndObject);
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
index d3aa924665e6531574a741623b3f7b2ff1c1c2bb..6223643f75a6e6082ebd295a21c80b7291f88b79 100644
--- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
@@ -143,7 +143,7 @@ bool KX_IpoSGController::Update(double currentTime)
 		{
 			if (m_ipo_as_force == true) 
 			{
-				if (m_game_object && ob) 
+				if (m_game_object && ob && m_game_object->GetPhysicsController()) 
 				{
 					m_game_object->GetPhysicsController()->ApplyForce(m_ipo_local ?
 						ob->GetWorldOrientation() * m_ipo_xform.GetPosition() :
diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.cpp b/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
index 2ce5d4693807f578c1f1611db6bdd06c50ff3df6..85d514bd22f029c7d7a03a14d5f54f586a0c9b0b 100644
--- a/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
+++ b/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
@@ -3,6 +3,8 @@
 #include "KX_ScalarInterpolator.h"
 #include "KX_GameObject.h"
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -76,10 +78,10 @@ SG_Controller*	KX_MaterialIpoController::GetReplica(class SG_Node* destnode)
 		iporeplica->AddInterpolator(copyipo);
 
 		MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget();
-		long orgbase = (long)this;
-		long orgloc = (long)scaal;
-		long offset = orgloc-orgbase;
-		long newaddrbase = (long)iporeplica + offset;
+		intptr_t orgbase = (intptr_t)this;
+		intptr_t orgloc = (intptr_t)scaal;
+		intptr_t offset = orgloc-orgbase;
+		intptr_t newaddrbase = (intptr_t)iporeplica + offset;
 		MT_Scalar* blaptr = (MT_Scalar*) newaddrbase;
 		copyipo->SetNewTarget((MT_Scalar*)blaptr);
 	}
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index a0ac9cfd4ff0338dfd57172e2a147d50da10ab29..29842af7fb6b6c116ac4ae0414f639c7e6d60b81 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -35,6 +35,7 @@
 #include "RAS_MeshObject.h"
 
 #include "KX_VertexProxy.h"
+#include "KX_PolyProxy.h"
 
 #include "KX_PolygonMaterial.h"
 #include "KX_BlenderMaterial.h"
@@ -71,10 +72,12 @@ PyParentObject KX_MeshProxy::Parents[] = {
 
 PyMethodDef KX_MeshProxy::Methods[] = {
 {"getNumMaterials", (PyCFunction)KX_MeshProxy::sPyGetNumMaterials,METH_VARARGS},
+{"getNumPolygons", (PyCFunction)KX_MeshProxy::sPyGetNumPolygons,METH_NOARGS},
 {"getMaterialName", (PyCFunction)KX_MeshProxy::sPyGetMaterialName,METH_VARARGS},
 {"getTextureName", (PyCFunction)KX_MeshProxy::sPyGetTextureName,METH_VARARGS},
 {"getVertexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetVertexArrayLength,METH_VARARGS},
 {"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS},
+{"getPolygon", (PyCFunction)KX_MeshProxy::sPyGetPolygon,METH_VARARGS},
 KX_PYMETHODTABLE(KX_MeshProxy, reinstancePhysicsMesh),
 //{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS},
 
@@ -146,6 +149,12 @@ PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* self,
 	return PyInt_FromLong(num);
 }
 
+PyObject* KX_MeshProxy::PyGetNumPolygons(PyObject* self)
+{
+	int num = m_meshobj->NumPolygons();
+	return PyInt_FromLong(num);
+}
+
 PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* self, 
 			       PyObject* args, 
 			       PyObject* kwds)
@@ -234,6 +243,28 @@ PyObject* KX_MeshProxy::PyGetVertex(PyObject* self,
 		
 }
 
+PyObject* KX_MeshProxy::PyGetPolygon(PyObject* self,
+			       PyObject* args, 
+			       PyObject* kwds)
+{
+    int polyindex= 1;
+	PyObject* polyob = NULL;
+
+	if (!PyArg_ParseTuple(args,"i",&polyindex))
+		return NULL;
+
+	RAS_Polygon* polygon = m_meshobj->GetPolygon(polyindex);
+	if (polygon)
+	{
+		polyob = new KX_PolyProxy(m_meshobj, polygon);
+	}
+	else
+	{
+		PyErr_SetString(PyExc_AttributeError, "Invalid polygon index");
+	}
+	return polyob;
+}
+
 KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh,
 "Reinstance the physics mesh.")
 {
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h
index 7c6202c15a4661bd4c312d74fe39d2d7f9ef8641..3335c349673f6b690aa6f605e4d67048f9751a32 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.h
+++ b/source/gameengine/Ketsji/KX_MeshProxy.h
@@ -57,10 +57,12 @@ public:
 	KX_PYMETHOD(KX_MeshProxy,GetNumMaterials);
 	KX_PYMETHOD(KX_MeshProxy,GetMaterialName);
 	KX_PYMETHOD(KX_MeshProxy,GetTextureName);
+	KX_PYMETHOD_NOARGS(KX_MeshProxy,GetNumPolygons);
 	
 	// both take materialid (int)
 	KX_PYMETHOD(KX_MeshProxy,GetVertexArrayLength);
 	KX_PYMETHOD(KX_MeshProxy,GetVertex);
+	KX_PYMETHOD(KX_MeshProxy,GetPolygon);
 	KX_PYMETHOD_DOC(KX_MeshProxy, reinstancePhysicsMesh);
 };
 
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index db0bef8b7e1d504f4d6910c4cc2b91697ffb4d70..3156f543ed57caf0c2297b7f328a5c0c35251b9d 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -122,16 +122,10 @@ bool KX_MouseFocusSensor::Evaluate(CValue* event)
 	return result;
 }
 
-bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo* client_info, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo* client_info, KX_RayCast* result, void * const data)
 {
 	KX_GameObject* hitKXObj = client_info->m_gameobject;
 	
-	if (client_info->m_type > KX_ClientObjectInfo::ACTOR)
-	{
-		// false hit
-		return false;
-	}
-	
 	/* Is this me? In the ray test, there are a lot of extra checks
 	* for aliasing artefacts from self-hits. That doesn't happen
 	* here, so a simple test suffices. Or does the camera also get
@@ -142,8 +136,8 @@ bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo* client_info, MT_Point3& hi
 	if ((m_focusmode == 2) || hitKXObj == thisObj)
 	{
 		m_hitObject = hitKXObj;
-		m_hitPosition = hit_point;
-		m_hitNormal = hit_normal;
+		m_hitPosition = result->m_hitPoint;
+		m_hitNormal = result->m_hitNormal;
 		return true;
 	}
 	
@@ -158,8 +152,6 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
 	m_hitObject = 0;
 	m_hitPosition = MT_Vector3(0,0,0);
 	m_hitNormal =	MT_Vector3(1,0,0);
-	MT_Point3 resultpoint;
-	MT_Vector3 resultnormal;
 
 	/* All screen handling in the gameengine is done by GL,
 	 * specifically the model/view and projection parts. The viewport
@@ -280,7 +272,8 @@ bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
 
 	bool result = false;
 
-	result = KX_RayCast::RayTest(physics_controller, physics_environment, frompoint3, topoint3, resultpoint, resultnormal, KX_RayCast::Callback<KX_MouseFocusSensor>(this));
+	KX_RayCast::Callback<KX_MouseFocusSensor> callback(this,physics_controller);
+	KX_RayCast::RayTest(physics_environment, frompoint3, topoint3, callback);
 	
 	result = (m_hitObject!=0);
 
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index b011ebe1288e9bc713a6674e746d53481f6af56c..a6cc39d66ebc41ae15cf8d5d1337810d3699d2d3 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -33,6 +33,8 @@
 
 #include "SCA_MouseSensor.h"
 
+class KX_RayCast;
+
 /**
  * The mouse focus sensor extends the basic SCA_MouseSensor. It has
  * been placed in KX because it needs access to the rasterizer and
@@ -76,7 +78,9 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
 		return result;
 	};
 
-	bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+	bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
+	bool NeedRayCast(KX_ClientObjectInfo* client) { return true; }
+	
 
 	
 	/* --------------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..658c8a98e4f34c706989b1ded5b327f292f6675e
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp
@@ -0,0 +1,265 @@
+/**
+ * $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 *****
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "KX_PolyProxy.h"
+#include "KX_MeshProxy.h"
+#include "RAS_MeshObject.h"
+#include "KX_BlenderMaterial.h"
+#include "KX_PolygonMaterial.h"
+
+#include "KX_PyMath.h"
+
+PyTypeObject KX_PolyProxy::Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"KX_PolyProxy",
+	sizeof(KX_PolyProxy),
+	0,
+	PyDestructor,
+	0,
+	__getattr,
+	__setattr,
+	0, //&MyPyCompare,
+	__repr,
+	0, //&cvalue_as_number,
+	0,
+	0,
+	0,
+	0
+};
+
+PyParentObject KX_PolyProxy::Parents[] = {
+	&KX_PolyProxy::Type,
+	&SCA_IObject::Type,
+	&CValue::Type,
+	NULL
+};
+
+PyMethodDef KX_PolyProxy::Methods[] = {
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,getMaterialIndex),
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,getNumVertex),
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,isVisible),
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,isCollider),
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,getMaterialName),
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,getTextureName),
+	KX_PYMETHODTABLE(KX_PolyProxy,getVertexIndex),
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,getMesh),
+	KX_PYMETHODTABLE_NOARG(KX_PolyProxy,getMaterial),
+	{NULL,NULL} //Sentinel
+};
+
+PyObject*
+KX_PolyProxy::_getattr(const STR_String& attr)
+{
+	if (attr == "matname")
+	{
+		return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
+	}
+	if (attr == "texture")
+	{
+		return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
+	}
+	if (attr == "material")
+	{
+		RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
+		if(polymat->GetFlag() & RAS_BLENDERMAT)
+		{
+			KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
+			Py_INCREF(mat);
+			return mat;
+		}
+		else
+		{
+			KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
+			Py_INCREF(mat);
+			return mat;
+		}
+	}
+	if (attr == "matid")
+	{
+		// we'll have to scan through the material bucket of the mes and compare with 
+		// the one of the polygon
+		RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
+		unsigned int matid;
+		for (matid=0; matid<m_mesh->NumMaterials(); matid++)
+		{
+			RAS_MaterialBucket* meshBucket = m_mesh->GetMaterialBucket(matid);
+			if (meshBucket == polyBucket)
+				// found it
+				break;
+		}
+		return PyInt_FromLong(matid);
+	}
+	if (attr == "v1")
+	{
+		return PyInt_FromLong(m_polygon->GetVertexIndexBase().m_indexarray[0]);
+	}
+	if (attr == "v2")
+	{
+		return PyInt_FromLong(m_polygon->GetVertexIndexBase().m_indexarray[1]);
+	}
+	if (attr == "v3")
+	{
+		return PyInt_FromLong(m_polygon->GetVertexIndexBase().m_indexarray[2]);
+	}
+	if (attr == "v4")
+	{
+		return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexIndexBase().m_indexarray[3]:0));
+	}
+	if (attr == "visible")
+	{
+		return PyInt_FromLong(m_polygon->IsVisible());
+	}
+	if (attr == "collide")
+	{
+		return PyInt_FromLong(m_polygon->IsCollider());
+	}
+	_getattr_up(SCA_IObject);
+}
+
+KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
+:	m_mesh((RAS_MeshObject*)mesh),
+	m_polygon(polygon)
+{
+}
+
+KX_PolyProxy::~KX_PolyProxy()
+{
+}
+
+
+// stuff for cvalue related things
+CValue*		KX_PolyProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;}
+CValue*		KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;}	
+STR_String	sPolyName="polygone";
+const STR_String &	KX_PolyProxy::GetText() {return sPolyName;};
+float		KX_PolyProxy::GetNumber() { return -1;}
+STR_String	KX_PolyProxy::GetName() { return sPolyName;}
+void		KX_PolyProxy::SetName(STR_String) { };
+CValue*		KX_PolyProxy::GetReplica() { return NULL;}
+void		KX_PolyProxy::ReplicaSetName(STR_String) {};
+
+
+// stuff for python integration
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, getMaterialIndex, 
+"getMaterialIndex() : return the material index of the polygon in the mesh\n")
+{
+	RAS_MaterialBucket* polyBucket = m_polygon->GetMaterial();
+	unsigned int matid;
+	for (matid=0; matid<m_mesh->NumMaterials(); matid++)
+	{
+		RAS_MaterialBucket* meshBucket = m_mesh->GetMaterialBucket(matid);
+		if (meshBucket == polyBucket)
+			// found it
+			break;
+	}
+	return PyInt_FromLong(matid);
+}
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, getNumVertex,
+"getNumVertex() : returns the number of vertex of the polygon, 3 or 4\n")
+{
+	return PyInt_FromLong(m_polygon->VertexCount());
+}
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, isVisible,
+"isVisible() : returns whether the polygon is visible or not\n")
+{
+	return PyInt_FromLong(m_polygon->IsVisible());
+}
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, isCollider,
+"isCollider() : returns whether the polygon is receives collision or not\n")
+{
+	return PyInt_FromLong(m_polygon->IsCollider());
+}
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, getMaterialName,
+"getMaterialName() : returns the polygon material name, \"NoMaterial\" if no material\n")
+{
+	return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
+}
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, getTextureName,
+"getTexturelName() : returns the polygon texture name, \"NULL\" if no texture\n")
+{
+	return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
+}
+
+KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex,
+"getVertexIndex(vertex) : returns the mesh vertex index of a polygon vertex\n"
+"vertex: index of the vertex in the polygon: 0->3\n"
+"return value can be used to retrieve the vertex details through mesh proxy\n"
+"Note: getVertexIndex(3) on a triangle polygon returns 0\n")
+{
+	int index;
+	if (!PyArg_ParseTuple(args,"i",&index))
+	{
+		return NULL;
+	}
+	if (index < 0 || index > 3)
+	{
+		PyErr_SetString(PyExc_AttributeError, "Valid range for index is 0-3");
+		return NULL;
+	}
+	if (index < m_polygon->VertexCount())
+	{
+		return PyInt_FromLong(m_polygon->GetVertexIndexBase().m_indexarray[index]);
+	}
+	return PyInt_FromLong(0);
+}
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, getMesh,
+"getMesh() : returns a mesh proxy\n")
+{
+	KX_MeshProxy* meshproxy = new KX_MeshProxy((RAS_MeshObject*)m_mesh);
+	return meshproxy;
+}
+
+KX_PYMETHODDEF_DOC_NOARG(KX_PolyProxy, getMaterial,
+"getMaterial() : returns a material\n")
+{
+	RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
+	if(polymat->GetFlag() & RAS_BLENDERMAT)
+	{
+		KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat);
+		Py_INCREF(mat);
+		return mat;
+	}
+	else
+	{
+		KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat);
+		Py_INCREF(mat);
+		return mat;
+	}
+}
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..506e2c2a65692fb0f625a8f05c33318faace8b5d
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_PolyProxy.h
@@ -0,0 +1,71 @@
+/**
+ * $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 *****
+ */
+#ifndef __KX_POLYROXY
+#define __KX_POLYPROXY
+
+#include "SCA_IObject.h"
+
+class KX_PolyProxy	: public SCA_IObject
+{
+	Py_Header;
+protected:
+	class RAS_Polygon*		m_polygon;
+	class RAS_MeshObject*	m_mesh;
+public:
+	KX_PolyProxy(const class RAS_MeshObject*mesh, class RAS_Polygon* polygon);
+	virtual ~KX_PolyProxy();
+
+	// stuff for cvalue related things
+	CValue*		Calc(VALUE_OPERATOR op, CValue *val) ;
+	CValue*		CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+	const STR_String &	GetText();
+	float		GetNumber();
+	STR_String	GetName();
+	void		SetName(STR_String name);								// Set the name of the value
+	void		ReplicaSetName(STR_String name);
+	CValue*		GetReplica();
+
+
+// stuff for python integration
+	virtual PyObject* _getattr(const STR_String& attr);
+
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterialIndex)
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getNumVertex)
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,isVisible)
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,isCollider)
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterialName)
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getTextureName)
+	KX_PYMETHOD_DOC(KX_PolyProxy,getVertexIndex)
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMesh)
+	KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterial)
+
+};
+
+#endif //__KX_POLYPROXY
+
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 868439546c3cff404f04b3fdf970e0653989da46..e9fb0278d7603bfb5bb2d4222ec21d64bc7d1a30 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -30,7 +30,13 @@
 
 #include "GL/glew.h"
 
+// directory header for py function getBlendFileList
 #include <stdlib.h>
+#ifndef WIN32
+  #include <dirent.h>
+#else
+  #include "BLI_winstuff.h"
+#endif
 
 #ifdef WIN32
 #pragma warning (disable : 4786)
@@ -112,9 +118,7 @@ static PyObject* gPyGetRandomFloat(PyObject*)
 	return PyFloat_FromDouble(MT_random());
 }
 
-static PyObject* gPySetGravity(PyObject*,
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPySetGravity(PyObject*, PyObject* args)
 {
 	MT_Vector3 vec = MT_Vector3(0., 0., 0.);
 	if (PyVecArgTo(args, vec))
@@ -138,9 +142,7 @@ file to make a full path name (doesn't change during the game, even if you load\
 other .blend).\n\
 The function also converts the directory separator to the local file system format.";
 
-static PyObject* gPyExpandPath(PyObject*,
-								PyObject* args, 
-								PyObject*)
+static PyObject* gPyExpandPath(PyObject*, PyObject* args)
 {
 	char expanded[FILE_MAXDIR + FILE_MAXFILE];
 	char* filename;
@@ -185,9 +187,7 @@ static PyObject* gPyGetSpectrum(PyObject*)
 
 
 
-static PyObject* gPyStartDSP(PyObject*,
-						PyObject* args, 
-						PyObject*)
+static PyObject* gPyStartDSP(PyObject*, PyObject* args)
 {
 	SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
 
@@ -205,9 +205,7 @@ static PyObject* gPyStartDSP(PyObject*,
 
 
 
-static PyObject* gPyStopDSP(PyObject*,
-					   PyObject* args, 
-					   PyObject*)
+static PyObject* gPyStopDSP(PyObject*, PyObject* args)
 {
 	SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
 
@@ -223,9 +221,7 @@ static PyObject* gPyStopDSP(PyObject*,
 	return NULL;
 }
 
-static PyObject* gPySetLogicTicRate(PyObject*,
-					PyObject* args,
-					PyObject*)
+static PyObject* gPySetLogicTicRate(PyObject*, PyObject* args)
 {
 	float ticrate;
 	if (PyArg_ParseTuple(args, "f", &ticrate))
@@ -242,9 +238,7 @@ static PyObject* gPyGetLogicTicRate(PyObject*)
 	return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate());
 }
 
-static PyObject* gPySetPhysicsTicRate(PyObject*,
-					PyObject* args,
-					PyObject*)
+static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args)
 {
 	float ticrate;
 	if (PyArg_ParseTuple(args, "f", &ticrate))
@@ -257,9 +251,7 @@ static PyObject* gPySetPhysicsTicRate(PyObject*,
 	return NULL;
 }
 
-static PyObject* gPySetPhysicsDebug(PyObject*,
-					PyObject* args,
-					PyObject*)
+static PyObject* gPySetPhysicsDebug(PyObject*, PyObject* args)
 {
 	int debugMode;
 	if (PyArg_ParseTuple(args, "i", &debugMode))
@@ -278,6 +270,44 @@ static PyObject* gPyGetPhysicsTicRate(PyObject*)
 	return PyFloat_FromDouble(PHY_GetActiveEnvironment()->getFixedTimeStep());
 }
 
+static PyObject* gPyGetBlendFileList(PyObject*, PyObject* args)
+{
+	char cpath[sizeof(G.sce)];
+	char *searchpath = NULL;
+	PyObject* list;
+	
+    DIR *dp;
+    struct dirent *dirp;
+	
+	if (!PyArg_ParseTuple(args, "|s", &searchpath))
+		return NULL;
+	
+	list = PyList_New(0);
+	
+	if (searchpath) {
+		BLI_strncpy(cpath, searchpath, FILE_MAXDIR + FILE_MAXFILE);
+		BLI_convertstringcode(cpath, G.sce);
+	} else {
+		/* Get the dir only */
+		BLI_split_dirfile_basic(G.sce, cpath, NULL);
+	}
+	
+    if((dp  = opendir(cpath)) == NULL) {
+		/* todo, show the errno, this shouldnt happen anyway if the blendfile is readable */
+		fprintf(stderr, "Could not read directoty () failed, code %d (%s)\n", cpath, errno, strerror(errno));
+		return list;
+    }
+	
+    while ((dirp = readdir(dp)) != NULL) {
+		if (BLI_testextensie(dirp->d_name, ".blend")) {
+			PyList_Append(list, PyString_FromString(dirp->d_name));
+		}
+    }
+	
+    closedir(dp);
+    return list;
+}
+
 static STR_String gPyGetCurrentScene_doc =  
 "getCurrentScene()\n"
 "Gets a reference to the current scene.\n";
@@ -377,14 +407,13 @@ static struct PyMethodDef game_methods[] = {
 	{"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, "Sets the logic tic rate"},
 	{"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, "Gets the physics tic rate"},
 	{"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, "Sets the physics tic rate"},
+	{"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, "Gets a list of blend files in the same directory as the current blend file"},
 	{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, "Prints GL Extension Info"},
 	{NULL, (PyCFunction) NULL, 0, NULL }
 };
 
 
-static PyObject* gPyGetWindowHeight(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args)
 {
 	int height = (gp_Canvas ? gp_Canvas->GetHeight() : 0);
 
@@ -394,9 +423,7 @@ static PyObject* gPyGetWindowHeight(PyObject*,
 
 
 
-static PyObject* gPyGetWindowWidth(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPyGetWindowWidth(PyObject*, PyObject* args)
 {
 		
 
@@ -411,9 +438,7 @@ static PyObject* gPyGetWindowWidth(PyObject*,
 // temporarility visibility thing, will be moved to rasterizer/renderer later
 bool gUseVisibilityTemp = false;
 
-static PyObject* gPyEnableVisibility(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPyEnableVisibility(PyObject*, PyObject* args)
 {
 	int visible;
 	if (PyArg_ParseTuple(args,"i",&visible))
@@ -429,9 +454,7 @@ static PyObject* gPyEnableVisibility(PyObject*,
 
 
 
-static PyObject* gPyShowMouse(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPyShowMouse(PyObject*, PyObject* args)
 {
 	int visible;
 	if (PyArg_ParseTuple(args,"i",&visible))
@@ -455,9 +478,7 @@ static PyObject* gPyShowMouse(PyObject*,
 
 
 
-static PyObject* gPySetMousePosition(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPySetMousePosition(PyObject*, PyObject* args)
 {
 	int x,y;
 	if (PyArg_ParseTuple(args,"ii",&x,&y))
@@ -472,9 +493,7 @@ static PyObject* gPySetMousePosition(PyObject*,
    Py_Return;
 }
 
-static PyObject* gPySetEyeSeparation(PyObject*,
-						PyObject* args,
-						PyObject*)
+static PyObject* gPySetEyeSeparation(PyObject*, PyObject* args)
 {
 	float sep;
 	if (PyArg_ParseTuple(args, "f", &sep))
@@ -496,9 +515,7 @@ static PyObject* gPyGetEyeSeparation(PyObject*, PyObject*, PyObject*)
 	return NULL;
 }
 
-static PyObject* gPySetFocalLength(PyObject*,
-					PyObject* args,
-					PyObject*)
+static PyObject* gPySetFocalLength(PyObject*, PyObject* args)
 {
 	float focus;
 	if (PyArg_ParseTuple(args, "f", &focus))
@@ -518,9 +535,7 @@ static PyObject* gPyGetFocalLength(PyObject*, PyObject*, PyObject*)
 	return NULL;
 }
 
-static PyObject* gPySetBackgroundColor(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPySetBackgroundColor(PyObject*, PyObject* args)
 {
 	
 	MT_Vector4 vec = MT_Vector4(0., 0., 0.3, 0.);
@@ -538,9 +553,7 @@ static PyObject* gPySetBackgroundColor(PyObject*,
 
 
 
-static PyObject* gPySetMistColor(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPySetMistColor(PyObject*, PyObject* args)
 {
 	
 	MT_Vector3 vec = MT_Vector3(0., 0., 0.);
@@ -558,9 +571,7 @@ static PyObject* gPySetMistColor(PyObject*,
 
 
 
-static PyObject* gPySetMistStart(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPySetMistStart(PyObject*, PyObject* args)
 {
 
 	float miststart;
@@ -579,9 +590,7 @@ static PyObject* gPySetMistStart(PyObject*,
 
 
 
-static PyObject* gPySetMistEnd(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPySetMistEnd(PyObject*, PyObject* args)
 {
 
 	float mistend;
@@ -599,9 +608,7 @@ static PyObject* gPySetMistEnd(PyObject*,
 }
 
 
-static PyObject* gPySetAmbientColor(PyObject*, 
-										 PyObject* args, 
-										 PyObject*)
+static PyObject* gPySetAmbientColor(PyObject*, PyObject* args)
 {
 	
 	MT_Vector3 vec = MT_Vector3(0., 0., 0.);
@@ -620,9 +627,7 @@ static PyObject* gPySetAmbientColor(PyObject*,
 
 
 
-static PyObject* gPyMakeScreenshot(PyObject*,
-									PyObject* args,
-									PyObject*)
+static PyObject* gPyMakeScreenshot(PyObject*, PyObject* args)
 {
 	char* filename;
 	if (PyArg_ParseTuple(args,"s",&filename))
@@ -638,9 +643,7 @@ static PyObject* gPyMakeScreenshot(PyObject*,
 	Py_Return;
 }
 
-static PyObject* gPyEnableMotionBlur(PyObject*,
-									PyObject* args,
-									PyObject*)
+static PyObject* gPyEnableMotionBlur(PyObject*, PyObject* args)
 {
 	float motionblurvalue;
 	if (PyArg_ParseTuple(args,"f",&motionblurvalue))
@@ -656,9 +659,7 @@ static PyObject* gPyEnableMotionBlur(PyObject*,
 	Py_Return;
 }
 
-static PyObject* gPyDisableMotionBlur(PyObject*,
-									PyObject* args,
-									PyObject*)
+static PyObject* gPyDisableMotionBlur(PyObject*, PyObject* args)
 {
 	if(gp_Rasterizer)
 	{
@@ -733,6 +734,10 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook
 
 	// Add some symbolic constants to the module
 	d = PyModule_GetDict(m);
+	
+	// can be overwritten later for gameEngine instances that can load new blend files and re-initialize this module
+	// for now its safe to make sure it exists for other areas such as the web plugin
+	PyDict_SetItemString(d, "globalDict", PyDict_New());
 
 	ErrorObject = PyString_FromString("GameLogic.error");
 	PyDict_SetItemString(d, "error", ErrorObject);
@@ -847,13 +852,30 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook
 // override builtin functions import() and open()
 
 
-PyObject *KXpy_open(PyObject *self, PyObject *args)
-{
+PyObject *KXpy_open(PyObject *self, PyObject *args) {
 	PyErr_SetString(PyExc_RuntimeError, "Sandbox: open() function disabled!\nGame Scripts should not use this function.");
 	return NULL;
 }
 
+PyObject *KXpy_reload(PyObject *self, PyObject *args) {
+	PyErr_SetString(PyExc_RuntimeError, "Sandbox: reload() function disabled!\nGame Scripts should not use this function.");
+	return NULL;
+}
+
+PyObject *KXpy_file(PyObject *self, PyObject *args) {
+	PyErr_SetString(PyExc_RuntimeError, "Sandbox: file() function disabled!\nGame Scripts should not use this function.");
+	return NULL;
+}
+
+PyObject *KXpy_execfile(PyObject *self, PyObject *args) {
+	PyErr_SetString(PyExc_RuntimeError, "Sandbox: execfile() function disabled!\nGame Scripts should not use this function.");
+	return NULL;
+}
 
+PyObject *KXpy_compile(PyObject *self, PyObject *args) {
+	PyErr_SetString(PyExc_RuntimeError, "Sandbox: compile() function disabled!\nGame Scripts should not use this function.");
+	return NULL;
+}
 
 PyObject *KXpy_import(PyObject *self, PyObject *args)
 {
@@ -890,19 +912,13 @@ PyObject *KXpy_import(PyObject *self, PyObject *args)
 }
 
 
+static PyMethodDef meth_open[] = {{ "open", KXpy_open, METH_VARARGS, "(disabled)"}};
+static PyMethodDef meth_reload[] = {{ "reload", KXpy_reload, METH_VARARGS, "(disabled)"}};
+static PyMethodDef meth_file[] = {{ "file", KXpy_file, METH_VARARGS, "(disabled)"}};
+static PyMethodDef meth_execfile[] = {{ "execfile", KXpy_execfile, METH_VARARGS, "(disabled)"}};
+static PyMethodDef meth_compile[] = {{ "compile", KXpy_compile, METH_VARARGS, "(disabled)"}};
 
-static PyMethodDef meth_open[] = {
-	{ "open", KXpy_open, METH_VARARGS,
-		"(disabled)"}
-};
-
-
-static PyMethodDef meth_import[] = {
-	{ "import", KXpy_import, METH_VARARGS,
-		"our own import"}
-};
-
-
+static PyMethodDef meth_import[] = {{ "import", KXpy_import, METH_VARARGS, "our own import"}};
 
 //static PyObject *g_oldopen = 0;
 //static PyObject *g_oldimport = 0;
@@ -913,15 +929,21 @@ void setSandbox(TPythonSecurityLevel level)
 {
     PyObject *m = PyImport_AddModule("__builtin__");
     PyObject *d = PyModule_GetDict(m);
-	PyObject *meth = PyCFunction_New(meth_open, NULL);
 
 	switch (level) {
 	case psl_Highest:
 		//if (!g_security) {
 			//g_oldopen = PyDict_GetItemString(d, "open");
-			PyDict_SetItemString(d, "open", meth);
-			meth = PyCFunction_New(meth_import, NULL);
-			PyDict_SetItemString(d, "__import__", meth);
+	
+			// functions we cant trust
+			PyDict_SetItemString(d, "open", PyCFunction_New(meth_open, NULL));
+			PyDict_SetItemString(d, "reload", PyCFunction_New(meth_reload, NULL));
+			PyDict_SetItemString(d, "file", PyCFunction_New(meth_file, NULL));
+			PyDict_SetItemString(d, "execfile", PyCFunction_New(meth_execfile, NULL));
+			PyDict_SetItemString(d, "compile", PyCFunction_New(meth_compile, NULL));
+			
+			// our own import
+			PyDict_SetItemString(d, "__import__", PyCFunction_New(meth_import, NULL));
 			//g_security = level;
 		//}
 		break;
@@ -1026,9 +1048,38 @@ static char GameKeys_module_documentation[] =
 "This modules provides defines for key-codes"
 ;
 
+static char gPyEventToString_doc[] =
+"Take a valid event from the GameKeys module or Keyboard Sensor and return a name"
+;
 
+static PyObject* gPyEventToString(PyObject*, PyObject* value)
+{
+	PyObject* mod, *dict, *key, *val, *ret = NULL;
+	Py_ssize_t pos = 0;
+	
+	mod = PyImport_ImportModule( "GameKeys" );
+	if (!mod)
+		return NULL;
+	
+	dict = PyModule_GetDict(mod);
+	
+	while (PyDict_Next(dict, &pos, &key, &val)) {
+		if (PyObject_Compare(value, val)==0) {
+			ret = key;
+			break;
+		}
+	}
+	
+	PyErr_Clear(); // incase there was an error clearing
+	Py_DECREF(mod);
+	if (!ret)	PyErr_SetString(PyExc_ValueError, "expected a valid int keyboard event");
+	else		Py_INCREF(ret);
+	
+	return ret;
+}
 
 static struct PyMethodDef gamekeys_methods[] = {
+	{"EventToString", (PyCFunction)gPyEventToString, METH_O, gPyEventToString_doc},
 	{ NULL, (PyCFunction) NULL, 0, NULL }
 };
 
diff --git a/source/gameengine/Ketsji/KX_RayCast.cpp b/source/gameengine/Ketsji/KX_RayCast.cpp
index 89e2d645d545b59e97b5ce6d6b01b1f76c46de13..974d4b992a647443b8f3f2d5235f87d378db53bb 100644
--- a/source/gameengine/Ketsji/KX_RayCast.cpp
+++ b/source/gameengine/Ketsji/KX_RayCast.cpp
@@ -40,7 +40,21 @@
 #include "PHY_IPhysicsEnvironment.h"
 #include "PHY_IPhysicsController.h"
 
-bool KX_RayCast::RayTest(KX_IPhysicsController* ignore_controller, PHY_IPhysicsEnvironment* physics_environment, const MT_Point3& _frompoint, const MT_Point3& topoint, MT_Point3& result_point, MT_Vector3& result_normal, const KX_RayCast& callback)
+KX_RayCast::KX_RayCast(KX_IPhysicsController* ignoreController, bool faceNormal)
+	:PHY_IRayCastFilterCallback(dynamic_cast<PHY_IPhysicsController*>(ignoreController), faceNormal) 
+{
+}
+
+void KX_RayCast::reportHit(PHY_RayCastResult* result)
+{
+	m_hitFound = true;
+	m_hitPoint.setValue((const float*)result->m_hitPoint);
+	m_hitNormal.setValue((const float*)result->m_hitNormal);
+	m_hitMesh = result->m_meshObject;
+	m_hitPolygon = result->m_polygon;
+}
+
+bool KX_RayCast::RayTest(PHY_IPhysicsEnvironment* physics_environment, const MT_Point3& _frompoint, const MT_Point3& topoint, KX_RayCast& callback)
 {
 	// Loops over all physics objects between frompoint and topoint,
 	// calling callback.RayHit for each one.
@@ -50,58 +64,51 @@ bool KX_RayCast::RayTest(KX_IPhysicsController* ignore_controller, PHY_IPhysicsE
 	// returns true if an object was found, false if not.
 	MT_Point3 frompoint(_frompoint);
 	const MT_Vector3 todir( (topoint - frompoint).safe_normalized() );
+	MT_Point3 prevpoint(_frompoint+todir*(-1.f));
 	
 	PHY_IPhysicsController* hit_controller;
-	PHY__Vector3 phy_pos;
-	PHY__Vector3 phy_normal;
 
-	while((hit_controller = physics_environment->rayTest(dynamic_cast<PHY_IPhysicsController*>(ignore_controller),
+	while((hit_controller = physics_environment->rayTest(callback,
 			frompoint.x(),frompoint.y(),frompoint.z(),
-			topoint.x(),topoint.y(),topoint.z(),
-			phy_pos[0],phy_pos[1],phy_pos[2],
-			phy_normal[0],phy_normal[1],phy_normal[2]))) 
+			topoint.x(),topoint.y(),topoint.z())) != NULL) 
 	{
-		result_point = MT_Point3(phy_pos);
-		result_normal = MT_Vector3(phy_normal);
 		KX_ClientObjectInfo* info = static_cast<KX_ClientObjectInfo*>(hit_controller->getNewClientInfo());
 		
 		if (!info)
 		{
 			printf("no info!\n");
 			MT_assert(info && "Physics controller with no client object info");
-			return false;
+			break;
 		}
 		
-		if (callback.RayHit(info, result_point, result_normal))
-			return true;
-	
-		// There is a bug in the code below: the delta is computed with the wrong
-		// sign on the face opposite to the center, resulting in infinite looping.
-		// In Blender 2.45 this code was never executed because callback.RayHit() always 
-		// returned true, causing the ray sensor to stop on the first object.
-		// To avoid changing the behaviour will simply return false here.
-		// It should be discussed if we want the ray sensor to "see" through objects
-		// that don't have the required property/material (condition to get here)
-		return false;
-	
-		// skip past the object and keep tracing
-		/* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */
-		MT_Scalar marg = 0.01 + hit_controller->GetMargin();
-		marg += 2.f * hit_controller->GetMargin();
+		// The biggest danger to to endless loop, prevent this by checking that the
+		// hit point always progresses along the ray direction..
+		prevpoint -= callback.m_hitPoint;
+		if (prevpoint.length2() < MT_EPSILON)
+			break;
+
+		if (callback.RayHit(info))
+			// caller may decide to stop the loop and still cancel the hit
+			return callback.m_hitFound;
+
+		// Skip past the object and keep tracing.
+		// Note that retrieving in a single shot multiple hit points would be possible 
+		// but it would require some change in Bullet.
+		prevpoint = callback.m_hitPoint;
+		/* We add 0.001 of fudge, so that if the margin && radius == 0., we don't endless loop. */
+		MT_Scalar marg = 0.001 + hit_controller->GetMargin();
+		marg *= 2.f;
 		/* Calculate the other side of this object */
-		PHY__Vector3 hitpos;
-		hit_controller->getPosition(hitpos);
-		MT_Point3 hitObjPos(hitpos);
-		
-		MT_Vector3 hitvector = hitObjPos - result_point;
-		if (hitvector.dot(hitvector) > MT_EPSILON)
-		{
-			hitvector.normalize();
-			marg *= 2.*todir.dot(hitvector);
-		}
-		frompoint = result_point + marg * todir;
+		MT_Scalar h = MT_abs(todir.dot(callback.m_hitNormal));
+		if (h <= 0.01)
+			// the normal is almost orthogonal to the ray direction, cannot compute the other side
+			break;
+		marg /= h; 
+		frompoint = callback.m_hitPoint + marg * todir;
+		// verify that we are not passed the to point
+		if ((topoint - frompoint).dot(todir) < 0.f)
+			break;
 	}
-	
-	return hit_controller;
+	return false;
 }
 
diff --git a/source/gameengine/Ketsji/KX_RayCast.h b/source/gameengine/Ketsji/KX_RayCast.h
index 607dabd8afca99e270485327d5d42f9902752364..c3084c997a193456a91039a4144c66526e1f9862 100644
--- a/source/gameengine/Ketsji/KX_RayCast.h
+++ b/source/gameengine/Ketsji/KX_RayCast.h
@@ -30,12 +30,14 @@
 #ifndef __KX_RAYCAST_H__
 #define __KX_RAYCAST_H__
 
-class MT_Point3;
-class MT_Vector3;
-class KX_IPhysicsController;
-class PHY_IPhysicsEnvironment;
+#include "PHY_IPhysicsEnvironment.h"
+#include "PHY_IPhysicsController.h"
+#include "MT_Point3.h"
+#include "MT_Vector3.h"
 
+class RAS_MeshObject; 
 struct KX_ClientObjectInfo;
+class KX_IPhysicsController;
 
 /**
  *  Defines a function for doing a ray cast.
@@ -49,17 +51,27 @@ struct KX_ClientObjectInfo;
  *
  *  Returns true if a client was accepted, false if nothing found.
  */
-class KX_RayCast
+class KX_RayCast : public PHY_IRayCastFilterCallback
 {
-protected:
-	KX_RayCast() {};
 public:
+	bool					m_hitFound;
+	MT_Point3				m_hitPoint;
+	MT_Vector3				m_hitNormal;
+	const RAS_MeshObject*	m_hitMesh;
+	int						m_hitPolygon;
+
+	KX_RayCast(KX_IPhysicsController* ignoreController, bool faceNormal);
 	virtual ~KX_RayCast() {}
 
+	/**
+	 * The physic environment returns the ray casting result through this function
+	 */
+	virtual void reportHit(PHY_RayCastResult* result);
+
 	/** ray test callback.
 	 *  either override this in your class, or use a callback wrapper.
 	 */
-	virtual bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal) const = 0;
+	virtual bool RayHit(KX_ClientObjectInfo* client) = 0;
 
 	/** 
 	 *  Callback wrapper.
@@ -71,13 +83,11 @@ public:
 	
 	/// Public interface.
 	/// Implement bool RayHit in your class to receive ray callbacks.
-	static bool RayTest(KX_IPhysicsController* physics_controller, 
+	static bool RayTest(
 		PHY_IPhysicsEnvironment* physics_environment, 
-		const MT_Point3& _frompoint, 
+		const MT_Point3& frompoint, 
 		const MT_Point3& topoint, 
-		MT_Point3& result_point, 
-		MT_Vector3& result_normal, 
-		const KX_RayCast& callback);
+		KX_RayCast& callback);
 	
 };
 
@@ -86,18 +96,32 @@ template<class T> class KX_RayCast::Callback : public KX_RayCast
 	T *self;
 	void *data;
 public:
-	Callback(T *_self, void *_data = NULL)
-		: self(_self),
+	Callback(T *_self, KX_IPhysicsController* controller=NULL, void *_data = NULL, bool faceNormal=false)
+		: KX_RayCast(controller, faceNormal),
+		self(_self),
 		data(_data)
 	{
 	}
 	
 	~Callback() {}
-	
-	virtual bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal) const
+
+	virtual bool RayHit(KX_ClientObjectInfo* client)
 	{
-		return self->RayHit(client, hit_point, hit_normal, data);
+		return self->RayHit(client, this, data);
 	}
+
+	virtual	bool needBroadphaseRayCast(PHY_IPhysicsController* controller)
+	{
+		KX_ClientObjectInfo* info = static_cast<KX_ClientObjectInfo*>(controller->getNewClientInfo());
+		
+		if (!info)
+		{
+			MT_assert(info && "Physics controller with no client object info");
+			return false;
+		}
+		return self->NeedRayCast(info);
+	}
+
 };
 	
 
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index a416c8c9f89bd5d7cadcb8f148fe6938bcd2ceb3..8dc22fe13c13bc1f067b9e7bc69a5c3cfc8a9adc 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -51,6 +51,7 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr,
 					SCA_IObject* gameobj,
 					const STR_String& propname,
 					bool bFindMaterial,
+					bool bXRay,
 					double distance,
 					int axis,
 					KX_Scene* ketsjiScene,
@@ -58,6 +59,7 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr,
 			: SCA_ISensor(gameobj,eventmgr, T),
 					m_propertyname(propname),
 					m_bFindMaterial(bFindMaterial),
+					m_bXRay(bXRay),
 					m_distance(distance),
 					m_scene(ketsjiScene),
 					m_axis(axis)
@@ -104,16 +106,10 @@ bool KX_RaySensor::IsPositiveTrigger()
 	return result;
 }
 
-bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
+bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
 {
 
 	KX_GameObject* hitKXObj = client->m_gameobject;
-	
-	if (client->m_type > KX_ClientObjectInfo::ACTOR)
-	{
-		// false hit
-		return false;
-	}
 	bool bFound = false;
 
 	if (m_propertyname.Length() == 0)
@@ -139,16 +135,43 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_
 	{
 		m_rayHit = true;
 		m_hitObject = hitKXObj;
-		m_hitPosition = hit_point;
-		m_hitNormal = hit_normal;
+		m_hitPosition = result->m_hitPoint;
+		m_hitNormal = result->m_hitNormal;
 			
 	}
-
-	return bFound;
-	
+	// no multi-hit search yet
+	return true;
 }
 
-
+/* this function is used to pre-filter the object before casting the ray on them.
+   This is useful for "X-Ray" option when we want to see "through" unwanted object.
+ */
+bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo* client)
+{
+	if (client->m_type > KX_ClientObjectInfo::ACTOR)
+	{
+		// Unknown type of object, skip it.
+		// Should not occur as the sensor objects are filtered in RayTest()
+		printf("Invalid client type %d found ray casting\n", client->m_type);
+		return false;
+	}
+	if (m_bXRay && m_propertyname.Length() != 0)
+	{
+		if (m_bFindMaterial)
+		{
+			// not quite correct: an object may have multiple material
+			// should check all the material and not only the first one
+			if (!client->m_auxilary_info || (m_propertyname != ((char*)client->m_auxilary_info)))
+				return false;
+		}
+		else
+		{
+			if (client->m_gameobject->GetProperty(m_propertyname) == NULL)
+				return false;
+		}
+	}
+	return true;
+}
 
 bool KX_RaySensor::Evaluate(CValue* event)
 {
@@ -215,8 +238,6 @@ bool KX_RaySensor::Evaluate(CValue* event)
 	m_rayDirection = todir;
 
 	MT_Point3 topoint = frompoint + (m_distance) * todir;
-	MT_Point3 resultpoint;
-	MT_Vector3 resultnormal;
 	PHY_IPhysicsEnvironment* pe = m_scene->GetPhysicsEnvironment();
 
 	if (!pe)
@@ -238,7 +259,8 @@ bool KX_RaySensor::Evaluate(CValue* event)
 	PHY_IPhysicsEnvironment* physics_environment = this->m_scene->GetPhysicsEnvironment();
 	
 
-	result = KX_RayCast::RayTest(spc, physics_environment, frompoint, topoint, resultpoint, resultnormal, KX_RayCast::Callback<KX_RaySensor>(this));
+	KX_RayCast::Callback<KX_RaySensor> callback(this, spc);
+	KX_RayCast::RayTest(physics_environment, frompoint, topoint, callback);
 
 	/* now pass this result to some controller */
 
@@ -265,6 +287,10 @@ bool KX_RaySensor::Evaluate(CValue* event)
 			// notify logicsystem that ray JUST left the Object
 			result = true;
 		}
+		else
+		{
+			result = false;
+		}
 	
       }
     if (reset)
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index f4305b053d147d424bab22acdfbcc54b887b45af..02a755fedc191d840d5c5207649c5c898d035084 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -36,12 +36,14 @@
 #include "MT_Point3.h"
 
 struct KX_ClientObjectInfo;
+class KX_RayCast;
 
 class KX_RaySensor : public SCA_ISensor
 {
 	Py_Header;
 	STR_String		m_propertyname;
 	bool			m_bFindMaterial;
+	bool			m_bXRay;
 	double			m_distance;
 	class KX_Scene* m_scene;
 	bool			m_bTriggered;
@@ -56,7 +58,8 @@ public:
 	KX_RaySensor(class SCA_EventManager* eventmgr,
 					SCA_IObject* gameobj,
 					const STR_String& propname,
-					bool fFindMaterial,
+					bool bFindMaterial,
+					bool bXRay,
 					double distance,
 					int axis,
 					class KX_Scene* ketsjiScene,
@@ -68,7 +71,8 @@ public:
 	virtual bool IsPositiveTrigger();
 	virtual void Init();
 
-	bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+	bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
+	bool NeedRayCast(KX_ClientObjectInfo* client);
 	
 	KX_PYMETHOD_DOC(KX_RaySensor,GetHitObject);
 	KX_PYMETHOD_DOC(KX_RaySensor,GetHitPosition);
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index ca0106d64d957e34cda49e850ffebb2276e43c63..a7330b9a20ac1d0fd798f5346e90b8217b8397e2 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -52,14 +52,20 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
 												   int time,
 												   SCA_IScene* scene,
 												   const MT_Vector3& linvel,
-												   bool local,
+												   bool linv_local,
+												   const MT_Vector3& angvel,
+												   bool angv_local,
 												   PyTypeObject* T)
 	: 
 	SCA_IActuator(gameobj, T),
 	m_OriginalObject(original),
 	m_scene(scene),
+	
 	m_linear_velocity(linvel),
-	m_localFlag(local)
+	m_localLinvFlag(linv_local),
+	
+	m_angular_velocity(angvel),
+	m_localAngvFlag(angv_local)
 {
 	if (m_OriginalObject)
 		m_OriginalObject->RegisterActuator(this);
@@ -181,13 +187,15 @@ PyParentObject KX_SCA_AddObjectActuator::Parents[] = {
 };
 PyMethodDef KX_SCA_AddObjectActuator::Methods[] = {
   {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_O, SetObject_doc},
-  {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_VARARGS, SetTime_doc},
+  {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_O, SetTime_doc},
   {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, GetObject_doc},
-  {"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_VARARGS, GetTime_doc},
-  {"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_VARARGS, GetLinearVelocity_doc},
+  {"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_NOARGS, GetTime_doc},
+  {"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_NOARGS, GetLinearVelocity_doc},
   {"setLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetLinearVelocity, METH_VARARGS, SetLinearVelocity_doc},
-  {"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_VARARGS,"getLastCreatedObject() : get the object handle to the last created object\n"},
-  {"instantAddObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyInstantAddObject, METH_VARARGS,"instantAddObject() : immediately add object without delay\n"},
+  {"getAngularVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetAngularVelocity, METH_NOARGS, GetAngularVelocity_doc},
+  {"setAngularVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetAngularVelocity, METH_VARARGS, SetAngularVelocity_doc},
+  {"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_NOARGS,"getLastCreatedObject() : get the object handle to the last created object\n"},
+  {"instantAddObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyInstantAddObject, METH_NOARGS,"instantAddObject() : immediately add object without delay\n"},
   
   {NULL,NULL} //Sentinel
 };
@@ -231,19 +239,18 @@ char KX_SCA_AddObjectActuator::SetTime_doc[] =
 "\tIf the duration is negative, it is set to 0.\n";
 
 
-PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self,
-											  PyObject* args,
-											  PyObject* kwds)
+PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self, PyObject* value)
 {
-	int deltatime;
-	
-	if (!PyArg_ParseTuple(args, "i", &deltatime))
+	int deltatime = PyInt_AsLong(value);
+	if (deltatime==-1 && PyErr_Occurred()) {
+		PyErr_SetString(PyExc_TypeError, "expected an int");
 		return NULL;
+	}
 	
 	m_timeProp = deltatime;
 	if (m_timeProp < 0) m_timeProp = 0;
 	
-	Py_Return;
+	Py_RETURN_NONE;
 }
 
 
@@ -254,9 +261,7 @@ char KX_SCA_AddObjectActuator::GetTime_doc[] =
 "\tReturns the lifetime of the object that will be added.\n";
 
 
-PyObject* KX_SCA_AddObjectActuator::PyGetTime(PyObject* self,
-											  PyObject* args,
-											  PyObject* kwds)
+PyObject* KX_SCA_AddObjectActuator::PyGetTime(PyObject* self)
 {
 	return PyInt_FromLong(m_timeProp);
 }
@@ -290,17 +295,13 @@ char KX_SCA_AddObjectActuator::GetLinearVelocity_doc[] =
 "\tReturns the linear velocity that will be assigned to \n"
 "\tthe created object.\n";
 
-
-
-PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self,
-														PyObject* args,
-														PyObject* kwds)
+PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self)
 {
 	PyObject *retVal = PyList_New(3);
 
-	PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
-	PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
-	PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
+	PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
+	PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
+	PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
 	
 	return retVal;
 }
@@ -313,12 +314,10 @@ char KX_SCA_AddObjectActuator::SetLinearVelocity_doc[] =
 "\t- vx: float\n"
 "\t- vy: float\n"
 "\t- vz: float\n"
+"\t- local: bool\n"
 "\tAssign this velocity to the created object. \n";
 
-
-PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self,
-														PyObject* args,
-														PyObject* kwds)
+PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self, PyObject* args)
 {
 	
 	float vecArg[3];
@@ -326,7 +325,46 @@ PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self,
 		return NULL;
 
 	m_linear_velocity.setValue(vecArg);
-	Py_Return;
+	Py_RETURN_NONE;
+}
+
+/* 7. getAngularVelocity */
+char KX_SCA_AddObjectActuator::GetAngularVelocity_doc[] = 
+"GetAngularVelocity()\n"
+"\tReturns the angular velocity that will be assigned to \n"
+"\tthe created object.\n";
+
+PyObject* KX_SCA_AddObjectActuator::PyGetAngularVelocity(PyObject* self)
+{
+	PyObject *retVal = PyList_New(3);
+
+	PyList_SET_ITEM(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
+	PyList_SET_ITEM(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
+	PyList_SET_ITEM(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
+	
+	return retVal;
+}
+
+
+
+/* 8. setAngularVelocity                                                 */
+char KX_SCA_AddObjectActuator::SetAngularVelocity_doc[] = 
+"setAngularVelocity(vx, vy, vz)\n"
+"\t- vx: float\n"
+"\t- vy: float\n"
+"\t- vz: float\n"
+"\t- local: bool\n"
+"\tAssign this angular velocity to the created object. \n";
+
+PyObject* KX_SCA_AddObjectActuator::PySetAngularVelocity(PyObject* self, PyObject* args)
+{
+	
+	float vecArg[3];
+	if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2]))
+		return NULL;
+
+	m_angular_velocity.setValue(vecArg);
+	Py_RETURN_NONE;
 }
 
 void	KX_SCA_AddObjectActuator::InstantAddObject()
@@ -337,8 +375,9 @@ void	KX_SCA_AddObjectActuator::InstantAddObject()
 		// Now it needs to be added to the current scene.
 		SCA_IObject* replica = m_scene->AddReplicaObject(m_OriginalObject,GetParent(),m_timeProp );
 		KX_GameObject * game_obj = static_cast<KX_GameObject *>(replica);
-		game_obj->setLinearVelocity(m_linear_velocity,m_localFlag);
-		game_obj->ResolveCombinedVelocities(m_linear_velocity, MT_Vector3(0., 0., 0.), m_localFlag, false);
+		game_obj->setLinearVelocity(m_linear_velocity,m_localLinvFlag);
+		game_obj->setAngularVelocity(m_angular_velocity,m_localAngvFlag);
+		game_obj->ResolveCombinedVelocities(m_linear_velocity, m_angular_velocity, m_localLinvFlag, m_localAngvFlag);
 
 		// keep a copy of the last object, to allow python scripters to change it
 		if (m_lastCreatedObject)
@@ -355,13 +394,11 @@ void	KX_SCA_AddObjectActuator::InstantAddObject()
 	}
 }
 
-PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject(PyObject* self,
-														   PyObject* args,
-														   PyObject* kwds)
+PyObject* KX_SCA_AddObjectActuator::PyInstantAddObject(PyObject* self)
 {
 	InstantAddObject();
 
-	Py_Return;
+	Py_RETURN_NONE;
 }
 
 
@@ -372,16 +409,17 @@ char KX_SCA_AddObjectActuator::GetLastCreatedObject_doc[] =
 "\tReturn the last created object. \n";
 
 
-PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self,
-														   PyObject* args,
-														   PyObject* kwds)
+PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self)
 {
 	SCA_IObject* result = this->GetLastCreatedObject();
-	if (result)
+	
+	// if result->GetSGNode() is NULL
+	// it means the object has ended, The BGE python api crashes in many places if the object is returned.
+	if (result && (static_cast<KX_GameObject *>(result))->GetSGNode()) 
 	{
 		result->AddRef();
 		return result;
 	}
 	// don't return NULL to python anymore, it gives trouble in the scripts
-	Py_Return;
+	Py_RETURN_NONE;
 }
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index e7fdb2fbfbc0e9e49b014d5a37844fc0ec02f63b..278d41802847832b39bbc89b20d952a5001d0554 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -60,9 +60,13 @@ class KX_SCA_AddObjectActuator : public SCA_IActuator
 
 	/// Linear velocity upon creation of the object. 
 	MT_Vector3  m_linear_velocity;
+	
+	/// Angular velocity upon creation of the object. 
+	MT_Vector3  m_angular_velocity;
 
 	/// Apply the velocity locally 
-	bool m_localFlag;
+	bool m_localLinvFlag;
+	bool m_localAngvFlag;
 	
 	SCA_IObject*	m_lastCreatedObject;
 	
@@ -79,7 +83,9 @@ public:
 		int time,
 		SCA_IScene* scene,
 		const MT_Vector3& linvel,
-		bool local,
+		bool linv_local,
+		const MT_Vector3& angvel,
+		bool angv_local,
 		PyTypeObject* T=&Type
 	);
 
@@ -115,19 +121,23 @@ public:
 	/* 1. setObject */
 	KX_PYMETHOD_DOC_O(KX_SCA_AddObjectActuator,SetObject);
 	/* 2. setTime */
-	KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetTime);
+	KX_PYMETHOD_DOC_O(KX_SCA_AddObjectActuator,SetTime);
 	/* 3. getTime */
-	KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetTime);
+	KX_PYMETHOD_DOC_NOARGS(KX_SCA_AddObjectActuator,GetTime);
 	/* 4. getObject */
 	KX_PYMETHOD_DOC_VARARGS(KX_SCA_AddObjectActuator,GetObject);
 	/* 5. getLinearVelocity */
-	KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetLinearVelocity);
+	KX_PYMETHOD_DOC_NOARGS(KX_SCA_AddObjectActuator,GetLinearVelocity);
 	/* 6. setLinearVelocity */
-	KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetLinearVelocity);
-	/* 7. getLastCreatedObject */
-	KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetLastCreatedObject);
-	/* 8. instantAddObject*/
-	KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,InstantAddObject);
+	KX_PYMETHOD_DOC_VARARGS(KX_SCA_AddObjectActuator,SetLinearVelocity);
+	/* 7. getAngularVelocity */
+	KX_PYMETHOD_DOC_NOARGS(KX_SCA_AddObjectActuator,GetAngularVelocity);
+	/* 8. setAngularVelocity */
+	KX_PYMETHOD_DOC_VARARGS(KX_SCA_AddObjectActuator,SetAngularVelocity);
+	/* 9. getLastCreatedObject */
+	KX_PYMETHOD_DOC_NOARGS(KX_SCA_AddObjectActuator,GetLastCreatedObject);
+	/* 10. instantAddObject*/
+	KX_PYMETHOD_DOC_NOARGS(KX_SCA_AddObjectActuator,InstantAddObject);
 
 	
 }; /* end of class KX_SCA_AddObjectActuator : public KX_EditObjectActuator */
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 2828663c63df602a45cdd716af1c97212313776d..1c37fcea77e060c09ac4a709961a19200a031cea 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -234,40 +234,9 @@ KX_Scene::~KX_Scene()
 	{
 		delete m_bucketmanager;
 	}
-#ifdef USE_BULLET
-	// This is a fix for memory leaks in bullet: the collision shapes is not destroyed 
-	// when the physical controllers are destroyed. The reason is that shapes are shared
-	// between replicas of an object. There is no reference count in Bullet so the
-	// only workaround that does not involve changes in Bullet is to save in this array
-	// the list of shapes that are created when the scene is created (see KX_ConvertPhysicsObjects.cpp)
-	class btCollisionShape* shape;
-	class btTriangleMeshShape* meshShape;
-	vector<class btCollisionShape*>::iterator it = m_shapes.begin();
-	while (it != m_shapes.end()) {
-		shape = *it;
-		if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
-		{
-			meshShape = static_cast<btTriangleMeshShape*>(shape);
-			// shapes based on meshes use an interface that contains the vertices.
-			// Again the idea is to be able to share the interface between shapes but
-			// this is not used in Blender: each base object will have its own interface 
-			btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
-			if (meshInterface)
-				delete meshInterface;
-		}
-		delete shape;
-		it++;
-	}
-#endif
 	//Py_DECREF(m_attrlist);
 }
 
-void KX_Scene::AddShape(class btCollisionShape*shape)
-{
-	m_shapes.push_back(shape);
-}
-
-
 void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
 {
 	m_projectionmat = pmat;
@@ -975,6 +944,8 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
 	
 	newobj->RemoveMeshes();
 	ret = 1;
+	if (m_lightlist->RemoveValue(newobj)) // TODO - use newobj->IsLight() test when its merged in from apricot. - Campbell
+		ret = newobj->Release();
 	if (m_objectlist->RemoveValue(newobj))
 		ret = newobj->Release();
 	if (m_tempObjectList->RemoveValue(newobj))
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 80a2abe287ad2e464ecf4a4d68fab9537273aeb2..1c56dd1ee55ef794e68b0510b311af63af06310e 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -121,11 +121,6 @@ protected:
 	 * The set of cameras for this scene
 	 */
 	list<class KX_Camera*>       m_cameras;
-	/**
-	 * The set of bullet shapes that must be deleted at the end of the scene
-	 * to avoid memory leak (not deleted by bullet because shape are shared between replicas)
-	 */
-	vector<class btCollisionShape*> m_shapes;
 	/**
 	 * Various SCA managers used by the scene
 	 */
@@ -322,7 +317,6 @@ public:
 	int NewRemoveObject(CValue* gameobj);
 	void ReplaceMesh(CValue* gameobj,
 					 void* meshobj);
-	void AddShape(class btCollisionShape* shape);
 	/**
 	 * @section Logic stuff
 	 * Initiate an update of the logic system.
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index 34a3baec0933f29a5895048ed8f190d464261a08..f75a1ee5c62cccd9c5e7cdaa647dd7171aa2ea42 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -69,11 +69,11 @@ KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj,
 
 KX_SoundActuator::~KX_SoundActuator()
 {
-	//m_soundScene->RemoveObject(this->m_soundObject);
-	//(this->m_soundObject)->DeleteWhenFinished();
-	m_soundScene->RemoveActiveObject(m_soundObject);
-//	m_soundScene->DeleteObjectWhenFinished(m_soundObject);
-	m_soundScene->DeleteObject(m_soundObject);
+	if (m_soundObject)
+	{
+		m_soundScene->RemoveActiveObject(m_soundObject);
+		m_soundScene->DeleteObject(m_soundObject);
+	}
 }
 
 
@@ -82,9 +82,12 @@ CValue* KX_SoundActuator::GetReplica()
 {
 	KX_SoundActuator* replica = new KX_SoundActuator(*this);
 	replica->ProcessReplica();
-	SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
-	replica->setSoundObject(soundobj);
-	m_soundScene->AddObject(soundobj);
+	if (m_soundObject)
+	{
+	    SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject);
+		replica->setSoundObject(soundobj);
+		m_soundScene->AddObject(soundobj);
+	}
 	
 	// this will copy properties and so on...
 	CValue::AddDataToReplica(replica);
@@ -104,6 +107,9 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
 
 	RemoveAllEvents();
 
+	if (!m_soundObject)
+		return false;
+
 	if (m_pino)
 	{
 		bNegativeEvent = true;
@@ -287,6 +293,10 @@ PyObject* KX_SoundActuator::PySetFilename(PyObject* self, PyObject* args, PyObje
 
 PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObject* kwds)
 {
+	if (!m_soundObject)
+	{
+		return PyString_FromString("");
+	}
 	STR_String objectname = m_soundObject->GetObjectName();
 	char* name = objectname.Ptr();
 	
@@ -301,7 +311,8 @@ PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObje
 
 PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObject* kwds)
 {
-	m_soundObject->StartSound();	
+	if (m_soundObject)
+		m_soundObject->StartSound();	
 	Py_Return;
 }         
 
@@ -309,7 +320,8 @@ PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObjec
 
 PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObject* kwds)
 {
-	m_soundObject->PauseSound();	
+	if (m_soundObject)
+		m_soundObject->PauseSound();	
 	Py_Return;
 } 
 
@@ -317,7 +329,8 @@ PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObjec
 
 PyObject* KX_SoundActuator::PyStopSound(PyObject* self, PyObject* args, PyObject* kwds)
 {
-	m_soundObject->StopSound();	
+	if (m_soundObject)
+		m_soundObject->StopSound();	
 	Py_Return;
 }
 
@@ -329,7 +342,8 @@ PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject*
 	if (!PyArg_ParseTuple(args, "f", &gain))
 		return NULL;
 	
-	m_soundObject->SetGain(gain);
+	if (m_soundObject)
+		m_soundObject->SetGain(gain);
 	
 	Py_Return;
 }         
@@ -338,7 +352,7 @@ PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject*
 
 PyObject* KX_SoundActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds)
 {
-	float gain = m_soundObject->GetGain();
+	float gain = (m_soundObject) ? m_soundObject->GetGain() : 1.0f;
 	PyObject* result = PyFloat_FromDouble(gain);
 	
 	return result;
@@ -352,7 +366,8 @@ PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject*
 	if (!PyArg_ParseTuple(args, "f", &pitch))
 		return NULL;
 	
-	m_soundObject->SetPitch(pitch);
+	if (m_soundObject)
+		m_soundObject->SetPitch(pitch);
 	
 	Py_Return;
 }         
@@ -361,7 +376,7 @@ PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject*
 
 PyObject* KX_SoundActuator::PyGetPitch(PyObject* self, PyObject* args, PyObject* kwds)
 {
-	float pitch = m_soundObject->GetPitch();
+	float pitch = (m_soundObject) ? m_soundObject->GetPitch() : 1.0;
 	PyObject* result = PyFloat_FromDouble(pitch);
 	
 	return result;
@@ -375,7 +390,8 @@ PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, P
 	if (!PyArg_ParseTuple(args, "f", &rollofffactor))
 		return NULL;
 	
-	m_soundObject->SetRollOffFactor(rollofffactor);
+	if (m_soundObject)
+		m_soundObject->SetRollOffFactor(rollofffactor);
 
 	Py_Return;
 }         
@@ -384,7 +400,7 @@ PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, P
 
 PyObject* KX_SoundActuator::PyGetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds)
 {
-	float rollofffactor = m_soundObject->GetRollOffFactor();
+	float rollofffactor = (m_soundObject) ? m_soundObject->GetRollOffFactor() : 1.0;
 	PyObject* result = PyFloat_FromDouble(rollofffactor);
 	
 	return result;
@@ -398,7 +414,8 @@ PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObjec
 	if (!PyArg_ParseTuple(args, "i", &looping))
 		return NULL;
 	
-	m_soundObject->SetLoopMode(looping);
+	if (m_soundObject)
+		m_soundObject->SetLoopMode(looping);
 	
 	Py_Return;
 }         
@@ -407,7 +424,7 @@ PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObjec
 
 PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObject* kwds)
 {
-	int looping = m_soundObject->GetLoopMode();
+	int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : SND_LOOP_OFF;
 	PyObject* result = PyInt_FromLong(looping);
 	
 	return result;
@@ -425,7 +442,8 @@ PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObje
 	if (!PyArg_ParseTuple(args, "fff", &pos[0], &pos[1], &pos[2]))
 		return NULL;
 	
-	m_soundObject->SetPosition(pos);
+	if (m_soundObject)
+		m_soundObject->SetPosition(pos);
 	
 	Py_Return;
 }         
@@ -442,7 +460,8 @@ PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObje
 	if (!PyArg_ParseTuple(args, "fff", &vel[0], &vel[1], &vel[2]))
 		return NULL;
 	
-	m_soundObject->SetVelocity(vel);
+	if (m_soundObject)
+		m_soundObject->SetVelocity(vel);
 	
 	Py_Return;
 }         
@@ -465,7 +484,8 @@ PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyO
 	if (!PyArg_ParseTuple(args, "fffffffff", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2]))
 		return NULL;
 	
-	m_soundObject->SetOrientation(ori);
+	if (m_soundObject)
+		m_soundObject->SetOrientation(ori);
 	
 	Py_Return;
 }
diff --git a/source/gameengine/Ketsji/Makefile b/source/gameengine/Ketsji/Makefile
index 47a4855b00c2c6796f5330665786a4c88f742e41..59cc6c8ca7ec1d47f2fcea78924d510ff6e7bf6a 100644
--- a/source/gameengine/Ketsji/Makefile
+++ b/source/gameengine/Ketsji/Makefile
@@ -38,7 +38,9 @@ CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
 CPPFLAGS += $(OGL_CPPFLAGS)
 CPPFLAGS += -I$(NAN_GLEW)/include
 CPPFLAGS += -I$(OPENGL_HEADERS)
-CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) -I../../blender/python
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) 
+CPPFLAGS += -I../../blender/python
+CPPFLAGS += -I../../blender/python/api2_2x
 CPPFLAGS += -I$(NAN_STRING)/include    
 CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include    
 CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO) -I$(NAN_MOTO)/include
diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp
index a04560aaf097d592d72f5f7828274053f2718b43..6d9b41e08d2772ae4bf1eeeac487c3715922c916 100644
--- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.cpp
@@ -206,8 +206,7 @@ void		ODEPhysicsEnvironment::removeConstraint(int constraintid)
 	}
 }
 
-PHY_IPhysicsController* ODEPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-									float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
+PHY_IPhysicsController* ODEPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ)
 {
 
 	//m_OdeWorld
diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
index 7c61902f8e2b09733270376077e7e56e8f198c6c..dcc87d614c0f1e503fbba9aa411f2edb20c56bb7 100644
--- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
+++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
@@ -54,8 +54,7 @@ public:
 			float axisX,float axisY,float axisZ);
 
 	virtual void		removeConstraint(void * constraintid);
-	virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-									float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+	virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
 
 
 	//gamelogic callbacks
diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt
index b610fd1bbb0dc5ed871bfcbcb90e5b9089b8f0d1..6c733786caf0af3a49aa2cf16268ac185070d2d0 100644
--- a/source/gameengine/Physics/Bullet/CMakeLists.txt
+++ b/source/gameengine/Physics/Bullet/CMakeLists.txt
@@ -30,6 +30,10 @@ SET(INC
   .
   ../common
   ../../../../extern/bullet2/src
+  ../../../../intern/moto/include
+  ../../../kernel/gen_system
+  ../../../../intern/string
+  ../../Rasterizer
 )
 
 BLENDERLIB(bf_bullet "${SRC}" "${INC}")
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index b872fae61388750bd1cb8eeea4e3c2a7540d9621..2ec96c75a6824d5b16a88b764207398a084060ad 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -18,6 +18,7 @@ subject to the following restrictions:
 
 #include "PHY_IMotionState.h"
 #include "CcdPhysicsEnvironment.h"
+#include "RAS_MeshObject.h"
 
 
 class BP_Proxy;
@@ -44,7 +45,18 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
 	m_newClientInfo = 0;
 	m_registerCount = 0;
 		
+	// copy pointers locally to allow smart release
 	m_MotionState = ci.m_MotionState;
+	m_collisionShape = ci.m_collisionShape;
+	// apply scaling before creating rigid body
+	m_collisionShape->setLocalScaling(m_cci.m_scaling);
+	if (m_cci.m_mass)
+		m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
+	// shape info is shared, increment ref count
+	m_shapeInfo = ci.m_shapeInfo;
+	if (m_shapeInfo)
+		m_shapeInfo->AddRef();
+	
 	m_bulletMotionState = 0;
 	
 	
@@ -116,7 +128,7 @@ void CcdPhysicsController::CreateRigidbody()
 
 	m_body = new btRigidBody(m_cci.m_mass,
 		m_bulletMotionState,
-		m_cci.m_collisionShape,
+		m_collisionShape,
 		m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor,
 		m_cci.m_linearDamping,m_cci.m_angularDamping,
 		m_cci.m_friction,m_cci.m_restitution);
@@ -144,6 +156,19 @@ void CcdPhysicsController::CreateRigidbody()
 	}
 }
 
+static void DeleteBulletShape(btCollisionShape* shape)
+{
+	if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
+	{
+		// shapes based on meshes use an interface that contains the vertices.
+		btTriangleMeshShape* meshShape = static_cast<btTriangleMeshShape*>(shape);
+		btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
+		if (meshInterface)
+			delete meshInterface;
+	}
+	delete shape;
+}
+
 CcdPhysicsController::~CcdPhysicsController()
 {
 	//will be reference counted, due to sharing
@@ -155,6 +180,27 @@ CcdPhysicsController::~CcdPhysicsController()
 	if (m_bulletMotionState)
 		delete m_bulletMotionState;
 	delete m_body;
+
+	if (m_collisionShape)
+	{
+		// collision shape is always unique to the controller, can delete it here
+		if (m_collisionShape->isCompound())
+		{
+			// bullet does not delete the child shape, must do it here
+			btCompoundShape* compoundShape = (btCompoundShape*)m_collisionShape;
+			int numChild = compoundShape->getNumChildShapes();
+			for (int i=numChild-1 ; i >= 0; i--)
+			{
+				btCollisionShape* childShape = compoundShape->getChildShape(i);
+				DeleteBulletShape(childShape);
+			}
+		}
+		DeleteBulletShape(m_collisionShape);
+	}
+	if (m_shapeInfo)
+	{
+		m_shapeInfo->Release();
+	}
 }
 
 
@@ -219,11 +265,33 @@ void		CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta
 {
 	m_MotionState = motionstate;
 	m_registerCount = 0;
-	
+	m_collisionShape = NULL;
+
+	// always create a new shape to avoid scaling bug
+	if (m_shapeInfo)
+	{
+		m_shapeInfo->AddRef();
+		m_collisionShape = m_shapeInfo->CreateBulletShape();
+
+		if (m_collisionShape)
+		{
+			// new shape has no scaling, apply initial scaling
+			m_collisionShape->setLocalScaling(m_cci.m_scaling);
+			if (m_cci.m_mass)
+				m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
+		}
+	}
 
 	m_body = 0;
 	CreateRigidbody();
-	
+
+	if (m_body)
+	{
+		if (m_cci.m_mass)
+		{
+			m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
+		} 
+	}			
 	m_cci.m_physicsEnv->addCcdPhysicsController(this);
 
 
@@ -597,29 +665,32 @@ bool CcdPhysicsController::wantsSleeping()
 
 PHY_IPhysicsController*	CcdPhysicsController::GetReplica()
 {
-	//very experimental, shape sharing is not implemented yet.
-	//just support btSphereShape/ConeShape for now
-
+	// This is used only to replicate Near and Radar sensor controllers
+	// The replication of object physics controller is done in KX_BulletPhysicsController::GetReplica()
 	CcdConstructionInfo cinfo = m_cci;
-	if (cinfo.m_collisionShape)
+	if (m_shapeInfo)
 	{
-		switch (cinfo.m_collisionShape->getShapeType())
+		// This situation does not normally happen
+		cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape();
+	} 
+	else if (m_collisionShape)
+	{
+		switch (m_collisionShape->getShapeType())
 		{
 		case SPHERE_SHAPE_PROXYTYPE:
 			{
-				btSphereShape* orgShape = (btSphereShape*)cinfo.m_collisionShape;
+				btSphereShape* orgShape = (btSphereShape*)m_collisionShape;
 				cinfo.m_collisionShape = new btSphereShape(*orgShape);
 				break;
 			}
 
-			case CONE_SHAPE_PROXYTYPE:
+		case CONE_SHAPE_PROXYTYPE:
 			{
-				btConeShape* orgShape = (btConeShape*)cinfo.m_collisionShape;
+				btConeShape* orgShape = (btConeShape*)m_collisionShape;
 				cinfo.m_collisionShape = new btConeShape(*orgShape);
 				break;
 			}
 
-
 		default:
 			{
 				return 0;
@@ -628,6 +699,7 @@ PHY_IPhysicsController*	CcdPhysicsController::GetReplica()
 	}
 
 	cinfo.m_MotionState = new DefaultMotionState();
+	cinfo.m_shapeInfo = m_shapeInfo;
 
 	CcdPhysicsController* replica = new CcdPhysicsController(cinfo);
 	return replica;
@@ -689,3 +761,206 @@ void	DefaultMotionState::calculateWorldTransformations()
 
 }
 
+// Shape constructor
+bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
+{
+	// assume no shape information
+	m_shapeType = PHY_SHAPE_NONE;
+	m_vertexArray.clear();
+	m_polygonIndexArray.clear();
+	m_meshObject = NULL;
+
+	if (!meshobj)
+		return false;
+
+	// Mesh has no polygons!
+	int numpolys = meshobj->NumPolygons();
+	if (!numpolys)
+	{
+		return false;
+	}
+
+	// check that we have at least one colliding polygon
+	int numvalidpolys = 0;
+
+	for (int p=0; p<numpolys; p++)
+	{
+		RAS_Polygon* poly = meshobj->GetPolygon(p);
+
+		// only add polygons that have the collisionflag set
+		if (poly->IsCollider())
+		{
+			numvalidpolys++;
+			break;
+		}
+	}
+
+	// No collision polygons
+	if (numvalidpolys < 1)
+		return false;
+
+	m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH;
+
+	numvalidpolys = 0;
+
+	for (int p2=0; p2<numpolys; p2++)
+	{
+		RAS_Polygon* poly = meshobj->GetPolygon(p2);
+
+		// only add polygons that have the collisionflag set
+		if (poly->IsCollider())
+		{   
+			//Bullet can raycast any shape, so
+			if (polytope)
+			{
+				for (int i=0;i<poly->VertexCount();i++)
+				{
+					const float* vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+						poly->GetVertexIndexBase().m_indexarray[i],
+						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
+					btPoint3 point(vtx[0],vtx[1],vtx[2]);
+					m_vertexArray.push_back(point);
+					numvalidpolys++;
+				}
+			} else
+			{
+				{
+					const float* vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+						poly->GetVertexIndexBase().m_indexarray[2],
+						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
+					btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
+					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+						poly->GetVertexIndexBase().m_indexarray[1],
+						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
+					btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
+					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+						poly->GetVertexIndexBase().m_indexarray[0],
+						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
+					btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
+					m_vertexArray.push_back(vertex0);
+					m_vertexArray.push_back(vertex1);
+					m_vertexArray.push_back(vertex2);
+					m_polygonIndexArray.push_back(p2);
+					numvalidpolys++;
+				}
+				if (poly->VertexCount() == 4)
+				{
+					const float* vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+						poly->GetVertexIndexBase().m_indexarray[3],
+						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
+					btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
+					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+						poly->GetVertexIndexBase().m_indexarray[2],
+						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
+					btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
+					vtx = meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+						poly->GetVertexIndexBase().m_indexarray[0],
+						poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ();
+					btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
+					m_vertexArray.push_back(vertex0);
+					m_vertexArray.push_back(vertex1);
+					m_vertexArray.push_back(vertex2);
+					m_polygonIndexArray.push_back(p2);
+					numvalidpolys++;
+				}
+			}		
+		}
+	}
+
+	if (!numvalidpolys)
+	{
+		// should not happen
+		m_shapeType = PHY_SHAPE_NONE;
+		return false;
+	}
+	m_meshObject = meshobj;
+	return true;
+}
+
+btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
+{
+	btCollisionShape* collisionShape = 0;
+	btTriangleMeshShape* concaveShape = 0;
+	btTriangleMesh* collisionMeshData = 0;
+	btCompoundShape* compoundShape = 0;
+	CcdShapeConstructionInfo* nextShapeInfo;
+
+	switch (m_shapeType) 
+	{
+	case PHY_SHAPE_NONE:
+		break;
+
+	case PHY_SHAPE_BOX:
+		collisionShape = new btBoxShape(m_halfExtend);
+		break;
+
+	case PHY_SHAPE_SPHERE:
+		collisionShape = new btSphereShape(m_radius);
+		break;
+
+	case PHY_SHAPE_CYLINDER:
+		collisionShape = new btCylinderShapeZ(m_halfExtend);
+		break;
+
+	case PHY_SHAPE_CONE:
+		collisionShape = new btConeShapeZ(m_radius, m_height);
+		break;
+
+	case PHY_SHAPE_POLYTOPE:
+		collisionShape = new btConvexHullShape(&m_vertexArray.begin()->getX(), m_vertexArray.size());
+		break;
+
+	case PHY_SHAPE_MESH:
+		collisionMeshData = new btTriangleMesh();
+		// m_vertexArray is necessarily a multiple of 3
+		for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
+		{
+            collisionMeshData->addTriangle(*it++,*it++,*it++);
+		}
+		concaveShape = new btBvhTriangleMeshShape( collisionMeshData, true );
+		concaveShape->recalcLocalAabb();
+		collisionShape = concaveShape;
+		break;
+
+	case PHY_SHAPE_COMPOUND:
+		if (m_nextShape)
+		{
+			compoundShape = new btCompoundShape();
+			for (nextShapeInfo=m_nextShape; nextShapeInfo; nextShapeInfo = nextShapeInfo->m_nextShape)
+			{
+				collisionShape = nextShapeInfo->CreateBulletShape();
+				if (collisionShape)
+				{
+					compoundShape->addChildShape(nextShapeInfo->m_childTrans, collisionShape);
+				}
+			}
+			collisionShape = compoundShape;
+		}
+	}
+	return collisionShape;
+}
+
+void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo)
+{
+	CcdShapeConstructionInfo* nextShape = this;
+	while (nextShape->m_nextShape != NULL)
+		nextShape = nextShape->m_nextShape;
+	nextShape->m_nextShape = shapeInfo;
+}
+
+CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
+{
+	CcdShapeConstructionInfo* childShape = m_nextShape;
+
+	while (childShape)
+	{
+		CcdShapeConstructionInfo* nextShape = childShape->m_nextShape;
+		childShape->m_nextShape = NULL;
+		childShape->Release();
+		childShape = nextShape;
+	}
+	
+	m_vertexArray.clear();
+}
+
+
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 448e5622eff579fb0ba3f9d8142f437027cacd79..8a7f1062f53b4dede0598b84b3e0ce2f0ed07b8b 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -17,11 +17,14 @@ subject to the following restrictions:
 #ifndef BULLET2_PHYSICSCONTROLLER_H
 #define BULLET2_PHYSICSCONTROLLER_H
 
+#include <vector>
+
 #include "PHY_IPhysicsController.h"
 
 ///	PHY_IPhysicsController is the abstract simplified Interface to a physical object.
 ///	It contains the IMotionState and IDeformableMesh Interfaces.
 #include "btBulletDynamicsCommon.h"
+#include "LinearMath/btTransform.h"
 
 #include "PHY_IMotionState.h"
 
@@ -31,8 +34,81 @@ extern float gAngularSleepingTreshold;
 extern bool gDisableDeactivation;
 class CcdPhysicsEnvironment;
 class btMotionState;
+class RAS_MeshObject;
+class btCollisionShape;
+
+// Shape contructor
+// It contains all the information needed to create a simple bullet shape at runtime
+class CcdShapeConstructionInfo
+{
+public:
+	CcdShapeConstructionInfo() :
+		m_shapeType(PHY_SHAPE_NONE),
+		m_radius(1.0),
+		m_height(1.0),
+		m_halfExtend(0.f,0.f,0.f),
+		m_nextShape(NULL),
+		m_refCount(1)
+	{
+		m_childTrans.setIdentity();
+	}
 
+	~CcdShapeConstructionInfo();
 
+	CcdShapeConstructionInfo* AddRef()
+	{ 
+		m_refCount++;
+		return this;
+	}
+
+	int Release()
+	{
+		if (--m_refCount > 0)
+			return m_refCount;
+		delete this;
+		return 0;
+	}
+
+	void AddShape(CcdShapeConstructionInfo* shapeInfo);
+
+	CcdShapeConstructionInfo* GetNextShape()
+	{
+		return m_nextShape;
+	}
+	CcdShapeConstructionInfo* GetChildShape(int i)
+	{
+		CcdShapeConstructionInfo* shape = m_nextShape;
+		while (i > 0 && shape != NULL)
+		{
+			shape = shape->m_nextShape;
+			i--;
+		}
+		return shape;
+	}
+
+	bool SetMesh(RAS_MeshObject* mesh, bool polytope);
+
+	btCollisionShape* CreateBulletShape();
+
+	// member variables
+	PHY_ShapeType			m_shapeType;
+	btScalar				m_radius;
+	btScalar				m_height;
+	btVector3				m_halfExtend;
+	btTransform				m_childTrans;
+	std::vector<btPoint3>	m_vertexArray;	// Contains both vertex array for polytope shape and
+											// triangle array for concave mesh shape.
+											// In this case a triangle is made of 3 consecutive points
+	std::vector<int>		m_polygonIndexArray;	// Contains the array of polygon index in the 
+													// original mesh that correspond to shape triangles.
+													// only set for concave mesh shape.
+	const RAS_MeshObject*	m_meshObject;	// Keep a pointer to the original mesh 
+
+protected:
+	CcdShapeConstructionInfo* m_nextShape;	// for compound shape
+	int						m_refCount;		// this class is shared between replicas
+											// keep track of users so that we can release it 
+};
 
 struct CcdConstructionInfo
 {
@@ -65,6 +141,7 @@ struct CcdConstructionInfo
 		m_collisionFilterMask(AllFilter),
 		m_collisionShape(0),
 		m_MotionState(0),
+		m_shapeInfo(0),
 		m_physicsEnv(0),
 		m_inertiaFactor(1.f)
 	{
@@ -89,8 +166,11 @@ struct CcdConstructionInfo
 	short int	m_collisionFilterGroup;
 	short int	m_collisionFilterMask;
 
+	///these pointers are used as argument passing for the CcdPhysicsController constructor
+	///and not anymore after that
 	class btCollisionShape*	m_collisionShape;
 	class PHY_IMotionState*	m_MotionState;
+	class CcdShapeConstructionInfo* m_shapeInfo;
 	
 	CcdPhysicsEnvironment*	m_physicsEnv; //needed for self-replication
 	float	m_inertiaFactor;//tweak the inertia (hooked up to Blender 'formfactor'
@@ -106,6 +186,9 @@ class CcdPhysicsController : public PHY_IPhysicsController
 	btRigidBody* m_body;
 	class PHY_IMotionState*		m_MotionState;
 	btMotionState* 	m_bulletMotionState;
+	class btCollisionShape*	m_collisionShape;
+	class CcdShapeConstructionInfo* m_shapeInfo;
+
 	friend class CcdPhysicsEnvironment;	// needed when updating the controller
 
 
@@ -137,6 +220,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
 
 
 		btRigidBody* GetRigidBody() { return m_body;}
+		CcdShapeConstructionInfo* GetShapeInfo() { return m_shapeInfo; }
 
 		btCollisionShape*	GetCollisionShape() { 
 			return m_body->getCollisionShape();
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index dfbcf115fd7c764da0bcef63804216c1bfbba7e2..d14ddf8f65ca11350f69317239c77296e0876f78 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -53,6 +53,7 @@ void DrawRasterizerLine(const float* from,const float* to,int color);
 
 
 #include <stdio.h>
+#include <string.h>		// for memset
 
 #ifdef NEW_BULLET_VEHICLE_SUPPORT
 class WrapperVehicle : public PHY_IVehicle
@@ -709,35 +710,51 @@ void		CcdPhysicsEnvironment::removeConstraint(int	constraintId)
 
 struct	FilterClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
 {
-	PHY_IPhysicsController*	m_ignoreClient;
+	PHY_IRayCastFilterCallback&	m_phyRayFilter;
+	const btCollisionShape*		m_hitTriangleShape;
+	int							m_hitTriangleIndex;
 
-	FilterClosestRayResultCallback (PHY_IPhysicsController* ignoreClient,const btVector3& rayFrom,const btVector3& rayTo)
+	FilterClosestRayResultCallback (PHY_IRayCastFilterCallback& phyRayFilter,const btVector3& rayFrom,const btVector3& rayTo)
 		: btCollisionWorld::ClosestRayResultCallback(rayFrom,rayTo),
-		m_ignoreClient(ignoreClient)
+		m_phyRayFilter(phyRayFilter),
+		m_hitTriangleShape(NULL),
+		m_hitTriangleIndex(0)
 	{
-
 	}
 
 	virtual ~FilterClosestRayResultCallback()
 	{
 	}
 
+	virtual bool    NeedRayCast(btCollisionObject* object)
+	{
+		CcdPhysicsController* phyCtrl = static_cast<CcdPhysicsController*>(object->getUserPointer());
+		if (phyCtrl != m_phyRayFilter.m_ignoreController)
+		{
+			return m_phyRayFilter.needBroadphaseRayCast(phyCtrl);
+		}
+		return false;
+	}
+
 	virtual	float	AddSingleResult( btCollisionWorld::LocalRayResult& rayResult)
 	{
 		CcdPhysicsController* curHit = static_cast<CcdPhysicsController*>(rayResult.m_collisionObject->getUserPointer());
-		//ignore client...
-		if (curHit != m_ignoreClient)
-		{		
-			//if valid
-			return ClosestRayResultCallback::AddSingleResult(rayResult);
+		// save shape information as ClosestRayResultCallback::AddSingleResult() does not do it
+		if (rayResult.m_localShapeInfo)
+		{
+			m_hitTriangleShape = rayResult.m_localShapeInfo->m_triangleShape;
+			m_hitTriangleIndex = rayResult.m_localShapeInfo->m_triangleIndex;
+		} else 
+		{
+			m_hitTriangleShape = NULL;
+			m_hitTriangleIndex = 0;
 		}
-		return m_closestHitFraction;
+		return ClosestRayResultCallback::AddSingleResult(rayResult);
 	}
 
 };
 
-PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-													   float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
+PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)
 {
 
 
@@ -751,18 +768,21 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
 	//Either Ray Cast with or without filtering
 
 	//btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
-	FilterClosestRayResultCallback	 rayCallback(ignoreClient,rayFrom,rayTo);
+	FilterClosestRayResultCallback	 rayCallback(filterCallback,rayFrom,rayTo);
 
 
-	PHY_IPhysicsController* nearestHit = 0;
+	PHY_RayCastResult result;
+	memset(&result, 0, sizeof(result));
+
 	// don't collision with sensor object
-	m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback, CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter);
+	m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback, CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter,filterCallback.m_faceNormal);
 	if (rayCallback.HasHit())
 	{
-		nearestHit = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->getUserPointer());
-		hitX = 	rayCallback.m_hitPointWorld.getX();
-		hitY = 	rayCallback.m_hitPointWorld.getY();
-		hitZ = 	rayCallback.m_hitPointWorld.getZ();
+		CcdPhysicsController* controller = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->getUserPointer());
+		result.m_controller = controller;
+		result.m_hitPoint[0] = rayCallback.m_hitPointWorld.getX();
+		result.m_hitPoint[1] = rayCallback.m_hitPointWorld.getY();
+		result.m_hitPoint[2] = rayCallback.m_hitPointWorld.getZ();
 
 		if (rayCallback.m_hitNormalWorld.length2() > (SIMD_EPSILON*SIMD_EPSILON))
 		{
@@ -771,14 +791,42 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* i
 		{
 			rayCallback.m_hitNormalWorld.setValue(1,0,0);
 		}
-		normalX = rayCallback.m_hitNormalWorld.getX();
-		normalY = rayCallback.m_hitNormalWorld.getY();
-		normalZ = rayCallback.m_hitNormalWorld.getZ();
-
+		result.m_hitNormal[0] = rayCallback.m_hitNormalWorld.getX();
+		result.m_hitNormal[1] = rayCallback.m_hitNormalWorld.getY();
+		result.m_hitNormal[2] = rayCallback.m_hitNormalWorld.getZ();
+		if (rayCallback.m_hitTriangleShape != NULL)
+		{
+			// identify the mesh polygon
+			CcdShapeConstructionInfo* shapeInfo = controller->m_shapeInfo;
+			if (shapeInfo)
+			{
+				btCollisionShape* shape = controller->GetRigidBody()->getCollisionShape();
+				if (shape->isCompound())
+				{
+					btCompoundShape* compoundShape = (btCompoundShape*)shape;
+					CcdShapeConstructionInfo* compoundShapeInfo = shapeInfo;
+					// need to search which sub-shape has been hit
+					for (int i=0; i<compoundShape->getNumChildShapes(); i++)
+					{
+						shapeInfo = compoundShapeInfo->GetChildShape(i);
+						shape=compoundShape->getChildShape(i);
+						if (shape == rayCallback.m_hitTriangleShape)
+							break;
+					}
+				}
+				if (shape == rayCallback.m_hitTriangleShape && 
+					rayCallback.m_hitTriangleIndex < shapeInfo->m_polygonIndexArray.size())
+				{
+					result.m_meshObject = shapeInfo->m_meshObject;
+					result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex);
+				}
+			}
+		}
+		filterCallback.reportHit(&result);
 	}	
 
 
-	return nearestHit;
+	return result.m_controller;
 }
 
 
@@ -1370,8 +1418,9 @@ int			CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl
 PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight)
 {
 	CcdConstructionInfo	cinfo;
-	//This is a memory leak: Bullet does not delete the shape and it cannot be added to 
-	//the KX_Scene.m_shapes list -- too bad but that's not a lot of data
+
+	// we don't need a CcdShapeConstructionInfo for this shape:
+	// it is simple enough for the standard copy constructor (see CcdPhysicsController::GetReplica)
 	cinfo.m_collisionShape = new btConeShape(coneradius,coneheight);
 	cinfo.m_MotionState = 0;
 	cinfo.m_physicsEnv = this;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 825a5e525f2c88e5937102dc536aeac3de3a447b..667e310dcb31f3de17368685594713922ddbf2ff 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -157,8 +157,7 @@ protected:
 
 		btTypedConstraint*	getConstraintById(int constraintId);
 
-		virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-										float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+		virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
 
 
 		//Methods for gamelogic collision/physics callbacks
diff --git a/source/gameengine/Physics/Bullet/Makefile b/source/gameengine/Physics/Bullet/Makefile
index 49259d0a67c811f5d6fb2f51393f77a35cde81e1..d5570e7583391fed6d4b7fc884bc6553373f3c09 100644
--- a/source/gameengine/Physics/Bullet/Makefile
+++ b/source/gameengine/Physics/Bullet/Makefile
@@ -37,5 +37,10 @@ CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
 
 CPPFLAGS += -I$(NAN_BULLET2)/include
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I../../../kernel/gen_system
 CPPFLAGS += -I../../Physics/common
 CPPFLAGS += -I../../Physics/Dummy
+CPPFLAGS += -I../../Rasterizer
+
diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript
index dd6eab0f0182a3f2397d885f104f5baa76f1d680..0936d45197afa8da67a9206dbcee504a39d0b49f 100644
--- a/source/gameengine/Physics/Bullet/SConscript
+++ b/source/gameengine/Physics/Bullet/SConscript
@@ -3,7 +3,7 @@ Import ('env')
 
 sources = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp'
 
-incs = '. ../common'
+incs = '. ../common #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer'
 
 incs += ' ' + env['BF_BULLET_INC']
 
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
index f512d44c9f27662614c7ac68e451e9cf2bc80006..d78958b746c4159c161b9befd5e69e8d61258f2e 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
@@ -109,8 +109,7 @@ void		DummyPhysicsEnvironment::removeConstraint(int	constraintid)
 	}
 }
 
-PHY_IPhysicsController* DummyPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-									float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
+PHY_IPhysicsController* DummyPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ)
 {
 	//collision detection / raytesting
 	return NULL;
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
index b5a61f72e4aa0cb179d4e1054d9e39e34330854e..975be84f2a7689c092b0f62950883f8c50c3ec1b 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
@@ -69,8 +69,7 @@ public:
 		return 0;
 	}
 
-	virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-									float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+	virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
 
 
 	//gamelogic callbacks
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
index 65018d2523ebc1f472b77382508996202c4e6388..80e4dc4044e7cffcf136ada52605c85a2b874a1a 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
@@ -26,6 +26,7 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  */
+#include <string.h>		// memset
 #include "SumoPhysicsEnvironment.h"
 #include "PHY_IMotionState.h"
 #include "SumoPhysicsController.h"
@@ -125,37 +126,35 @@ void SumoPhysicsEnvironment::removeConstraint(int	constraintid)
 	}
 }
 
-PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClientCtrl, 
+PHY_IPhysicsController* SumoPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback, 
 	float fromX,float fromY,float fromZ, 
-	float toX,float toY,float toZ, 
-	float& hitX,float& hitY,float& hitZ,
-	float& normalX,float& normalY,float& normalZ)
+	float toX,float toY,float toZ)
 {
-	SumoPhysicsController* ignoreCtr = static_cast<SumoPhysicsController*> (ignoreClientCtrl);
+	SumoPhysicsController* ignoreCtr = static_cast<SumoPhysicsController*> (filterCallback.m_ignoreController);
 
 	//collision detection / raytesting
 	MT_Point3 hit, normal;
-	PHY_IPhysicsController *ret = 0;
+	PHY_RayCastResult result;
 
 	SM_Object* sm_ignore = 0;
 	if (ignoreCtr)
 		sm_ignore = ignoreCtr->GetSumoObject();
 
+	memset(&result, 0, sizeof(result));
 
 	SM_Object* smOb = m_sumoScene->rayTest(sm_ignore,MT_Point3(fromX, fromY, fromZ),MT_Point3(toX, toY, toZ), hit, normal);
 	if (smOb)
 	{
-		ret = (PHY_IPhysicsController *) smOb->getPhysicsClientObject();
+		result.m_controller = (PHY_IPhysicsController *) smOb->getPhysicsClientObject();
+		result.m_hitPoint[0] = hit[0];
+		result.m_hitPoint[1] = hit[1];
+		result.m_hitPoint[2] = hit[2];
+		result.m_hitNormal[0] = normal[0];
+		result.m_hitNormal[1] = normal[1];
+		result.m_hitNormal[2] = normal[2];
+		filterCallback.reportHit(&result);
 	}
-	hitX = hit[0];
-	hitY = hit[1];
-	hitZ = hit[2];
-
-	normalX = normal[0];
-	normalY = normal[1];
-	normalZ = normal[2];
-	
-	return ret;
+	return result.m_controller;
 }
 //gamelogic callbacks
 void SumoPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
index 8b9fb4630345cc43fba493a5366f41e8b56f1217..100adf969d5a595bedc01802a59e48fa267a04cb 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
@@ -75,8 +75,7 @@ public:
 		return 0;
 	}
 
-	virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient,float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-									float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ);
+	virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
 
 	
 	//gamelogic callbacks
diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h
index c289b9d8bcb7c57bd0c11c91e39fe4d62db7f8cd..3b3e42c38d241e5be44936f441865247af08878c 100644
--- a/source/gameengine/Physics/common/PHY_DynamicTypes.h
+++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h
@@ -87,6 +87,18 @@ typedef enum PHY_ConstraintType {
 
 } PHY_ConstraintType;
 
+typedef enum PHY_ShapeType {
+	PHY_SHAPE_NONE,
+	PHY_SHAPE_BOX,
+	PHY_SHAPE_SPHERE,
+	PHY_SHAPE_CYLINDER,
+	PHY_SHAPE_CONE,
+	PHY_SHAPE_MESH,
+	PHY_SHAPE_POLYTOPE,
+	PHY_SHAPE_COMPOUND
+} PHY_ShapeType;
+
+
 typedef float	PHY_Vector3[3];
 
 #endif //__PHY_DYNAMIC_TYPES
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index 5b2750666657a3e1531966d6bb8142a70f2b2702..98496fb7f9ef08819bcc2dc8d6d696e0ee66cbaa 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -33,6 +33,50 @@
 #include <vector>
 #include "PHY_DynamicTypes.h"
 class PHY_IVehicle;
+class RAS_MeshObject;
+class PHY_IPhysicsController;
+
+/**
+ * pass back information from rayTest
+ */
+struct PHY_RayCastResult
+{
+	PHY_IPhysicsController* m_controller;	
+	PHY__Vector3			m_hitPoint;
+	PHY__Vector3			m_hitNormal;
+	const RAS_MeshObject*	m_meshObject;	// !=NULL for mesh object (only for Bullet controllers) 
+	int						m_polygon;		// index of the polygon hit by the ray,
+											// only if m_meshObject != NULL
+};
+
+/**
+ * This class replaces the ignoreController parameter of rayTest function. 
+ * It allows more sophisticated filtering on the physics controller before computing the ray intersection to save CPU. 
+ * It is only used to its full extend by the Ccd physics environement (Bullet).
+ */
+class PHY_IRayCastFilterCallback
+{
+public:
+	PHY_IPhysicsController* m_ignoreController;
+	bool					m_faceNormal;
+
+	virtual		~PHY_IRayCastFilterCallback()
+	{
+	}
+
+	virtual	bool needBroadphaseRayCast(PHY_IPhysicsController* controller)
+	{
+		return true;
+	}
+
+	virtual void reportHit(PHY_RayCastResult* result) = 0;
+
+	PHY_IRayCastFilterCallback(PHY_IPhysicsController* ignoreController, bool faceNormal=false) 
+		:m_ignoreController(ignoreController),
+		m_faceNormal(faceNormal)
+	{
+	}
+};
 
 /**
 *	Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.)
@@ -94,8 +138,7 @@ class PHY_IPhysicsEnvironment
 		//complex constraint for vehicles
 		virtual PHY_IVehicle*	getVehicleConstraint(int constraintId) =0;
 
-		virtual PHY_IPhysicsController* rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
-										float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)=0;
+		virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)=0;
 
 
 		//Methods for gamelogic collision/physics callbacks
diff --git a/source/gameengine/PyDoc/GameKeys.py b/source/gameengine/PyDoc/GameKeys.py
index 268fb9cc172c06caadca69b9ea1918eca66491ac..1a0a737718eb5028170cfe2e2944583ec305c0f1 100644
--- a/source/gameengine/PyDoc/GameKeys.py
+++ b/source/gameengine/PyDoc/GameKeys.py
@@ -164,3 +164,12 @@ Example::
 				# Activate Right!
 		
 """
+
+def EventToString(event):
+	"""
+	Return the string name of a key event. Will raise a ValueError error if its invalid.
+	
+	@type event: int
+	@param event: key event from GameKeys or the keyboard sensor.
+	@rtype: string
+	"""
diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py
index 965c0522bd7ebea64fb0baad2fd45c3cf55e1182..b65bc0f3ce857efa98add5f445af86a0bfddddfc 100644
--- a/source/gameengine/PyDoc/GameLogic.py
+++ b/source/gameengine/PyDoc/GameLogic.py
@@ -14,8 +14,7 @@ Documentation for the GameLogic Module.
 	
 	Examples::
 		# To get a controller:
-		import GameLogic
-		co = GameLogic.getCurrentController()
+		co = GameLogic.getCurrentController() # GameLogic is automatically imported
 		
 		# To get the game object associated with this controller:
 		obj = co.getOwner()
@@ -42,6 +41,7 @@ Documentation for the GameLogic Module.
 		- L{SCA_MouseSensor}
 		- L{SCA_PropertySensor} 
 		- L{SCA_RandomSensor} 
+		- L{SCA_DelaySensor}
 	
 	You can also access actuators linked to the controller::
 		# To get an actuator attached to the controller:
@@ -236,3 +236,13 @@ def expandPath(path):
 	@return: The converted string
 	@rtype: string
 	"""
+
+def getBlendFileList(path = "//"):
+	"""
+	Returns a list of blend files in the same directory as the open blend file, or from using the option argument.
+
+	@param path: Optional directory argument, will be expanded (like expandPath) into the full path.
+	@type path: string
+	@return: A list of filenames, with no directory prefix
+	@rtype: list
+	"""
\ No newline at end of file
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index a5ba5b1d63408545d2ff175e6d36ce42f3b5d4bf..2136ce54e307155b7e514e005b57cc22b0d1b5aa 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -135,6 +135,26 @@ class KX_GameObject:
 		@param local: - False: you get the "global" velocity ie: relative to world orientation (default).
 		              - True: you get the "local" velocity ie: relative to object orientation.
 		"""
+	def getAngularVelocity(local = 0):
+		"""
+		Gets the game object's angular velocity.
+		
+		@type local: boolean
+		@param local: - False: you get the "global" velocity ie: relative to world orientation (default).
+		              - True: you get the "local" velocity ie: relative to object orientation.
+		@rtype: list [vx, vy, vz]
+		@return: the object's angular velocity.
+		"""
+	def setAngularVelocity(velocity, local = 0):
+		"""
+		Sets the game object's angular velocity.
+		
+		@type velocity: 3d vector.
+		@param velocity: angular velocity vector.
+		@type local: boolean
+		@param local: - False: you get the "global" velocity ie: relative to world orientation (default).
+		              - True: you get the "local" velocity ie: relative to object orientation.
+		"""
 	def getVelocity(point):
 		"""
 		Gets the game object's velocity at the specified point.
@@ -280,10 +300,11 @@ class KX_GameObject:
 		@rtype: L{KX_GameObject}
 		@return: the first object hit or None if no object or object does not match prop
 		"""
-	def rayCast(to,from,dist,prop):
+	def rayCast(to,from,dist,prop,face,xray,poly):
 		"""
 		Look from a point/object to another point/object and find first object hit within dist that matches prop.
-		Returns a 3-tuple with object reference, hit point and hit normal or (None,None,None) if no hit.
+		if poly is 0, returns a 3-tuple with object reference, hit point and hit normal or (None,None,None) if no hit.
+		if poly is 1, returns a 4-tuple with in addition a L{KX_PolyProxy} as 4th element.
 		Ex:
 			# shoot along the axis gun-gunAim (gunAim should be collision-free)
 			ob,point,normal = gun.rayCast(gunAim,None,50)
@@ -292,9 +313,18 @@ class KX_GameObject:
 
 		Notes:				
 		The ray ignores the object on which the method is called.
-		If is casted from/to object center or explicit [x,y,z] points.
-		The ray does not have X-Ray capability: the first object hit (other than self object) stops the ray
-		If a property was specified and the first object hit does not have that property, there is no hit
+		It is casted from/to object center or explicit [x,y,z] points.
+		The face paremeter determines the orientation of the normal: 
+		  0 => hit normal is always oriented towards the ray origin (as if you casted the ray from outside)
+		  1 => hit normal is the real face normal (only for mesh object, otherwise face has no effect)
+		The ray has X-Ray capability if xray parameter is 1, otherwise the first object hit (other than self object) stops the ray.
+		The prop and xray parameters interact as follow:
+		    prop off, xray off: return closest hit or no hit if there is no object on the full extend of the ray.
+		    prop off, xray on : idem.
+		    prop on,  xray off: return closest hit if it matches prop, no hit otherwise.
+		    prop on,  xray on : return closest hit matching prop or no hit if there is no object matching prop on the full extend of the ray.
+		The L{KX_PolyProxy} 4th element of the return tuple when poly=1 allows to retrieve information on the polygon hit by the ray.
+		If there is no hit or the hit object is not a static mesh, None is returned as 4th element. 
 		The	ray ignores collision-free objects and faces that dont have the collision flag enabled, you can however use ghost objects.
 
 		@param to: [x,y,z] or object to which the ray is casted
@@ -305,8 +335,17 @@ class KX_GameObject:
 		@type dist: float
 		@param prop: property name that object must have; can be omitted => detect any object
 		@type prop: string
-		@rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz))
-		@return: (object,hitpoint,hitnormal) or (None,None,None)
+		@param face: normal option: 1=>return face normal; 0 or omitted => normal is oriented towards origin
+		@type face: int
+		@param xray: X-ray option: 1=>skip objects that don't match prop; 0 or omitted => stop on first object
+		@type xray: int
+		@param poly: polygon option: 1=>return value is a 4-tuple and the 4th element is a L{KX_PolyProxy}
+		@type poly: int
+		@rtype:    3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz))
+		        or 4-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz), L{KX_PolyProxy))
+		@return: (object,hitpoint,hitnormal) or (object,hitpoint,hitnormal,polygon)
+		         If no hit, returns (None,None,None) or (None,None,None,None)
+		         If the object hit is not a static mesh, polygon is None
 		"""
 
 
diff --git a/source/gameengine/PyDoc/KX_MeshProxy.py b/source/gameengine/PyDoc/KX_MeshProxy.py
index e43fa3598f07e0f424e8ba7239d534ef158fc9cc..03bc36b6ac1f5c5e248bdae8b2d323c676b27013 100644
--- a/source/gameengine/PyDoc/KX_MeshProxy.py
+++ b/source/gameengine/PyDoc/KX_MeshProxy.py
@@ -95,6 +95,21 @@ class KX_MeshProxy:
 		@rtype: L{KX_VertexProxy}
 		@return: a vertex object.
 		"""
+	def getNumPolygons():
+		"""
+		Returns the number of polygon in the mesh.
+		
+		@rtype: integer
+		"""
+	def getPolygon(index):
+		"""
+		Gets the specified polygon from the mesh.
+		
+		@type index: integer
+		@param index: polygon number
+		@rtype: L{KX_PolyProxy}
+		@return: a polygon object.
+		"""
 	def reinstancePhysicsMesh():
 		"""
 		Updates the physics system with the changed mesh.
diff --git a/source/gameengine/PyDoc/KX_PolyProxy.py b/source/gameengine/PyDoc/KX_PolyProxy.py
new file mode 100644
index 0000000000000000000000000000000000000000..45ae30a13dd389d5994526a6a135e971afb2212b
--- /dev/null
+++ b/source/gameengine/PyDoc/KX_PolyProxy.py
@@ -0,0 +1,100 @@
+# $Id$
+# Documentation for the polygon proxy class
+
+class KX_PolyProxy:
+	"""
+	A polygon holds the index of the vertex forming the poylgon.
+
+	Note: 
+	The polygon attributes are read-only, you need to retrieve the vertex proxy if you want
+	to change the vertex settings. 
+	
+	@ivar matname: The name of polygon material, empty if no material.
+	@type matname: string
+	@ivar material: The material of the polygon
+	@type material: L{KX_PolygonMaterial} or KX_BlenderMaterial
+	@ivar texture: The texture name of the polygon.
+	@type texture: string
+	@ivar matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
+	@type matid: integer
+	@ivar v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
+	@type v1: integer	
+	@ivar v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
+	@type v2: integer	
+	@ivar v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
+	@type v3: integer	
+	@ivar v4: vertex index of the fourth vertex of the polygon, 0 if polygon has only 3 vertex
+	          use this to retrieve vertex proxy from mesh proxy
+	@type v4: integer	
+	@ivar visible: visible state of the polygon: 1=visible, 0=invisible
+	@type visible: integer
+	@ivar collide: collide state of the polygon: 1=receives collision, 0=collision free.
+	@type collide: integer
+	"""
+
+	def getMaterialName(): 
+		"""
+		Returns the polygon material name with MA prefix
+		
+		@rtype: string
+		@return: material name
+		"""
+	def getMaterial(): 
+		"""
+		Returns the polygon material
+		
+		@rtype: L{KX_PolygonMaterial} or KX_BlenderMaterial
+		"""
+	def getTextureName():
+		"""
+		Returns the polygon texture name
+		
+		@rtype: string
+		@return: texture name
+		"""
+	def getMaterialIndex():
+		"""
+		Returns the material bucket index of the polygon. 
+		This index and the ones returned by getVertexIndex() are needed to retrieve the vertex proxy from L{KX_MeshProxy}.
+		
+		@rtype: integer
+		@return: the material index in the mesh
+	
+	def getNumVertex(): 
+		"""
+		Returns the number of vertex of the polygon.
+		
+		@rtype: integer
+		@return: number of vertex, 3 or 4.
+		"""
+	def isVisible():
+		"""
+		Returns whether the polygon is visible or not
+		
+		@rtype: integer
+		@return: 0=invisible, 1=visible
+		"""
+	def isCollider():
+		"""
+		Returns whether the polygon is receives collision or not
+		
+		@rtype: integer
+		@return: 0=collision free, 1=receives collision
+		"""
+	def getVertexIndex(vertex):
+		"""
+		Returns the mesh vertex index of a polygon vertex
+		This index and the one returned by getMaterialIndex() are needed to retrieve the vertex proxy from L{KX_MeshProxy}.
+		
+		@type vertex: integer
+		@param vertex: index of the vertex in the polygon: 0->3
+		@rtype: integer
+		@return: mesh vertex index
+		"""
+	def getMesh():
+		"""
+		Returns a mesh proxy
+		
+		@rtype: L{KX_MeshProxy}
+		@return: mesh proxy
+		"""
diff --git a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py b/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
index 4f2bf85bff3bcd058117836d6154686b34f353a2..c3b2e947ddbca023916cbd5ed1a19b6486eb5a6a 100644
--- a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
+++ b/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
@@ -64,6 +64,23 @@ class KX_SCA_AddObjectActuator(SCA_IActuator):
 		"""
 		Returns the initial linear velocity of added objects.
 		
+		@rtype: list [vx, vy, vz]
+		"""
+	def setAngularVelocity(vx, vy, vz):
+		"""
+		Sets the initial angular velocity of added objects.
+		
+		@type vx: float
+		@param vx: the x component of the initial angular velocity.
+		@type vy: float
+		@param vy: the y component of the initial angular velocity.
+		@type vz: float
+		@param vz: the z component of the initial angular velocity.
+		"""
+	def getAngularVelocity():
+		"""
+		Returns the initial angular velocity of added objects.
+		
 		@rtype: list [vx, vy, vz]
 		"""
 	def getLastCreatedObject():
diff --git a/source/gameengine/PyDoc/SCA_DelaySensor.py b/source/gameengine/PyDoc/SCA_DelaySensor.py
new file mode 100644
index 0000000000000000000000000000000000000000..46b74f461a7e2f841635685fa62a77a8b5198c07
--- /dev/null
+++ b/source/gameengine/PyDoc/SCA_DelaySensor.py
@@ -0,0 +1,56 @@
+# $Id$
+# Documentation for SCA_DelaySensor
+from SCA_IActuator import *
+
+class SCA_DelaySensor(SCA_ISensor):
+	"""
+	The Delay sensor generates positive and negative triggers at precise time,
+	expressed in number of frames. The delay parameter defines the length
+	of the initial OFF period. A positive trigger is generated at the end of this period. 
+	The duration parameter defines the length of the ON period following the OFF period.
+	There is a negative trigger at the end of the ON period. If duration is 0, the sensor
+	stays ON and there is no negative trigger.
+	The sensor runs the OFF-ON cycle once unless the repeat option is set: the
+	OFF-ON cycle repeats indefinately (or the OFF cycle if duration is 0).
+	Use SCA_ISensor::reset() at any time to restart sensor.
+	"""
+	def setDelay(delay):
+		"""
+		Set the initial delay before the positive trigger.
+		
+		@param delay: length of the initial OFF period as number of frame, 0 for immediate trigger
+		@type delay: integer
+		"""
+	def setDuration(duration):
+		"""
+		Set the duration of the ON pulse after initial delay and the generation of the positive trigger.
+		If duration is greater than 0, a negative trigger is sent at the end of the ON pulse.
+		
+		@param duration: length of the ON period in number of frame after the initial OFF period
+		@type duration: integer
+		"""	
+	def setRepeat(repeat):
+		"""
+		Set if the sensor repeat mode.
+		
+		@param repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once.
+		@type repeat: integer
+		"""		
+	def getDelay():
+		"""
+		Return the delay parameter value.
+		
+		@rtype: integer
+		"""
+	def getDuration():
+		"""
+		Return the duration parameter value
+		
+		@rtype: integer
+		"""
+	def getRepeat():
+		"""
+		Return the repeat parameter value
+		
+		@rtype: KX_TRUE or KX_FALSE
+		"""
diff --git a/source/gameengine/PyDoc/SCA_ISensor.py b/source/gameengine/PyDoc/SCA_ISensor.py
index 0ebc2debb314a8525b6e8de5f24dda3b2dd1fe25..14858505e2435d7b5816e5a4334b344612ffef2c 100644
--- a/source/gameengine/PyDoc/SCA_ISensor.py
+++ b/source/gameengine/PyDoc/SCA_ISensor.py
@@ -9,7 +9,12 @@ class SCA_ISensor(SCA_ILogicBrick):
 	
 	def isPositive():
 		"""
-		True if this sensor brick has been activated.
+		True if this sensor brick is in a positive state.
+		"""
+	
+	def isTriggered():
+		"""
+		True if this sensor brick has triggered the current controller.
 		"""
 	
 	def getUsePosPulseMode():
@@ -77,4 +82,10 @@ class SCA_ISensor(SCA_ILogicBrick):
 		@param level: Detect level instead of edge? (KX_TRUE, KX_FALSE)
 		@type level: boolean
 		"""
+	def reset():
+		"""
+		Reset sensor internal state, effect depends on the type of sensor and settings.
+		
+		The sensor is put in its initial state as if it was just activated.
+		"""
 
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index af5228e4c35194d82fc173bbe25899018376f3d6..a4f7f3f01dd84a06b66b1b4de5951ddd1be41b10 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -134,7 +134,7 @@ int RAS_MeshObject::NumPolygons()
 
 
 
-RAS_Polygon* RAS_MeshObject::GetPolygon(int num)
+RAS_Polygon* RAS_MeshObject::GetPolygon(int num) const
 {
 	return m_Polygons[num];
 }
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 99806666fa646d4d6bf7d1ecd9b73fac5e1708c6..9a46d89c393773c847253135f81ae4defd98bc6b 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -178,7 +178,7 @@ public:
 	void				UpdateMaterialList();
 	
 	int					NumPolygons();
-	RAS_Polygon*		GetPolygon(int num);
+	RAS_Polygon*		GetPolygon(int num) const;
 	
 	virtual void		Bucketize(
 							double* oglmatrix,
diff --git a/source/kernel/CMakeLists.txt b/source/kernel/CMakeLists.txt
index 3d966152cc5f8522426ce76db34e26493fc53df8..ac759393326f590f46266345c24f59d9543fd804 100644
--- a/source/kernel/CMakeLists.txt
+++ b/source/kernel/CMakeLists.txt
@@ -24,7 +24,7 @@
 #
 # ***** END GPL LICENSE BLOCK *****
 
-SET(INC gen_messaging gen_system ../../intern/string ../../intern/moto/include)
+SET(INC gen_messaging gen_system ../../intern/string ../../intern/moto/include ../../source/blender/blenloader )
 
 FILE(GLOB SRC   
   gen_messaging/intern/messaging.c
diff --git a/source/kernel/SConscript b/source/kernel/SConscript
index 9e678c041dc821af776ca79e1120244404883932..8bd1a18f835f2514256885ff1a843b9bbb772067 100644
--- a/source/kernel/SConscript
+++ b/source/kernel/SConscript
@@ -5,6 +5,6 @@ sources = 'gen_messaging/intern/messaging.c gen_system/GEN_HashedPtr.cpp'
 sources += ' gen_system/GEN_Matrix4x4.cpp gen_system/SYS_SingletonSystem.cpp'
 sources += ' gen_system/SYS_System.cpp'
 
-incs = 'gen_messaging gen_system #/intern/string #/intern/moto/include'
+incs = 'gen_messaging gen_system #/intern/string #/intern/moto/include #/source/blender/blenloader '
 
 env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['common','game2', 'player'], priority = [15, 10, 150] )
diff --git a/source/kernel/gen_system/GEN_HashedPtr.cpp b/source/kernel/gen_system/GEN_HashedPtr.cpp
index 49ccb2522461e350447c52d76577f445e56e2863..6dbed1fb7a8d6159451ba2ec0213cf7cfcc5a6c2 100644
--- a/source/kernel/gen_system/GEN_HashedPtr.cpp
+++ b/source/kernel/gen_system/GEN_HashedPtr.cpp
@@ -33,6 +33,8 @@
 #include <config.h>
 #endif
 
+#include "BLO_sys_types.h" // for intptr_t support
+
 //
 // Build hash index from pointer.  Even though the final result
 // is a 32-bit integer, use all the bits of the pointer as long
@@ -41,11 +43,7 @@
 
 unsigned int GEN_Hash(void * inDWord)
 {
-#if defined(_WIN64)
-	unsigned __int64 key = (unsigned __int64)inDWord;
-#else
-	unsigned long key = (unsigned long)inDWord;
-#endif
+	uintptr_t key = (uintptr_t)inDWord;
 
 	key += ~(key << 16);
 	key ^=  (key >>  5);
diff --git a/source/kernel/gen_system/Makefile b/source/kernel/gen_system/Makefile
index 855af3766154847e05c6e78642d6dc3676ec2500..31535ad2a9742f27785812fa60de32fc0dc10ef4 100644
--- a/source/kernel/gen_system/Makefile
+++ b/source/kernel/gen_system/Makefile
@@ -37,4 +37,5 @@ CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
 
 CPPFLAGS += -I$(NAN_MOTO)/include    
 CPPFLAGS += -I$(NAN_STRING)/include    
+CPPFLAGS += -I../../../source/blender/blenloader
 
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index 9c1a28de99929d990da6cd9d92f4d88a26b137ed..6200d430dd4e87ae58a21c579b7d33deefa41d44 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -287,7 +287,7 @@ endif
     export FREEDESKTOP ?= true
 
     export NAN_PYTHON ?= /usr/local
-    export NAN_PYTHON_VERSION ?= 2.3
+    export NAN_PYTHON_VERSION ?= 2.5
     export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION)
     export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a
     export NAN_OPENAL ?= /usr/local
@@ -302,9 +302,9 @@ endif
     export NAN_NSPR ?= /usr/local
     export NAN_FREETYPE ?= $(LCGDIR)/freetype
     export NAN_GETTEXT ?= $(LCGDIR)/gettext
-    export NAN_SDL ?= $(shell sdl11-config --prefix)
-    export NAN_SDLLIBS ?= $(shell sdl11-config --libs)
-    export NAN_SDLCFLAGS ?= $(shell sdl11-config --cflags)
+    export NAN_SDL ?= $(shell sdl-config --prefix)
+    export NAN_SDLLIBS ?= $(shell sdl-config --libs)
+    export NAN_SDLCFLAGS ?= $(shell sdl-config --cflags)
 
     # Uncomment the following line to use Mozilla inplace of netscape
     # CPPFLAGS +=-DMOZ_NOT_NET