06 Dec 2007
This commit is contained in:
parent
f139116d59
commit
94d044bb27
|
@ -24,13 +24,15 @@ scroll = visible_offset
|
|||
|
||||
// замеченные баги
|
||||
1. не выводится текущее значение переменной в консоль
|
||||
2. imglib не выводит сообщения в консоль
|
||||
|
||||
Имплементация roqlib
|
||||
1. Вернуть read\save codebook
|
||||
1. Вернуть read\save codebook OK
|
||||
2. подключить звуковой кодер
|
||||
|
||||
Смена физического движка:
|
||||
1. Первичная имплементация OK
|
||||
2. Подключить инициализацию окружения
|
||||
2. Подключить инициализацию окружения OK
|
||||
3. Подключить DebugDrawer
|
||||
|
||||
//==================================================
|
||||
|
|
|
@ -68,5 +68,5 @@ if exist compile.log del /f /q compile.log
|
|||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
xash.exe +map qctest -log -debug -dev 3
|
||||
xash.exe +map phystest -log -debug -dev 3
|
||||
:done
|
|
@ -109,6 +109,11 @@ void Host_FreeCommon( void )
|
|||
Mem_FreePool( &zonepool );
|
||||
}
|
||||
|
||||
void Host_DrawLine( vec3_t color, vec3_t from, vec3_t to )
|
||||
{
|
||||
if( re ) re->DrawLine( color, from, to);
|
||||
}
|
||||
|
||||
void Host_InitPhysic( void )
|
||||
{
|
||||
static physic_imp_t pi;
|
||||
|
@ -118,6 +123,7 @@ void Host_InitPhysic( void )
|
|||
pi.api_size = sizeof(physic_imp_t);
|
||||
pi.Transform = SV_Transform;
|
||||
pi.GetModelVerts = SV_GetModelVerts;
|
||||
pi.DrawLine = Host_DrawLine;
|
||||
|
||||
Sys_LoadLibrary( &physic_dll );
|
||||
|
||||
|
@ -146,7 +152,7 @@ void Host_InitRender( void )
|
|||
|
||||
// studio callbacks
|
||||
ri.StudioEvent = CL_StudioEvent;
|
||||
ri.CM_DrawCollision = pe->DrawCollision;
|
||||
ri.DrawCollision = pe->DrawCollision;
|
||||
|
||||
Sys_LoadLibrary( &render_dll );
|
||||
|
||||
|
|
|
@ -61,8 +61,7 @@ struct sv_edict_s
|
|||
int serialnumber; // unical entity #id
|
||||
int solid; // see entity_state_t for details
|
||||
int event; // apply sv.events too
|
||||
NewtonBody *physbody; // ptr to phys body
|
||||
NewtonCollision *collision; // collision callback
|
||||
physbody_t *physbody; // ptr to phys body
|
||||
|
||||
// baselines
|
||||
entity_state_t s;
|
||||
|
|
|
@ -282,9 +282,8 @@ void Sav_LoadLocals( lump_t *l )
|
|||
SV_LinkEdict( ent );
|
||||
if(ent->progs.sv->movetype == MOVETYPE_PHYSIC)
|
||||
{
|
||||
pe->CreateBody( ent->priv.sv, ent->progs.sv->mins, ent->progs.sv->maxs,
|
||||
ent->progs.sv->origin, ent->progs.sv->angles, ent->progs.sv->solid,
|
||||
&ent->priv.sv->collision, &ent->priv.sv->physbody );
|
||||
ent->priv.sv->physbody = pe->CreateBody( ent->priv.sv, ent->progs.sv->mins, ent->progs.sv->maxs,
|
||||
ent->progs.sv->origin, ent->progs.sv->angles, ent->progs.sv->solid );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,6 +453,7 @@ void SV_RunFrame( void )
|
|||
|
||||
// build the playerstate_t structures for all players
|
||||
ClientEndServerFrames ();
|
||||
pe->Update();
|
||||
|
||||
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(prog->edicts);
|
||||
prog->globals.sv->other = PRVM_EDICT_TO_PROG(prog->edicts);
|
||||
|
|
|
@ -113,9 +113,8 @@ void SV_SetModel (edict_t *ent, const char *name)
|
|||
|
||||
if(ent->progs.sv->movetype == MOVETYPE_PHYSIC)
|
||||
{
|
||||
pe->CreateBody( ent->priv.sv, ent->progs.sv->mins, ent->progs.sv->maxs,
|
||||
ent->progs.sv->origin, ent->progs.sv->angles, ent->progs.sv->solid,
|
||||
&ent->priv.sv->collision, &ent->priv.sv->physbody );
|
||||
ent->priv.sv->physbody = pe->CreateBody( ent->priv.sv, ent->progs.sv->mins, ent->progs.sv->maxs,
|
||||
ent->progs.sv->origin, ent->progs.sv->angles, ent->progs.sv->solid );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -853,6 +853,7 @@ void Sys_Init( void )
|
|||
if(abs((short)hStdout) < 100) Sys.hooked_out = false;
|
||||
else Sys.hooked_out = true;
|
||||
FS_UpdateEnvironmentVariables(); // set working directory
|
||||
SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors
|
||||
|
||||
Sys.con_showalways = true;
|
||||
Sys.con_readonly = true;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -102,14 +102,34 @@ void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
|
|||
}
|
||||
}
|
||||
|
||||
void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
||||
void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
||||
{
|
||||
//debug vehicle wheels
|
||||
|
||||
|
||||
// todo: iterate over awake simulation islands!
|
||||
for ( int i = 0; i < m_collisionObjects.size(); i++)
|
||||
{
|
||||
//todo: iterate over awake simulation islands!
|
||||
for ( int i=0;i<m_collisionObjects.size();i++)
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
btRigidBody* body = btRigidBody::upcast(colObj);
|
||||
if (body && body->getMotionState() && !body->isStaticOrKinematicObject())
|
||||
{
|
||||
// we need to call the update at least once, even for sleeping objects
|
||||
// otherwise the 'graphics' transform never updates properly
|
||||
// so todo: add 'dirty' flag
|
||||
//if (body->getActivationState() != ISLAND_SLEEPING)
|
||||
{
|
||||
btTransform interpolatedTransform;
|
||||
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
|
||||
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime,interpolatedTransform);
|
||||
body->getMotionState()->setWorldTransform(interpolatedTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void btDiscreteDynamicsWorld::DrawDebug( void )
|
||||
{
|
||||
// debug vehicle wheels
|
||||
{
|
||||
for ( int i = 0; i < m_collisionObjects.size(); i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
|
||||
|
@ -128,69 +148,48 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
|
|||
case DISABLE_SIMULATION:
|
||||
color = btVector3(btScalar(255.),btScalar(255.),btScalar(0.));break;
|
||||
default:
|
||||
{
|
||||
color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));
|
||||
}
|
||||
color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.)); break;
|
||||
};
|
||||
|
||||
debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
|
||||
}
|
||||
btRigidBody* body = btRigidBody::upcast(colObj);
|
||||
if (body && body->getMotionState() && !body->isStaticOrKinematicObject())
|
||||
{
|
||||
//we need to call the update at least once, even for sleeping objects
|
||||
//otherwise the 'graphics' transform never updates properly
|
||||
//so todo: add 'dirty' flag
|
||||
//if (body->getActivationState() != ISLAND_SLEEPING)
|
||||
{
|
||||
btTransform interpolatedTransform;
|
||||
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
|
||||
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime,interpolatedTransform);
|
||||
body->getMotionState()->setWorldTransform(interpolatedTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
|
||||
{
|
||||
for ( int i=0;i<this->m_vehicles.size();i++)
|
||||
for ( int i = 0; i < this->m_vehicles.size(); i++)
|
||||
{
|
||||
for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
|
||||
for (int v = 0; v < m_vehicles[i]->getNumWheels(); v++)
|
||||
{
|
||||
btVector3 wheelColor(0,255,255);
|
||||
if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact)
|
||||
{
|
||||
wheelColor.setValue(0,0,255);
|
||||
} else
|
||||
wheelColor.setValue(0, 0, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
wheelColor.setValue(255,0,255);
|
||||
wheelColor.setValue(255, 0, 255);
|
||||
}
|
||||
|
||||
//synchronize the wheels with the (interpolated) chassis worldtransform
|
||||
m_vehicles[i]->updateWheelTransform(v,true);
|
||||
|
||||
btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin();
|
||||
|
||||
// synchronize the wheels with the (interpolated) chassis worldtransform
|
||||
m_vehicles[i]->updateWheelTransform(v, true);
|
||||
|
||||
btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin();
|
||||
btVector3 axle = btVector3(
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()],
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()],
|
||||
m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]);
|
||||
|
||||
|
||||
//m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS
|
||||
//debug wheels (cylinders)
|
||||
m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);
|
||||
m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
|
||||
int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
|
||||
{
|
||||
int numSimulationSubSteps = 0;
|
||||
|
||||
|
|
|
@ -1,159 +1,160 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_DISCRETE_DYNAMICS_WORLD_H
|
||||
#define BT_DISCRETE_DYNAMICS_WORLD_H
|
||||
|
||||
#include "btDynamicsWorld.h"
|
||||
|
||||
class btDispatcher;
|
||||
class btOverlappingPairCache;
|
||||
class btConstraintSolver;
|
||||
class btSimulationIslandManager;
|
||||
class btTypedConstraint;
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
|
||||
class btRaycastVehicle;
|
||||
class btIDebugDraw;
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
|
||||
///btDiscreteDynamicsWorld provides discrete rigid body simulation
|
||||
///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController
|
||||
class btDiscreteDynamicsWorld : public btDynamicsWorld
|
||||
{
|
||||
protected:
|
||||
|
||||
btConstraintSolver* m_constraintSolver;
|
||||
|
||||
btSimulationIslandManager* m_islandManager;
|
||||
|
||||
btAlignedObjectArray<btTypedConstraint*> m_constraints;
|
||||
|
||||
btIDebugDraw* m_debugDrawer;
|
||||
|
||||
btVector3 m_gravity;
|
||||
|
||||
//for variable timesteps
|
||||
btScalar m_localTime;
|
||||
//for variable timesteps
|
||||
|
||||
bool m_ownsIslandManager;
|
||||
bool m_ownsConstraintSolver;
|
||||
|
||||
btContactSolverInfo m_solverInfo;
|
||||
|
||||
|
||||
btAlignedObjectArray<btRaycastVehicle*> m_vehicles;
|
||||
|
||||
int m_profileTimings;
|
||||
|
||||
void predictUnconstraintMotion(btScalar timeStep);
|
||||
|
||||
void integrateTransforms(btScalar timeStep);
|
||||
|
||||
void calculateSimulationIslands();
|
||||
|
||||
void solveConstraints(btContactSolverInfo& solverInfo);
|
||||
|
||||
void updateActivationState(btScalar timeStep);
|
||||
|
||||
void updateVehicles(btScalar timeStep);
|
||||
|
||||
void startProfiling(btScalar timeStep);
|
||||
|
||||
virtual void internalSingleStepSimulation( btScalar timeStep);
|
||||
|
||||
void synchronizeMotionStates();
|
||||
|
||||
void saveKinematicState(btScalar timeStep);
|
||||
|
||||
void debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those
|
||||
btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver);
|
||||
|
||||
virtual ~btDiscreteDynamicsWorld();
|
||||
|
||||
///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
|
||||
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
|
||||
|
||||
virtual void updateAabbs();
|
||||
|
||||
void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
|
||||
|
||||
void removeConstraint(btTypedConstraint* constraint);
|
||||
|
||||
void addVehicle(btRaycastVehicle* vehicle);
|
||||
|
||||
void removeVehicle(btRaycastVehicle* vehicle);
|
||||
|
||||
btSimulationIslandManager* getSimulationIslandManager()
|
||||
{
|
||||
return m_islandManager;
|
||||
}
|
||||
|
||||
const btSimulationIslandManager* getSimulationIslandManager() const
|
||||
{
|
||||
return m_islandManager;
|
||||
}
|
||||
|
||||
btCollisionWorld* getCollisionWorld()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
|
||||
{
|
||||
m_debugDrawer = debugDrawer;
|
||||
}
|
||||
|
||||
virtual btIDebugDraw* getDebugDrawer()
|
||||
{
|
||||
return m_debugDrawer;
|
||||
}
|
||||
|
||||
virtual void setGravity(const btVector3& gravity);
|
||||
|
||||
virtual void addRigidBody(btRigidBody* body);
|
||||
|
||||
virtual void addRigidBody(btRigidBody* body, short group, short mask);
|
||||
|
||||
virtual void removeRigidBody(btRigidBody* body);
|
||||
|
||||
void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
|
||||
|
||||
virtual void setConstraintSolver(btConstraintSolver* solver);
|
||||
|
||||
virtual btConstraintSolver* getConstraintSolver();
|
||||
|
||||
virtual int getNumConstraints() const;
|
||||
|
||||
virtual btTypedConstraint* getConstraint(int index) ;
|
||||
|
||||
virtual const btTypedConstraint* getConstraint(int index) const;
|
||||
|
||||
btContactSolverInfo& getSolverInfo()
|
||||
{
|
||||
return m_solverInfo;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_DISCRETE_DYNAMICS_WORLD_H
|
||||
#define BT_DISCRETE_DYNAMICS_WORLD_H
|
||||
|
||||
#include "btDynamicsWorld.h"
|
||||
|
||||
class btDispatcher;
|
||||
class btOverlappingPairCache;
|
||||
class btConstraintSolver;
|
||||
class btSimulationIslandManager;
|
||||
class btTypedConstraint;
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
|
||||
class btRaycastVehicle;
|
||||
class btIDebugDraw;
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
|
||||
///btDiscreteDynamicsWorld provides discrete rigid body simulation
|
||||
///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController
|
||||
class btDiscreteDynamicsWorld : public btDynamicsWorld
|
||||
{
|
||||
protected:
|
||||
|
||||
btConstraintSolver* m_constraintSolver;
|
||||
|
||||
btSimulationIslandManager* m_islandManager;
|
||||
|
||||
btAlignedObjectArray<btTypedConstraint*> m_constraints;
|
||||
|
||||
btIDebugDraw* m_debugDrawer;
|
||||
|
||||
btVector3 m_gravity;
|
||||
|
||||
//for variable timesteps
|
||||
btScalar m_localTime;
|
||||
//for variable timesteps
|
||||
|
||||
bool m_ownsIslandManager;
|
||||
bool m_ownsConstraintSolver;
|
||||
|
||||
btContactSolverInfo m_solverInfo;
|
||||
|
||||
|
||||
btAlignedObjectArray<btRaycastVehicle*> m_vehicles;
|
||||
|
||||
int m_profileTimings;
|
||||
|
||||
void predictUnconstraintMotion(btScalar timeStep);
|
||||
|
||||
void integrateTransforms(btScalar timeStep);
|
||||
|
||||
void calculateSimulationIslands();
|
||||
|
||||
void solveConstraints(btContactSolverInfo& solverInfo);
|
||||
|
||||
void updateActivationState(btScalar timeStep);
|
||||
|
||||
void updateVehicles(btScalar timeStep);
|
||||
|
||||
void startProfiling(btScalar timeStep);
|
||||
|
||||
virtual void internalSingleStepSimulation( btScalar timeStep);
|
||||
|
||||
void synchronizeMotionStates();
|
||||
|
||||
void saveKinematicState(btScalar timeStep);
|
||||
|
||||
void debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those
|
||||
btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver);
|
||||
|
||||
virtual ~btDiscreteDynamicsWorld();
|
||||
|
||||
///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
|
||||
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
|
||||
|
||||
virtual void updateAabbs();
|
||||
|
||||
void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
|
||||
|
||||
void removeConstraint(btTypedConstraint* constraint);
|
||||
|
||||
void addVehicle(btRaycastVehicle* vehicle);
|
||||
|
||||
void removeVehicle(btRaycastVehicle* vehicle);
|
||||
|
||||
btSimulationIslandManager* getSimulationIslandManager()
|
||||
{
|
||||
return m_islandManager;
|
||||
}
|
||||
|
||||
const btSimulationIslandManager* getSimulationIslandManager() const
|
||||
{
|
||||
return m_islandManager;
|
||||
}
|
||||
|
||||
btCollisionWorld* getCollisionWorld()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
|
||||
{
|
||||
m_debugDrawer = debugDrawer;
|
||||
}
|
||||
|
||||
virtual btIDebugDraw* getDebugDrawer()
|
||||
{
|
||||
return m_debugDrawer;
|
||||
}
|
||||
|
||||
virtual void DrawDebug( void );
|
||||
virtual void setGravity(const btVector3& gravity);
|
||||
|
||||
virtual void addRigidBody(btRigidBody* body);
|
||||
|
||||
virtual void addRigidBody(btRigidBody* body, short group, short mask);
|
||||
|
||||
virtual void removeRigidBody(btRigidBody* body);
|
||||
|
||||
void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
|
||||
|
||||
virtual void setConstraintSolver(btConstraintSolver* solver);
|
||||
|
||||
virtual btConstraintSolver* getConstraintSolver();
|
||||
|
||||
virtual int getNumConstraints() const;
|
||||
|
||||
virtual btTypedConstraint* getConstraint(int index) ;
|
||||
|
||||
virtual const btTypedConstraint* getConstraint(int index) const;
|
||||
|
||||
btContactSolverInfo& getSolverInfo()
|
||||
{
|
||||
return m_solverInfo;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
|
||||
|
|
|
@ -1,80 +1,81 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_DYNAMICS_WORLD_H
|
||||
#define BT_DYNAMICS_WORLD_H
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
|
||||
class btTypedConstraint;
|
||||
class btRaycastVehicle;
|
||||
class btConstraintSolver;
|
||||
|
||||
|
||||
///btDynamicsWorld is the baseclass for several dynamics implementation, basic, discrete, parallel, and continuous
|
||||
class btDynamicsWorld : public btCollisionWorld
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase)
|
||||
:btCollisionWorld(dispatcher,broadphase)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btDynamicsWorld()
|
||||
{
|
||||
}
|
||||
|
||||
///stepSimulation proceeds the simulation over timeStep units
|
||||
///if maxSubSteps > 0, it will interpolate time steps
|
||||
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0;
|
||||
|
||||
virtual void updateAabbs() = 0;
|
||||
|
||||
virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) { (void)constraint;};
|
||||
|
||||
virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;};
|
||||
|
||||
virtual void addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;};
|
||||
|
||||
virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;};
|
||||
|
||||
|
||||
virtual void setDebugDrawer(btIDebugDraw* debugDrawer) = 0;
|
||||
|
||||
virtual btIDebugDraw* getDebugDrawer() = 0;
|
||||
|
||||
//once a rigidbody is added to the dynamics world, it will get this gravity assigned
|
||||
//existing rigidbodies in the world get gravity assigned too, during this method
|
||||
virtual void setGravity(const btVector3& gravity) = 0;
|
||||
|
||||
virtual void addRigidBody(btRigidBody* body) = 0;
|
||||
|
||||
virtual void removeRigidBody(btRigidBody* body) = 0;
|
||||
|
||||
virtual void setConstraintSolver(btConstraintSolver* solver) = 0;
|
||||
|
||||
virtual btConstraintSolver* getConstraintSolver() = 0;
|
||||
|
||||
virtual int getNumConstraints() const { return 0; }
|
||||
|
||||
virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; }
|
||||
|
||||
virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; }
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_DYNAMICS_WORLD_H
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_DYNAMICS_WORLD_H
|
||||
#define BT_DYNAMICS_WORLD_H
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
|
||||
class btTypedConstraint;
|
||||
class btRaycastVehicle;
|
||||
class btConstraintSolver;
|
||||
|
||||
|
||||
///btDynamicsWorld is the baseclass for several dynamics implementation, basic, discrete, parallel, and continuous
|
||||
class btDynamicsWorld : public btCollisionWorld
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase)
|
||||
:btCollisionWorld(dispatcher,broadphase)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btDynamicsWorld()
|
||||
{
|
||||
}
|
||||
|
||||
///stepSimulation proceeds the simulation over timeStep units
|
||||
///if maxSubSteps > 0, it will interpolate time steps
|
||||
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0;
|
||||
|
||||
virtual void updateAabbs() = 0;
|
||||
|
||||
virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) { (void)constraint;};
|
||||
|
||||
virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;};
|
||||
|
||||
virtual void addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;};
|
||||
|
||||
virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;};
|
||||
|
||||
|
||||
virtual void setDebugDrawer(btIDebugDraw* debugDrawer) = 0;
|
||||
virtual void DrawDebug( void ){ }; // called from renderer
|
||||
|
||||
virtual btIDebugDraw* getDebugDrawer() = 0;
|
||||
|
||||
//once a rigidbody is added to the dynamics world, it will get this gravity assigned
|
||||
//existing rigidbodies in the world get gravity assigned too, during this method
|
||||
virtual void setGravity(const btVector3& gravity) = 0;
|
||||
|
||||
virtual void addRigidBody(btRigidBody* body) = 0;
|
||||
|
||||
virtual void removeRigidBody(btRigidBody* body) = 0;
|
||||
|
||||
virtual void setConstraintSolver(btConstraintSolver* solver) = 0;
|
||||
|
||||
virtual btConstraintSolver* getConstraintSolver() = 0;
|
||||
|
||||
virtual int getNumConstraints() const { return 0; }
|
||||
|
||||
virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; }
|
||||
|
||||
virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; }
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_DYNAMICS_WORLD_H
|
||||
|
||||
|
|
|
@ -1,321 +1,318 @@
|
|||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef SIMD__QUATERNION_H_
|
||||
#define SIMD__QUATERNION_H_
|
||||
|
||||
#include "btVector3.h"
|
||||
|
||||
class btQuaternion : public btQuadWord {
|
||||
public:
|
||||
btQuaternion() {}
|
||||
|
||||
// template <typename btScalar>
|
||||
// explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
|
||||
|
||||
btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w)
|
||||
: btQuadWord(x, y, z, w)
|
||||
{}
|
||||
|
||||
btQuaternion(const btVector3& axis, const btScalar& angle)
|
||||
{
|
||||
setRotation(axis, angle);
|
||||
}
|
||||
|
||||
btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
setEuler(yaw, pitch, roll);
|
||||
}
|
||||
|
||||
void setRotation(const btVector3& axis, const btScalar& angle)
|
||||
{
|
||||
btScalar d = axis.length();
|
||||
assert(d != btScalar(0.0));
|
||||
btScalar s = btSin(angle * btScalar(0.5)) / d;
|
||||
setValue(axis.x() * s, axis.y() * s, axis.z() * s,
|
||||
btCos(angle * btScalar(0.5)));
|
||||
}
|
||||
|
||||
void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
|
||||
btScalar halfPitch = btScalar(pitch) * btScalar(0.5);
|
||||
btScalar halfRoll = btScalar(roll) * btScalar(0.5);
|
||||
btScalar cosYaw = btCos(halfYaw);
|
||||
btScalar sinYaw = btSin(halfYaw);
|
||||
btScalar cosPitch = btCos(halfPitch);
|
||||
btScalar sinPitch = btSin(halfPitch);
|
||||
btScalar cosRoll = btCos(halfRoll);
|
||||
btScalar sinRoll = btSin(halfRoll);
|
||||
setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
|
||||
cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
|
||||
sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
|
||||
cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
|
||||
}
|
||||
|
||||
btQuaternion& operator+=(const btQuaternion& q)
|
||||
{
|
||||
m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW;
|
||||
return *this;
|
||||
}
|
||||
|
||||
btQuaternion& operator-=(const btQuaternion& q)
|
||||
{
|
||||
m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW;
|
||||
return *this;
|
||||
}
|
||||
|
||||
btQuaternion& operator*=(const btScalar& s)
|
||||
{
|
||||
m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
btQuaternion& operator*=(const btQuaternion& q)
|
||||
{
|
||||
setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(),
|
||||
m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(),
|
||||
m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(),
|
||||
m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z());
|
||||
return *this;
|
||||
}
|
||||
|
||||
btScalar dot(const btQuaternion& q) const
|
||||
{
|
||||
return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW;
|
||||
}
|
||||
|
||||
btScalar length2() const
|
||||
{
|
||||
return dot(*this);
|
||||
}
|
||||
|
||||
btScalar length() const
|
||||
{
|
||||
return btSqrt(length2());
|
||||
}
|
||||
|
||||
btQuaternion& normalize()
|
||||
{
|
||||
return *this /= length();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btScalar& s) const
|
||||
{
|
||||
return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
btQuaternion operator/(const btScalar& s) const
|
||||
{
|
||||
assert(s != btScalar(0.0));
|
||||
return *this * (btScalar(1.0) / s);
|
||||
}
|
||||
|
||||
|
||||
btQuaternion& operator/=(const btScalar& s)
|
||||
{
|
||||
assert(s != btScalar(0.0));
|
||||
return *this *= btScalar(1.0) / s;
|
||||
}
|
||||
|
||||
|
||||
btQuaternion normalized() const
|
||||
{
|
||||
return *this / length();
|
||||
}
|
||||
|
||||
btScalar angle(const btQuaternion& q) const
|
||||
{
|
||||
btScalar s = btSqrt(length2() * q.length2());
|
||||
assert(s != btScalar(0.0));
|
||||
return btAcos(dot(q) / s);
|
||||
}
|
||||
|
||||
btScalar getAngle() const
|
||||
{
|
||||
btScalar s = btScalar(2.) * btAcos(m_unusedW);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
btQuaternion inverse() const
|
||||
{
|
||||
return btQuaternion(m_x, m_y, m_z, -m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator+(const btQuaternion& q2) const
|
||||
{
|
||||
const btQuaternion& q1 = *this;
|
||||
return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator-(const btQuaternion& q2) const
|
||||
{
|
||||
const btQuaternion& q1 = *this;
|
||||
return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion operator-() const
|
||||
{
|
||||
const btQuaternion& q2 = *this;
|
||||
return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
|
||||
{
|
||||
btQuaternion diff,sum;
|
||||
diff = *this - qd;
|
||||
sum = *this + qd;
|
||||
if( diff.dot(diff) > sum.dot(sum) )
|
||||
return qd;
|
||||
return (-qd);
|
||||
}
|
||||
|
||||
btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
|
||||
{
|
||||
btScalar theta = angle(q);
|
||||
if (theta != btScalar(0.0))
|
||||
{
|
||||
btScalar d = btScalar(1.0) / btSin(theta);
|
||||
btScalar s0 = btSin((btScalar(1.0) - t) * theta);
|
||||
btScalar s1 = btSin(t * theta);
|
||||
return btQuaternion((m_x * s0 + q.x() * s1) * d,
|
||||
(m_y * s0 + q.y() * s1) * d,
|
||||
(m_z * s0 + q.z() * s1) * d,
|
||||
(m_unusedW * s0 + q.m_unusedW * s1) * d);
|
||||
}
|
||||
else
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator-(const btQuaternion& q)
|
||||
{
|
||||
return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btQuaternion& q1, const btQuaternion& q2) {
|
||||
return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
|
||||
q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
|
||||
q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
|
||||
q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btQuaternion& q, const btVector3& w)
|
||||
{
|
||||
return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
|
||||
q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
|
||||
q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
|
||||
-q.x() * w.x() - q.y() * w.y() - q.z() * w.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btVector3& w, const btQuaternion& q)
|
||||
{
|
||||
return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(),
|
||||
w.y() * q.w() + w.z() * q.x() - w.x() * q.z(),
|
||||
w.z() * q.w() + w.x() * q.y() - w.y() * q.x(),
|
||||
-w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
dot(const btQuaternion& q1, const btQuaternion& q2)
|
||||
{
|
||||
return q1.dot(q2);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
length(const btQuaternion& q)
|
||||
{
|
||||
return q.length();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
angle(const btQuaternion& q1, const btQuaternion& q2)
|
||||
{
|
||||
return q1.angle(q2);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
inverse(const btQuaternion& q)
|
||||
{
|
||||
return q.inverse();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
|
||||
{
|
||||
return q1.slerp(q2, t);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
quatRotate(const btQuaternion& rotation, const btVector3& v)
|
||||
{
|
||||
btQuaternion q = rotation * v;
|
||||
q *= rotation.inverse();
|
||||
return btVector3(q.getX(),q.getY(),q.getZ());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized
|
||||
{
|
||||
btVector3 c = v0.cross(v1);
|
||||
btScalar d = v0.dot(v1);
|
||||
|
||||
if (d < -1.0 + SIMD_EPSILON)
|
||||
return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector
|
||||
|
||||
btScalar s = btSqrt((1.0f + d) * 2.0f);
|
||||
btScalar rs = 1.0f / s;
|
||||
|
||||
return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
shortestArcQuatNormalize2(btVector3& v0,btVector3& v1)
|
||||
{
|
||||
v0.normalize();
|
||||
v1.normalize();
|
||||
return shortestArcQuat(v0,v1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef SIMD__QUATERNION_H_
|
||||
#define SIMD__QUATERNION_H_
|
||||
|
||||
#include "btVector3.h"
|
||||
|
||||
class btQuaternion : public btQuadWord {
|
||||
public:
|
||||
btQuaternion() {}
|
||||
|
||||
// template <typename btScalar>
|
||||
// explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
|
||||
|
||||
btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) : btQuadWord(x, y, z, w) {}
|
||||
|
||||
btQuaternion(const btVector3& axis, const btScalar& angle)
|
||||
{
|
||||
setRotation(axis, angle);
|
||||
}
|
||||
|
||||
btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
setEuler(yaw, pitch, roll);
|
||||
}
|
||||
|
||||
void setRotation(const btVector3& axis, const btScalar& angle)
|
||||
{
|
||||
btScalar d = axis.length();
|
||||
assert(d != btScalar(0.0));
|
||||
btScalar s = btSin(angle * btScalar(0.5)) / d;
|
||||
setValue(axis.x() * s, axis.y() * s, axis.z() * s, btCos(angle * btScalar(0.5)));
|
||||
}
|
||||
|
||||
void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
|
||||
{
|
||||
btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
|
||||
btScalar halfPitch = btScalar(pitch) * btScalar(0.5);
|
||||
btScalar halfRoll = btScalar(roll) * btScalar(0.5);
|
||||
btScalar cosYaw = btCos(halfYaw);
|
||||
btScalar sinYaw = btSin(halfYaw);
|
||||
btScalar cosPitch = btCos(halfPitch);
|
||||
btScalar sinPitch = btSin(halfPitch);
|
||||
btScalar cosRoll = btCos(halfRoll);
|
||||
btScalar sinRoll = btSin(halfRoll);
|
||||
setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
|
||||
cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
|
||||
sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
|
||||
cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
|
||||
}
|
||||
|
||||
btQuaternion& operator+=(const btQuaternion& q)
|
||||
{
|
||||
m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW;
|
||||
return *this;
|
||||
}
|
||||
|
||||
btQuaternion& operator-=(const btQuaternion& q)
|
||||
{
|
||||
m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW;
|
||||
return *this;
|
||||
}
|
||||
|
||||
btQuaternion& operator*=(const btScalar& s)
|
||||
{
|
||||
m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
btQuaternion& operator*=(const btQuaternion& q)
|
||||
{
|
||||
setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(),
|
||||
m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(),
|
||||
m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(),
|
||||
m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z());
|
||||
return *this;
|
||||
}
|
||||
|
||||
btScalar dot(const btQuaternion& q) const
|
||||
{
|
||||
return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW;
|
||||
}
|
||||
|
||||
btScalar length2() const
|
||||
{
|
||||
return dot(*this);
|
||||
}
|
||||
|
||||
btScalar length() const
|
||||
{
|
||||
return btSqrt(length2());
|
||||
}
|
||||
|
||||
btQuaternion& normalize()
|
||||
{
|
||||
return *this /= length();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btScalar& s) const
|
||||
{
|
||||
return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
btQuaternion operator/(const btScalar& s) const
|
||||
{
|
||||
assert(s != btScalar(0.0));
|
||||
return *this * (btScalar(1.0) / s);
|
||||
}
|
||||
|
||||
|
||||
btQuaternion& operator/=(const btScalar& s)
|
||||
{
|
||||
assert(s != btScalar(0.0));
|
||||
return *this *= btScalar(1.0) / s;
|
||||
}
|
||||
|
||||
|
||||
btQuaternion normalized() const
|
||||
{
|
||||
return *this / length();
|
||||
}
|
||||
|
||||
btScalar angle(const btQuaternion& q) const
|
||||
{
|
||||
btScalar s = btSqrt(length2() * q.length2());
|
||||
assert(s != btScalar(0.0));
|
||||
return btAcos(dot(q) / s);
|
||||
}
|
||||
|
||||
btScalar getAngle() const
|
||||
{
|
||||
btScalar s = btScalar(2.) * btAcos(m_unusedW);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
btQuaternion inverse() const
|
||||
{
|
||||
return btQuaternion(m_x, m_y, m_z, -m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator+(const btQuaternion& q2) const
|
||||
{
|
||||
const btQuaternion& q1 = *this;
|
||||
return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator-(const btQuaternion& q2) const
|
||||
{
|
||||
const btQuaternion& q1 = *this;
|
||||
return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion operator-() const
|
||||
{
|
||||
const btQuaternion& q2 = *this;
|
||||
return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
|
||||
{
|
||||
btQuaternion diff,sum;
|
||||
diff = *this - qd;
|
||||
sum = *this + qd;
|
||||
if( diff.dot(diff) > sum.dot(sum) )
|
||||
return qd;
|
||||
return (-qd);
|
||||
}
|
||||
|
||||
btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
|
||||
{
|
||||
btScalar theta = angle(q);
|
||||
if (theta != btScalar(0.0))
|
||||
{
|
||||
btScalar d = btScalar(1.0) / btSin(theta);
|
||||
btScalar s0 = btSin((btScalar(1.0) - t) * theta);
|
||||
btScalar s1 = btSin(t * theta);
|
||||
return btQuaternion((m_x * s0 + q.x() * s1) * d,
|
||||
(m_y * s0 + q.y() * s1) * d,
|
||||
(m_z * s0 + q.z() * s1) * d,
|
||||
(m_unusedW * s0 + q.m_unusedW * s1) * d);
|
||||
}
|
||||
else
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator-(const btQuaternion& q)
|
||||
{
|
||||
return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btQuaternion& q1, const btQuaternion& q2) {
|
||||
return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
|
||||
q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
|
||||
q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
|
||||
q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btQuaternion& q, const btVector3& w)
|
||||
{
|
||||
return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
|
||||
q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
|
||||
q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
|
||||
-q.x() * w.x() - q.y() * w.y() - q.z() * w.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
operator*(const btVector3& w, const btQuaternion& q)
|
||||
{
|
||||
return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(),
|
||||
w.y() * q.w() + w.z() * q.x() - w.x() * q.z(),
|
||||
w.z() * q.w() + w.x() * q.y() - w.y() * q.x(),
|
||||
-w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
dot(const btQuaternion& q1, const btQuaternion& q2)
|
||||
{
|
||||
return q1.dot(q2);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
length(const btQuaternion& q)
|
||||
{
|
||||
return q.length();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar
|
||||
angle(const btQuaternion& q1, const btQuaternion& q2)
|
||||
{
|
||||
return q1.angle(q2);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
inverse(const btQuaternion& q)
|
||||
{
|
||||
return q.inverse();
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
|
||||
{
|
||||
return q1.slerp(q2, t);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
quatRotate(const btQuaternion& rotation, const btVector3& v)
|
||||
{
|
||||
btQuaternion q = rotation * v;
|
||||
q *= rotation.inverse();
|
||||
return btVector3(q.getX(),q.getY(),q.getZ());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized
|
||||
{
|
||||
btVector3 c = v0.cross(v1);
|
||||
btScalar d = v0.dot(v1);
|
||||
|
||||
if (d < -1.0 + SIMD_EPSILON)
|
||||
return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector
|
||||
|
||||
btScalar s = btSqrt((1.0f + d) * 2.0f);
|
||||
btScalar rs = 1.0f / s;
|
||||
|
||||
return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btQuaternion
|
||||
shortestArcQuatNormalize2(btVector3& v0,btVector3& v1)
|
||||
{
|
||||
v0.normalize();
|
||||
v1.normalize();
|
||||
return shortestArcQuat(v0,v1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,391 +1,391 @@
|
|||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef SIMD___SCALAR_H
|
||||
#define SIMD___SCALAR_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cfloat>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
|
||||
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) a
|
||||
#else
|
||||
#define BT_HAS_ALIGNED_ALLOCATOR
|
||||
#pragma warning(disable:4530)
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4786)
|
||||
#define SIMD_FORCE_INLINE __forceinline
|
||||
#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
|
||||
#ifdef _XBOX
|
||||
#define BT_USE_VMX128
|
||||
|
||||
#include <ppcintrinsics.h>
|
||||
#define BT_HAVE_NATIVE_FSEL
|
||||
#define btFsel(a,b,c) __fsel((a),(b),(c))
|
||||
#else
|
||||
#define BT_USE_SSE
|
||||
#endif
|
||||
#endif //__MINGW32__
|
||||
|
||||
#include <assert.h>
|
||||
#define btAssert assert
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#if defined (__CELLOS_LV2__)
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define btAssert assert
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_LIBSPE2
|
||||
|
||||
#define SIMD_FORCE_INLINE __inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define btAssert assert
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
|
||||
#define btLikely(_c) __builtin_expect((_c), 1)
|
||||
#define btUnlikely(_c) __builtin_expect((_c), 0)
|
||||
|
||||
|
||||
#else
|
||||
//non-windows systems
|
||||
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) a
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define btAssert assert
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
|
||||
#endif // LIBSPE2
|
||||
|
||||
#endif //__CELLOS_LV2__
|
||||
#endif
|
||||
|
||||
/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
|
||||
/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor)
|
||||
#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
|
||||
//use slow double float precision operation on those platforms
|
||||
#ifndef BT_USE_DOUBLE_PRECISION
|
||||
#define BT_FORCE_DOUBLE_FUNCTIONS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BT_USE_DOUBLE_PRECISION)
|
||||
typedef double btScalar;
|
||||
#else
|
||||
typedef float btScalar;
|
||||
#endif
|
||||
|
||||
|
||||
#define BT_DECLARE_ALIGNED_ALLOCATOR() \
|
||||
SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \
|
||||
SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \
|
||||
SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \
|
||||
SIMD_FORCE_INLINE void operator delete(void*, void*) { } \
|
||||
|
||||
|
||||
|
||||
#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
|
||||
SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
|
||||
SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
|
||||
SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
|
||||
SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
|
||||
SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
|
||||
SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
|
||||
SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
|
||||
|
||||
#else
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
|
||||
{
|
||||
#ifdef USE_APPROXIMATION
|
||||
double x, z, tempf;
|
||||
unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
|
||||
|
||||
tempf = y;
|
||||
*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
|
||||
x = tempf;
|
||||
z = y*btScalar(0.5); /* hoist out the “/2” */
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
return x*y;
|
||||
#else
|
||||
return sqrtf(y);
|
||||
#endif
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAcos(btScalar x) {
|
||||
btAssert(x <= btScalar(1.));
|
||||
return acosf(x);
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
|
||||
SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
|
||||
|
||||
#endif
|
||||
|
||||
#define SIMD_2_PI btScalar(6.283185307179586232)
|
||||
#define SIMD_PI (SIMD_2_PI * btScalar(0.5))
|
||||
#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25))
|
||||
#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
|
||||
#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI)
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define SIMD_EPSILON DBL_EPSILON
|
||||
#define SIMD_INFINITY DBL_MAX
|
||||
#else
|
||||
#define SIMD_EPSILON FLT_EPSILON
|
||||
#define SIMD_INFINITY FLT_MAX
|
||||
#endif
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
|
||||
{
|
||||
btScalar coeff_1 = SIMD_PI / 4.0f;
|
||||
btScalar coeff_2 = 3.0f * coeff_1;
|
||||
btScalar abs_y = btFabs(y);
|
||||
btScalar angle;
|
||||
if (x >= 0.0f) {
|
||||
btScalar r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
btScalar r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
|
||||
|
||||
SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) {
|
||||
return (((a) <= eps) && !((a) < -eps));
|
||||
}
|
||||
SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) {
|
||||
return (!((a) <= eps));
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btIsNegative(btScalar x) {
|
||||
return x < btScalar(0.0) ? 1 : 0;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
|
||||
SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
|
||||
|
||||
#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
|
||||
|
||||
#ifndef btFsel
|
||||
SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
|
||||
{
|
||||
return a >= 0 ? b : c;
|
||||
}
|
||||
#endif
|
||||
#define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
|
||||
{
|
||||
long int i = 1;
|
||||
const char *p = (const char *) &i;
|
||||
if (p[0] == 1) // Lowest address contains the least significant byte
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
|
||||
///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
|
||||
SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
|
||||
{
|
||||
// Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
|
||||
// Rely on positive value or'ed with its negative having sign bit on
|
||||
// and zero value or'ed with its negative (which is still zero) having sign bit off
|
||||
// Use arithmetic shift right, shifting the sign bit through all 32 bits
|
||||
unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
|
||||
unsigned testEqz = ~testNz;
|
||||
return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
|
||||
}
|
||||
SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
|
||||
{
|
||||
unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
|
||||
unsigned testEqz = ~testNz;
|
||||
return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
|
||||
}
|
||||
SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
|
||||
{
|
||||
#ifdef BT_HAVE_NATIVE_FSEL
|
||||
return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
|
||||
#else
|
||||
return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
|
||||
{
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
|
||||
//PCK: endian swapping functions
|
||||
SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
|
||||
{
|
||||
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
|
||||
{
|
||||
return (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
|
||||
{
|
||||
return btSwapEndian((unsigned)val);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
|
||||
{
|
||||
return btSwapEndian((unsigned short) val);
|
||||
}
|
||||
|
||||
///btSwapFloat uses using char pointers to swap the endianness
|
||||
////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
|
||||
///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754.
|
||||
///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception.
|
||||
///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you.
|
||||
///so instead of returning a float/double, we return integer/long long integer
|
||||
SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d)
|
||||
{
|
||||
unsigned int a;
|
||||
unsigned char *dst = (unsigned char *)&a;
|
||||
unsigned char *src = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
// unswap using char pointers
|
||||
SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a)
|
||||
{
|
||||
float d;
|
||||
unsigned char *src = (unsigned char *)&a;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
// swap using char pointers
|
||||
SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst)
|
||||
{
|
||||
unsigned char *src = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[7];
|
||||
dst[1] = src[6];
|
||||
dst[2] = src[5];
|
||||
dst[3] = src[4];
|
||||
dst[4] = src[3];
|
||||
dst[5] = src[2];
|
||||
dst[6] = src[1];
|
||||
dst[7] = src[0];
|
||||
|
||||
}
|
||||
|
||||
// unswap using char pointers
|
||||
SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src)
|
||||
{
|
||||
double d;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[7];
|
||||
dst[1] = src[6];
|
||||
dst[2] = src[5];
|
||||
dst[3] = src[4];
|
||||
dst[4] = src[3];
|
||||
dst[5] = src[2];
|
||||
dst[6] = src[1];
|
||||
dst[7] = src[0];
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
#endif //SIMD___SCALAR_H
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef SIMD___SCALAR_H
|
||||
#define SIMD___SCALAR_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cfloat>
|
||||
#include <float.h>
|
||||
#include "physic.h"
|
||||
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
|
||||
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) a
|
||||
#else
|
||||
#define BT_HAS_ALIGNED_ALLOCATOR
|
||||
#pragma warning(disable:4530)
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4786)
|
||||
#define SIMD_FORCE_INLINE __forceinline
|
||||
#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
|
||||
#ifdef _XBOX
|
||||
#define BT_USE_VMX128
|
||||
|
||||
#include <ppcintrinsics.h>
|
||||
#define BT_HAVE_NATIVE_FSEL
|
||||
#define btFsel(a,b,c) __fsel((a),(b),(c))
|
||||
#else
|
||||
#define BT_USE_SSE
|
||||
#endif
|
||||
#endif //__MINGW32__
|
||||
|
||||
#include <assert.h>
|
||||
#define btAssert(x) if(!(x)) Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ );
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#if defined (__CELLOS_LV2__)
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define btAssert assert
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
#define btLikely(_c) _c
|
||||
#define btUnlikely(_c) _c
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_LIBSPE2
|
||||
|
||||
#define SIMD_FORCE_INLINE __inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
|
||||
#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define btAssert assert
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
|
||||
#define btLikely(_c) __builtin_expect((_c), 1)
|
||||
#define btUnlikely(_c) __builtin_expect((_c), 0)
|
||||
|
||||
|
||||
#else
|
||||
//non-windows systems
|
||||
|
||||
#define SIMD_FORCE_INLINE inline
|
||||
#define ATTRIBUTE_ALIGNED16(a) a
|
||||
#define ATTRIBUTE_ALIGNED128(a) a
|
||||
#ifndef assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#define btAssert assert
|
||||
//btFullAssert is optional, slows down a lot
|
||||
#define btFullAssert(x)
|
||||
|
||||
|
||||
#endif // LIBSPE2
|
||||
|
||||
#endif //__CELLOS_LV2__
|
||||
#endif
|
||||
|
||||
/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
|
||||
/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor)
|
||||
#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
|
||||
//use slow double float precision operation on those platforms
|
||||
#ifndef BT_USE_DOUBLE_PRECISION
|
||||
#define BT_FORCE_DOUBLE_FUNCTIONS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BT_USE_DOUBLE_PRECISION)
|
||||
typedef double btScalar;
|
||||
#else
|
||||
typedef float btScalar;
|
||||
#endif
|
||||
|
||||
|
||||
#define BT_DECLARE_ALIGNED_ALLOCATOR() \
|
||||
SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \
|
||||
SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \
|
||||
SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \
|
||||
SIMD_FORCE_INLINE void operator delete(void*, void*) { } \
|
||||
|
||||
|
||||
|
||||
#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
|
||||
SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
|
||||
SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
|
||||
SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
|
||||
SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
|
||||
SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
|
||||
SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
|
||||
SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
|
||||
|
||||
#else
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
|
||||
{
|
||||
#ifdef USE_APPROXIMATION
|
||||
double x, z, tempf;
|
||||
unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
|
||||
|
||||
tempf = y;
|
||||
*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
|
||||
x = tempf;
|
||||
z = y*btScalar(0.5); /* hoist out the “/2” */
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
x = (btScalar(1.5)*x)-(x*x)*(x*z);
|
||||
return x*y;
|
||||
#else
|
||||
return sqrtf(y);
|
||||
#endif
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAcos(btScalar x) {
|
||||
btAssert(x <= btScalar(1.));
|
||||
return acosf(x);
|
||||
}
|
||||
SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
|
||||
SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
|
||||
SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
|
||||
|
||||
#endif
|
||||
|
||||
#define SIMD_2_PI btScalar(6.283185307179586232)
|
||||
#define SIMD_PI (SIMD_2_PI * btScalar(0.5))
|
||||
#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25))
|
||||
#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
|
||||
#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI)
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define SIMD_EPSILON DBL_EPSILON
|
||||
#define SIMD_INFINITY DBL_MAX
|
||||
#else
|
||||
#define SIMD_EPSILON FLT_EPSILON
|
||||
#define SIMD_INFINITY FLT_MAX
|
||||
#endif
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x)
|
||||
{
|
||||
btScalar coeff_1 = SIMD_PI / 4.0f;
|
||||
btScalar coeff_2 = 3.0f * coeff_1;
|
||||
btScalar abs_y = btFabs(y);
|
||||
btScalar angle;
|
||||
if (x >= 0.0f) {
|
||||
btScalar r = (x - abs_y) / (x + abs_y);
|
||||
angle = coeff_1 - coeff_1 * r;
|
||||
} else {
|
||||
btScalar r = (x + abs_y) / (abs_y - x);
|
||||
angle = coeff_2 - coeff_1 * r;
|
||||
}
|
||||
return (y < 0.0f) ? -angle : angle;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
|
||||
|
||||
SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) {
|
||||
return (((a) <= eps) && !((a) < -eps));
|
||||
}
|
||||
SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) {
|
||||
return (!((a) <= eps));
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btIsNegative(btScalar x) {
|
||||
return x < btScalar(0.0) ? 1 : 0;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
|
||||
SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
|
||||
|
||||
#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
|
||||
|
||||
#ifndef btFsel
|
||||
SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
|
||||
{
|
||||
return a >= 0 ? b : c;
|
||||
}
|
||||
#endif
|
||||
#define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
|
||||
{
|
||||
long int i = 1;
|
||||
const char *p = (const char *) &i;
|
||||
if (p[0] == 1) // Lowest address contains the least significant byte
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
|
||||
///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
|
||||
SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero)
|
||||
{
|
||||
// Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
|
||||
// Rely on positive value or'ed with its negative having sign bit on
|
||||
// and zero value or'ed with its negative (which is still zero) having sign bit off
|
||||
// Use arithmetic shift right, shifting the sign bit through all 32 bits
|
||||
unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
|
||||
unsigned testEqz = ~testNz;
|
||||
return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
|
||||
}
|
||||
SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
|
||||
{
|
||||
unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
|
||||
unsigned testEqz = ~testNz;
|
||||
return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
|
||||
}
|
||||
SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
|
||||
{
|
||||
#ifdef BT_HAVE_NATIVE_FSEL
|
||||
return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
|
||||
#else
|
||||
return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
|
||||
{
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
|
||||
//PCK: endian swapping functions
|
||||
SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
|
||||
{
|
||||
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
|
||||
{
|
||||
return (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
|
||||
{
|
||||
return btSwapEndian((unsigned)val);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
|
||||
{
|
||||
return btSwapEndian((unsigned short) val);
|
||||
}
|
||||
|
||||
///btSwapFloat uses using char pointers to swap the endianness
|
||||
////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
|
||||
///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754.
|
||||
///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception.
|
||||
///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you.
|
||||
///so instead of returning a float/double, we return integer/long long integer
|
||||
SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d)
|
||||
{
|
||||
unsigned int a;
|
||||
unsigned char *dst = (unsigned char *)&a;
|
||||
unsigned char *src = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
// unswap using char pointers
|
||||
SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a)
|
||||
{
|
||||
float d;
|
||||
unsigned char *src = (unsigned char *)&a;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[3];
|
||||
dst[1] = src[2];
|
||||
dst[2] = src[1];
|
||||
dst[3] = src[0];
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
// swap using char pointers
|
||||
SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst)
|
||||
{
|
||||
unsigned char *src = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[7];
|
||||
dst[1] = src[6];
|
||||
dst[2] = src[5];
|
||||
dst[3] = src[4];
|
||||
dst[4] = src[3];
|
||||
dst[5] = src[2];
|
||||
dst[6] = src[1];
|
||||
dst[7] = src[0];
|
||||
|
||||
}
|
||||
|
||||
// unswap using char pointers
|
||||
SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src)
|
||||
{
|
||||
double d;
|
||||
unsigned char *dst = (unsigned char *)&d;
|
||||
|
||||
dst[0] = src[7];
|
||||
dst[1] = src[6];
|
||||
dst[2] = src[5];
|
||||
dst[3] = src[4];
|
||||
dst[4] = src[3];
|
||||
dst[5] = src[2];
|
||||
dst[6] = src[1];
|
||||
dst[7] = src[0];
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
#endif //SIMD___SCALAR_H
|
||||
|
|
|
@ -1,206 +1,212 @@
|
|||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef btTransform_H
|
||||
#define btTransform_H
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btMatrix3x3.h"
|
||||
|
||||
|
||||
///btTransform supports rigid transforms (only translation and rotation, no scaling/shear)
|
||||
class btTransform {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
btTransform() {}
|
||||
|
||||
explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q,
|
||||
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
|
||||
: m_basis(q),
|
||||
m_origin(c)
|
||||
{}
|
||||
|
||||
explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b,
|
||||
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
|
||||
: m_basis(b),
|
||||
m_origin(c)
|
||||
{}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform (const btTransform& other)
|
||||
: m_basis(other.m_basis),
|
||||
m_origin(other.m_origin)
|
||||
{
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
|
||||
{
|
||||
m_basis = other.m_basis;
|
||||
m_origin = other.m_origin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
|
||||
m_basis = t1.m_basis * t2.m_basis;
|
||||
m_origin = t1(t2.m_origin);
|
||||
}
|
||||
|
||||
/* void multInverseLeft(const btTransform& t1, const btTransform& t2) {
|
||||
btVector3 v = t2.m_origin - t1.m_origin;
|
||||
m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis);
|
||||
m_origin = v * t1.m_basis;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
|
||||
{
|
||||
return btVector3(m_basis[0].dot(x) + m_origin.x(),
|
||||
m_basis[1].dot(x) + m_origin.y(),
|
||||
m_basis[2].dot(x) + m_origin.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
|
||||
{
|
||||
return (*this)(x);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; }
|
||||
SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; }
|
||||
|
||||
SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; }
|
||||
SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; }
|
||||
|
||||
btQuaternion getRotation() const {
|
||||
btQuaternion q;
|
||||
m_basis.getRotation(q);
|
||||
return q;
|
||||
}
|
||||
template <typename Scalar2>
|
||||
void setValue(const Scalar2 *m)
|
||||
{
|
||||
m_basis.setValue(m);
|
||||
m_origin.setValue(&m[12]);
|
||||
}
|
||||
|
||||
|
||||
void setFromOpenGLMatrix(const btScalar *m)
|
||||
{
|
||||
m_basis.setFromOpenGLSubMatrix(m);
|
||||
m_origin.setValue(m[12],m[13],m[14]);
|
||||
}
|
||||
|
||||
void getOpenGLMatrix(btScalar *m) const
|
||||
{
|
||||
m_basis.getOpenGLSubMatrix(m);
|
||||
m[12] = m_origin.x();
|
||||
m[13] = m_origin.y();
|
||||
m[14] = m_origin.z();
|
||||
m[15] = btScalar(1.0);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
|
||||
{
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const;
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
|
||||
{
|
||||
m_basis = basis;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
|
||||
{
|
||||
m_basis.setRotation(q);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setIdentity()
|
||||
{
|
||||
m_basis.setIdentity();
|
||||
m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
|
||||
}
|
||||
|
||||
|
||||
btTransform& operator*=(const btTransform& t)
|
||||
{
|
||||
m_origin += m_basis * t.m_origin;
|
||||
m_basis *= t.m_basis;
|
||||
return *this;
|
||||
}
|
||||
|
||||
btTransform inverse() const
|
||||
{
|
||||
btMatrix3x3 inv = m_basis.transpose();
|
||||
return btTransform(inv, inv * -m_origin);
|
||||
}
|
||||
|
||||
btTransform inverseTimes(const btTransform& t) const;
|
||||
|
||||
btTransform operator*(const btTransform& t) const;
|
||||
|
||||
static btTransform getIdentity()
|
||||
{
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
return tr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
btMatrix3x3 m_basis;
|
||||
btVector3 m_origin;
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
btTransform::invXform(const btVector3& inVec) const
|
||||
{
|
||||
btVector3 v = inVec - m_origin;
|
||||
return (m_basis.transpose() * v);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform
|
||||
btTransform::inverseTimes(const btTransform& t) const
|
||||
{
|
||||
btVector3 v = t.getOrigin() - m_origin;
|
||||
return btTransform(m_basis.transposeTimes(t.m_basis),
|
||||
v * m_basis);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform
|
||||
btTransform::operator*(const btTransform& t) const
|
||||
{
|
||||
return btTransform(m_basis * t.m_basis,
|
||||
(*this)(t.m_origin));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef btTransform_H
|
||||
#define btTransform_H
|
||||
|
||||
#include "btVector3.h"
|
||||
#include "btMatrix3x3.h"
|
||||
|
||||
|
||||
///btTransform supports rigid transforms (only translation and rotation, no scaling/shear)
|
||||
class btTransform {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
btTransform() {}
|
||||
|
||||
explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q,
|
||||
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
|
||||
: m_basis(q),
|
||||
m_origin(c)
|
||||
{}
|
||||
|
||||
explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b,
|
||||
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
|
||||
: m_basis(b),
|
||||
m_origin(c)
|
||||
{}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform (const btTransform& other)
|
||||
: m_basis(other.m_basis),
|
||||
m_origin(other.m_origin)
|
||||
{
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
|
||||
{
|
||||
m_basis = other.m_basis;
|
||||
m_origin = other.m_origin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
|
||||
m_basis = t1.m_basis * t2.m_basis;
|
||||
m_origin = t1(t2.m_origin);
|
||||
}
|
||||
|
||||
/* void multInverseLeft(const btTransform& t1, const btTransform& t2) {
|
||||
btVector3 v = t2.m_origin - t1.m_origin;
|
||||
m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis);
|
||||
m_origin = v * t1.m_basis;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
|
||||
{
|
||||
return btVector3(m_basis[0].dot(x) + m_origin.x(),
|
||||
m_basis[1].dot(x) + m_origin.y(),
|
||||
m_basis[2].dot(x) + m_origin.z());
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
|
||||
{
|
||||
return (*this)(x);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; }
|
||||
SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; }
|
||||
|
||||
SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; }
|
||||
SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; }
|
||||
|
||||
btQuaternion getRotation() const {
|
||||
btQuaternion q;
|
||||
m_basis.getRotation(q);
|
||||
return q;
|
||||
}
|
||||
|
||||
void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const
|
||||
{
|
||||
m_basis.getEuler(yaw, pitch, roll);
|
||||
}
|
||||
|
||||
template <typename Scalar2>
|
||||
void setValue(const Scalar2 *m)
|
||||
{
|
||||
m_basis.setValue(m);
|
||||
m_origin.setValue(&m[12]);
|
||||
}
|
||||
|
||||
|
||||
void setFromOpenGLMatrix(const btScalar *m)
|
||||
{
|
||||
m_basis.setFromOpenGLSubMatrix(m);
|
||||
m_origin.setValue(m[12],m[13],m[14]);
|
||||
}
|
||||
|
||||
void getOpenGLMatrix(btScalar *m) const
|
||||
{
|
||||
m_basis.getOpenGLSubMatrix(m);
|
||||
m[12] = m_origin.x();
|
||||
m[13] = m_origin.y();
|
||||
m[14] = m_origin.z();
|
||||
m[15] = btScalar(1.0);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
|
||||
{
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const;
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
|
||||
{
|
||||
m_basis = basis;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
|
||||
{
|
||||
m_basis.setRotation(q);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setIdentity()
|
||||
{
|
||||
m_basis.setIdentity();
|
||||
m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
|
||||
}
|
||||
|
||||
|
||||
btTransform& operator*=(const btTransform& t)
|
||||
{
|
||||
m_origin += m_basis * t.m_origin;
|
||||
m_basis *= t.m_basis;
|
||||
return *this;
|
||||
}
|
||||
|
||||
btTransform inverse() const
|
||||
{
|
||||
btMatrix3x3 inv = m_basis.transpose();
|
||||
return btTransform(inv, inv * -m_origin);
|
||||
}
|
||||
|
||||
btTransform inverseTimes(const btTransform& t) const;
|
||||
|
||||
btTransform operator*(const btTransform& t) const;
|
||||
|
||||
static btTransform getIdentity()
|
||||
{
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
return tr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
btMatrix3x3 m_basis;
|
||||
btVector3 m_origin;
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btVector3
|
||||
btTransform::invXform(const btVector3& inVec) const
|
||||
{
|
||||
btVector3 v = inVec - m_origin;
|
||||
return (m_basis.transpose() * v);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform
|
||||
btTransform::inverseTimes(const btTransform& t) const
|
||||
{
|
||||
btVector3 v = t.getOrigin() - m_origin;
|
||||
return btTransform(m_basis.transposeTimes(t.m_basis),
|
||||
v * m_basis);
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE btTransform
|
||||
btTransform::operator*(const btTransform& t) const
|
||||
{
|
||||
return btTransform(m_basis * t.m_basis,
|
||||
(*this)(t.m_origin));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btBulletBspLoader.h"
|
||||
#include "btBulletWorld.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
int extrasize = 100;
|
||||
|
||||
bool BspLoader::loadBSPFile( uint* memoryBuffer)
|
||||
{
|
||||
dheader_t *header = (dheader_t*)memoryBuffer;
|
||||
|
||||
// load the file header
|
||||
if (header)
|
||||
{
|
||||
// swap the header
|
||||
swapBlock( (int *)header, sizeof(*header));
|
||||
|
||||
int length = (header->lumps[LUMP_MODELS].filelen) / sizeof(dmodel_t);
|
||||
m_dmodels.resize(length + extrasize);
|
||||
m_nummodels = copyLump( header, LUMP_MODELS, &m_dmodels[0], sizeof(dmodel_t));
|
||||
|
||||
length = (header->lumps[LUMP_PLANES].filelen) / sizeof(dplane_t);
|
||||
m_dplanes.resize(length + extrasize);
|
||||
m_numplanes = copyLump( header, LUMP_PLANES, &m_dplanes[0], sizeof(dplane_t));
|
||||
|
||||
length = (header->lumps[LUMP_LEAFS].filelen) / sizeof(dleaf_t);
|
||||
m_dleafs.resize(length + extrasize);
|
||||
m_numleafs = copyLump( header, LUMP_LEAFS, &m_dleafs[0], sizeof(dleaf_t));
|
||||
|
||||
length = (header->lumps[LUMP_NODES].filelen) / sizeof(dnode_t);
|
||||
m_dnodes.resize(length + extrasize);
|
||||
m_numnodes = copyLump( header, LUMP_NODES, &m_dnodes[0], sizeof(dnode_t));
|
||||
|
||||
length = (header->lumps[LUMP_LEAFFACES].filelen) / sizeof(m_dleafsurfaces[0]);
|
||||
m_dleafsurfaces.resize(length + extrasize);
|
||||
m_numleafsurfaces = copyLump( header, LUMP_LEAFFACES, &m_dleafsurfaces[0], sizeof(m_dleafsurfaces[0]));
|
||||
|
||||
length = (header->lumps[LUMP_LEAFBRUSHES].filelen) / sizeof(m_dleafbrushes[0]) ;
|
||||
m_dleafbrushes.resize(length+extrasize);
|
||||
m_numleafbrushes = copyLump( header, LUMP_LEAFBRUSHES, &m_dleafbrushes[0], sizeof(m_dleafbrushes[0]));
|
||||
|
||||
length = (header->lumps[LUMP_BRUSHES].filelen) / sizeof(dbrush_t);
|
||||
m_dbrushes.resize(length+extrasize);
|
||||
m_numbrushes = copyLump( header, LUMP_BRUSHES, &m_dbrushes[0], sizeof(dbrush_t));
|
||||
|
||||
|
||||
length = (header->lumps[LUMP_BRUSHSIDES].filelen) / sizeof(dbrushside_t);
|
||||
m_dbrushsides.resize(length+extrasize);
|
||||
m_numbrushsides = copyLump( header, LUMP_BRUSHSIDES, &m_dbrushsides[0], sizeof(dbrushside_t));
|
||||
|
||||
// swap everything
|
||||
//swapBSPFile();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BspLoader::convertBsp( float scale )
|
||||
{
|
||||
for (int i = 0; i < m_numleafs; i++)
|
||||
{
|
||||
Msg("Reading bspLeaf %i from total %i (%f procent)\n", i, m_numleafs, (100.f*(float)i/float(m_numleafs)));
|
||||
|
||||
bool isValidBrush = false;
|
||||
dleaf_t& leaf = m_dleafs[i];
|
||||
|
||||
for (int b = 0; b < leaf.numleafbrushes; b++)
|
||||
{
|
||||
btAlignedObjectArray<btVector3> planeEquations;
|
||||
|
||||
int brushid = m_dleafbrushes[leaf.firstleafbrush + b];
|
||||
dbrush_t& brush = m_dbrushes[brushid];
|
||||
if(brush.contents & CONTENTS_SOLID)
|
||||
{
|
||||
for (int p = 0; p < brush.numsides; p++)
|
||||
{
|
||||
int sideid = brush.firstside + p;
|
||||
dbrushside_t& brushside = m_dbrushsides[sideid];
|
||||
int planeid = brushside.planenum;
|
||||
dplane_t& plane = m_dplanes[planeid];
|
||||
btVector3 planeEq;
|
||||
planeEq.setValue( plane.normal[0], plane.normal[2], plane.normal[1], scale * -plane.dist);
|
||||
planeEquations.push_back(planeEq);
|
||||
isValidBrush = true;
|
||||
}
|
||||
if (isValidBrush)
|
||||
{
|
||||
btAlignedObjectArray<btVector3> vertices;
|
||||
btGeometryUtil::getVerticesFromPlaneEquations(planeEquations, vertices);
|
||||
addConvexVerticesCollider( vertices );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BspLoader::addConvexVerticesCollider( btAlignedObjectArray<btVector3>& vertices )
|
||||
{
|
||||
// perhaps we can do something special with entities (isEntity)
|
||||
// like adding a collision Triggering (as example)
|
||||
|
||||
if (vertices.size() > 0)
|
||||
{
|
||||
btTransform startTransform;
|
||||
startTransform.setIdentity();
|
||||
startTransform.setOrigin(btVector3(0, 0, 0));
|
||||
|
||||
// this create an internal copy of the vertices
|
||||
btCollisionShape* shape = new btConvexHullShape(&(vertices[0].getX()), vertices.size());
|
||||
g_PhysWorld->AddStaticRigidBody(startTransform, shape);
|
||||
}
|
||||
}
|
||||
|
||||
int BspLoader::copyLump( dheader_t *header, int lump, void *dest, int size )
|
||||
{
|
||||
int length, ofs;
|
||||
|
||||
length = header->lumps[lump].filelen;
|
||||
ofs = header->lumps[lump].fileofs;
|
||||
Mem_Copy( dest, (byte *)header + ofs, length );
|
||||
|
||||
return length / size;
|
||||
}
|
||||
|
||||
void BspLoader::swapBlock( int *block, int sizeOfBlock )
|
||||
{
|
||||
int i;
|
||||
|
||||
sizeOfBlock >>= 2;
|
||||
for ( i = 0; i < sizeOfBlock; i++ )
|
||||
{
|
||||
block[i] = LittleLong( block[i] );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BSP_LOADER_H
|
||||
#define BSP_LOADER_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btGeometryUtil.h"
|
||||
#include "physic.h"
|
||||
|
||||
class BspLoader
|
||||
{
|
||||
public:
|
||||
BspLoader(){ } // constructor
|
||||
|
||||
bool loadBSPFile( uint* memoryBuffer);
|
||||
void convertBsp( float scale );
|
||||
|
||||
int copyLump( dheader_t *header, int lump, void *dest, int size );
|
||||
void swapBlock( int *block, int sizeOfBlock );
|
||||
void addConvexVerticesCollider( btAlignedObjectArray<btVector3>& vertices );
|
||||
|
||||
int m_nummodels;
|
||||
btAlignedObjectArray<dmodel_t> m_dmodels;
|
||||
|
||||
int m_numleafs;
|
||||
btAlignedObjectArray<dleaf_t> m_dleafs;
|
||||
|
||||
int m_numplanes;
|
||||
btAlignedObjectArray<dplane_t> m_dplanes;
|
||||
|
||||
int m_numnodes;
|
||||
btAlignedObjectArray<dnode_t> m_dnodes;
|
||||
|
||||
int m_numleafsurfaces;
|
||||
btAlignedObjectArray<short> m_dleafsurfaces;
|
||||
|
||||
int m_numleafbrushes;
|
||||
btAlignedObjectArray<word> m_dleafbrushes;
|
||||
|
||||
int m_numbrushes;
|
||||
btAlignedObjectArray<dbrush_t> m_dbrushes;
|
||||
|
||||
int m_numbrushsides;
|
||||
btAlignedObjectArray<dbrushside_t> m_dbrushsides;
|
||||
|
||||
int m_numPhysSurfaces;
|
||||
btAlignedObjectArray<csurface_t> m_physSurfaces;
|
||||
};
|
||||
#endif//BSP_LOADER_H
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "BulletDynamics/Dynamics/btDynamicsWorld.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btBoxShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btUniformScalingShape.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "LinearMath/btDefaultMotionState.h"
|
||||
#include "btBulletWorld.h"
|
||||
|
||||
CM_Debug DebugDrawer;
|
||||
|
||||
btBulletPhysic::btBulletPhysic(): m_World(0), m_numBodies(0), m_debugMode(0), m_WorldScale(METERS_PER_INCH)
|
||||
{
|
||||
btVector3 m_worldAabbMin(-1000, -1000, -1000), m_worldAabbMax(1000, 1000, 1000);
|
||||
|
||||
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
btDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
|
||||
btBroadphaseInterface* pairCache = new btAxisSweep3(m_worldAabbMin, m_worldAabbMax);
|
||||
btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver();
|
||||
|
||||
m_World = new btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver);
|
||||
m_World->getDispatchInfo().m_enableSPU = true;
|
||||
m_World->setGravity(btVector3(0, -9.8, 0));
|
||||
m_World->setDebugDrawer(&DebugDrawer);
|
||||
|
||||
m_debugMode |= btIDebugDraw::DBG_DrawAabb;
|
||||
m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
|
||||
}
|
||||
|
||||
btBulletPhysic::~btBulletPhysic()
|
||||
{
|
||||
DeleteAllBodies();
|
||||
}
|
||||
|
||||
void btBulletPhysic::DeleteAllBodies( void )
|
||||
{
|
||||
int numObj = m_World->getNumCollisionObjects();
|
||||
|
||||
for(int i = numObj; i > 0; i--)
|
||||
{
|
||||
btCollisionObject* obj = m_World->getCollisionObjectArray()[i-1];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
m_World->removeRigidBody( body );
|
||||
m_World->removeCollisionObject(obj);
|
||||
m_numBodies--;
|
||||
}
|
||||
}
|
||||
|
||||
btRigidBody* btBulletPhysic::AddDynamicRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape)
|
||||
{
|
||||
// rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
if(!mass) return AddStaticRigidBody(startTransform, shape);
|
||||
|
||||
btVector3 localInertia(0,0,0);
|
||||
shape->calculateLocalInertia(mass, localInertia);
|
||||
btDefaultMotionState* m_State = new btDefaultMotionState( startTransform );
|
||||
btRigidBody* m_body = new btRigidBody(mass, m_State, shape, localInertia );
|
||||
m_World->addRigidBody(m_body);
|
||||
m_numBodies++;
|
||||
|
||||
return m_body;
|
||||
}
|
||||
|
||||
btRigidBody* btBulletPhysic::AddStaticRigidBody(const btTransform& startTransform,btCollisionShape* shape)
|
||||
{
|
||||
btVector3 localInertia(0,0,0);
|
||||
btDefaultMotionState* m_State = new btDefaultMotionState(startTransform);
|
||||
btRigidBody* m_body = new btRigidBody(0.f, m_State, shape);
|
||||
m_World->addRigidBody(m_body);
|
||||
m_numBodies++;
|
||||
|
||||
return m_body;
|
||||
}
|
||||
|
||||
bool btBulletPhysic::ApplyTransform( btRigidBody* body)
|
||||
{
|
||||
if(!body) return false;
|
||||
|
||||
sv_edict_t *edict = GetUserData( body );
|
||||
if(!edict) return false;
|
||||
vec3_t origin, angles;
|
||||
|
||||
GetTransform( body, origin, angles );
|
||||
|
||||
pi.Transform( edict, origin, angles );
|
||||
return true;
|
||||
}
|
||||
|
||||
void btBulletPhysic::PhysicFrame( void )
|
||||
{
|
||||
if(m_World)
|
||||
{
|
||||
int numObjects = m_World->getNumCollisionObjects();
|
||||
Msg("total bodies %d, realnum %d\n", m_numBodies, numObjects );
|
||||
for (int i = 0; i < numObjects; i++)
|
||||
{
|
||||
btCollisionObject* colObj = m_World->getCollisionObjectArray()[i];
|
||||
btRigidBody* body = btRigidBody::upcast(colObj);
|
||||
|
||||
if(body && body->getMotionState()) ApplyTransform( body );
|
||||
else
|
||||
{
|
||||
// world
|
||||
}
|
||||
|
||||
if(colObj->getActivationState() == 1) // active
|
||||
{
|
||||
}
|
||||
if(colObj->getActivationState() == 2) // sleeping
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void btBulletPhysic::UpdateWorld( float timeStep )
|
||||
{
|
||||
m_World->stepSimulation( 0.1 );
|
||||
|
||||
if (m_World->getDebugDrawer())
|
||||
m_World->getDebugDrawer()->setDebugMode( m_debugMode );
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_BULLET_WORLD_H
|
||||
#define BT_BULLET_WORLD_H
|
||||
|
||||
#include "btBulletBspLoader.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
class CM_Debug : public btIDebugDraw
|
||||
{
|
||||
int m_debugMode;
|
||||
|
||||
public:
|
||||
virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
|
||||
{
|
||||
if(m_debugMode > 0)
|
||||
{
|
||||
vec3_t start, end, col;
|
||||
|
||||
// convert to Xash vec3_t
|
||||
VectorSet( start, from.getX(), from.getY(), from.getZ());
|
||||
VectorSet( end, to.getX(), to.getY(), to.getZ());
|
||||
VectorSet( col, color.getX(), color.getY(), color.getZ());
|
||||
|
||||
TransformRGB( col, col );
|
||||
ConvertPositionToGame( start );
|
||||
ConvertPositionToGame( end );
|
||||
|
||||
pi.DrawLine( col, start, end );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void drawContactPoint(const btVector3& pointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)
|
||||
{
|
||||
if (m_debugMode & btIDebugDraw::DBG_DrawContactPoints)
|
||||
{
|
||||
btVector3 to = pointOnB+normalOnB*distance;
|
||||
const btVector3&from = pointOnB;
|
||||
vec3_t start, end, col;
|
||||
|
||||
// convert to Xash vec3_t
|
||||
VectorSet( start, from.getX(), from.getY(), from.getZ());
|
||||
VectorSet( end, to.getX(), to.getY(), to.getZ());
|
||||
VectorSet( col, color.getX(), color.getY(), color.getZ());
|
||||
|
||||
TransformRGB( col, col );
|
||||
ConvertPositionToGame( start );
|
||||
ConvertPositionToGame( end );
|
||||
|
||||
pi.DrawLine( col, start, end );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void reportErrorWarning(const char* warningString)
|
||||
{
|
||||
MsgWarn( warningString );
|
||||
}
|
||||
|
||||
virtual void setDebugMode(int debugMode) { m_debugMode = debugMode; }
|
||||
virtual int getDebugMode() const { return m_debugMode;}
|
||||
};
|
||||
|
||||
class btBulletPhysic
|
||||
{
|
||||
protected:
|
||||
// physic world
|
||||
btDynamicsWorld* m_World;
|
||||
btClock m_clock;
|
||||
|
||||
int m_debugMode; // replace with cvar
|
||||
float m_WorldScale; // convert units to meters
|
||||
int m_numBodies;
|
||||
public:
|
||||
|
||||
btBulletPhysic();
|
||||
virtual ~btBulletPhysic();
|
||||
|
||||
btDynamicsWorld* getWorld( void )
|
||||
{
|
||||
return m_World;
|
||||
}
|
||||
|
||||
int getDebugMode( void )
|
||||
{
|
||||
return m_debugMode ;
|
||||
}
|
||||
|
||||
void setDebugMode( int mode )
|
||||
{
|
||||
m_debugMode = mode;
|
||||
}
|
||||
|
||||
void DrawDebug( void )
|
||||
{
|
||||
m_World->DrawDebug();
|
||||
}
|
||||
|
||||
float getScale( void )
|
||||
{
|
||||
return m_WorldScale;
|
||||
}
|
||||
|
||||
btRigidBody* AddStaticRigidBody(const btTransform& startTransform,btCollisionShape* shape); // bodies with infinite mass
|
||||
btRigidBody* AddDynamicRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape);
|
||||
void DelRigidBody(btRigidBody* body)
|
||||
{
|
||||
if( body )m_World->removeRigidBody( body );
|
||||
}
|
||||
|
||||
void SetUserData( btRigidBody* body, sv_edict_t *entity )
|
||||
{
|
||||
body->setUserPointer( entity );
|
||||
}
|
||||
|
||||
sv_edict_t *GetUserData( btRigidBody* body )
|
||||
{
|
||||
return (sv_edict_t *)body->getUserPointer();
|
||||
}
|
||||
|
||||
// set body angles and origin
|
||||
void SetOrigin(btRigidBody* body, const vec3_t origin )
|
||||
{
|
||||
btVector3 pos(INCH2METER(origin[0]), INCH2METER(origin[2]), INCH2METER(origin[1]));
|
||||
|
||||
btTransform worldTrans = body->getWorldTransform();
|
||||
worldTrans.setOrigin(pos);
|
||||
body->setWorldTransform(worldTrans);
|
||||
}
|
||||
|
||||
void SetAngles(btRigidBody* body, const vec3_t angles )
|
||||
{
|
||||
btQuaternion q;
|
||||
q.setEuler(angles[YAW], angles[PITCH], angles[ROLL]);
|
||||
|
||||
btTransform worldTrans = body->getWorldTransform();
|
||||
worldTrans.setRotation(q);
|
||||
body->setWorldTransform(worldTrans);
|
||||
}
|
||||
|
||||
void SetTransform( btRigidBody* body, vec3_t origin, vec3_t angles )
|
||||
{
|
||||
matrix4x4 matrix;
|
||||
|
||||
MatrixLoadIdentity( matrix );
|
||||
AnglesMatrix( origin, angles, matrix );
|
||||
ConvertPositionToPhysic( matrix[3] );
|
||||
body->getWorldTransform().setFromOpenGLMatrix((float *)matrix);
|
||||
}
|
||||
|
||||
// get body angles and origin
|
||||
void GetTransform( btRigidBody* body, vec3_t origin, vec3_t angles )
|
||||
{
|
||||
matrix4x4 matrix;
|
||||
|
||||
body->getWorldTransform().getOpenGLMatrix((float *)matrix);
|
||||
MatrixAngles( matrix, origin, angles );
|
||||
ConvertPositionToGame( origin );
|
||||
}
|
||||
|
||||
void UpdateWorld( float timescale ); // update simulation state
|
||||
void DeleteAllBodies( void ); // clear scene
|
||||
void PhysicFrame( void ); // update entities transform
|
||||
bool ApplyTransform( btRigidBody* body);// apply transform to current body
|
||||
};
|
||||
|
||||
extern btBulletPhysic *g_PhysWorld;
|
||||
extern void* Palloc( int size );
|
||||
extern void Pfree( void *ptr );
|
||||
|
||||
#endif//BT_BULLET_WORLD_H
|
|
@ -25,6 +25,7 @@ physic_exp_t DLLEXPORT *CreateAPI ( stdlib_api_t *input, physic_imp_t *engfuncs
|
|||
Phys.FreeBSP = Phys_FreeBSP;
|
||||
Phys.DrawCollision = DebugShowCollision;
|
||||
Phys.Frame = Phys_Frame;
|
||||
Phys.Update = Phys_WorldUpdate;
|
||||
Phys.CreateBody = Phys_CreateBody;
|
||||
Phys.RemoveBody = Phys_RemoveBody;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PHYSIC_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /Ob0 /I "../public" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "../public" /I "./" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
|
@ -129,6 +129,14 @@ SOURCE=.\BulletCollision\BroadphaseCollision\btBroadphaseProxy.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\btBulletBspLoader.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\btBulletWorld.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BulletCollision\CollisionShapes\btBvhTriangleMeshShape.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -465,6 +473,10 @@ SOURCE=.\BulletCollision\BroadphaseCollision\btBroadphaseProxy.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\btBulletBspLoader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\btBulletCollisionCommon.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -473,6 +485,10 @@ SOURCE=.\btBulletDynamicsCommon.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\btBulletWorld.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\BulletCollision\CollisionShapes\btBvhTriangleMeshShape.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -20,10 +20,11 @@ extern byte *physpool;
|
|||
|
||||
extern void Phys_LoadBSP( uint *buffer );
|
||||
extern void Phys_FreeBSP( void );
|
||||
extern void DebugShowCollision ( cmdraw_t callback );
|
||||
extern void DebugShowCollision ( void );
|
||||
extern void Phys_Frame( float time );
|
||||
extern void Phys_CreateBody( sv_edict_t *ed, vec3_t mins, vec3_t maxs, vec3_t org, vec3_t ang, int solid, NewtonCollision **newcol, NewtonBody **newbody );
|
||||
extern void Phys_RemoveBody( NewtonBody *body );
|
||||
extern void Phys_WorldUpdate( void );
|
||||
extern physbody_t *Phys_CreateBody( sv_edict_t *ed, vec3_t mins, vec3_t maxs, vec3_t org, vec3_t ang, int solid );
|
||||
extern void Phys_RemoveBody( physbody_t *body );
|
||||
extern bool InitPhysics( void );
|
||||
extern void FreePhysics( void );
|
||||
|
||||
|
|
|
@ -4,18 +4,20 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "physic.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "btBulletWorld.h"
|
||||
|
||||
physic_imp_t pi;
|
||||
stdlib_api_t com;
|
||||
byte *physpool;
|
||||
|
||||
void* Palloc (int size )
|
||||
btBulletPhysic *g_PhysWorld;
|
||||
|
||||
void* Palloc( int size )
|
||||
{
|
||||
return Mem_Alloc( physpool, size );
|
||||
}
|
||||
|
||||
void Pfree (void *ptr, int size )
|
||||
void Pfree( void *ptr )
|
||||
{
|
||||
Mem_Free( ptr );
|
||||
}
|
||||
|
@ -24,34 +26,87 @@ bool InitPhysics( void )
|
|||
{
|
||||
physpool = Mem_AllocPool("Physics Pool");
|
||||
|
||||
// create world
|
||||
g_PhysWorld = new btBulletPhysic();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreePhysics( void )
|
||||
{
|
||||
delete g_PhysWorld;
|
||||
Mem_FreePool( &physpool );
|
||||
}
|
||||
|
||||
void Phys_LoadBSP( uint *buffer )
|
||||
{
|
||||
BspLoader WorldHull;
|
||||
|
||||
WorldHull.loadBSPFile( buffer );
|
||||
WorldHull.convertBsp( g_PhysWorld->getScale());
|
||||
}
|
||||
|
||||
void Phys_FreeBSP( void )
|
||||
{
|
||||
g_PhysWorld->DeleteAllBodies();
|
||||
}
|
||||
|
||||
void Phys_Frame( float time )
|
||||
{
|
||||
g_PhysWorld->UpdateWorld( time );
|
||||
}
|
||||
|
||||
void Phys_CreateBody( sv_edict_t *ed, vec3_t mins, vec3_t maxs, vec3_t org, vec3_t ang, int solid, NewtonCollision **newcol, NewtonBody **newbody )
|
||||
void Phys_WorldUpdate( void )
|
||||
{
|
||||
g_PhysWorld->PhysicFrame();
|
||||
}
|
||||
|
||||
void Phys_RemoveBody( NewtonBody *body )
|
||||
physbody_t *Phys_CreateBody( sv_edict_t *ed, vec3_t mins, vec3_t maxs, vec3_t org, vec3_t ang, int solid )
|
||||
{
|
||||
btCollisionShape *col;
|
||||
vec3_t size, ofs;
|
||||
|
||||
VectorSubtract (maxs, mins, size );
|
||||
ConvertPositionToPhysic( size );
|
||||
VectorAdd( mins, maxs, ofs );
|
||||
ConvertPositionToPhysic( ofs );
|
||||
|
||||
switch( (solid_t)solid )
|
||||
{
|
||||
case SOLID_BOX:
|
||||
col = new btBoxShape(btVector3( size[0]/2, size[1]/2, size[2]/2 ));
|
||||
break;
|
||||
case SOLID_SPHERE:
|
||||
col = new btSphereShape( size[0]/2 );
|
||||
break;
|
||||
case SOLID_CYLINDER:
|
||||
col = new btCylinderShape(btVector3( size[0]/2, size[1]/2, size[0]/2 ));
|
||||
break;
|
||||
case SOLID_MESH:
|
||||
default:
|
||||
Host_Error("Phys_CreateBody: unsupported solid type %d\n", solid );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
btTransform offset;
|
||||
offset.setIdentity();
|
||||
offset.setOrigin(btVector3(0, 0, 0));
|
||||
|
||||
btRigidBody* body = g_PhysWorld->AddDynamicRigidBody( 10.0f, offset, col ); // 10 kg
|
||||
g_PhysWorld->SetUserData( body, ed );
|
||||
|
||||
// move to position
|
||||
g_PhysWorld->SetTransform( body, org, ang );
|
||||
return (physbody_t *)body;
|
||||
}
|
||||
|
||||
void DebugShowCollision ( cmdraw_t callback )
|
||||
void Phys_RemoveBody( physbody_t *object )
|
||||
{
|
||||
btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
|
||||
g_PhysWorld->DelRigidBody( body );
|
||||
}
|
||||
|
||||
void DebugShowCollision ( void )
|
||||
{
|
||||
g_PhysWorld->DrawDebug();
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
entity pev; // Pointer EntVars (same as pev)
|
||||
entity other;
|
||||
entity world;
|
||||
|
||||
|
||||
// timer
|
||||
float time;
|
||||
float frametime;
|
||||
|
@ -281,7 +281,7 @@ enum
|
|||
// edict.solid values
|
||||
enum
|
||||
{
|
||||
SOLID_NOT, // no interaction with other objects
|
||||
SOLID_NOT = 0, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP, // bsp clip, touch on edge
|
||||
|
|
|
@ -159,7 +159,18 @@ void misc_barrel( void )
|
|||
|
||||
precache_model( name );
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_MESH; //test
|
||||
pev->solid = SOLID_CYLINDER; //test
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, name );
|
||||
}
|
||||
|
||||
void misc_sphere( void )
|
||||
{
|
||||
string name = "models/nexplode.mdl";
|
||||
|
||||
precache_model( name );
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_SPHERE; //test
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, name );
|
||||
}
|
||||
|
@ -168,7 +179,7 @@ void item_healthkit( void )
|
|||
{
|
||||
precache_model( "models/w_medkit.mdl" );
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_MESH;
|
||||
pev->solid = SOLID_CYLINDER;
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, "models/w_medkit.mdl" );
|
||||
}
|
||||
|
|
|
@ -105,20 +105,13 @@ typedef struct cl_edict_s cl_edict_t;
|
|||
typedef struct ui_edict_s ui_edict_t;
|
||||
typedef int progsnum_t;
|
||||
typedef struct progfuncs_s progfuncs_t;
|
||||
typedef struct physbody_s physbody_t;
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4];
|
||||
typedef long fs_offset_t;
|
||||
typedef vec_t matrix3x4[3][4];
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
typedef struct physbody_s NewtonBody;
|
||||
typedef struct physworld_s NewtonWorld;
|
||||
typedef struct physjoint_s NewtonJoint;
|
||||
typedef struct physcontact_s NewtonContact;
|
||||
typedef struct physragdoll_s NewtonRagDoll;
|
||||
typedef struct physmaterial_s NewtonMaterial;
|
||||
typedef struct physcolision_s NewtonCollision;
|
||||
typedef struct physragbone_s NewtonRagDollBone;
|
||||
typedef struct { size_t api_size; } generic_api_t;
|
||||
typedef struct { int fileofs; int filelen; } lump_t; // many formats use lumps to store blocks
|
||||
typedef struct { int type; char *name; } activity_map_t; // studio activity map conversion
|
||||
|
@ -127,7 +120,6 @@ typedef struct { byte r:8; byte g:8; byte b:8; } color24;
|
|||
typedef struct { byte r; byte g; byte b; byte a; } color32;
|
||||
typedef struct { const char *name; void **func; } dllfunc_t; // Sys_LoadLibrary stuff
|
||||
typedef struct { int ofs; int type; const char *name; } fields_t; // prvm custom fields
|
||||
typedef void (*cmdraw_t)( int color, int numpoints, const float *points );
|
||||
typedef struct { int numfilenames; char **filenames; char *filenamesbuffer; } search_t;
|
||||
typedef void (*cvarcmd_t)(const char *s, const char *m, const char *d, void *ptr );
|
||||
|
||||
|
|
|
@ -192,6 +192,7 @@ typedef struct render_exp_s
|
|||
void (*SetColor)( const float *rgba );
|
||||
bool (*ScrShot)( const char *filename, bool force_gamma ); // write screenshot with same name
|
||||
void (*DrawFill)(float x, float y, float w, float h );
|
||||
void (*DrawLine)( vec3_t color, vec3_t from, vec3_t to ); // collision debug draw
|
||||
void (*DrawStretchRaw) (int x, int y, int w, int h, int cols, int rows, byte *data, bool redraw );
|
||||
void (*DrawStretchPic)(float x, float y, float w, float h, float s1, float t1, float s2, float t2, char *name);
|
||||
|
||||
|
@ -206,8 +207,7 @@ typedef struct render_imp_s
|
|||
|
||||
// client fundamental callbacks
|
||||
void (*StudioEvent)( mstudioevent_t *event, entity_t *ent );
|
||||
void (*CM_DrawCollision)( cmdraw_t drawfunc );
|
||||
void (*ShowCollision)( void ); // debug
|
||||
void (*DrawCollision)( void ); // debug
|
||||
|
||||
} render_imp_t;
|
||||
|
||||
|
@ -228,12 +228,13 @@ typedef struct physic_exp_s
|
|||
|
||||
void (*LoadBSP)( uint *buf ); // generate tree collision
|
||||
void (*FreeBSP)( void ); // release tree collision
|
||||
void (*DrawCollision)( cmdraw_t callback );// debug
|
||||
void (*DrawCollision)( void );// debug
|
||||
void (*Frame)( float time ); // physics frame
|
||||
void (*Update)( void ); // world frame
|
||||
|
||||
// simple objects
|
||||
void (*CreateBody)( sv_edict_t *ed, vec3_t mins, vec3_t maxs, vec3_t org, vec3_t ang, int solid, NewtonCollision **newcol, NewtonBody **newbody );
|
||||
void (*RemoveBody)( NewtonBody *body );
|
||||
physbody_t *(*CreateBody)( sv_edict_t *ed, vec3_t mins, vec3_t maxs, vec3_t org, vec3_t ang, int solid );
|
||||
void (*RemoveBody)( physbody_t *body );
|
||||
|
||||
} physic_exp_t;
|
||||
|
||||
|
@ -244,7 +245,7 @@ typedef struct physic_imp_s
|
|||
|
||||
void (*Transform)( sv_edict_t *ed, vec3_t origin, vec3_t angles );
|
||||
float *(*GetModelVerts)( sv_edict_t *ent, int *numvertices );
|
||||
|
||||
void (*DrawLine)( vec3_t color, vec3_t from, vec3_t to );
|
||||
} physic_imp_t;
|
||||
|
||||
// this is the only function actually exported at the linker level
|
||||
|
|
143
public/mathlib.h
143
public/mathlib.h
|
@ -342,36 +342,6 @@ _inline void AngleVectorsFLU(const vec3_t angles, vec3_t forward, vec3_t left, v
|
|||
}
|
||||
}
|
||||
|
||||
_inline void MatrixAnglesFLU( const matrix4x4 matrix, vec3_t origin, vec3_t angles )
|
||||
{
|
||||
vec3_t forward, left, up;
|
||||
float xyDist;
|
||||
|
||||
forward[0] = matrix[0][0];
|
||||
forward[1] = matrix[0][1];
|
||||
forward[2] = matrix[0][2];
|
||||
left[0] = matrix[1][0];
|
||||
left[1] = matrix[1][1];
|
||||
left[2] = matrix[1][2];
|
||||
up[2] = matrix[2][2];
|
||||
|
||||
xyDist = sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
|
||||
|
||||
if ( xyDist > EQUAL_EPSILON ) // enough here to get angles?
|
||||
{
|
||||
angles[1] = RAD2DEG( atan2( forward[1], forward[0] ) );
|
||||
angles[0] = RAD2DEG( atan2( -forward[2], xyDist ) );
|
||||
angles[2] = RAD2DEG( atan2( left[2], up[2] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
angles[1] = RAD2DEG( atan2( -left[0], left[1] ) );
|
||||
angles[0] = RAD2DEG( atan2( -forward[2], xyDist ) );
|
||||
angles[2] = 0;
|
||||
}
|
||||
VectorCopy(matrix[3], origin );// extract origin
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
AngleMatrix
|
||||
|
@ -517,12 +487,12 @@ _inline void MatrixAngles( const matrix4x4 matrix, vec3_t origin, vec3_t angles
|
|||
float xyDist;
|
||||
|
||||
forward[0] = matrix[0][0];
|
||||
forward[1] = matrix[0][1];
|
||||
forward[2] = matrix[0][2];
|
||||
forward[1] = matrix[0][2];
|
||||
forward[2] = matrix[0][1];
|
||||
right[0] = matrix[1][0];
|
||||
right[1] = matrix[1][1];
|
||||
right[2] = matrix[1][2];
|
||||
up[2] = matrix[2][2];
|
||||
right[1] = matrix[1][2];
|
||||
right[2] = matrix[1][1];
|
||||
up[2] = matrix[2][1];
|
||||
|
||||
xyDist = sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
|
||||
|
||||
|
@ -541,6 +511,84 @@ _inline void MatrixAngles( const matrix4x4 matrix, vec3_t origin, vec3_t angles
|
|||
VectorCopy(matrix[3], origin );// extract origin
|
||||
}
|
||||
|
||||
_inline void MatrixAnglesFLU( const matrix4x4 matrix, vec3_t origin, vec3_t angles )
|
||||
{
|
||||
vec3_t forward, left, up;
|
||||
float xyDist;
|
||||
|
||||
forward[0] = matrix[0][0];
|
||||
forward[1] = matrix[0][2];
|
||||
forward[2] = matrix[0][1];
|
||||
left[0] = matrix[1][0];
|
||||
left[1] = matrix[1][2];
|
||||
left[2] = matrix[1][1];
|
||||
up[2] = matrix[2][1];
|
||||
|
||||
xyDist = sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
|
||||
|
||||
if ( xyDist > EQUAL_EPSILON ) // enough here to get angles?
|
||||
{
|
||||
angles[1] = RAD2DEG( atan2( forward[1], forward[0] ) );
|
||||
angles[0] = RAD2DEG( atan2( -forward[2], xyDist ) );
|
||||
angles[2] = RAD2DEG( atan2( left[2], up[2] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
angles[1] = RAD2DEG( atan2( -left[0], left[1] ) );
|
||||
angles[0] = RAD2DEG( atan2( -forward[2], xyDist ) );
|
||||
angles[2] = 0;
|
||||
}
|
||||
VectorCopy(matrix[3], origin );// extract origin
|
||||
}
|
||||
|
||||
_inline void AnglesMatrix(const vec3_t origin, const vec3_t angles, matrix4x4 matrix )
|
||||
{
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
angle = angles[YAW] * (M_PI*2 / 360);
|
||||
sy = sin(angle);
|
||||
cy = cos(angle);
|
||||
angle = angles[PITCH] * (M_PI*2 / 360);
|
||||
sp = sin(angle);
|
||||
cp = cos(angle);
|
||||
|
||||
// forward
|
||||
matrix[0][0] = cp*cy;
|
||||
matrix[0][2] = cp*sy;
|
||||
matrix[0][1] = -sp;
|
||||
|
||||
if (angles[ROLL])
|
||||
{
|
||||
angle = angles[ROLL] * (M_PI*2 / 360);
|
||||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
// right
|
||||
matrix[1][0] = -1*(sr*sp*cy+cr*-sy);
|
||||
matrix[1][2] = -1*(sr*sp*sy+cr*cy);
|
||||
matrix[1][1] = -1*(sr*cp);
|
||||
|
||||
// up
|
||||
matrix[2][0] = (cr*sp*cy+-sr*-sy);
|
||||
matrix[2][2] = (cr*sp*sy+-sr*cy);
|
||||
matrix[2][1] = cr*cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// right
|
||||
matrix[1][0] = sy;
|
||||
matrix[1][2] = -cy;
|
||||
matrix[1][1] = 0;
|
||||
|
||||
// up
|
||||
matrix[2][0] = (sp*cy);
|
||||
matrix[2][2] = (sp*sy);
|
||||
matrix[2][1] = cp;
|
||||
}
|
||||
VectorCopy(origin, matrix[3] ); // pack origin
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -548,7 +596,7 @@ AngleQuaternion
|
|||
|
||||
====================
|
||||
*/
|
||||
_inline void AngleQuaternion( float *angles, vec4_t quaternion )
|
||||
_inline void AngleQuaternion( float *angles, vec4_t q )
|
||||
{
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
@ -564,12 +612,27 @@ _inline void AngleQuaternion( float *angles, vec4_t quaternion )
|
|||
sr = sin(angle);
|
||||
cr = cos(angle);
|
||||
|
||||
quaternion[0] = sr*cp*cy-cr*sp*sy; // X
|
||||
quaternion[1] = cr*sp*cy+sr*cp*sy; // Y
|
||||
quaternion[2] = cr*cp*sy-sr*sp*cy; // Z
|
||||
quaternion[3] = cr*cp*cy+sr*sp*sy; // W
|
||||
q[0] = sr*cp*cy-cr*sp*sy; // X
|
||||
q[1] = cr*sp*cy+sr*cp*sy; // Y
|
||||
q[2] = cr*cp*sy-sr*sp*cy; // Z
|
||||
q[3] = cr*cp*cy+sr*sp*sy; // W
|
||||
}
|
||||
|
||||
_inline void QuaternionAngles( vec4_t q, vec3_t angles )
|
||||
{
|
||||
float m11, m12, m13, m23, m33;
|
||||
|
||||
m11 = ( 2.0f * q[3] * q[3] ) + ( 2.0f * q[0] * q[0] ) - 1.0f;
|
||||
m12 = ( 2.0f * q[0] * q[1] ) + ( 2.0f * q[3] * q[2] );
|
||||
m13 = ( 2.0f * q[0] * q[2] ) - ( 2.0f * q[3] * q[1] );
|
||||
m23 = ( 2.0f * q[1] * q[2] ) + ( 2.0f * q[3] * q[0] );
|
||||
m33 = ( 2.0f * q[3] * q[3] ) + ( 2.0f * q[2] * q[2] ) - 1.0f;
|
||||
|
||||
// FIXME: this code has a singularity near PITCH +-90
|
||||
angles[YAW] = RAD2DEG( atan2(m12, m11));
|
||||
angles[PITCH] = RAD2DEG( asin(-m13));
|
||||
angles[ROLL] = RAD2DEG( atan2(m23, m33));
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
|
|
|
@ -1855,7 +1855,7 @@ typedef enum
|
|||
// phys collision mode
|
||||
typedef enum
|
||||
{
|
||||
SOLID_NOT, // no interaction with other objects
|
||||
SOLID_NOT = 0, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP, // bsp clip, touch on edge
|
||||
|
@ -1874,8 +1874,10 @@ typedef struct physdata_s
|
|||
vec3_t mins; // for calculate size
|
||||
vec3_t maxs; // and setup offset matrix
|
||||
|
||||
NewtonCollision *collision; // ptr to collision mesh
|
||||
NewtonBody *physbody; // ptr to physic body
|
||||
int movetype; // moving type
|
||||
int hulltype; // solid type
|
||||
|
||||
physbody_t *body; // ptr to physic body
|
||||
} physdata_t;
|
||||
|
||||
/*
|
||||
|
|
|
@ -61,9 +61,9 @@ if exist launch\launch.plg del /f /q launch\launch.plg
|
|||
if exist common\common.plg del /f /q common\common.plg
|
||||
if exist physic\physic.plg del /f /q physic\physic.plg
|
||||
if exist render\render.plg del /f /q render\render.plg
|
||||
if exist pr_server\server.dat move pr_server\server.dat D:\Xash3D\xash\vprogs\server.dat
|
||||
if exist pr_client\client.dat move pr_client\client.dat D:\Xash3D\xash\vprogs\client.dat
|
||||
if exist pr_uimenu\uimenu.dat move pr_uimenu\uimenu.dat D:\Xash3D\xash\vprogs\uimenu.dat
|
||||
if exist temp\server.dat move temp\server.dat D:\Xash3D\xash\vprogs\server.dat
|
||||
if exist temp\client.dat move temp\client.dat D:\Xash3D\xash\vprogs\client.dat
|
||||
if exist temp\uimenu.dat move temp\uimenu.dat D:\Xash3D\xash\vprogs\uimenu.dat
|
||||
if exist compile.log del /f /q compile.log
|
||||
|
||||
echo Build succeeded!
|
||||
|
|
|
@ -667,24 +667,13 @@ void R_Flash( void )
|
|||
R_PolyBlend ();
|
||||
}
|
||||
|
||||
static void R_DrawLine( int color, int numpoints, const float *points )
|
||||
static void R_DrawLine( vec3_t color, vec3_t start, vec3_t end )
|
||||
{
|
||||
int i = numpoints - 1;
|
||||
vec3_t p0, p1;
|
||||
|
||||
VectorSet(p0, points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
|
||||
ConvertPositionToGame( p0 );
|
||||
|
||||
for (i = 0; i < numpoints; i ++)
|
||||
{
|
||||
VectorSet(p1, points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
|
||||
ConvertPositionToGame( p1 );
|
||||
|
||||
qglVertex3fv(p0);
|
||||
qglVertex3fv(p1);
|
||||
|
||||
VectorCopy(p1, p0);
|
||||
}
|
||||
qglBegin(GL_LINES);
|
||||
qglColor3f(color[0], color[1], color[2]);
|
||||
qglVertex3d(start[0], start[1], start[2]);
|
||||
qglVertex3d(end[0], end[1], end[2]);
|
||||
qglEnd();
|
||||
}
|
||||
|
||||
void R_DebugGraphics( void )
|
||||
|
@ -694,15 +683,8 @@ void R_DebugGraphics( void )
|
|||
|
||||
if(r_physbdebug->integer)
|
||||
{
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
qglColor3f (1, 0.7f, 0);
|
||||
qglBegin(GL_LINES);
|
||||
|
||||
// physic debug
|
||||
ri.CM_DrawCollision( R_DrawLine );
|
||||
|
||||
qglEnd();
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
ri.DrawCollision();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1582,6 +1564,7 @@ render_exp_t DLLEXPORT *CreateAPI(stdlib_api_t *input, render_imp_t *engfuncs )
|
|||
re.SetColor = GL_SetColor;
|
||||
re.ScrShot = VID_ScreenShot;
|
||||
re.DrawFill = Draw_Fill;
|
||||
re.DrawLine = R_DrawLine;
|
||||
re.DrawStretchRaw = Draw_StretchRaw;
|
||||
re.DrawStretchPic = Draw_StretchPic;
|
||||
|
||||
|
|
Reference in New Issue