| 
									
										
										
										
											2011-02-25 13:37:23 +00:00
										 |  |  | /** \file gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
 | 
					
						
							|  |  |  |  *  \ingroup physbullet | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  | Bullet Continuous Collision Detection and Physics Library | 
					
						
							|  |  |  | Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This software is provided 'as-is', without any express or implied warranty. | 
					
						
							|  |  |  | In no event will the authors be held liable for any damages arising from the use of this software. | 
					
						
							|  |  |  | Permission is granted to anyone to use this software for any purpose,  | 
					
						
							|  |  |  | including commercial applications, and to alter it and redistribute it freely,  | 
					
						
							|  |  |  | subject to the following restrictions: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. | 
					
						
							|  |  |  | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | 
					
						
							|  |  |  | 3. This notice may not be removed or altered from any source distribution. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | #include "CcdPhysicsEnvironment.h"
 | 
					
						
							|  |  |  | #include "CcdPhysicsController.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | #include "CcdGraphicController.h"
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | #include "btBulletDynamicsCommon.h"
 | 
					
						
							|  |  |  | #include "LinearMath/btIDebugDraw.h"
 | 
					
						
							| 
									
										
										
										
											2012-05-28 21:36:29 +00:00
										 |  |  | #include "BulletCollision/CollisionDispatch/btGhostObject.h"
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | #include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
 | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
 | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
 | 
					
						
							| 
									
										
										
										
											2008-09-26 02:27:59 +00:00
										 |  |  | #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | //profiling/timings
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | #include "LinearMath/btQuickprof.h"
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-21 05:36:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | #include "PHY_IMotionState.h"
 | 
					
						
							| 
									
										
										
										
											2012-11-04 20:56:02 +00:00
										 |  |  | #include "PHY_ICharacter.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | #include "KX_GameObject.h"
 | 
					
						
							|  |  |  | #include "RAS_MeshObject.h"
 | 
					
						
							|  |  |  | #include "RAS_Polygon.h"
 | 
					
						
							|  |  |  | #include "RAS_TexVert.h"
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | #define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool useIslands = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | #ifdef NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | #include "BulletDynamics/Vehicle/btRaycastVehicle.h"
 | 
					
						
							|  |  |  | #include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
 | 
					
						
							|  |  |  | #include "BulletDynamics/Vehicle/btWheelInfo.h"
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | #include "PHY_IVehicle.h"
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | btRaycastVehicle::btVehicleTuning	gTuning; | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif //NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | #include "LinearMath/btAabbUtil2.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | #include "MT_Matrix4x4.h"
 | 
					
						
							|  |  |  | #include "MT_Vector3.h"
 | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  | void DrawRasterizerLine(const float* from,const float* to,int color); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | #include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2008-08-28 12:12:56 +00:00
										 |  |  | #include <string.h>		// for memset
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | #ifdef NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							|  |  |  | class WrapperVehicle : public PHY_IVehicle | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btRaycastVehicle*	m_vehicle; | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	PHY_IPhysicsController*	m_chassis; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | public: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	WrapperVehicle(btRaycastVehicle* vehicle,PHY_IPhysicsController* chassis) | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 		:m_vehicle(vehicle), | 
					
						
							|  |  |  | 		m_chassis(chassis) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btRaycastVehicle*	GetVehicle() | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		return m_vehicle; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PHY_IPhysicsController*	GetChassis() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return m_chassis; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual void	AddWheel( | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 		PHY_IMotionState*	motionState, | 
					
						
							| 
									
										
										
										
											2013-02-21 18:30:11 +00:00
										 |  |  | 		MT_Vector3	connectionPoint, | 
					
						
							|  |  |  | 		MT_Vector3	downDirection, | 
					
						
							|  |  |  | 		MT_Vector3	axleDirection, | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 		float	suspensionRestLength, | 
					
						
							|  |  |  | 		float wheelRadius, | 
					
						
							|  |  |  | 		bool hasSteering | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 		) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		btVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]); | 
					
						
							|  |  |  | 		btVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]); | 
					
						
							|  |  |  | 		btVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		btWheelInfo& info = m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle, | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 			suspensionRestLength,wheelRadius,gTuning,hasSteering); | 
					
						
							|  |  |  | 		info.m_clientInfo = motionState; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void	SyncWheels() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int numWheels = GetNumWheels(); | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 		for (i=0;i<numWheels;i++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(i); | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 			PHY_IMotionState* motionState = (PHY_IMotionState*)info.m_clientInfo; | 
					
						
							| 
									
										
										
										
											2006-12-04 04:13:42 +00:00
										 |  |  | 	//		m_vehicle->updateWheelTransformsWS(info,false);
 | 
					
						
							|  |  |  | 			m_vehicle->updateWheelTransform(i,false); | 
					
						
							| 
									
										
										
										
											2006-12-02 22:25:47 +00:00
										 |  |  | 			btTransform trans = m_vehicle->getWheelInfo(i).m_worldTransform; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btQuaternion orn = trans.getRotation(); | 
					
						
							|  |  |  | 			const btVector3& pos = trans.getOrigin(); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 			motionState->setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); | 
					
						
							|  |  |  | 			motionState->setWorldPosition(pos.x(),pos.y(),pos.z()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual	int		GetNumWheels() const | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		return m_vehicle->getNumWheels(); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	virtual void	GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		btTransform	trans = m_vehicle->getWheelTransformWS(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 		posX = trans.getOrigin().x(); | 
					
						
							|  |  |  | 		posY = trans.getOrigin().y(); | 
					
						
							|  |  |  | 		posZ = trans.getOrigin().z(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	virtual void	GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		btTransform	trans = m_vehicle->getWheelTransformWS(wheelIndex); | 
					
						
							|  |  |  | 		btQuaternion quat = trans.getRotation(); | 
					
						
							|  |  |  | 		btMatrix3x3 orn2(quat); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		quatX = trans.getRotation().x(); | 
					
						
							|  |  |  | 		quatY = trans.getRotation().y(); | 
					
						
							|  |  |  | 		quatZ = trans.getRotation().z(); | 
					
						
							|  |  |  | 		quatW = trans.getRotation()[3]; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		//printf("test");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual float	GetWheelRotation(int wheelIndex) const | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		float rotation = 0.f; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 			rotation = info.m_rotation; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return rotation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	virtual int	GetUserConstraintId() const | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		return m_vehicle->getUserConstraintId(); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual int	GetUserConstraintType() const | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		return m_vehicle->getUserConstraintType(); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual	void	SetSteeringValue(float steering,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		m_vehicle->setSteeringValue(steering,wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual	void	ApplyEngineForce(float force,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		m_vehicle->applyEngineForce(force,wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual	void	ApplyBraking(float braking,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 			info.m_brake = braking; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 	virtual	void	SetWheelFriction(float friction,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 			info.m_frictionSlip = friction; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 	virtual	void	SetSuspensionStiffness(float suspensionStiffness,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 			info.m_suspensionStiffness = suspensionStiffness; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual	void	SetSuspensionDamping(float suspensionDamping,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 			info.m_wheelsDampingRelaxation = suspensionDamping; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual	void	SetSuspensionCompression(float suspensionCompression,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 			info.m_wheelsDampingCompression = suspensionCompression; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 	virtual	void	SetRollInfluence(float rollInfluence,int wheelIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 			info.m_rollInfluence = rollInfluence; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	virtual void	SetCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-21 07:08:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif //NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-04 20:56:02 +00:00
										 |  |  | class CharacterWrapper : public PHY_ICharacter | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2012-12-26 01:25:53 +00:00
										 |  |  | 	BlenderBulletCharacterController* m_controller; | 
					
						
							| 
									
										
										
										
											2012-11-04 20:56:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2012-12-26 01:25:53 +00:00
										 |  |  | 	CharacterWrapper(BlenderBulletCharacterController* cont) | 
					
						
							| 
									
										
										
										
											2012-11-04 20:56:02 +00:00
										 |  |  | 		: m_controller(cont) | 
					
						
							|  |  |  | 	{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual void Jump() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_controller->jump(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual bool OnGround() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return m_controller->onGround(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual float GetGravity() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return m_controller->getGravity(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	virtual void SetGravity(float gravity) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_controller->setGravity(gravity); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-26 01:25:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	virtual int GetMaxJumps() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return m_controller->getMaxJumps(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual void SetMaxJumps(int maxJumps) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_controller->setMaxJumps(maxJumps); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-29 10:22:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	virtual int GetJumpCount() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return m_controller->getJumpCount(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-01-30 05:55:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-21 18:30:11 +00:00
										 |  |  | 	virtual void SetWalkDirection(const MT_Vector3& dir) | 
					
						
							| 
									
										
										
										
											2013-01-30 05:55:17 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		btVector3 vec = btVector3(dir[0], dir[1], dir[2]); | 
					
						
							|  |  |  | 		m_controller->setWalkDirection(vec); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-21 18:30:11 +00:00
										 |  |  | 	virtual MT_Vector3 GetWalkDirection() | 
					
						
							| 
									
										
										
										
											2013-01-30 05:55:17 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		btVector3 vec = m_controller->getWalkDirection(); | 
					
						
							| 
									
										
										
										
											2013-02-21 18:30:11 +00:00
										 |  |  | 		return MT_Vector3(vec[0], vec[1], vec[2]); | 
					
						
							| 
									
										
										
										
											2013-01-30 05:55:17 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-11-04 20:56:02 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | class CcdOverlapFilterCallBack : public btOverlapFilterCallback | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 	class CcdPhysicsEnvironment* m_physEnv; | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	CcdOverlapFilterCallBack(CcdPhysicsEnvironment* env) :  | 
					
						
							|  |  |  | 		m_physEnv(env) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	virtual ~CcdOverlapFilterCallBack() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// return true when pairs need collision
 | 
					
						
							|  |  |  | 	virtual bool	needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 12:26:05 +00:00
										 |  |  | void CcdPhysicsEnvironment::setDebugDrawer(btIDebugDraw* debugDrawer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (debugDrawer && m_dynamicsWorld) | 
					
						
							|  |  |  | 		m_dynamicsWorld->setDebugDrawer(debugDrawer); | 
					
						
							|  |  |  | 	m_debugDrawer = debugDrawer; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-20 12:33:00 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVector3& to,const btVector3& color) | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btVector3 halfExtents = (to-from)* 0.5f; | 
					
						
							|  |  |  | 	btVector3 center = (to+from) *0.5f; | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 	int i,j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btVector3 edgecoord(1.f,1.f,1.f),pa,pb; | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 	for (i=0;i<4;i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		for (j=0;j<3;j++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 			pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 				edgecoord[2]*halfExtents[2]); | 
					
						
							|  |  |  | 			pa+=center; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 			int othercoord = j%3; | 
					
						
							|  |  |  | 			edgecoord[othercoord]*=-1.f; | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 			pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 				edgecoord[2]*halfExtents[2]); | 
					
						
							|  |  |  | 			pb+=center; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			debugDrawer->drawLine(pa,pb,color); | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		edgecoord = btVector3(-1.f,-1.f,-1.f); | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 		if (i<3) | 
					
						
							|  |  |  | 			edgecoord[i]*=-1.f; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-10-20 12:33:00 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-07-27 09:30:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | CcdPhysicsEnvironment::CcdPhysicsEnvironment(bool useDbvtCulling,btDispatcher* dispatcher,btOverlappingPairCache* pairCache) | 
					
						
							|  |  |  | :m_cullingCache(NULL), | 
					
						
							|  |  |  | m_cullingTree(NULL), | 
					
						
							|  |  |  | m_numIterations(10), | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | m_numTimeSubSteps(1), | 
					
						
							| 
									
										
										
										
											2005-08-04 19:07:39 +00:00
										 |  |  | m_ccdMode(0), | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | m_solverType(-1), | 
					
						
							|  |  |  | m_profileTimings(0), | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | m_enableSatCollisionDetection(false), | 
					
						
							|  |  |  | m_solver(NULL), | 
					
						
							|  |  |  | m_ownPairCache(NULL), | 
					
						
							| 
									
										
										
										
											2009-02-25 03:26:02 +00:00
										 |  |  | m_filterCallback(NULL), | 
					
						
							| 
									
										
										
										
											2012-07-08 20:05:40 +00:00
										 |  |  | m_ghostPairCallback(NULL), | 
					
						
							| 
									
										
										
										
											2009-08-26 06:15:43 +00:00
										 |  |  | m_ownDispatcher(NULL), | 
					
						
							|  |  |  | m_scalingPropagated(false) | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-08-04 19:07:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	for (int i=0;i<PHY_NUM_RESPONSE;i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_triggerCallbacks[i] = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //	m_collisionConfiguration = new btDefaultCollisionConfiguration();
 | 
					
						
							|  |  |  | 	m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); | 
					
						
							| 
									
										
										
										
											2009-03-09 04:21:28 +00:00
										 |  |  | 	//m_collisionConfiguration->setConvexConvexMultipointIterations();
 | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-21 05:36:56 +00:00
										 |  |  | 	if (!dispatcher) | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-09-26 02:27:59 +00:00
										 |  |  | 		btCollisionDispatcher* disp = new btCollisionDispatcher(m_collisionConfiguration); | 
					
						
							|  |  |  | 		dispatcher = disp; | 
					
						
							|  |  |  | 		btGImpactCollisionAlgorithm::registerAlgorithm(disp); | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 		m_ownDispatcher = dispatcher; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | 	//m_broadphase = new btAxisSweep3(btVector3(-1000,-1000,-1000),btVector3(1000,1000,1000));
 | 
					
						
							|  |  |  | 	//m_broadphase = new btSimpleBroadphase();
 | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 	m_broadphase = new btDbvtBroadphase(); | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 	// avoid any collision in the culling tree
 | 
					
						
							|  |  |  | 	if (useDbvtCulling) { | 
					
						
							|  |  |  | 		m_cullingCache = new btNullPairCache(); | 
					
						
							|  |  |  | 		m_cullingTree = new btDbvtBroadphase(m_cullingCache); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	m_filterCallback = new CcdOverlapFilterCallBack(this); | 
					
						
							| 
									
										
										
										
											2012-07-08 20:05:40 +00:00
										 |  |  | 	m_ghostPairCallback = new btGhostPairCallback(); | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 	m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback); | 
					
						
							| 
									
										
										
										
											2012-07-08 20:05:40 +00:00
										 |  |  | 	m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(m_ghostPairCallback); | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-09 01:15:12 +00:00
										 |  |  | 	setSolverType(1);//issues with quickstep and memory allocations
 | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | //	m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
 | 
					
						
							|  |  |  | 	m_dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration); | 
					
						
							| 
									
										
										
										
											2009-03-09 04:21:28 +00:00
										 |  |  | 	//m_dynamicsWorld->getSolverInfo().m_linearSlop = 0.01f;
 | 
					
						
							| 
									
										
										
										
											2009-03-03 03:41:24 +00:00
										 |  |  | 	//m_dynamicsWorld->getSolverInfo().m_solverMode=	SOLVER_USE_WARMSTARTING +	SOLVER_USE_2_FRICTION_DIRECTIONS +	SOLVER_RANDMIZE_ORDER +	SOLVER_USE_FRICTION_WARMSTARTING;
 | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 	m_debugDrawer = 0; | 
					
						
							| 
									
										
										
										
											2009-11-24 22:44:29 +00:00
										 |  |  | 	setGravity(0.f,0.f,-9.81f); | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void	CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btRigidBody* body = ctrl->GetRigidBody(); | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 	btCollisionObject* obj = ctrl->GetCollisionObject(); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	//this m_userPointer is just used for triggers, see CallbackTriggers
 | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 	obj->setUserPointer(ctrl); | 
					
						
							|  |  |  | 	if (body) | 
					
						
							|  |  |  | 		body->setGravity( m_gravity ); | 
					
						
							| 
									
										
										
										
											2006-02-21 05:36:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 	m_controllers.insert(ctrl); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 	if (body) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		//use explicit group/filter for finer control over collision in bullet => near/radar sensor
 | 
					
						
							|  |  |  | 		m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask()); | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (ctrl->GetSoftBody()) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | 			btSoftBody* softBody = ctrl->GetSoftBody(); | 
					
						
							|  |  |  | 			m_dynamicsWorld->addSoftBody(softBody); | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		} else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (obj->getCollisionShape()) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2012-05-28 21:36:29 +00:00
										 |  |  | 				m_dynamicsWorld->addCollisionObject(obj, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (ctrl->GetCharacterController()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				m_dynamicsWorld->addAction(ctrl->GetCharacterController()); | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (obj->isStaticOrKinematicObject()) | 
					
						
							| 
									
										
										
										
											2006-11-21 12:26:05 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		obj->setActivationState(ISLAND_SLEEPING); | 
					
						
							| 
									
										
										
										
											2006-11-21 12:26:05 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 	assert(obj->getBroadphaseHandle()); | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-24 03:12:10 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-15 23:58:56 +00:00
										 |  |  | bool	CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl) | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	//also remove constraint
 | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 	btRigidBody* body = ctrl->GetRigidBody(); | 
					
						
							|  |  |  | 	if (body) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 		for (int i=body->getNumConstraintRefs()-1;i>=0;i--) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			btTypedConstraint* con = body->getConstraintRef(i); | 
					
						
							|  |  |  | 			m_dynamicsWorld->removeConstraint(con); | 
					
						
							|  |  |  | 			body->removeConstraintRef(con); | 
					
						
							|  |  |  | 			//delete con; //might be kept by python KX_ConstraintWrapper
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody()); | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		//if a softbody
 | 
					
						
							|  |  |  | 		if (ctrl->GetSoftBody()) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | 			m_dynamicsWorld->removeSoftBody(ctrl->GetSoftBody()); | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		} else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject()); | 
					
						
							| 
									
										
										
										
											2012-08-05 22:31:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (ctrl->GetCharacterController()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				m_dynamicsWorld->removeAction(ctrl->GetCharacterController()); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-08-05 16:23:33 +00:00
										 |  |  | 	if (ctrl->m_registerCount != 0) | 
					
						
							|  |  |  | 		printf("Warning: removing controller with non-zero m_registerCount: %d\n", ctrl->m_registerCount); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	//remove it from the triggers
 | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 	m_triggerControllers.erase(ctrl); | 
					
						
							| 
									
										
										
										
											2009-11-15 23:58:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return (m_controllers.erase(ctrl) != 0); | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-20 15:40:03 +00:00
										 |  |  | void	CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask) | 
					
						
							| 
									
										
										
										
											2008-07-19 10:27:52 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	// this function is used when the collisionning group of a controller is changed
 | 
					
						
							|  |  |  | 	// remove and add the collistioning object
 | 
					
						
							|  |  |  | 	btRigidBody* body = ctrl->GetRigidBody(); | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 	btCollisionObject* obj = ctrl->GetCollisionObject(); | 
					
						
							|  |  |  | 	if (obj) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btVector3 inertia(0.0,0.0,0.0); | 
					
						
							|  |  |  | 		m_dynamicsWorld->removeCollisionObject(obj); | 
					
						
							|  |  |  | 		obj->setCollisionFlags(newCollisionFlags); | 
					
						
							|  |  |  | 		if (body) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (newMass) | 
					
						
							|  |  |  | 				body->getCollisionShape()->calculateLocalInertia(newMass, inertia); | 
					
						
							|  |  |  | 			body->setMassProps(newMass, inertia); | 
					
						
							| 
									
										
										
										
											2011-03-29 15:46:02 +00:00
										 |  |  | 			m_dynamicsWorld->addRigidBody(body, newCollisionGroup, newCollisionMask); | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2011-03-29 15:46:02 +00:00
										 |  |  | 			m_dynamicsWorld->addCollisionObject(obj, newCollisionGroup, newCollisionMask); | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-07-20 15:40:03 +00:00
										 |  |  | 	// to avoid nasty interaction, we must update the property of the controller as well
 | 
					
						
							|  |  |  | 	ctrl->m_cci.m_mass = newMass; | 
					
						
							|  |  |  | 	ctrl->m_cci.m_collisionFilterGroup = newCollisionGroup; | 
					
						
							|  |  |  | 	ctrl->m_cci.m_collisionFilterMask = newCollisionMask; | 
					
						
							|  |  |  | 	ctrl->m_cci.m_collisionFlags = newCollisionFlags; | 
					
						
							| 
									
										
										
										
											2008-07-19 10:27:52 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-20 15:40:03 +00:00
										 |  |  | void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 	if (m_controllers.insert(ctrl).second) | 
					
						
							| 
									
										
										
										
											2008-07-20 15:40:03 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		btCollisionObject* obj = ctrl->GetCollisionObject(); | 
					
						
							|  |  |  | 		obj->setUserPointer(ctrl); | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 		// update the position of the object from the user
 | 
					
						
							|  |  |  | 		if (ctrl->GetMotionState())  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			btTransform xform = CcdPhysicsController::GetTransformFromMotionState(ctrl->GetMotionState()); | 
					
						
							|  |  |  | 			ctrl->SetCenterOfMassTransform(xform); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		m_dynamicsWorld->addCollisionObject(obj,  | 
					
						
							| 
									
										
										
										
											2008-07-20 15:40:03 +00:00
										 |  |  | 			ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-05 16:23:33 +00:00
										 |  |  | void CcdPhysicsEnvironment::disableCcdPhysicsController(CcdPhysicsController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_controllers.erase(ctrl)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 		btRigidBody* body = ctrl->GetRigidBody(); | 
					
						
							|  |  |  | 		if (body) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_dynamicsWorld->removeRigidBody(body); | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (ctrl->GetSoftBody()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:18 +00:00
										 |  |  | 				m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject()); | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-08-05 16:23:33 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-07-20 15:40:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:18 +00:00
										 |  |  | void CcdPhysicsEnvironment::refreshCcdPhysicsController(CcdPhysicsController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	btCollisionObject* obj = ctrl->GetCollisionObject(); | 
					
						
							|  |  |  | 	if (obj) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btBroadphaseProxy* proxy = obj->getBroadphaseHandle(); | 
					
						
							|  |  |  | 		if (proxy) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_dynamicsWorld->getPairCache()->cleanProxyFromPairs(proxy,m_dynamicsWorld->getDispatcher()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-07-20 15:40:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | void CcdPhysicsEnvironment::addCcdGraphicController(CcdGraphicController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	if (m_cullingTree && !ctrl->getBroadphaseHandle()) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		btVector3	minAabb; | 
					
						
							|  |  |  | 		btVector3	maxAabb; | 
					
						
							|  |  |  | 		ctrl->getAabb(minAabb, maxAabb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ctrl->setBroadphaseHandle(m_cullingTree->createProxy( | 
					
						
							|  |  |  | 				minAabb, | 
					
						
							|  |  |  | 				maxAabb, | 
					
						
							|  |  |  | 				INVALID_SHAPE_PROXYTYPE,	// this parameter is not used
 | 
					
						
							|  |  |  | 				ctrl, | 
					
						
							|  |  |  | 				0,							// this object does not collision with anything
 | 
					
						
							|  |  |  | 				0, | 
					
						
							|  |  |  | 				NULL,						// dispatcher => this parameter is not used
 | 
					
						
							|  |  |  | 				0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert(ctrl->getBroadphaseHandle()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CcdPhysicsEnvironment::removeCcdGraphicController(CcdGraphicController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_cullingTree) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btBroadphaseProxy* bp = ctrl->getBroadphaseHandle(); | 
					
						
							|  |  |  | 		if (bp) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_cullingTree->destroyProxy(bp,NULL); | 
					
						
							|  |  |  | 			ctrl->setBroadphaseHandle(0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-01 00:20:50 +00:00
										 |  |  | void	CcdPhysicsEnvironment::beginFrame() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-01 00:20:50 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 05:01:16 +00:00
										 |  |  | void CcdPhysicsEnvironment::debugDrawWorld() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (m_dynamicsWorld->getDebugDrawer() &&  m_dynamicsWorld->getDebugDrawer()->getDebugMode() >0) | 
					
						
							|  |  |  | 			m_dynamicsWorld->debugDrawWorld(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | bool	CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep,float interval) | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 	std::set<CcdPhysicsController*>::iterator it; | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2006-01-15 11:34:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 	for (it=m_controllers.begin(); it!=m_controllers.end(); it++) | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 		(*it)->SynchronizeMotionStates(timeStep); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-07 17:10:44 +00:00
										 |  |  | 	float subStep = timeStep / float(m_numTimeSubSteps); | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	i = m_dynamicsWorld->stepSimulation(interval,25,subStep);//perform always a full simulation step
 | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | //uncomment next line to see where Bullet spend its time (printf in console)
 | 
					
						
							| 
									
										
										
										
											2011-04-20 04:55:58 +00:00
										 |  |  | //CProfileManager::dumpAll();
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	processFhSprings(curTime,i*subStep); | 
					
						
							| 
									
										
										
										
											2007-05-07 17:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 	for (it=m_controllers.begin(); it!=m_controllers.end(); it++) | 
					
						
							| 
									
										
										
										
											2006-11-21 12:26:05 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 		(*it)->SynchronizeMotionStates(timeStep); | 
					
						
							| 
									
										
										
										
											2006-11-21 12:26:05 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 	//for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
 | 
					
						
							|  |  |  | 	//{
 | 
					
						
							|  |  |  | 	//	(*it)->SynchronizeMotionStates(timeStep);
 | 
					
						
							|  |  |  | 	//}
 | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 12:26:05 +00:00
										 |  |  | 	for (i=0;i<m_wrapperVehicles.size();i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		WrapperVehicle* veh = m_wrapperVehicles[i]; | 
					
						
							|  |  |  | 		veh->SyncWheels(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-29 07:23:01 +00:00
										 |  |  | 	CallbackTriggers(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | class ClosestRayResultCallbackNotMe : public btCollisionWorld::ClosestRayResultCallback | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	btCollisionObject* m_owner; | 
					
						
							|  |  |  | 	btCollisionObject* m_parent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	ClosestRayResultCallbackNotMe(const btVector3& rayFromWorld,const btVector3& rayToWorld,btCollisionObject* owner,btCollisionObject* parent) | 
					
						
							|  |  |  | 		:btCollisionWorld::ClosestRayResultCallback(rayFromWorld,rayToWorld), | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		m_owner(owner), | 
					
						
							|  |  |  | 		m_parent(parent) | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual bool needsCollision(btBroadphaseProxy* proxy0) const | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		//don't collide with self
 | 
					
						
							|  |  |  | 		if (proxy0->m_clientObject == m_owner) | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (proxy0->m_clientObject == m_parent) | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return btCollisionWorld::ClosestRayResultCallback::needsCollision(proxy0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | void	CcdPhysicsEnvironment::processFhSprings(double curTime,float interval) | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	std::set<CcdPhysicsController*>::iterator it; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	// dynamic of Fh spring is based on a timestep of 1/60
 | 
					
						
							|  |  |  | 	int numIter = (int)(interval*60.0001f); | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	for (it=m_controllers.begin(); it!=m_controllers.end(); it++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		CcdPhysicsController* ctrl = (*it); | 
					
						
							| 
									
										
										
										
											2008-09-29 08:00:38 +00:00
										 |  |  | 		btRigidBody* body = ctrl->GetRigidBody(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (body && (ctrl->getConstructionInfo().m_do_fh || ctrl->getConstructionInfo().m_do_rot_fh)) | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			//printf("has Fh or RotFh\n");
 | 
					
						
							|  |  |  | 			//re-implement SM_FhObject.cpp using btCollisionWorld::rayTest and info from ctrl->getConstructionInfo()
 | 
					
						
							|  |  |  | 			//send a ray from {0.0, 0.0, 0.0} towards {0.0, 0.0, -10.0}, in local coordinates
 | 
					
						
							|  |  |  | 			CcdPhysicsController* parentCtrl = ctrl->getParentCtrl(); | 
					
						
							|  |  |  | 			btRigidBody* parentBody = parentCtrl?parentCtrl->GetRigidBody() : 0; | 
					
						
							|  |  |  | 			btRigidBody* cl_object = parentBody ? parentBody : body; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (body->isStaticOrKinematicObject()) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			btVector3 rayDirLocal(0,0,-10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			//m_dynamicsWorld
 | 
					
						
							|  |  |  | 			//ctrl->GetRigidBody();
 | 
					
						
							|  |  |  | 			btVector3 rayFromWorld = body->getCenterOfMassPosition(); | 
					
						
							|  |  |  | 			//btVector3	rayToWorld = rayFromWorld + body->getCenterOfMassTransform().getBasis() * rayDirLocal;
 | 
					
						
							|  |  |  | 			//ray always points down the z axis in world space...
 | 
					
						
							|  |  |  | 			btVector3	rayToWorld = rayFromWorld + rayDirLocal; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 			ClosestRayResultCallbackNotMe	resultCallback(rayFromWorld,rayToWorld,body,parentBody); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			m_dynamicsWorld->rayTest(rayFromWorld,rayToWorld,resultCallback); | 
					
						
							|  |  |  | 			if (resultCallback.hasHit()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				//we hit this one: resultCallback.m_collisionObject;
 | 
					
						
							|  |  |  | 				CcdPhysicsController* controller = static_cast<CcdPhysicsController*>(resultCallback.m_collisionObject->getUserPointer()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (controller) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (controller->getConstructionInfo().m_fh_distance < SIMD_EPSILON) | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					btRigidBody* hit_object = controller->GetRigidBody(); | 
					
						
							|  |  |  | 					if (!hit_object) | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					CcdConstructionInfo& hitObjShapeProps = controller->getConstructionInfo(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					float distance = resultCallback.m_closestHitFraction*rayDirLocal.length()-ctrl->getConstructionInfo().m_radius; | 
					
						
							|  |  |  | 					if (distance >= hitObjShapeProps.m_fh_distance) | 
					
						
							|  |  |  | 						continue; | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					//btVector3 ray_dir = cl_object->getCenterOfMassTransform().getBasis()* rayDirLocal.normalized();
 | 
					
						
							|  |  |  | 					btVector3 ray_dir = rayDirLocal.normalized(); | 
					
						
							|  |  |  | 					btVector3 normal = resultCallback.m_hitNormalWorld; | 
					
						
							|  |  |  | 					normal.normalize(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 					for (int i=0; i<numIter; i++) | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 						if (ctrl->getConstructionInfo().m_do_fh)  | 
					
						
							|  |  |  | 						{ | 
					
						
							| 
									
										
										
										
											2012-06-05 22:12:17 +00:00
										 |  |  | 							btVector3 lspot = cl_object->getCenterOfMassPosition() + | 
					
						
							|  |  |  | 							        rayDirLocal * resultCallback.m_closestHitFraction; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 								 | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 							lspot -= hit_object->getCenterOfMassPosition(); | 
					
						
							|  |  |  | 							btVector3 rel_vel = cl_object->getLinearVelocity() - hit_object->getVelocityInLocalPoint(lspot); | 
					
						
							|  |  |  | 							btScalar rel_vel_ray = ray_dir.dot(rel_vel); | 
					
						
							|  |  |  | 							btScalar spring_extent = 1.0 - distance / hitObjShapeProps.m_fh_distance;  | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							btScalar i_spring = spring_extent * hitObjShapeProps.m_fh_spring; | 
					
						
							|  |  |  | 							btScalar i_damp =   rel_vel_ray * hitObjShapeProps.m_fh_damping; | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							cl_object->setLinearVelocity(cl_object->getLinearVelocity() + (-(i_spring + i_damp) * ray_dir));  | 
					
						
							|  |  |  | 							if (hitObjShapeProps.m_fh_normal)  | 
					
						
							|  |  |  | 							{ | 
					
						
							|  |  |  | 								cl_object->setLinearVelocity(cl_object->getLinearVelocity()+(i_spring + i_damp) *(normal - normal.dot(ray_dir) * ray_dir)); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 							 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 							btVector3 lateral = rel_vel - rel_vel_ray * ray_dir; | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							if (ctrl->getConstructionInfo().m_do_anisotropic) { | 
					
						
							|  |  |  | 								//Bullet basis contains no scaling/shear etc.
 | 
					
						
							|  |  |  | 								const btMatrix3x3& lcs = cl_object->getCenterOfMassTransform().getBasis(); | 
					
						
							|  |  |  | 								btVector3 loc_lateral = lateral * lcs; | 
					
						
							|  |  |  | 								const btVector3& friction_scaling = cl_object->getAnisotropicFriction(); | 
					
						
							|  |  |  | 								loc_lateral *= friction_scaling; | 
					
						
							|  |  |  | 								lateral = lcs * loc_lateral; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 							btScalar rel_vel_lateral = lateral.length(); | 
					
						
							|  |  |  | 							 | 
					
						
							|  |  |  | 							if (rel_vel_lateral > SIMD_EPSILON) { | 
					
						
							|  |  |  | 								btScalar friction_factor = hit_object->getFriction();//cl_object->getFriction();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								btScalar max_friction = friction_factor * btMax(btScalar(0.0), i_spring); | 
					
						
							|  |  |  | 								 | 
					
						
							|  |  |  | 								btScalar rel_mom_lateral = rel_vel_lateral / cl_object->getInvMass(); | 
					
						
							|  |  |  | 								 | 
					
						
							|  |  |  | 								btVector3 friction = (rel_mom_lateral > max_friction) ? | 
					
						
							|  |  |  | 									-lateral * (max_friction / rel_vel_lateral) : | 
					
						
							|  |  |  | 									-lateral; | 
					
						
							|  |  |  | 								 | 
					
						
							|  |  |  | 									cl_object->applyCentralImpulse(friction); | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 						if (ctrl->getConstructionInfo().m_do_rot_fh) { | 
					
						
							|  |  |  | 							btVector3 up2 = cl_object->getWorldTransform().getBasis().getColumn(2); | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 							btVector3 t_spring = up2.cross(normal) * hitObjShapeProps.m_fh_spring; | 
					
						
							|  |  |  | 							btVector3 ang_vel = cl_object->getAngularVelocity(); | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 							 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 							// only rotations that tilt relative to the normal are damped
 | 
					
						
							|  |  |  | 							ang_vel -= ang_vel.dot(normal) * normal; | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 							 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 							btVector3 t_damp = ang_vel * hitObjShapeProps.m_fh_damping;   | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 							 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 							cl_object->setAngularVelocity(cl_object->getAngularVelocity() + (t_spring - t_damp)); | 
					
						
							| 
									
										
										
										
											2008-09-29 06:58:49 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void		CcdPhysicsEnvironment::setDebugMode(int debugMode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-28 05:03:24 +00:00
										 |  |  | 	if (m_debugDrawer) { | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		m_debugDrawer->setDebugMode(debugMode); | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setNumIterations(int numIter) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_numIterations = numIter; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void		CcdPhysicsEnvironment::setDeactivationTime(float dTime) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	gDeactivationTime = dTime; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void		CcdPhysicsEnvironment::setDeactivationLinearTreshold(float linTresh) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	gLinearSleepingTreshold = linTresh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void		CcdPhysicsEnvironment::setDeactivationAngularTreshold(float angTresh)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	gAngularSleepingTreshold = angTresh; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setContactBreakingTreshold(float contactBreakingTreshold) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	gContactBreakingThreshold = contactBreakingTreshold; | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setCcdMode(int ccdMode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_ccdMode = ccdMode; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setSolverSorConstant(float sor) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-01 17:59:32 +00:00
										 |  |  | 	m_dynamicsWorld->getSolverInfo().m_sor = sor; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setSolverTau(float tau) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-01 17:59:32 +00:00
										 |  |  | 	m_dynamicsWorld->getSolverInfo().m_tau = tau; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | void		CcdPhysicsEnvironment::setSolverDamping(float damping) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-01 17:59:32 +00:00
										 |  |  | 	m_dynamicsWorld->getSolverInfo().m_damping = damping; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setLinearAirDamping(float damping) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 	//gLinearAirDamping = damping;
 | 
					
						
							| 
									
										
										
										
											2006-01-15 11:34:55 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setUseEpa(bool epa) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-11-29 05:25:37 +00:00
										 |  |  | 	//gUseEpa = epa;
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setSolverType(int solverType) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	switch (solverType) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case 1: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (m_solverType != solverType) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 				m_solver = new btSequentialImpulseConstraintSolver(); | 
					
						
							| 
									
										
										
										
											2009-03-03 03:41:24 +00:00
										 |  |  | 				 | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	case 0: | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		if (m_solverType != solverType) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | //			m_solver = new OdeConstraintSolver();
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-27 10:35:39 +00:00
										 |  |  | 	m_solverType = solverType; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-21 18:30:11 +00:00
										 |  |  | void		CcdPhysicsEnvironment::getGravity(MT_Vector3& grav) | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 		const btVector3& gravity = m_dynamicsWorld->getGravity(); | 
					
						
							|  |  |  | 		grav[0] = gravity.getX(); | 
					
						
							|  |  |  | 		grav[1] = gravity.getY(); | 
					
						
							|  |  |  | 		grav[2] = gravity.getZ(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::setGravity(float x,float y,float z) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_gravity = btVector3(x,y,z); | 
					
						
							|  |  |  | 	m_dynamicsWorld->setGravity(m_gravity); | 
					
						
							| 
									
										
										
										
											2009-11-24 22:44:29 +00:00
										 |  |  | 	m_dynamicsWorld->getWorldInfo().m_gravity.setValue(x,y,z); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-08-13 08:05:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-08 17:08:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | static int gConstraintUid = 1; | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | //Following the COLLADA physics specification for constraints
 | 
					
						
							|  |  |  | int			CcdPhysicsEnvironment::createUniversalD6Constraint( | 
					
						
							|  |  |  | 						class PHY_IPhysicsController* ctrlRef,class PHY_IPhysicsController* ctrlOther, | 
					
						
							|  |  |  | 						btTransform& frameInA, | 
					
						
							|  |  |  | 						btTransform& frameInB, | 
					
						
							|  |  |  | 						const btVector3& linearMinLimits, | 
					
						
							|  |  |  | 						const btVector3& linearMaxLimits, | 
					
						
							|  |  |  | 						const btVector3& angularMinLimits, | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 						const btVector3& angularMaxLimits,int flags | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-05-11 00:13:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:32:04 +00:00
										 |  |  | 	bool disableCollisionBetweenLinkedBodies = (0!=(flags & CCD_CONSTRAINT_DISABLE_LINKED_COLLISION)); | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	//we could either add some logic to recognize ball-socket and hinge, or let that up to the user
 | 
					
						
							|  |  |  | 	//perhaps some warning or hint that hinge/ball-socket is more efficient?
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btGeneric6DofConstraint* genericConstraint = 0; | 
					
						
							|  |  |  | 	CcdPhysicsController* ctrl0 = (CcdPhysicsController*) ctrlRef; | 
					
						
							|  |  |  | 	CcdPhysicsController* ctrl1 = (CcdPhysicsController*) ctrlOther; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	btRigidBody* rb0 = ctrl0->GetRigidBody(); | 
					
						
							|  |  |  | 	btRigidBody* rb1 = ctrl1->GetRigidBody(); | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	if (rb1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 		bool useReferenceFrameA = true; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 		genericConstraint = new btGeneric6DofSpringConstraint( | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			*rb0,*rb1, | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 			frameInA,frameInB,useReferenceFrameA); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		genericConstraint->setLinearLowerLimit(linearMinLimits); | 
					
						
							|  |  |  | 		genericConstraint->setLinearUpperLimit(linearMaxLimits); | 
					
						
							|  |  |  | 		genericConstraint->setAngularLowerLimit(angularMinLimits); | 
					
						
							|  |  |  | 		genericConstraint->setAngularUpperLimit(angularMaxLimits); | 
					
						
							|  |  |  | 	} else | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		// TODO: Implement single body case...
 | 
					
						
							| 
									
										
										
										
											2011-05-28 13:11:24 +00:00
										 |  |  | 		//No, we can use a fixed rigidbody in above code, rather than unnecessary duplation of code
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (genericConstraint) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	//	m_constraints.push_back(genericConstraint);
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 		m_dynamicsWorld->addConstraint(genericConstraint,disableCollisionBetweenLinkedBodies); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		genericConstraint->setUserConstraintId(gConstraintUid++); | 
					
						
							|  |  |  | 		genericConstraint->setUserConstraintType(PHY_GENERIC_6DOF_CONSTRAINT); | 
					
						
							|  |  |  | 		//64 bit systems can't cast pointer to int. could use size_t instead.
 | 
					
						
							|  |  |  | 		return genericConstraint->getUserConstraintId(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void		CcdPhysicsEnvironment::removeConstraint(int	constraintId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	int numConstraints = m_dynamicsWorld->getNumConstraints(); | 
					
						
							|  |  |  | 	for (i=0;i<numConstraints;i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); | 
					
						
							|  |  |  | 		if (constraint->getUserConstraintId() == constraintId) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-12-25 02:02:13 +00:00
										 |  |  | 			constraint->getRigidBodyA().activate(); | 
					
						
							|  |  |  | 			constraint->getRigidBodyB().activate(); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			m_dynamicsWorld->removeConstraint(constraint); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | struct	FilterClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 	PHY_IRayCastFilterCallback&	m_phyRayFilter; | 
					
						
							|  |  |  | 	const btCollisionShape*		m_hitTriangleShape; | 
					
						
							|  |  |  | 	int							m_hitTriangleIndex; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 	FilterClosestRayResultCallback (PHY_IRayCastFilterCallback& phyRayFilter,const btVector3& rayFrom,const btVector3& rayTo) | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		: btCollisionWorld::ClosestRayResultCallback(rayFrom,rayTo), | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 		m_phyRayFilter(phyRayFilter), | 
					
						
							|  |  |  | 		m_hitTriangleShape(NULL), | 
					
						
							|  |  |  | 		m_hitTriangleIndex(0) | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	virtual ~FilterClosestRayResultCallback() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-04 23:07:43 +00:00
										 |  |  | 	virtual bool needsCollision(btBroadphaseProxy* proxy0) const | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-09-04 23:07:43 +00:00
										 |  |  | 		if (!(proxy0->m_collisionFilterGroup & m_collisionFilterMask)) | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		if (!(m_collisionFilterGroup & proxy0->m_collisionFilterMask)) | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		btCollisionObject* object = (btCollisionObject*)proxy0->m_clientObject; | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 		CcdPhysicsController* phyCtrl = static_cast<CcdPhysicsController*>(object->getUserPointer()); | 
					
						
							| 
									
										
										
										
											2008-09-04 23:07:43 +00:00
										 |  |  | 		if (phyCtrl == m_phyRayFilter.m_ignoreController) | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		return m_phyRayFilter.needBroadphaseRayCast(phyCtrl); | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-04 23:07:43 +00:00
										 |  |  | 	virtual	btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 		//CcdPhysicsController* curHit = static_cast<CcdPhysicsController*>(rayResult.m_collisionObject->getUserPointer());
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 		// save shape information as ClosestRayResultCallback::AddSingleResult() does not do it
 | 
					
						
							|  |  |  | 		if (rayResult.m_localShapeInfo) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-09-11 20:16:30 +00:00
										 |  |  | 			m_hitTriangleShape = rayResult.m_collisionObject->getCollisionShape(); | 
					
						
							|  |  |  | 			m_hitTriangleIndex = rayResult.m_localShapeInfo->m_triangleIndex; | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 		} else  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_hitTriangleShape = NULL; | 
					
						
							|  |  |  | 			m_hitTriangleIndex = 0; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-09-04 23:07:43 +00:00
										 |  |  | 		return ClosestRayResultCallback::addSingleResult(rayResult,normalInWorldSpace); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2006-04-13 05:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | static bool GetHitTriangle(btCollisionShape* shape, CcdShapeConstructionInfo* shapeInfo, int hitTriangleIndex, btVector3 triangle[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// this code is copied from Bullet 
 | 
					
						
							|  |  |  | 	const unsigned char *vertexbase; | 
					
						
							|  |  |  | 	int numverts; | 
					
						
							|  |  |  | 	PHY_ScalarType type; | 
					
						
							|  |  |  | 	int stride; | 
					
						
							|  |  |  | 	const unsigned char *indexbase; | 
					
						
							|  |  |  | 	int indexstride; | 
					
						
							|  |  |  | 	int numfaces; | 
					
						
							|  |  |  | 	PHY_ScalarType indicestype; | 
					
						
							|  |  |  | 	btStridingMeshInterface* meshInterface = NULL; | 
					
						
							|  |  |  | 	btTriangleMeshShape* triangleShape = shapeInfo->GetMeshShape(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (triangleShape) | 
					
						
							|  |  |  | 		meshInterface = triangleShape->getMeshInterface(); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// other possibility is gImpact
 | 
					
						
							|  |  |  | 		if (shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) | 
					
						
							|  |  |  | 			meshInterface = (static_cast<btGImpactMeshShape*>(shape))->getMeshInterface(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!meshInterface) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	meshInterface->getLockedReadOnlyVertexIndexBase( | 
					
						
							|  |  |  | 		&vertexbase, | 
					
						
							|  |  |  | 		numverts, | 
					
						
							|  |  |  | 		type, | 
					
						
							|  |  |  | 		stride, | 
					
						
							|  |  |  | 		&indexbase, | 
					
						
							|  |  |  | 		indexstride, | 
					
						
							|  |  |  | 		numfaces, | 
					
						
							|  |  |  | 		indicestype, | 
					
						
							|  |  |  | 		0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	unsigned int* gfxbase = (unsigned int*)(indexbase+hitTriangleIndex*indexstride); | 
					
						
							|  |  |  | 	const btVector3& meshScaling = shape->getLocalScaling(); | 
					
						
							|  |  |  | 	for (int j=2;j>=0;j--) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-10-20 18:46:57 +00:00
										 |  |  | 		int graphicsindex = (indicestype == PHY_SHORT) ? ((unsigned short *)gfxbase)[j] : gfxbase[j]; | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 		triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	meshInterface->unLockReadOnlyVertexBase(0); | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ) | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	btVector3 rayFrom(fromX,fromY,fromZ); | 
					
						
							|  |  |  | 	btVector3 rayTo(toX,toY,toZ); | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btVector3	hitPointWorld,normalWorld; | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	//Either Ray Cast with or without filtering
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	//btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 	FilterClosestRayResultCallback	 rayCallback(filterCallback,rayFrom,rayTo); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 	PHY_RayCastResult result; | 
					
						
							|  |  |  | 	memset(&result, 0, sizeof(result)); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-10 20:17:12 +00:00
										 |  |  | 	// don't collision with sensor object
 | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 	rayCallback.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; | 
					
						
							|  |  |  | 	//, ,filterCallback.m_faceNormal);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback); | 
					
						
							|  |  |  | 	if (rayCallback.hasHit()) | 
					
						
							| 
									
										
										
										
											2006-06-17 13:55:59 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 		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(); | 
					
						
							| 
									
										
										
										
											2006-06-17 13:55:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 		if (rayCallback.m_hitTriangleShape != NULL) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// identify the mesh polygon
 | 
					
						
							|  |  |  | 			CcdShapeConstructionInfo* shapeInfo = controller->m_shapeInfo; | 
					
						
							|  |  |  | 			if (shapeInfo) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2008-09-17 01:49:47 +00:00
										 |  |  | 				btCollisionShape* shape = controller->GetCollisionObject()->getCollisionShape(); | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 				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()) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 					// save original collision shape triangle for soft body
 | 
					
						
							|  |  |  | 					int hitTriangleIndex = rayCallback.m_hitTriangleIndex; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-20 21:33:54 +00:00
										 |  |  | 					result.m_meshObject = shapeInfo->GetMesh(); | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 					if (shape->isSoftBody()) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						// soft body using different face numbering because of randomization
 | 
					
						
							|  |  |  | 						// hopefully we have stored the original face number in m_tag
 | 
					
						
							| 
									
										
										
										
											2013-03-07 17:53:16 +00:00
										 |  |  | 						const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject); | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 						if (softBody->m_faces[hitTriangleIndex].m_tag != 0) | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							rayCallback.m_hitTriangleIndex = (int)((uintptr_t)(softBody->m_faces[hitTriangleIndex].m_tag)-1); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					// retrieve the original mesh polygon (in case of quad->tri conversion)
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 					result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex); | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 					// hit triangle in world coordinate, for face normal and UV coordinate
 | 
					
						
							|  |  |  | 					btVector3 triangle[3]; | 
					
						
							|  |  |  | 					bool triangleOK = false; | 
					
						
							|  |  |  | 					if (filterCallback.m_faceUV && (3*rayCallback.m_hitTriangleIndex) < shapeInfo->m_triFaceUVcoArray.size()) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						// interpolate the UV coordinate of the hit point
 | 
					
						
							|  |  |  | 						CcdShapeConstructionInfo::UVco* uvCo = &shapeInfo->m_triFaceUVcoArray[3*rayCallback.m_hitTriangleIndex]; | 
					
						
							|  |  |  | 						// 1. get the 3 coordinate of the triangle in world space
 | 
					
						
							|  |  |  | 						btVector3 v1, v2, v3; | 
					
						
							|  |  |  | 						if (shape->isSoftBody()) | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							// soft body give points directly in world coordinate
 | 
					
						
							| 
									
										
										
										
											2013-03-07 17:53:16 +00:00
										 |  |  | 							const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject); | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 							v1 = softBody->m_faces[hitTriangleIndex].m_n[0]->m_x; | 
					
						
							|  |  |  | 							v2 = softBody->m_faces[hitTriangleIndex].m_n[1]->m_x; | 
					
						
							|  |  |  | 							v3 = softBody->m_faces[hitTriangleIndex].m_n[2]->m_x; | 
					
						
							|  |  |  | 						} else  | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							// for rigid body we must apply the world transform
 | 
					
						
							|  |  |  | 							triangleOK = GetHitTriangle(shape, shapeInfo, hitTriangleIndex, triangle); | 
					
						
							|  |  |  | 							if (!triangleOK) | 
					
						
							|  |  |  | 								// if we cannot get the triangle, no use to continue
 | 
					
						
							|  |  |  | 								goto SKIP_UV_NORMAL; | 
					
						
							|  |  |  | 							v1 = rayCallback.m_collisionObject->getWorldTransform()(triangle[0]); | 
					
						
							|  |  |  | 							v2 = rayCallback.m_collisionObject->getWorldTransform()(triangle[1]); | 
					
						
							|  |  |  | 							v3 = rayCallback.m_collisionObject->getWorldTransform()(triangle[2]); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						// 2. compute barycentric coordinate of the hit point
 | 
					
						
							|  |  |  | 						btVector3 v = v2-v1; | 
					
						
							|  |  |  | 						btVector3 w = v3-v1; | 
					
						
							|  |  |  | 						btVector3 u = v.cross(w); | 
					
						
							|  |  |  | 						btScalar A = u.length(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						v = v2-rayCallback.m_hitPointWorld; | 
					
						
							|  |  |  | 						w = v3-rayCallback.m_hitPointWorld; | 
					
						
							|  |  |  | 						u = v.cross(w); | 
					
						
							|  |  |  | 						btScalar A1 = u.length(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						v = rayCallback.m_hitPointWorld-v1; | 
					
						
							|  |  |  | 						w = v3-v1; | 
					
						
							|  |  |  | 						u = v.cross(w); | 
					
						
							|  |  |  | 						btScalar A2 = u.length(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						btVector3 baryCo; | 
					
						
							|  |  |  | 						baryCo.setX(A1/A); | 
					
						
							|  |  |  | 						baryCo.setY(A2/A); | 
					
						
							|  |  |  | 						baryCo.setZ(1.0f-baryCo.getX()-baryCo.getY()); | 
					
						
							|  |  |  | 						// 3. compute UV coordinate
 | 
					
						
							|  |  |  | 						result.m_hitUV[0] = baryCo.getX()*uvCo[0].uv[0] + baryCo.getY()*uvCo[1].uv[0] + baryCo.getZ()*uvCo[2].uv[0]; | 
					
						
							|  |  |  | 						result.m_hitUV[1] = baryCo.getX()*uvCo[0].uv[1] + baryCo.getY()*uvCo[1].uv[1] + baryCo.getZ()*uvCo[2].uv[1]; | 
					
						
							|  |  |  | 						result.m_hitUVOK = 1; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 						 | 
					
						
							| 
									
										
										
										
											2008-09-11 20:16:30 +00:00
										 |  |  | 					// Bullet returns the normal from "outside".
 | 
					
						
							|  |  |  | 					// If the user requests the real normal, compute it now
 | 
					
						
							| 
									
										
										
										
											2011-09-01 02:12:53 +00:00
										 |  |  | 					if (filterCallback.m_faceNormal) | 
					
						
							| 
									
										
										
										
											2008-09-11 20:16:30 +00:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2009-11-28 17:30:34 +00:00
										 |  |  | 						if (shape->isSoftBody())  | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							// we can get the real normal directly from the body
 | 
					
						
							| 
									
										
										
										
											2013-03-07 17:53:16 +00:00
										 |  |  | 							const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject); | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 							rayCallback.m_hitNormalWorld = softBody->m_faces[hitTriangleIndex].m_normal; | 
					
						
							|  |  |  | 						} else | 
					
						
							| 
									
										
										
										
											2008-09-11 20:16:30 +00:00
										 |  |  | 						{ | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 							if (!triangleOK) | 
					
						
							|  |  |  | 								triangleOK = GetHitTriangle(shape, shapeInfo, hitTriangleIndex, triangle); | 
					
						
							|  |  |  | 							if (triangleOK) | 
					
						
							| 
									
										
										
										
											2008-09-13 16:03:11 +00:00
										 |  |  | 							{ | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 								btVector3 triangleNormal;  | 
					
						
							|  |  |  | 								triangleNormal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]); | 
					
						
							|  |  |  | 								rayCallback.m_hitNormalWorld = rayCallback.m_collisionObject->getWorldTransform().getBasis()*triangleNormal; | 
					
						
							| 
									
										
										
										
											2008-09-13 16:03:11 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2008-09-11 20:16:30 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2009-12-04 11:27:40 +00:00
										 |  |  | 				SKIP_UV_NORMAL: | 
					
						
							|  |  |  | 					; | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-09-11 20:16:30 +00:00
										 |  |  | 		if (rayCallback.m_hitNormalWorld.length2() > (SIMD_EPSILON*SIMD_EPSILON)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rayCallback.m_hitNormalWorld.normalize(); | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			rayCallback.m_hitNormalWorld.setValue(1,0,0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		result.m_hitNormal[0] = rayCallback.m_hitNormalWorld.getX(); | 
					
						
							|  |  |  | 		result.m_hitNormal[1] = rayCallback.m_hitNormalWorld.getY(); | 
					
						
							|  |  |  | 		result.m_hitNormal[2] = rayCallback.m_hitNormalWorld.getZ(); | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 		filterCallback.reportHit(&result); | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-06-17 13:55:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												BGE patch: KX_GameObject::rayCast() improvements to have X-Ray option, return true face normal and hit polygon information.
rayCast(to,from,dist,prop,face,xray,poly):
The face paremeter determines the orientation of the normal: 
  0 or omitted => 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.
if poly is 0 or omitted, 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 KX_PolyProxy as 4th element.
The KX_PolyProxy object holds information on the polygon hit by the ray: the index of the vertex forming the poylgon, material, etc.
Attributes (read-only):
 matname: The name of polygon material, empty if no material.
 material: The material of the polygon
 texture: The texture name of the polygon.
 matid: The material index of the polygon, use this to retrieve vertex proxy from mesh proxy
 v1: vertex index of the first vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v2: vertex index of the second vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 v3: vertex index of the third vertex of the polygon, use this to retrieve vertex proxy from mesh proxy
 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
 visible: visible state of the polygon: 1=visible, 0=invisible
 collide: collide state of the polygon: 1=receives collision, 0=collision free.
Methods:
 getMaterialName(): Returns the polygon material name with MA prefix
 getMaterial(): Returns the polygon material
 getTextureName(): Returns the polygon texture name
 getMaterialIndex(): Returns the material bucket index of the polygon. 
 getNumVertex(): Returns the number of vertex of the polygon.
 isVisible(): Returns whether the polygon is visible or not
 isCollider(): Returns whether the polygon is receives collision or not
 getVertexIndex(vertex): Returns the mesh vertex index of a polygon vertex
 getMesh(): Returns a mesh proxy
New methods of KX_MeshProxy have been implemented to retrieve KX_PolyProxy objects:
 getNumPolygons(): Returns the number of polygon in the mesh.
 getPolygon(index): Gets the specified polygon from the mesh.
More details in PyDoc.
											
										 
											2008-08-27 19:34:19 +00:00
										 |  |  | 	return result.m_controller; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | // Handles occlusion culling. 
 | 
					
						
							|  |  |  | // The implementation is based on the CDTestFramework
 | 
					
						
							|  |  |  | struct OcclusionBuffer | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct WriteOCL | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		static inline bool Process(btScalar& q,btScalar v) { if (q<v) q=v;return(false); } | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		static inline void Occlusion(bool& flag) { flag = true; } | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	struct QueryOCL | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		static inline bool Process(btScalar& q,btScalar v) { return(q<=v); } | 
					
						
							|  |  |  | 		static inline void Occlusion(bool& flag) { } | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	btScalar*						m_buffer; | 
					
						
							|  |  |  | 	size_t							m_bufferSize; | 
					
						
							|  |  |  | 	bool							m_initialized; | 
					
						
							|  |  |  | 	bool							m_occlusion; | 
					
						
							|  |  |  | 	int								m_sizes[2]; | 
					
						
							|  |  |  | 	btScalar						m_scales[2]; | 
					
						
							|  |  |  | 	btScalar						m_offsets[2]; | 
					
						
							|  |  |  | 	btScalar						m_wtc[16];		// world to clip transform
 | 
					
						
							|  |  |  | 	btScalar						m_mtc[16];		// model to clip transform
 | 
					
						
							|  |  |  | 	// constructor: size=largest dimension of the buffer. 
 | 
					
						
							|  |  |  | 	// Buffer size depends on aspect ratio
 | 
					
						
							|  |  |  | 	OcclusionBuffer() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_initialized=false; | 
					
						
							|  |  |  | 		m_occlusion = false; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 		m_buffer = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		m_bufferSize = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// multiplication of column major matrices: m=m1*m2
 | 
					
						
							|  |  |  | 	template<typename T1, typename T2> | 
					
						
							|  |  |  | 	void		CMmat4mul(btScalar* m, const T1* m1, const T2* m2) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m[ 0] = btScalar(m1[ 0]*m2[ 0]+m1[ 4]*m2[ 1]+m1[ 8]*m2[ 2]+m1[12]*m2[ 3]); | 
					
						
							|  |  |  | 		m[ 1] = btScalar(m1[ 1]*m2[ 0]+m1[ 5]*m2[ 1]+m1[ 9]*m2[ 2]+m1[13]*m2[ 3]); | 
					
						
							|  |  |  | 		m[ 2] = btScalar(m1[ 2]*m2[ 0]+m1[ 6]*m2[ 1]+m1[10]*m2[ 2]+m1[14]*m2[ 3]); | 
					
						
							|  |  |  | 		m[ 3] = btScalar(m1[ 3]*m2[ 0]+m1[ 7]*m2[ 1]+m1[11]*m2[ 2]+m1[15]*m2[ 3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		m[ 4] = btScalar(m1[ 0]*m2[ 4]+m1[ 4]*m2[ 5]+m1[ 8]*m2[ 6]+m1[12]*m2[ 7]); | 
					
						
							|  |  |  | 		m[ 5] = btScalar(m1[ 1]*m2[ 4]+m1[ 5]*m2[ 5]+m1[ 9]*m2[ 6]+m1[13]*m2[ 7]); | 
					
						
							|  |  |  | 		m[ 6] = btScalar(m1[ 2]*m2[ 4]+m1[ 6]*m2[ 5]+m1[10]*m2[ 6]+m1[14]*m2[ 7]); | 
					
						
							|  |  |  | 		m[ 7] = btScalar(m1[ 3]*m2[ 4]+m1[ 7]*m2[ 5]+m1[11]*m2[ 6]+m1[15]*m2[ 7]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		m[ 8] = btScalar(m1[ 0]*m2[ 8]+m1[ 4]*m2[ 9]+m1[ 8]*m2[10]+m1[12]*m2[11]); | 
					
						
							|  |  |  | 		m[ 9] = btScalar(m1[ 1]*m2[ 8]+m1[ 5]*m2[ 9]+m1[ 9]*m2[10]+m1[13]*m2[11]); | 
					
						
							|  |  |  | 		m[10] = btScalar(m1[ 2]*m2[ 8]+m1[ 6]*m2[ 9]+m1[10]*m2[10]+m1[14]*m2[11]); | 
					
						
							|  |  |  | 		m[11] = btScalar(m1[ 3]*m2[ 8]+m1[ 7]*m2[ 9]+m1[11]*m2[10]+m1[15]*m2[11]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		m[12] = btScalar(m1[ 0]*m2[12]+m1[ 4]*m2[13]+m1[ 8]*m2[14]+m1[12]*m2[15]); | 
					
						
							|  |  |  | 		m[13] = btScalar(m1[ 1]*m2[12]+m1[ 5]*m2[13]+m1[ 9]*m2[14]+m1[13]*m2[15]); | 
					
						
							|  |  |  | 		m[14] = btScalar(m1[ 2]*m2[12]+m1[ 6]*m2[13]+m1[10]*m2[14]+m1[14]*m2[15]); | 
					
						
							|  |  |  | 		m[15] = btScalar(m1[ 3]*m2[12]+m1[ 7]*m2[13]+m1[11]*m2[14]+m1[15]*m2[15]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-10-08 03:28:11 +00:00
										 |  |  | 	void		setup(int size, const int *view, double modelview[16], double projection[16]) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		m_initialized=false; | 
					
						
							|  |  |  | 		m_occlusion=false; | 
					
						
							|  |  |  | 		// compute the size of the buffer
 | 
					
						
							|  |  |  | 		int			maxsize; | 
					
						
							|  |  |  | 		double		ratio; | 
					
						
							| 
									
										
										
										
											2012-10-08 03:28:11 +00:00
										 |  |  | 		maxsize = (view[2] > view[3]) ? view[2] : view[3]; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		assert(maxsize > 0); | 
					
						
							|  |  |  | 		ratio = 1.0/(2*maxsize); | 
					
						
							|  |  |  | 		// ensure even number
 | 
					
						
							| 
									
										
										
										
											2012-10-08 03:28:11 +00:00
										 |  |  | 		m_sizes[0] = 2*((int)(size*view[2]*ratio+0.5)); | 
					
						
							|  |  |  | 		m_sizes[1] = 2*((int)(size*view[3]*ratio+0.5)); | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		m_scales[0]=btScalar(m_sizes[0]/2); | 
					
						
							|  |  |  | 		m_scales[1]=btScalar(m_sizes[1]/2); | 
					
						
							|  |  |  | 		m_offsets[0]=m_scales[0]+0.5f; | 
					
						
							|  |  |  | 		m_offsets[1]=m_scales[1]+0.5f; | 
					
						
							|  |  |  | 		// prepare matrix
 | 
					
						
							|  |  |  | 		// at this time of the rendering, the modelview matrix is the 
 | 
					
						
							|  |  |  | 		// world to camera transformation and the projection matrix is
 | 
					
						
							| 
									
										
										
										
											2012-10-08 03:28:11 +00:00
										 |  |  | 		// camera to clip transformation. combine both so that
 | 
					
						
							|  |  |  | 		CMmat4mul(m_wtc, projection, modelview); | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	void		initialize() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		size_t newsize = (m_sizes[0]*m_sizes[1])*sizeof(btScalar); | 
					
						
							|  |  |  | 		if (m_buffer) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// see if we can reuse
 | 
					
						
							|  |  |  | 			if (newsize > m_bufferSize) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				free(m_buffer); | 
					
						
							|  |  |  | 				m_buffer = NULL; | 
					
						
							|  |  |  | 				m_bufferSize = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!m_buffer) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			m_buffer = (btScalar*)calloc(1, newsize); | 
					
						
							|  |  |  | 			m_bufferSize = newsize; | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// buffer exists already, just clears it
 | 
					
						
							|  |  |  | 			memset(m_buffer, 0, newsize); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// memory allocate must succeed
 | 
					
						
							|  |  |  | 		assert(m_buffer != NULL); | 
					
						
							|  |  |  | 		m_initialized = true; | 
					
						
							|  |  |  | 		m_occlusion = false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	void		SetModelMatrix(double *fl) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		CMmat4mul(m_mtc,m_wtc,fl); | 
					
						
							|  |  |  | 		if (!m_initialized) | 
					
						
							|  |  |  | 			initialize(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// transform a segment in world coordinate to clip coordinate
 | 
					
						
							|  |  |  | 	void		transformW(const btVector3& x, btVector4& t) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		t[0]	=	x[0]*m_wtc[0]+x[1]*m_wtc[4]+x[2]*m_wtc[8]+m_wtc[12]; | 
					
						
							|  |  |  | 		t[1]	=	x[0]*m_wtc[1]+x[1]*m_wtc[5]+x[2]*m_wtc[9]+m_wtc[13]; | 
					
						
							|  |  |  | 		t[2]	=	x[0]*m_wtc[2]+x[1]*m_wtc[6]+x[2]*m_wtc[10]+m_wtc[14]; | 
					
						
							|  |  |  | 		t[3]	=	x[0]*m_wtc[3]+x[1]*m_wtc[7]+x[2]*m_wtc[11]+m_wtc[15]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	void		transformM(const float* x, btVector4& t) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		t[0]	=	x[0]*m_mtc[0]+x[1]*m_mtc[4]+x[2]*m_mtc[8]+m_mtc[12]; | 
					
						
							|  |  |  | 		t[1]	=	x[0]*m_mtc[1]+x[1]*m_mtc[5]+x[2]*m_mtc[9]+m_mtc[13]; | 
					
						
							|  |  |  | 		t[2]	=	x[0]*m_mtc[2]+x[1]*m_mtc[6]+x[2]*m_mtc[10]+m_mtc[14]; | 
					
						
							|  |  |  | 		t[3]	=	x[0]*m_mtc[3]+x[1]*m_mtc[7]+x[2]*m_mtc[11]+m_mtc[15]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// convert polygon to device coordinates
 | 
					
						
							|  |  |  | 	static bool	project(btVector4* p,int n) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		for (int i=0;i<n;++i) | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			p[i][2]=1/p[i][3]; | 
					
						
							|  |  |  | 			p[i][0]*=p[i][2]; | 
					
						
							|  |  |  | 			p[i][1]*=p[i][2]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return(true); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// pi: closed polygon in clip coordinate, NP = number of segments
 | 
					
						
							|  |  |  | 	// po: same polygon with clipped segments removed
 | 
					
						
							|  |  |  | 	template <const int NP> | 
					
						
							|  |  |  | 	static int	clip(const btVector4* pi,btVector4* po) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btScalar	s[2*NP]; | 
					
						
							|  |  |  | 		btVector4	pn[2*NP]; | 
					
						
							|  |  |  | 		int			i, j, m, n, ni; | 
					
						
							|  |  |  | 		// deal with near clipping
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		for (i=0, m=0;i<NP;++i) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			s[i]=pi[i][2]+pi[i][3]; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			if (s[i]<0) m+=1<<i; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		if (m==((1<<NP)-1))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			return(0); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		if (m!=0) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			for (i=NP-1,j=0,n=0;j<NP;i=j++) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				const btVector4&	a=pi[i]; | 
					
						
							|  |  |  | 				const btVector4&	b=pi[j]; | 
					
						
							|  |  |  | 				const btScalar		t=s[i]/(a[3]+a[2]-b[3]-b[2]); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if ((t>0)&&(t<1)) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					pn[n][0]	=	a[0]+(b[0]-a[0])*t; | 
					
						
							|  |  |  | 					pn[n][1]	=	a[1]+(b[1]-a[1])*t; | 
					
						
							|  |  |  | 					pn[n][2]	=	a[2]+(b[2]-a[2])*t; | 
					
						
							|  |  |  | 					pn[n][3]	=	a[3]+(b[3]-a[3])*t; | 
					
						
							|  |  |  | 					++n; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (s[j]>0) pn[n++]=b; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			// ready to test far clipping, start from the modified polygon
 | 
					
						
							|  |  |  | 			pi = pn; | 
					
						
							|  |  |  | 			ni = n; | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// no clipping on the near plane, keep same vector
 | 
					
						
							|  |  |  | 			ni = NP; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// now deal with far clipping
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		for (i=0, m=0;i<ni;++i) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			s[i]=pi[i][2]-pi[i][3]; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			if (s[i]>0) m+=1<<i; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		if (m==((1<<ni)-1))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			return(0); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		if (m!=0) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			for (i=ni-1,j=0,n=0;j<ni;i=j++) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				const btVector4&	a=pi[i]; | 
					
						
							|  |  |  | 				const btVector4&	b=pi[j]; | 
					
						
							|  |  |  | 				const btScalar		t=s[i]/(a[2]-a[3]-b[2]+b[3]); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if ((t>0)&&(t<1)) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					po[n][0]	=	a[0]+(b[0]-a[0])*t; | 
					
						
							|  |  |  | 					po[n][1]	=	a[1]+(b[1]-a[1])*t; | 
					
						
							|  |  |  | 					po[n][2]	=	a[2]+(b[2]-a[2])*t; | 
					
						
							|  |  |  | 					po[n][3]	=	a[3]+(b[3]-a[3])*t; | 
					
						
							|  |  |  | 					++n; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (s[j]<0) po[n++]=b; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return(n); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		for (int i=0;i<ni;++i) po[i]=pi[i]; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		return(ni); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// write or check a triangle to buffer. a,b,c in device coordinates (-1,+1)
 | 
					
						
							|  |  |  | 	template <typename POLICY> | 
					
						
							|  |  |  | 	inline bool	draw(	const btVector4& a, | 
					
						
							|  |  |  | 						const btVector4& b, | 
					
						
							|  |  |  | 						const btVector4& c, | 
					
						
							|  |  |  | 						const float face, | 
					
						
							|  |  |  | 						const btScalar minarea) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-03-12 20:34:17 +00:00
										 |  |  | 		const btScalar		a2=btCross(b-a,c-a)[2]; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		if ((face*a2)<0.f || btFabs(a2)<minarea) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			return false; | 
					
						
							|  |  |  | 		// further down we are normally going to write to the Zbuffer, mark it so
 | 
					
						
							|  |  |  | 		POLICY::Occlusion(m_occlusion); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		int x[3], y[3], ib=1, ic=2; | 
					
						
							|  |  |  | 		btScalar z[3]; | 
					
						
							|  |  |  | 		x[0]=(int)(a.x()*m_scales[0]+m_offsets[0]); | 
					
						
							|  |  |  | 		y[0]=(int)(a.y()*m_scales[1]+m_offsets[1]); | 
					
						
							|  |  |  | 		z[0]=a.z(); | 
					
						
							|  |  |  | 		if (a2 < 0.f) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// negative aire is possible with double face => must
 | 
					
						
							|  |  |  | 			// change the order of b and c otherwise the algorithm doesn't work
 | 
					
						
							|  |  |  | 			ib=2; | 
					
						
							|  |  |  | 			ic=1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		x[ib]=(int)(b.x()*m_scales[0]+m_offsets[0]); | 
					
						
							|  |  |  | 		x[ic]=(int)(c.x()*m_scales[0]+m_offsets[0]); | 
					
						
							|  |  |  | 		y[ib]=(int)(b.y()*m_scales[1]+m_offsets[1]); | 
					
						
							|  |  |  | 		y[ic]=(int)(c.y()*m_scales[1]+m_offsets[1]); | 
					
						
							|  |  |  | 		z[ib]=b.z(); | 
					
						
							|  |  |  | 		z[ic]=c.z(); | 
					
						
							|  |  |  | 		const int		mix=btMax(0,btMin(x[0],btMin(x[1],x[2]))); | 
					
						
							|  |  |  | 		const int		mxx=btMin(m_sizes[0],1+btMax(x[0],btMax(x[1],x[2]))); | 
					
						
							|  |  |  | 		const int		miy=btMax(0,btMin(y[0],btMin(y[1],y[2]))); | 
					
						
							|  |  |  | 		const int		mxy=btMin(m_sizes[1],1+btMax(y[0],btMax(y[1],y[2]))); | 
					
						
							|  |  |  | 		const int		width=mxx-mix; | 
					
						
							|  |  |  | 		const int		height=mxy-miy; | 
					
						
							|  |  |  | 		if ((width*height) <= 1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// degenerated in at most one single pixel
 | 
					
						
							|  |  |  | 			btScalar* scan=&m_buffer[miy*m_sizes[0]+mix]; | 
					
						
							|  |  |  | 			// use for loop to detect the case where width or height == 0
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			for (int iy=miy;iy<mxy;++iy) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				for (int ix=mix;ix<mxx;++ix) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 					if (POLICY::Process(*scan,z[0]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 						return(true); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 					if (POLICY::Process(*scan,z[1]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 						return(true); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 					if (POLICY::Process(*scan,z[2]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 						return(true); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (width == 1)  { | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			// Degenerated in at least 2 vertical lines
 | 
					
						
							|  |  |  | 			// The algorithm below doesn't work when face has a single pixel width
 | 
					
						
							|  |  |  | 			// We cannot use general formulas because the plane is degenerated. 
 | 
					
						
							|  |  |  | 			// We have to interpolate along the 3 edges that overlaps and process each pixel.
 | 
					
						
							|  |  |  | 			// sort the y coord to make formula simpler
 | 
					
						
							|  |  |  | 			int ytmp; | 
					
						
							|  |  |  | 			btScalar ztmp; | 
					
						
							|  |  |  | 			if (y[0] > y[1]) { ytmp=y[1];y[1]=y[0];y[0]=ytmp;ztmp=z[1];z[1]=z[0];z[0]=ztmp; } | 
					
						
							|  |  |  | 			if (y[0] > y[2]) { ytmp=y[2];y[2]=y[0];y[0]=ytmp;ztmp=z[2];z[2]=z[0];z[0]=ztmp; } | 
					
						
							|  |  |  | 			if (y[1] > y[2]) { ytmp=y[2];y[2]=y[1];y[1]=ytmp;ztmp=z[2];z[2]=z[1];z[1]=ztmp; } | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			int	dy[] = {y[0] - y[1], | 
					
						
							|  |  |  | 			            y[1] - y[2], | 
					
						
							|  |  |  | 			            y[2] - y[0]}; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			btScalar dzy[3]; | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			dzy[0] = (dy[0]) ? (z[0] - z[1]) / dy[0] : btScalar(0.f); | 
					
						
							|  |  |  | 			dzy[1] = (dy[1]) ? (z[1] - z[2]) / dy[1] : btScalar(0.f); | 
					
						
							|  |  |  | 			dzy[2] = (dy[2]) ? (z[2] - z[0]) / dy[2] : btScalar(0.f); | 
					
						
							|  |  |  | 			btScalar v[3] = {dzy[0] * (miy - y[0]) + z[0], | 
					
						
							|  |  |  | 			                 dzy[1] * (miy - y[1]) + z[1], | 
					
						
							|  |  |  | 			                 dzy[2] * (miy - y[2]) + z[2]}; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			dy[0] = y[1]-y[0]; | 
					
						
							|  |  |  | 			dy[1] = y[0]-y[1]; | 
					
						
							|  |  |  | 			dy[2] = y[2]-y[0]; | 
					
						
							|  |  |  | 			btScalar* scan=&m_buffer[miy*m_sizes[0]+mix]; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			for (int iy=miy;iy<mxy;++iy) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (dy[0] >= 0 && POLICY::Process(*scan,v[0]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 					return(true); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (dy[1] >= 0 && POLICY::Process(*scan,v[1]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 					return(true); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (dy[2] >= 0 && POLICY::Process(*scan,v[2]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 					return(true); | 
					
						
							|  |  |  | 				scan+=m_sizes[0]; | 
					
						
							|  |  |  | 				v[0] += dzy[0]; v[1] += dzy[1]; v[2] += dzy[2]; | 
					
						
							|  |  |  | 				dy[0]--; dy[1]++, dy[2]--; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (height == 1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// Degenerated in at least 2 horizontal lines
 | 
					
						
							|  |  |  | 			// The algorithm below doesn't work when face has a single pixel width
 | 
					
						
							|  |  |  | 			// We cannot use general formulas because the plane is degenerated. 
 | 
					
						
							|  |  |  | 			// We have to interpolate along the 3 edges that overlaps and process each pixel.
 | 
					
						
							|  |  |  | 			int xtmp; | 
					
						
							|  |  |  | 			btScalar ztmp; | 
					
						
							|  |  |  | 			if (x[0] > x[1]) { xtmp=x[1];x[1]=x[0];x[0]=xtmp;ztmp=z[1];z[1]=z[0];z[0]=ztmp; } | 
					
						
							|  |  |  | 			if (x[0] > x[2]) { xtmp=x[2];x[2]=x[0];x[0]=xtmp;ztmp=z[2];z[2]=z[0];z[0]=ztmp; } | 
					
						
							|  |  |  | 			if (x[1] > x[2]) { xtmp=x[2];x[2]=x[1];x[1]=xtmp;ztmp=z[2];z[2]=z[1];z[1]=ztmp; } | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			int dx[] = {x[0] - x[1], | 
					
						
							|  |  |  | 			            x[1] - x[2], | 
					
						
							|  |  |  | 			            x[2] - x[0]}; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			btScalar dzx[3]; | 
					
						
							|  |  |  | 			dzx[0] = (dx[0]) ? (z[0]-z[1])/dx[0] : btScalar(0.f); | 
					
						
							|  |  |  | 			dzx[1] = (dx[1]) ? (z[1]-z[2])/dx[1] : btScalar(0.f); | 
					
						
							|  |  |  | 			dzx[2] = (dx[2]) ? (z[2]-z[0])/dx[2] : btScalar(0.f); | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			btScalar v[3] = {dzx[0] * (mix - x[0]) + z[0], | 
					
						
							|  |  |  | 			                 dzx[1] * (mix - x[1]) + z[1], | 
					
						
							|  |  |  | 			                 dzx[2] * (mix - x[2]) + z[2]}; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			dx[0] = x[1]-x[0]; | 
					
						
							|  |  |  | 			dx[1] = x[0]-x[1]; | 
					
						
							|  |  |  | 			dx[2] = x[2]-x[0]; | 
					
						
							|  |  |  | 			btScalar* scan=&m_buffer[miy*m_sizes[0]+mix]; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			for (int ix=mix;ix<mxx;++ix) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (dx[0] >= 0 && POLICY::Process(*scan,v[0]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 					return(true); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (dx[1] >= 0 && POLICY::Process(*scan,v[1]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 					return(true); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				if (dx[2] >= 0 && POLICY::Process(*scan,v[2]))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 					return(true); | 
					
						
							|  |  |  | 				scan++; | 
					
						
							|  |  |  | 				v[0] += dzx[0]; v[1] += dzx[1]; v[2] += dzx[2]; | 
					
						
							|  |  |  | 				dx[0]--; dx[1]++, dx[2]--; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			// general case
 | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			const int       dx[] = {y[0] - y[1], | 
					
						
							|  |  |  | 			                        y[1] - y[2], | 
					
						
							|  |  |  | 			                        y[2] - y[0]}; | 
					
						
							|  |  |  | 			const int       dy[] = {x[1] - x[0] - dx[0] * width, | 
					
						
							|  |  |  | 			                        x[2] - x[1] - dx[1] * width, | 
					
						
							|  |  |  | 			                        x[0] - x[2] - dx[2] * width}; | 
					
						
							|  |  |  | 			const int       a = x[2] * y[0] + x[0] * y[1] - x[2] * y[1] - x[0] * y[2] + x[1] * y[2] - x[1] * y[0]; | 
					
						
							|  |  |  | 			const btScalar  ia = 1 / (btScalar)a; | 
					
						
							|  |  |  | 			const btScalar  dzx = ia*(y[2]*(z[1]-z[0])+y[1]*(z[0]-z[2])+y[0]*(z[2]-z[1])); | 
					
						
							|  |  |  | 			const btScalar  dzy = ia*(x[2]*(z[0]-z[1])+x[0]*(z[1]-z[2])+x[1]*(z[2]-z[0]))-(dzx*width); | 
					
						
							|  |  |  | 			int             c[] = {miy*x[1]+mix*y[0]-x[1]*y[0]-mix*y[1]+x[0]*y[1]-miy*x[0], | 
					
						
							|  |  |  | 			                        miy*x[2]+mix*y[1]-x[2]*y[1]-mix*y[2]+x[1]*y[2]-miy*x[1], | 
					
						
							|  |  |  | 			                        miy*x[0]+mix*y[2]-x[0]*y[2]-mix*y[0]+x[2]*y[0]-miy*x[2]}; | 
					
						
							|  |  |  | 			btScalar        v = ia*((z[2]*c[0])+(z[0]*c[1])+(z[1]*c[2])); | 
					
						
							|  |  |  | 			btScalar       *scan = &m_buffer[miy*m_sizes[0]]; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			for (int iy=miy;iy<mxy;++iy) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 				for (int ix=mix;ix<mxx;++ix) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 					if ((c[0]>=0)&&(c[1]>=0)&&(c[2]>=0)) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 						if (POLICY::Process(scan[ix],v))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 							return(true); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					c[0]+=dx[0];c[1]+=dx[1];c[2]+=dx[2];v+=dzx; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				c[0]+=dy[0];c[1]+=dy[1];c[2]+=dy[2];v+=dzy; | 
					
						
							|  |  |  | 				scan+=m_sizes[0]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return(false); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// clip than write or check a polygon 
 | 
					
						
							|  |  |  | 	template <const int NP,typename POLICY> | 
					
						
							|  |  |  | 	inline bool	clipDraw(	const btVector4* p, | 
					
						
							|  |  |  | 							const float face, | 
					
						
							|  |  |  | 							btScalar minarea) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btVector4	o[NP*2]; | 
					
						
							|  |  |  | 		int			n=clip<NP>(p,o); | 
					
						
							|  |  |  | 		bool		earlyexit=false; | 
					
						
							|  |  |  | 		if (n) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			project(o,n); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			for (int i=2;i<n && !earlyexit;++i) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				earlyexit|=draw<POLICY>(o[0],o[i-1],o[i],face,minarea); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return(earlyexit); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// add a triangle (in model coordinate)
 | 
					
						
							|  |  |  | 	// face =  0.f if face is double side, 
 | 
					
						
							|  |  |  | 	//      =  1.f if face is single sided and scale is positive
 | 
					
						
							|  |  |  | 	//      = -1.f if face is single sided and scale is negative
 | 
					
						
							|  |  |  | 	void		appendOccluderM(const float* a, | 
					
						
							|  |  |  | 								const float* b, | 
					
						
							|  |  |  | 								const float* c, | 
					
						
							|  |  |  | 								const float face) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btVector4	p[3]; | 
					
						
							|  |  |  | 		transformM(a,p[0]); | 
					
						
							|  |  |  | 		transformM(b,p[1]); | 
					
						
							|  |  |  | 		transformM(c,p[2]); | 
					
						
							|  |  |  | 		clipDraw<3,WriteOCL>(p,face,btScalar(0.f)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// add a quad (in model coordinate)
 | 
					
						
							|  |  |  | 	void		appendOccluderM(const float* a, | 
					
						
							|  |  |  | 								const float* b, | 
					
						
							|  |  |  | 								const float* c, | 
					
						
							|  |  |  | 								const float* d, | 
					
						
							|  |  |  | 								const float face) | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		btVector4	p[4]; | 
					
						
							|  |  |  | 		transformM(a,p[0]); | 
					
						
							|  |  |  | 		transformM(b,p[1]); | 
					
						
							|  |  |  | 		transformM(c,p[2]); | 
					
						
							|  |  |  | 		transformM(d,p[3]); | 
					
						
							|  |  |  | 		clipDraw<4,WriteOCL>(p,face,btScalar(0.f)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// query occluder for a box (c=center, e=extend) in world coordinate
 | 
					
						
							|  |  |  | 	inline bool	queryOccluderW(	const btVector3& c, | 
					
						
							|  |  |  | 								const btVector3& e) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (!m_occlusion) | 
					
						
							|  |  |  | 			// no occlusion yet, no need to check
 | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		btVector4	x[8]; | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]-e[0],c[1]-e[1],c[2]-e[2]),x[0]); | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]+e[0],c[1]-e[1],c[2]-e[2]),x[1]); | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]+e[0],c[1]+e[1],c[2]-e[2]),x[2]); | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]-e[0],c[1]+e[1],c[2]-e[2]),x[3]); | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]-e[0],c[1]-e[1],c[2]+e[2]),x[4]); | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]+e[0],c[1]-e[1],c[2]+e[2]),x[5]); | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]+e[0],c[1]+e[1],c[2]+e[2]),x[6]); | 
					
						
							|  |  |  | 		transformW(btVector3(c[0]-e[0],c[1]+e[1],c[2]+e[2]),x[7]); | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		for (int i=0;i<8;++i) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			// the box is clipped, it's probably a large box, don't waste our time to check
 | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			if ((x[i][2]+x[i][3])<=0) return(true); | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 		static const int d[] = {1,0,3,2, | 
					
						
							|  |  |  | 		                        4,5,6,7, | 
					
						
							|  |  |  | 		                        4,7,3,0, | 
					
						
							|  |  |  | 		                        6,5,1,2, | 
					
						
							|  |  |  | 		                        7,6,2,3, | 
					
						
							|  |  |  | 		                        5,4,0,1}; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 		for (unsigned int i=0;i<(sizeof(d)/sizeof(d[0]));) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			const btVector4 p[] = {x[d[i++]], | 
					
						
							|  |  |  | 			                       x[d[i++]], | 
					
						
							|  |  |  | 			                       x[d[i++]], | 
					
						
							|  |  |  | 			                       x[d[i++]]}; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 			if (clipDraw<4,QueryOCL>(p,1.f,0.f))  | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 				return(true); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return(false); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct	DbvtCullingCallback : btDbvt::ICollide | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PHY_CullingCallback m_clientCallback; | 
					
						
							|  |  |  | 	void* m_userData; | 
					
						
							|  |  |  | 	OcclusionBuffer *m_ocb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DbvtCullingCallback(PHY_CullingCallback clientCallback, void* userData) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_clientCallback = clientCallback; | 
					
						
							|  |  |  | 		m_userData = userData; | 
					
						
							|  |  |  | 		m_ocb = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	bool Descent(const btDbvtNode* node) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return(m_ocb->queryOccluderW(node->volume.Center(),node->volume.Extents())); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	void Process(const btDbvtNode* node,btScalar depth) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		Process(node); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	void Process(const btDbvtNode* leaf) | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		btBroadphaseProxy*	proxy=(btBroadphaseProxy*)leaf->data; | 
					
						
							|  |  |  | 		// the client object is a graphic controller
 | 
					
						
							|  |  |  | 		CcdGraphicController* ctrl = static_cast<CcdGraphicController*>(proxy->m_clientObject); | 
					
						
							|  |  |  | 		KX_ClientObjectInfo* info = (KX_ClientObjectInfo*)ctrl->getNewClientInfo(); | 
					
						
							|  |  |  | 		if (m_ocb) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// means we are doing occlusion culling. Check if this object is an occluders
 | 
					
						
							|  |  |  | 			KX_GameObject* gameobj = KX_GameObject::GetClientObject(info); | 
					
						
							|  |  |  | 			if (gameobj && gameobj->GetOccluder()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				double* fl = gameobj->GetOpenGLMatrixPtr()->getPointer(); | 
					
						
							|  |  |  | 				// this will create the occlusion buffer if not already done
 | 
					
						
							|  |  |  | 				// and compute the transformation from model local space to clip space
 | 
					
						
							|  |  |  | 				m_ocb->SetModelMatrix(fl); | 
					
						
							|  |  |  | 				float face = (gameobj->IsNegativeScaling()) ? -1.0f : 1.0f; | 
					
						
							|  |  |  | 				// walk through the meshes and for each add to buffer
 | 
					
						
							|  |  |  | 				for (int i=0; i<gameobj->GetMeshCount(); i++) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					RAS_MeshObject* meshobj = gameobj->GetMesh(i); | 
					
						
							|  |  |  | 					const float *v1, *v2, *v3, *v4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					int polycount = meshobj->NumPolygons(); | 
					
						
							|  |  |  | 					for (int j=0; j<polycount; j++) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						RAS_Polygon* poly = meshobj->GetPolygon(j); | 
					
						
							|  |  |  | 						switch (poly->VertexCount()) | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 						case 3: | 
					
						
							|  |  |  | 							v1 = poly->GetVertex(0)->getXYZ(); | 
					
						
							|  |  |  | 							v2 = poly->GetVertex(1)->getXYZ(); | 
					
						
							|  |  |  | 							v3 = poly->GetVertex(2)->getXYZ(); | 
					
						
							|  |  |  | 							m_ocb->appendOccluderM(v1,v2,v3,((poly->IsTwoside())?0.f:face)); | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						case 4: | 
					
						
							|  |  |  | 							v1 = poly->GetVertex(0)->getXYZ(); | 
					
						
							|  |  |  | 							v2 = poly->GetVertex(1)->getXYZ(); | 
					
						
							|  |  |  | 							v3 = poly->GetVertex(2)->getXYZ(); | 
					
						
							|  |  |  | 							v4 = poly->GetVertex(3)->getXYZ(); | 
					
						
							|  |  |  | 							m_ocb->appendOccluderM(v1,v2,v3,v4,((poly->IsTwoside())?0.f:face)); | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (info) | 
					
						
							|  |  |  | 			(*m_clientCallback)(info, m_userData); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | static OcclusionBuffer gOcb; | 
					
						
							| 
									
										
										
										
											2013-02-21 18:30:11 +00:00
										 |  |  | bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, MT_Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, double modelview[16], double projection[16]) | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (!m_cullingTree) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	DbvtCullingCallback dispatcher(callback, userData); | 
					
						
							|  |  |  | 	btVector3 planes_n[6]; | 
					
						
							|  |  |  | 	btScalar planes_o[6]; | 
					
						
							|  |  |  | 	if (nplanes > 6) | 
					
						
							|  |  |  | 		nplanes = 6; | 
					
						
							|  |  |  | 	for (int i=0; i<nplanes; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		planes_n[i].setValue(planes[i][0], planes[i][1], planes[i][2]); | 
					
						
							|  |  |  | 		planes_o[i] = planes[i][3]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// if occlusionRes != 0 => occlusion culling
 | 
					
						
							|  |  |  | 	if (occlusionRes) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-10-08 03:28:11 +00:00
										 |  |  | 		gOcb.setup(occlusionRes, viewport, modelview, projection); | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		dispatcher.m_ocb = &gOcb; | 
					
						
							|  |  |  | 		// occlusion culling, the direction of the view is taken from the first plan which MUST be the near plane
 | 
					
						
							|  |  |  | 		btDbvt::collideOCL(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher); | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 		btDbvt::collideOCL(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher); | 
					
						
							| 
									
										
										
										
											2012-06-17 09:58:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 		btDbvt::collideKDOP(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,nplanes,dispatcher); | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | 		btDbvt::collideKDOP(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,nplanes,dispatcher); | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-07-29 18:14:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | int	CcdPhysicsEnvironment::getNumContactPoints() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | void CcdPhysicsEnvironment::getContactPoint(int i,float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | btBroadphaseInterface*	CcdPhysicsEnvironment::getBroadphase() | 
					
						
							|  |  |  | {  | 
					
						
							|  |  |  | 	return m_dynamicsWorld->getBroadphase();  | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | btDispatcher*	CcdPhysicsEnvironment::getDispatcher() | 
					
						
							|  |  |  | {  | 
					
						
							|  |  |  | 	return m_dynamicsWorld->getDispatcher(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-15 23:58:56 +00:00
										 |  |  | void CcdPhysicsEnvironment::MergeEnvironment(CcdPhysicsEnvironment *other) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::set<CcdPhysicsController*>::iterator it; | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-15 23:58:56 +00:00
										 |  |  | 	while (other->m_controllers.begin() != other->m_controllers.end()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		it= other->m_controllers.begin(); | 
					
						
							|  |  |  | 		CcdPhysicsController* ctrl= (*it); | 
					
						
							| 
									
										
										
										
											2008-09-21 15:17:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-15 23:58:56 +00:00
										 |  |  | 		other->removeCcdPhysicsController(ctrl); | 
					
						
							|  |  |  | 		this->addCcdPhysicsController(ctrl); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | CcdPhysicsEnvironment::~CcdPhysicsEnvironment() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | #ifdef NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	m_wrapperVehicles.clear(); | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | #endif //NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	//m_broadphase->DestroyScene();
 | 
					
						
							|  |  |  | 	//delete broadphase ? release reference on broadphase ?
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	//first delete scene, then dispatcher, because pairs have to release manifolds on the dispatcher
 | 
					
						
							|  |  |  | 	//delete m_dispatcher;
 | 
					
						
							|  |  |  | 	delete m_dynamicsWorld; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-02-21 05:36:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	if (NULL != m_ownPairCache) | 
					
						
							|  |  |  | 		delete m_ownPairCache; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (NULL != m_ownDispatcher) | 
					
						
							|  |  |  | 		delete m_ownDispatcher; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (NULL != m_solver) | 
					
						
							|  |  |  | 		delete m_solver; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (NULL != m_debugDrawer) | 
					
						
							|  |  |  | 		delete m_debugDrawer; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	if (NULL != m_filterCallback) | 
					
						
							|  |  |  | 		delete m_filterCallback; | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-08 20:05:40 +00:00
										 |  |  | 	if (NULL != m_ghostPairCallback) | 
					
						
							|  |  |  | 		delete m_ghostPairCallback; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 	if (NULL != m_collisionConfiguration) | 
					
						
							|  |  |  | 		delete m_collisionConfiguration; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (NULL != m_broadphase) | 
					
						
							|  |  |  | 		delete m_broadphase; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (NULL != m_cullingTree) | 
					
						
							|  |  |  | 		delete m_cullingTree; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (NULL != m_cullingCache) | 
					
						
							|  |  |  | 		delete m_cullingCache; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-07-18 05:41:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | float	CcdPhysicsEnvironment::getConstraintParam(int constraintId,int param) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	btTypedConstraint* typedConstraint = getConstraintById(constraintId); | 
					
						
							|  |  |  | 	switch (typedConstraint->getUserConstraintType()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case PHY_GENERIC_6DOF_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			switch (param) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 			case 0:	case 1: case 2:  | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					//param = 0..2 are linear constraint values
 | 
					
						
							|  |  |  | 					btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; | 
					
						
							|  |  |  | 					genCons->calculateTransforms(); | 
					
						
							|  |  |  | 					return genCons->getRelativePivotPosition(param); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				case 3: case 4: case 5: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					//param = 3..5 are relative constraint (Euler) angles
 | 
					
						
							|  |  |  | 					btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; | 
					
						
							|  |  |  | 					genCons->calculateTransforms(); | 
					
						
							|  |  |  | 					return genCons->getAngle(param-3); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	return 0.f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | void	CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float value0,float value1) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	btTypedConstraint* typedConstraint = getConstraintById(constraintId); | 
					
						
							|  |  |  | 	switch (typedConstraint->getUserConstraintType()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case PHY_GENERIC_6DOF_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			switch (param) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 			case 0:	case 1: case 2: case 3: case 4: case 5: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					//param = 0..5 are constraint limits, with low/high limit value
 | 
					
						
							|  |  |  | 					btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; | 
					
						
							|  |  |  | 					genCons->setLimit(param,value0,value1); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			case 6: case 7: case 8: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					//param = 6,7,8 are translational motors, with value0=target velocity, value1 = max motor force
 | 
					
						
							|  |  |  | 					btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; | 
					
						
							|  |  |  | 					int transMotorIndex = param-6; | 
					
						
							|  |  |  | 					btTranslationalLimitMotor* transMotor = genCons->getTranslationalLimitMotor(); | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 					transMotor->m_targetVelocity[transMotorIndex] = value0; | 
					
						
							|  |  |  | 					transMotor->m_maxMotorForce[transMotorIndex] = value1; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 					transMotor->m_enableMotor[transMotorIndex] = (value1>0.f); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			case 9: case 10: case 11: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					//param = 9,10,11 are rotational motors, with value0=target velocity, value1 = max motor force
 | 
					
						
							|  |  |  | 					btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; | 
					
						
							|  |  |  | 					int angMotorIndex = param-9; | 
					
						
							|  |  |  | 					btRotationalLimitMotor* rotMotor = genCons->getRotationalLimitMotor(angMotorIndex); | 
					
						
							|  |  |  | 					rotMotor->m_enableMotor = (value1 > 0.f); | 
					
						
							|  |  |  | 					rotMotor->m_targetVelocity = value0; | 
					
						
							|  |  |  | 					rotMotor->m_maxMotorForce = value1; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case 12: case 13: case 14: case 15: case 16: case 17: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				//param 13-17 are for motorized springs on each of the degrees of freedom
 | 
					
						
							|  |  |  | 					btGeneric6DofSpringConstraint* genCons = (btGeneric6DofSpringConstraint*)typedConstraint; | 
					
						
							|  |  |  | 					int springIndex = param-12; | 
					
						
							|  |  |  | 					if (value0!=0.f) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						bool springEnabled = true; | 
					
						
							|  |  |  | 						genCons->setStiffness(springIndex,value0); | 
					
						
							|  |  |  | 						genCons->setDamping(springIndex,value1); | 
					
						
							|  |  |  | 						genCons->enableSpring(springIndex,springEnabled); | 
					
						
							|  |  |  | 						genCons->setEquilibriumPoint(springIndex); | 
					
						
							|  |  |  | 					} else | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						bool springEnabled = false; | 
					
						
							|  |  |  | 						genCons->enableSpring(springIndex,springEnabled); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 09:21:13 +00:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	case PHY_CONE_TWIST_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			switch (param) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 			case 3: case 4: case 5: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					//param = 3,4,5 are constraint limits, high limit values
 | 
					
						
							|  |  |  | 					btConeTwistConstraint* coneTwist = (btConeTwistConstraint*)typedConstraint; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:52:14 +00:00
										 |  |  | 					if (value1<0.0f) | 
					
						
							| 
									
										
										
										
											2011-02-28 20:22:28 +00:00
										 |  |  | 						coneTwist->setLimit(param,btScalar(BT_LARGE_FLOAT)); | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						coneTwist->setLimit(param,value1); | 
					
						
							| 
									
										
										
										
											2011-02-27 09:21:13 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	case PHY_ANGULAR_CONSTRAINT: | 
					
						
							|  |  |  | 	case PHY_LINEHINGE_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			switch (param) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 			case 3: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					//param = 3 is a constraint limit, with low/high limit value
 | 
					
						
							|  |  |  | 					btHingeConstraint* hingeCons = (btHingeConstraint*)typedConstraint; | 
					
						
							|  |  |  | 					hingeCons->setLimit(value0,value1); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | btTypedConstraint*	CcdPhysicsEnvironment::getConstraintById(int constraintId) | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int numConstraints = m_dynamicsWorld->getNumConstraints(); | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 	for (i=0;i<numConstraints;i++) | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 		btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if (constraint->getUserConstraintId()==constraintId) | 
					
						
							| 
									
										
										
										
											2006-04-06 20:37:38 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			return constraint; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl; | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 	// addSensor() is a "light" function for bullet because it is used
 | 
					
						
							|  |  |  | 	// dynamically when the sensor is activated. Use enableCcdPhysicsController() instead 
 | 
					
						
							|  |  |  | 	//if (m_controllers.insert(ctrl1).second)
 | 
					
						
							|  |  |  | 	//{
 | 
					
						
							|  |  |  | 	//	addCcdPhysicsController(ctrl1);
 | 
					
						
							|  |  |  | 	//}
 | 
					
						
							|  |  |  | 	enableCcdPhysicsController(ctrl1); | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | bool CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl) | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-08-05 16:23:33 +00:00
										 |  |  | 	CcdPhysicsController* ccdCtrl = (CcdPhysicsController*)ctrl; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	if (!ccdCtrl->Unregister()) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	m_triggerControllers.erase(ccdCtrl); | 
					
						
							|  |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-08-05 16:23:33 +00:00
										 |  |  | 	disableCcdPhysicsController((CcdPhysicsController*)ctrl); | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	/*	printf("addTouchCallback\n(response class = %i)\n",response_class);
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	//map PHY_ convention into SM_ convention
 | 
					
						
							|  |  |  | 	switch (response_class) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case	PHY_FH_RESPONSE: | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	printf("PHY_FH_RESPONSE\n"); | 
					
						
							|  |  |  | 	break; | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	case PHY_SENSOR_RESPONSE: | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	printf("PHY_SENSOR_RESPONSE\n"); | 
					
						
							|  |  |  | 	break; | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	case PHY_CAMERA_RESPONSE: | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	printf("PHY_CAMERA_RESPONSE\n"); | 
					
						
							|  |  |  | 	break; | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	case PHY_OBJECT_RESPONSE: | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	printf("PHY_OBJECT_RESPONSE\n"); | 
					
						
							|  |  |  | 	break; | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	case PHY_STATIC_RESPONSE: | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	printf("PHY_STATIC_RESPONSE\n"); | 
					
						
							|  |  |  | 	break; | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	assert(0); | 
					
						
							|  |  |  | 	return; | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m_triggerCallbacks[response_class] = callback; | 
					
						
							|  |  |  | 	m_triggerCallbacksUserPtrs[response_class] = user; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | bool CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctrl) | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	if (!ccdCtrl->Register()) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	m_triggerControllers.insert(ccdCtrl); | 
					
						
							|  |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void	CcdPhysicsEnvironment::CallbackTriggers() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	if (m_triggerCallbacks[PHY_OBJECT_RESPONSE] || (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints))) | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-04-17 06:27:57 +00:00
										 |  |  | 		//walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback
 | 
					
						
							| 
									
										
										
										
											2008-08-07 11:31:24 +00:00
										 |  |  | 		btDispatcher* dispatcher = m_dynamicsWorld->getDispatcher(); | 
					
						
							|  |  |  | 		int numManifolds = dispatcher->getNumManifolds(); | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 		for (int i=0;i<numManifolds;i++) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-08-07 11:31:24 +00:00
										 |  |  | 			btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			int numContacts = manifold->getNumContacts(); | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 			if (numContacts) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2013-03-07 17:53:16 +00:00
										 |  |  | 				const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0()); | 
					
						
							|  |  |  | 				const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1()); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 				if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)) | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					for (int j=0;j<numContacts;j++) | 
					
						
							|  |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 						btVector3 color(1,0,0); | 
					
						
							|  |  |  | 						const btManifoldPoint& cp = manifold->getContactPoint(j); | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 						if (m_debugDrawer) | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 							m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color); | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-03-07 17:53:16 +00:00
										 |  |  | 				const btRigidBody* obj0 = rb0; | 
					
						
							|  |  |  | 				const btRigidBody* obj1 = rb1; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 				//m_internalOwner is set in 'addPhysicsController'
 | 
					
						
							|  |  |  | 				CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer()); | 
					
						
							|  |  |  | 				CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer()); | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 				std::set<CcdPhysicsController*>::const_iterator i = m_triggerControllers.find(ctrl0); | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 				if (i == m_triggerControllers.end()) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2008-07-30 17:41:47 +00:00
										 |  |  | 					i = m_triggerControllers.find(ctrl1); | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (!(i == m_triggerControllers.end())) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE], | 
					
						
							|  |  |  | 						ctrl0,ctrl1,0); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2008-08-07 17:29:06 +00:00
										 |  |  | 				// Bullet does not refresh the manifold contact point for object without contact response
 | 
					
						
							|  |  |  | 				// may need to remove this when a newer Bullet version is integrated
 | 
					
						
							|  |  |  | 				if (!dispatcher->needsResponse(rb0, rb1)) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					// Refresh algorithm fails sometimes when there is penetration 
 | 
					
						
							|  |  |  | 					// (usuall the case with ghost and sensor objects)
 | 
					
						
							|  |  |  | 					// Let's just clear the manifold, in any case, it is recomputed on each frame.
 | 
					
						
							|  |  |  | 					manifold->clearManifold(); //refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
 | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-04-17 06:27:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | // This call back is called before a pair is added in the cache
 | 
					
						
							|  |  |  | // Handy to remove objects that must be ignored by sensors
 | 
					
						
							|  |  |  | bool CcdOverlapFilterCallBack::needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	btCollisionObject *colObj0, *colObj1; | 
					
						
							|  |  |  | 	CcdPhysicsController *sensorCtrl, *objCtrl; | 
					
						
							| 
									
										
										
										
											2012-10-30 15:44:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	KX_GameObject *kxObj0 = KX_GameObject::GetClientObject( | 
					
						
							|  |  |  | 			(KX_ClientObjectInfo*) | 
					
						
							|  |  |  | 			((CcdPhysicsController*) | 
					
						
							|  |  |  | 					(((btCollisionObject*)proxy0->m_clientObject)->getUserPointer())) | 
					
						
							|  |  |  | 			->getNewClientInfo()); | 
					
						
							|  |  |  | 	KX_GameObject *kxObj1 = KX_GameObject::GetClientObject( | 
					
						
							|  |  |  | 			(KX_ClientObjectInfo*) | 
					
						
							|  |  |  | 			((CcdPhysicsController*) | 
					
						
							|  |  |  | 					(((btCollisionObject*)proxy1->m_clientObject)->getUserPointer())) | 
					
						
							|  |  |  | 			->getNewClientInfo()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// First check the filters. Note that this is called during scene
 | 
					
						
							|  |  |  | 	// conversion, so we can't assume the KX_GameObject instances exist. This
 | 
					
						
							|  |  |  | 	// may make some objects erroneously collide on the first frame, but the
 | 
					
						
							|  |  |  | 	// alternative is to have them erroneously miss.
 | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	bool collides; | 
					
						
							|  |  |  | 	collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; | 
					
						
							|  |  |  | 	collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); | 
					
						
							| 
									
										
										
										
											2012-10-30 15:44:16 +00:00
										 |  |  | 	if (kxObj0 && kxObj1) { | 
					
						
							|  |  |  | 		collides = collides && kxObj0->CheckCollision(kxObj1); | 
					
						
							|  |  |  | 		collides = collides && kxObj1->CheckCollision(kxObj0); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	if (!collides) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// additional check for sensor object
 | 
					
						
							|  |  |  | 	if (proxy0->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// this is a sensor object, the other one can't be a sensor object because 
 | 
					
						
							|  |  |  | 		// they exclude each other in the above test
 | 
					
						
							|  |  |  | 		assert(!(proxy1->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger)); | 
					
						
							|  |  |  | 		colObj0 = (btCollisionObject*)proxy0->m_clientObject; | 
					
						
							|  |  |  | 		colObj1 = (btCollisionObject*)proxy1->m_clientObject; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (proxy1->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		colObj0 = (btCollisionObject*)proxy1->m_clientObject; | 
					
						
							|  |  |  | 		colObj1 = (btCollisionObject*)proxy0->m_clientObject; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!colObj0 || !colObj1) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	sensorCtrl = static_cast<CcdPhysicsController*>(colObj0->getUserPointer()); | 
					
						
							|  |  |  | 	objCtrl = static_cast<CcdPhysicsController*>(colObj1->getUserPointer()); | 
					
						
							|  |  |  | 	if (m_physEnv->m_triggerCallbacks[PHY_BROADPH_RESPONSE]) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return m_physEnv->m_triggerCallbacks[PHY_BROADPH_RESPONSE](m_physEnv->m_triggerCallbacksUserPtrs[PHY_BROADPH_RESPONSE], sensorCtrl, objCtrl, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-17 01:33:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | #ifdef NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //complex constraint for vehicles
 | 
					
						
							|  |  |  | PHY_IVehicle*	CcdPhysicsEnvironment::getVehicleConstraint(int constraintId) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int numVehicles = m_wrapperVehicles.size(); | 
					
						
							|  |  |  | 	for (i=0;i<numVehicles;i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		if (wrapperVehicle->GetVehicle()->getUserConstraintId() == constraintId) | 
					
						
							| 
									
										
										
										
											2006-02-13 06:28:35 +00:00
										 |  |  | 			return wrapperVehicle; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-24 16:40:32 +00:00
										 |  |  | #endif //NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-04 20:56:02 +00:00
										 |  |  | PHY_ICharacter* CcdPhysicsEnvironment::getCharacterController(KX_GameObject *ob) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CcdPhysicsController* controller = (CcdPhysicsController*)ob->GetPhysicsController()->GetUserData(); | 
					
						
							|  |  |  | 	if (controller->GetCharacterController()) | 
					
						
							| 
									
										
										
										
											2012-12-26 01:25:53 +00:00
										 |  |  | 		return new CharacterWrapper((BlenderBulletCharacterController*)controller->GetCharacterController()); | 
					
						
							| 
									
										
										
										
											2012-11-04 20:56:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | int currentController = 0; | 
					
						
							|  |  |  | int numController = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-21 18:30:11 +00:00
										 |  |  | PHY_IPhysicsController*	CcdPhysicsEnvironment::CreateSphereController(float radius,const MT_Vector3& position) | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	CcdConstructionInfo	cinfo; | 
					
						
							| 
									
										
										
										
											2009-04-20 15:06:46 +00:00
										 |  |  | 	memset(&cinfo, 0, sizeof(cinfo)); /* avoid uninitialized values */ | 
					
						
							|  |  |  | 	cinfo.m_collisionShape = new btSphereShape(radius); // memory leak! The shape is not deleted by Bullet and we cannot add it to the KX_Scene.m_shapes list
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	cinfo.m_MotionState = 0; | 
					
						
							|  |  |  | 	cinfo.m_physicsEnv = this; | 
					
						
							| 
									
										
										
										
											2011-05-28 13:11:24 +00:00
										 |  |  | 	// declare this object as Dyamic rather than static!!
 | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	// The reason as it is designed to detect all type of object, including static object
 | 
					
						
							|  |  |  | 	// It would cause static-static message to be printed on the console otherwise
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_STATIC_OBJECT; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	DefaultMotionState* motionState = new DefaultMotionState(); | 
					
						
							|  |  |  | 	cinfo.m_MotionState = motionState; | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	// we will add later the possibility to select the filter from option
 | 
					
						
							|  |  |  | 	cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; | 
					
						
							|  |  |  | 	cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	cinfo.m_bSensor = true; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	motionState->m_worldTransform.setIdentity(); | 
					
						
							|  |  |  | 	motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return sphereController; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | int findClosestNode(btSoftBody* sb,const btVector3& worldPoint); | 
					
						
							|  |  |  | int findClosestNode(btSoftBody* sb,const btVector3& worldPoint) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int node = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	btSoftBody::tNodeArray&   nodes(sb->m_nodes); | 
					
						
							|  |  |  | 	float maxDistSqr = 1e30f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int n=0;n<nodes.size();n++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btScalar distSqr = (nodes[n].m_x - worldPoint).length2(); | 
					
						
							|  |  |  | 		if (distSqr<maxDistSqr) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			maxDistSqr = distSqr; | 
					
						
							|  |  |  | 			node = n; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return node; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | int			CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl0,class PHY_IPhysicsController* ctrl1,PHY_ConstraintType type, | 
					
						
							|  |  |  | 													float pivotX,float pivotY,float pivotZ, | 
					
						
							| 
									
										
										
										
											2006-12-16 05:50:38 +00:00
										 |  |  | 													float axisX,float axisY,float axisZ, | 
					
						
							|  |  |  | 													float axis1X,float axis1Y,float axis1Z, | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 													float axis2X,float axis2Y,float axis2Z,int flags | 
					
						
							| 
									
										
										
										
											2006-12-16 05:50:38 +00:00
										 |  |  | 													) | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:32:04 +00:00
										 |  |  | 	bool disableCollisionBetweenLinkedBodies = (0!=(flags & CCD_CONSTRAINT_DISABLE_LINKED_COLLISION)); | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	CcdPhysicsController* c0 = (CcdPhysicsController*)ctrl0; | 
					
						
							|  |  |  | 	CcdPhysicsController* c1 = (CcdPhysicsController*)ctrl1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	btRigidBody* rb0 = c0 ? c0->GetRigidBody() : 0; | 
					
						
							|  |  |  | 	btRigidBody* rb1 = c1 ? c1->GetRigidBody() : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	bool rb0static = rb0 ? rb0->isStaticOrKinematicObject() : true; | 
					
						
							|  |  |  | 	bool rb1static = rb1 ? rb1->isStaticOrKinematicObject() : true; | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	btCollisionObject* colObj0 = c0->GetCollisionObject(); | 
					
						
							|  |  |  | 	if (!colObj0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	btVector3 pivotInA(pivotX,pivotY,pivotZ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 	//it might be a soft body, let's try
 | 
					
						
							|  |  |  | 	btSoftBody* sb0 = c0 ? c0->GetSoftBody() : 0; | 
					
						
							|  |  |  | 	btSoftBody* sb1 = c1 ? c1->GetSoftBody() : 0; | 
					
						
							|  |  |  | 	if (sb0 && sb1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		//not between two soft bodies?
 | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (sb0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		//either cluster or node attach, let's find closest node first
 | 
					
						
							|  |  |  | 		//the soft body doesn't have a 'real' world transform, so get its initial world transform for now
 | 
					
						
							|  |  |  | 		btVector3 pivotPointSoftWorld = sb0->m_initialWorldTransform(pivotInA); | 
					
						
							|  |  |  | 		int node=findClosestNode(sb0,pivotPointSoftWorld); | 
					
						
							|  |  |  | 		if (node >=0) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 			bool clusterconstaint = false; | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | 			switch (type) | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 			case PHY_LINEHINGE_CONSTRAINT: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (sb0->clusterCount() && rb1) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						btSoftBody::LJoint::Specs	ls; | 
					
						
							|  |  |  | 						ls.erp=0.5f; | 
					
						
							|  |  |  | 						ls.position=sb0->clusterCom(0); | 
					
						
							|  |  |  | 						sb0->appendLinearJoint(ls,rb1); | 
					
						
							|  |  |  | 						clusterconstaint = true; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			case PHY_GENERIC_6DOF_CONSTRAINT: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (sb0->clusterCount() && rb1) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						btSoftBody::AJoint::Specs as; | 
					
						
							|  |  |  | 						as.erp = 1; | 
					
						
							|  |  |  | 						as.cfm = 1; | 
					
						
							|  |  |  | 						as.axis.setValue(axisX,axisY,axisZ); | 
					
						
							|  |  |  | 						sb0->appendAngularJoint(as,rb1); | 
					
						
							|  |  |  | 						clusterconstaint = true; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 			*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!clusterconstaint) | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 				if (rb1) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2008-10-11 20:19:04 +00:00
										 |  |  | 					sb0->appendAnchor(node,rb1,disableCollisionBetweenLinkedBodies); | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 				} else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					sb0->setMass(node,0.f); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return 0;//can't remove soft body anchors yet
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (sb1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		btVector3 pivotPointAWorld = colObj0->getWorldTransform()(pivotInA); | 
					
						
							|  |  |  | 		int node=findClosestNode(sb1,pivotPointAWorld); | 
					
						
							|  |  |  | 		if (node >=0) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 			bool clusterconstaint = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/*
 | 
					
						
							|  |  |  | 			switch (type) | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 			case PHY_LINEHINGE_CONSTRAINT: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (sb1->clusterCount() && rb0) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						btSoftBody::LJoint::Specs	ls; | 
					
						
							|  |  |  | 						ls.erp=0.5f; | 
					
						
							|  |  |  | 						ls.position=sb1->clusterCom(0); | 
					
						
							|  |  |  | 						sb1->appendLinearJoint(ls,rb0); | 
					
						
							|  |  |  | 						clusterconstaint = true; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			case PHY_GENERIC_6DOF_CONSTRAINT: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (sb1->clusterCount() && rb0) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						btSoftBody::AJoint::Specs as; | 
					
						
							|  |  |  | 						as.erp = 1; | 
					
						
							|  |  |  | 						as.cfm = 1; | 
					
						
							|  |  |  | 						as.axis.setValue(axisX,axisY,axisZ); | 
					
						
							|  |  |  | 						sb1->appendAngularJoint(as,rb0); | 
					
						
							|  |  |  | 						clusterconstaint = true; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			};*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!clusterconstaint) | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 				if (rb0) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2008-10-11 20:19:04 +00:00
										 |  |  | 					sb1->appendAnchor(node,rb0,disableCollisionBetweenLinkedBodies); | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 				} else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					sb1->setMass(node,0.f); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-10-01 06:36:17 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return 0;//can't remove soft body anchors yet
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	if (rb0static && rb1static) | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-30 23:34:25 +00:00
										 |  |  | 	if (!rb0) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 	btVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) :  | 
					
						
							|  |  |  | 		rb0->getCenterOfMassTransform() * pivotInA; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	btVector3 axisInA(axisX,axisY,axisZ); | 
					
						
							| 
									
										
										
										
											2007-01-19 03:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	bool angularOnly = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (type) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case PHY_POINT2POINT_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			btPoint2PointConstraint* p2p = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (rb1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				p2p = new btPoint2PointConstraint(*rb0, | 
					
						
							|  |  |  | 					*rb1,pivotInA,pivotInB); | 
					
						
							|  |  |  | 			} else | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 				p2p = new btPoint2PointConstraint(*rb0, | 
					
						
							|  |  |  | 					pivotInA); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 			m_dynamicsWorld->addConstraint(p2p,disableCollisionBetweenLinkedBodies); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | //			m_constraints.push_back(p2p);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			p2p->setUserConstraintId(gConstraintUid++); | 
					
						
							|  |  |  | 			p2p->setUserConstraintType(type); | 
					
						
							|  |  |  | 			//64 bit systems can't cast pointer to int. could use size_t instead.
 | 
					
						
							|  |  |  | 			return p2p->getUserConstraintId(); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	case PHY_GENERIC_6DOF_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			btGeneric6DofConstraint* genericConstraint = 0; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			if (rb1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				btTransform frameInA; | 
					
						
							|  |  |  | 				btTransform frameInB; | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2006-12-16 05:50:38 +00:00
										 |  |  | 				btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); | 
					
						
							|  |  |  | 				if (axis1.length() == 0.0) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					btPlaneSpace1( axisInA, axis1, axis2 ); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 				frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), | 
					
						
							|  |  |  | 					                          axisInA.y(), axis1.y(), axis2.y(), | 
					
						
							|  |  |  | 											  axisInA.z(), axis1.z(), axis2.z() ); | 
					
						
							|  |  |  | 				frameInA.setOrigin( pivotInA ); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-19 03:14:51 +00:00
										 |  |  | 				btTransform inv = rb1->getCenterOfMassTransform().inverse(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				frameInB = inv  * globalFrameA; | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 				bool useReferenceFrameA = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 				genericConstraint = new btGeneric6DofSpringConstraint( | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 					*rb0,*rb1, | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 					frameInA,frameInB,useReferenceFrameA); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			} else | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 				static btRigidBody s_fixedObject2( 0,0,0); | 
					
						
							| 
									
										
										
										
											2007-01-19 03:14:51 +00:00
										 |  |  | 				btTransform frameInA; | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 				btTransform frameInB; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				btVector3 axis1, axis2; | 
					
						
							|  |  |  | 				btPlaneSpace1( axisInA, axis1, axis2 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), | 
					
						
							| 
									
										
										
										
											2011-09-03 02:15:49 +00:00
										 |  |  | 				                              axisInA.y(), axis1.y(), axis2.y(), | 
					
						
							|  |  |  | 				                              axisInA.z(), axis1.z(), axis2.z() ); | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				frameInA.setOrigin( pivotInA ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-01-19 03:14:51 +00:00
										 |  |  | 				///frameInB in worldspace
 | 
					
						
							|  |  |  | 				frameInB = rb0->getCenterOfMassTransform() * frameInA; | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 				bool useReferenceFrameA = true; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 				genericConstraint = new btGeneric6DofSpringConstraint( | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 					*rb0,s_fixedObject2, | 
					
						
							| 
									
										
										
										
											2008-09-03 02:27:16 +00:00
										 |  |  | 					frameInA,frameInB,useReferenceFrameA); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-06-22 01:10:50 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 			if (genericConstraint) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				//m_constraints.push_back(genericConstraint);
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 				m_dynamicsWorld->addConstraint(genericConstraint,disableCollisionBetweenLinkedBodies); | 
					
						
							| 
									
										
										
										
											2006-12-02 03:48:36 +00:00
										 |  |  | 				genericConstraint->setUserConstraintId(gConstraintUid++); | 
					
						
							|  |  |  | 				genericConstraint->setUserConstraintType(type); | 
					
						
							|  |  |  | 				//64 bit systems can't cast pointer to int. could use size_t instead.
 | 
					
						
							|  |  |  | 				return genericConstraint->getUserConstraintId(); | 
					
						
							|  |  |  | 			}  | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-16 05:56:51 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	case PHY_CONE_TWIST_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			btConeTwistConstraint* coneTwistContraint = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (rb1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				btTransform frameInA; | 
					
						
							|  |  |  | 				btTransform frameInB; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); | 
					
						
							|  |  |  | 				if (axis1.length() == 0.0) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					btPlaneSpace1( axisInA, axis1, axis2 ); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), | 
					
						
							|  |  |  | 					                          axisInA.y(), axis1.y(), axis2.y(), | 
					
						
							|  |  |  | 											  axisInA.z(), axis1.z(), axis2.z() ); | 
					
						
							|  |  |  | 				frameInA.setOrigin( pivotInA ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				btTransform inv = rb1->getCenterOfMassTransform().inverse(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				frameInB = inv  * globalFrameA; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				coneTwistContraint = new btConeTwistConstraint(	*rb0,*rb1, | 
					
						
							|  |  |  | 					frameInA,frameInB); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				static btRigidBody s_fixedObject2( 0,0,0); | 
					
						
							|  |  |  | 				btTransform frameInA; | 
					
						
							|  |  |  | 				btTransform frameInB; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				btVector3 axis1, axis2; | 
					
						
							|  |  |  | 				btPlaneSpace1( axisInA, axis1, axis2 ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), | 
					
						
							|  |  |  | 					                          axisInA.y(), axis1.y(), axis2.y(), | 
					
						
							|  |  |  | 											  axisInA.z(), axis1.z(), axis2.z() ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				frameInA.setOrigin( pivotInA ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				///frameInB in worldspace
 | 
					
						
							|  |  |  | 				frameInB = rb0->getCenterOfMassTransform() * frameInA; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				coneTwistContraint = new btConeTwistConstraint( | 
					
						
							|  |  |  | 					*rb0,s_fixedObject2, | 
					
						
							|  |  |  | 					frameInA,frameInB); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			if (coneTwistContraint) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				//m_constraints.push_back(genericConstraint);
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 				m_dynamicsWorld->addConstraint(coneTwistContraint,disableCollisionBetweenLinkedBodies); | 
					
						
							| 
									
										
										
										
											2007-07-16 05:56:51 +00:00
										 |  |  | 				coneTwistContraint->setUserConstraintId(gConstraintUid++); | 
					
						
							|  |  |  | 				coneTwistContraint->setUserConstraintType(type); | 
					
						
							|  |  |  | 				//64 bit systems can't cast pointer to int. could use size_t instead.
 | 
					
						
							|  |  |  | 				return coneTwistContraint->getUserConstraintId(); | 
					
						
							|  |  |  | 			}  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	case PHY_ANGULAR_CONSTRAINT: | 
					
						
							|  |  |  | 		angularOnly = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case PHY_LINEHINGE_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			btHingeConstraint* hinge = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (rb1) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-02-27 09:21:13 +00:00
										 |  |  | 				// We know the orientations so we should use them instead of
 | 
					
						
							|  |  |  | 				// having btHingeConstraint fill in the blanks any way it wants to.
 | 
					
						
							|  |  |  | 				btTransform frameInA; | 
					
						
							|  |  |  | 				btTransform frameInB; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); | 
					
						
							|  |  |  | 				if (axis1.length() == 0.0) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					btPlaneSpace1( axisInA, axis1, axis2 ); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				// Internally btHingeConstraint's hinge-axis is z
 | 
					
						
							|  |  |  | 				frameInA.getBasis().setValue( axis1.x(), axis2.x(), axisInA.x(), | 
					
						
							|  |  |  | 											axis1.y(), axis2.y(), axisInA.y(), | 
					
						
							|  |  |  | 											axis1.z(), axis2.z(), axisInA.z() ); | 
					
						
							|  |  |  | 											 | 
					
						
							|  |  |  | 				frameInA.setOrigin( pivotInA ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				btTransform inv = rb1->getCenterOfMassTransform().inverse(); | 
					
						
							| 
									
										
										
										
											2007-01-19 03:14:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 09:21:13 +00:00
										 |  |  | 				btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				frameInB = inv  * globalFrameA; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				hinge = new btHingeConstraint(*rb0,*rb1,frameInA,frameInB); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-02-27 09:21:13 +00:00
										 |  |  | 				static btRigidBody s_fixedObject2( 0,0,0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				btTransform frameInA; | 
					
						
							|  |  |  | 				btTransform frameInB; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); | 
					
						
							|  |  |  | 				if (axis1.length() == 0.0) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					btPlaneSpace1( axisInA, axis1, axis2 ); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Internally btHingeConstraint's hinge-axis is z
 | 
					
						
							|  |  |  | 				frameInA.getBasis().setValue( axis1.x(), axis2.x(), axisInA.x(), | 
					
						
							|  |  |  | 											axis1.y(), axis2.y(), axisInA.y(), | 
					
						
							|  |  |  | 											axis1.z(), axis2.z(), axisInA.z() ); | 
					
						
							|  |  |  | 				frameInA.setOrigin( pivotInA ); | 
					
						
							|  |  |  | 				frameInB = rb0->getCenterOfMassTransform() * frameInA; | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 09:21:13 +00:00
										 |  |  | 				hinge = new btHingeConstraint(*rb0, s_fixedObject2, frameInA, frameInB); | 
					
						
							| 
									
										
										
										
											2006-04-28 00:08:18 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			hinge->setAngularOnly(angularOnly); | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			//m_constraints.push_back(hinge);
 | 
					
						
							| 
									
										
										
										
											2008-10-10 05:12:57 +00:00
										 |  |  | 			m_dynamicsWorld->addConstraint(hinge,disableCollisionBetweenLinkedBodies); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			hinge->setUserConstraintId(gConstraintUid++); | 
					
						
							|  |  |  | 			hinge->setUserConstraintType(type); | 
					
						
							|  |  |  | 			//64 bit systems can't cast pointer to int. could use size_t instead.
 | 
					
						
							|  |  |  | 			return hinge->getUserConstraintId(); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #ifdef NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	case PHY_VEHICLE_CONSTRAINT: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			btRaycastVehicle::btVehicleTuning* tuning = new btRaycastVehicle::btVehicleTuning(); | 
					
						
							|  |  |  | 			btRigidBody* chassis = rb0; | 
					
						
							|  |  |  | 			btDefaultVehicleRaycaster* raycaster = new btDefaultVehicleRaycaster(m_dynamicsWorld); | 
					
						
							|  |  |  | 			btRaycastVehicle* vehicle = new btRaycastVehicle(*tuning,chassis,raycaster); | 
					
						
							|  |  |  | 			WrapperVehicle* wrapperVehicle = new WrapperVehicle(vehicle,ctrl0); | 
					
						
							|  |  |  | 			m_wrapperVehicles.push_back(wrapperVehicle); | 
					
						
							|  |  |  | 			m_dynamicsWorld->addVehicle(vehicle); | 
					
						
							|  |  |  | 			vehicle->setUserConstraintId(gConstraintUid++); | 
					
						
							|  |  |  | 			vehicle->setUserConstraintType(type); | 
					
						
							|  |  |  | 			return vehicle->getUserConstraintId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | #endif //NEW_BULLET_VEHICLE_SUPPORT
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CcdConstructionInfo	cinfo; | 
					
						
							| 
									
										
										
										
											2011-04-20 04:55:58 +00:00
										 |  |  | //don't memset cinfo: this is C++ and values should be set in the constructor!
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-21 15:19:54 +00:00
										 |  |  | 	// we don't need a CcdShapeConstructionInfo for this shape:
 | 
					
						
							|  |  |  | 	// it is simple enough for the standard copy constructor (see CcdPhysicsController::GetReplica)
 | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	cinfo.m_collisionShape = new btConeShape(coneradius,coneheight); | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 	cinfo.m_MotionState = 0; | 
					
						
							|  |  |  | 	cinfo.m_physicsEnv = this; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_STATIC_OBJECT; | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 	DefaultMotionState* motionState = new DefaultMotionState(); | 
					
						
							|  |  |  | 	cinfo.m_MotionState = motionState; | 
					
						
							| 
									
										
										
										
											2008-03-01 19:17:37 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	// we will add later the possibility to select the filter from option
 | 
					
						
							|  |  |  | 	cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; | 
					
						
							|  |  |  | 	cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter; | 
					
						
							| 
									
										
										
										
											2009-06-08 20:08:19 +00:00
										 |  |  | 	cinfo.m_bSensor = true; | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 	motionState->m_worldTransform.setIdentity(); | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | //	motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2]));
 | 
					
						
							| 
									
										
										
										
											2006-05-22 21:03:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return sphereController; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | float		CcdPhysicsEnvironment::getAppliedImpulse(int	constraintid) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 	int numConstraints = m_dynamicsWorld->getNumConstraints(); | 
					
						
							|  |  |  | 	for (i=0;i<numConstraints;i++) | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 		btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); | 
					
						
							|  |  |  | 		if (constraint->getUserConstraintId() == constraintid) | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 			return constraint->getAppliedImpulse(); | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-11-21 00:53:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-28 06:44:29 +00:00
										 |  |  | 	return 0.f; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-03-12 20:34:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void	CcdPhysicsEnvironment::exportFile(const char* filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	btDefaultSerializer*	serializer = new btDefaultSerializer(); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-03-16 21:20:24 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	for (int i=0;i<m_dynamicsWorld->getNumCollisionObjects();i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		CcdPhysicsController* controller = static_cast<CcdPhysicsController*>(colObj->getUserPointer()); | 
					
						
							|  |  |  | 		if (controller) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			const char* name = controller->getName(); | 
					
						
							|  |  |  | 			if (name) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				serializer->registerNameForPointer(colObj,name); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_dynamicsWorld->serialize(serializer); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-12 20:34:17 +00:00
										 |  |  | 	FILE* file = fopen(filename,"wb"); | 
					
						
							|  |  |  | 	if (file) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); | 
					
						
							|  |  |  | 		fclose(file); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |