Blender  V2.59
CcdGraphicController.cpp
Go to the documentation of this file.
00001 
00004 /*
00005 Bullet Continuous Collision Detection and Physics Library
00006 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00007 
00008 This software is provided 'as-is', without any express or implied warranty.
00009 In no event will the authors be held liable for any damages arising from the use of this software.
00010 Permission is granted to anyone to use this software for any purpose, 
00011 including commercial applications, and to alter it and redistribute it freely, 
00012 subject to the following restrictions:
00013 
00014 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00015 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00016 3. This notice may not be removed or altered from any source distribution.
00017 */
00018 
00019 #include "CcdPhysicsEnvironment.h"
00020 #include "CcdGraphicController.h"
00021 #include "btBulletDynamicsCommon.h"
00022 #include "MT_Point3.h"
00023 
00024 
00025 CcdGraphicController::CcdGraphicController (CcdPhysicsEnvironment* phyEnv, PHY_IMotionState* motionState) :
00026         m_localAabbMin(0.f, 0.f, 0.f),
00027         m_localAabbMax(0.f, 0.f, 0.f),
00028         m_motionState(motionState),
00029         m_phyEnv(phyEnv),
00030         m_handle(NULL),
00031         m_newClientInfo(NULL)
00032 {
00033 }
00034 
00035 CcdGraphicController::~CcdGraphicController()
00036 {
00037         if (m_phyEnv)
00038                 m_phyEnv->removeCcdGraphicController(this);
00039 
00040         if (m_motionState)
00041                 delete m_motionState;
00042 }
00043 
00044 void CcdGraphicController::setLocalAabb(const btVector3& aabbMin,const btVector3& aabbMax)
00045 {
00046         m_localAabbMin = aabbMin;
00047         m_localAabbMax = aabbMax;
00048         SetGraphicTransform();
00049 }
00050 
00051 void CcdGraphicController::setLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax)
00052 {
00053         m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]);
00054         m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]);
00055         SetGraphicTransform();
00056 }
00057 
00058 void CcdGraphicController::setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax)
00059 {
00060         m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]);
00061         m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]);
00062         SetGraphicTransform();
00063 }
00064 
00065 void CcdGraphicController::setLocalAabb(const float* aabbMin,const float* aabbMax)
00066 {
00067         m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]);
00068         m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]);
00069         SetGraphicTransform();
00070 }
00071 
00072 void CcdGraphicController::getAabb(btVector3& aabbMin, btVector3& aabbMax)
00073 {
00074         btVector3 pos;
00075         btVector3 scale;
00076         float ori[12];
00077         m_motionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]);
00078         m_motionState->getWorldScaling(scale.m_floats[0],scale.m_floats[1],scale.m_floats[2]);
00079         m_motionState->getWorldOrientation(ori);
00080         btMatrix3x3 rot(ori[0], ori[4], ori[8],
00081                                         ori[1], ori[5], ori[9],
00082                                         ori[2], ori[6], ori[10]);
00083 
00084         btVector3 localAabbMin = m_localAabbMin;
00085         btVector3 localAabbMax = m_localAabbMax;
00086         btVector3 tmpAabbMin = m_localAabbMin * scale;
00087         btVector3 tmpAabbMax = m_localAabbMax * scale;
00088 
00089         localAabbMin[0] = (scale.getX() >= 0.) ? tmpAabbMin[0] : tmpAabbMax[0];
00090         localAabbMin[1] = (scale.getY() >= 0.) ? tmpAabbMin[1] : tmpAabbMax[1];
00091         localAabbMin[2] = (scale.getZ() >= 0.) ? tmpAabbMin[2] : tmpAabbMax[2];
00092         localAabbMax[0] = (scale.getX() <= 0.) ? tmpAabbMin[0] : tmpAabbMax[0];
00093         localAabbMax[1] = (scale.getY() <= 0.) ? tmpAabbMin[1] : tmpAabbMax[1];
00094         localAabbMax[2] = (scale.getZ() <= 0.) ? tmpAabbMin[2] : tmpAabbMax[2];
00095 
00096         btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin);
00097         btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
00098         
00099         btMatrix3x3 abs_b = rot.absolute();  
00100         btVector3 center = rot*localCenter + pos;
00101         btVector3 extent = abs_b*localHalfExtents;
00102         aabbMin = center - extent;
00103         aabbMax = center + extent;
00104 }
00105 
00106 bool CcdGraphicController::SetGraphicTransform()
00107 {
00108         if (!m_handle) 
00109                 return false;
00110         btVector3 aabbMin;
00111         btVector3 aabbMax;
00112         getAabb(aabbMin, aabbMax);
00113         // update Aabb in broadphase
00114         m_phyEnv->getCullingTree()->setAabb(m_handle,aabbMin,aabbMax,NULL);
00115         return true;
00116 }
00117 
00118 PHY_IGraphicController* CcdGraphicController::GetReplica(class PHY_IMotionState* motionState)
00119 {
00120         CcdGraphicController* replica = new CcdGraphicController(*this);
00121         replica->m_motionState = motionState;
00122         replica->m_newClientInfo = NULL;
00123         replica->m_handle = NULL;
00124         // don't add the graphic controller now: work around a bug in Bullet with rescaling, 
00125         // (the scale of the controller is not yet defined).
00126         //m_phyEnv->addCcdGraphicController(replica);
00127         return replica;
00128 }
00129 
00130 void CcdGraphicController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* env)
00131 {
00132         CcdPhysicsEnvironment* phyEnv = static_cast<CcdPhysicsEnvironment*>(env);
00133         /* Updates the m_phyEnv's m_cullingTree & m_cullingCache */
00134         if(getBroadphaseHandle()) {
00135                 /* insert into the new physics scene */
00136                 Activate(false);
00137                 m_phyEnv= phyEnv;
00138                 Activate(true);
00139         }
00140         else {
00141                 m_phyEnv= phyEnv;
00142         }
00143 }
00144 
00145 void CcdGraphicController::Activate(bool active)
00146 {
00147         if (active)
00148                 m_phyEnv->addCcdGraphicController(this);
00149         else
00150                 m_phyEnv->removeCcdGraphicController(this);
00151 
00152 }