06 Dec 2007

This commit is contained in:
g-cont 2007-12-06 00:00:00 +03:00 committed by Alibek Omarov
parent f139116d59
commit 94d044bb27
31 changed files with 2583 additions and 1915 deletions

View File

@ -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
//==================================================

View File

@ -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

View File

@ -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 );

View File

@ -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;

View File

@ -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 );
}
}
}

View File

@ -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);

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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] );
}
}

View File

@ -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

139
physic/btBulletWorld.cpp Normal file
View File

@ -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 );
}

182
physic/btBulletWorld.h Normal file
View File

@ -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

View File

@ -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;

View File

@ -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

View 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 );

View File

@ -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();
}

View File

@ -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

View File

@ -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" );
}

View File

@ -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 );

View File

@ -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

View File

@ -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));
}
/*
====================

View File

@ -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;
/*

View File

@ -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!

View File

@ -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;