Try to add some ragdoll joints to the bullet plugin.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5518 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
a6ec9fd9b5
commit
87fdee2282
1 changed files with 161 additions and 233 deletions
|
@ -135,19 +135,22 @@ class QCFilterCallback : public btOverlapFilterCallback
|
|||
//owners don't collide (unless one is world, obviouslyish)
|
||||
if (collides)
|
||||
{
|
||||
btRigidBody *b1 = (btRigidBody*)proxy0->m_clientObject;
|
||||
btRigidBody *b2 = (btRigidBody*)proxy1->m_clientObject;
|
||||
auto b1 = (btRigidBody*)proxy0->m_clientObject;
|
||||
auto b2 = (btRigidBody*)proxy1->m_clientObject;
|
||||
//don't let two qc-controlled entities collide in Bullet, that's the job of quake.
|
||||
if (b1->isStaticOrKinematicObject() && b2->isStaticOrKinematicObject())
|
||||
return false;
|
||||
wedict_t *e1 = (wedict_t*)b1->getUserPointer();
|
||||
wedict_t *e2 = (wedict_t*)b2->getUserPointer();
|
||||
auto e1 = (wedict_t*)b1->getUserPointer();
|
||||
auto e2 = (wedict_t*)b2->getUserPointer();
|
||||
if (e1&&e2)
|
||||
{
|
||||
if ((e1->v->solid == SOLID_TRIGGER && e2->v->solid != SOLID_BSP) ||
|
||||
(e2->v->solid == SOLID_TRIGGER && e1->v->solid != SOLID_BSP))
|
||||
return false; //triggers only collide with bsp objects.
|
||||
if (e1->entnum && e2->entnum)
|
||||
collides = e1->v->owner != e2->entnum && e2->v->owner != e1->entnum;
|
||||
}
|
||||
}
|
||||
|
||||
return collides;
|
||||
}
|
||||
|
@ -155,8 +158,8 @@ class QCFilterCallback : public btOverlapFilterCallback
|
|||
|
||||
static void QDECL World_Bullet_End(world_t *world)
|
||||
{
|
||||
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
||||
world->rbe = NULL;
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
world->rbe = nullptr;
|
||||
delete ctx->dworld;
|
||||
delete ctx->solver;
|
||||
delete ctx->collisionconfig;
|
||||
|
@ -176,7 +179,7 @@ static void QDECL World_Bullet_RemoveJointFromEntity(world_t *world, wedict_t *e
|
|||
|
||||
static void QDECL World_Bullet_RemoveFromEntity(world_t *world, wedict_t *ed)
|
||||
{
|
||||
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
btRigidBody *body;
|
||||
btCollisionShape *geom;
|
||||
if (!ed->rbe.physics)
|
||||
|
@ -202,115 +205,6 @@ static void QDECL World_Bullet_RemoveFromEntity(world_t *world, wedict_t *ed)
|
|||
ed->rbe.massbuf = NULL;
|
||||
}
|
||||
|
||||
static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
|
||||
{
|
||||
return;
|
||||
|
||||
#if 0
|
||||
model_t *model;
|
||||
const float *avel;
|
||||
const float *o;
|
||||
const float *r; // for some reason dBodyGetRotation returns a [3][4] matrix
|
||||
const float *vel;
|
||||
btRigidBody *body = (btRigidBody*)ed->rbe.body.body;
|
||||
int movetype;
|
||||
float bodymatrix[16];
|
||||
float entitymatrix[16];
|
||||
vec3_t angles;
|
||||
vec3_t avelocity;
|
||||
vec3_t forward, left, up;
|
||||
vec3_t origin;
|
||||
vec3_t spinvelocity;
|
||||
vec3_t velocity;
|
||||
if (!body)
|
||||
return;
|
||||
|
||||
movetype = (int)ed->v->movetype;
|
||||
if (movetype != MOVETYPE_PHYSICS)
|
||||
{
|
||||
switch((int)ed->xv->jointtype)
|
||||
{
|
||||
// TODO feed back data from physics
|
||||
case JOINTTYPE_POINT:
|
||||
break;
|
||||
case JOINTTYPE_HINGE:
|
||||
break;
|
||||
case JOINTTYPE_SLIDER:
|
||||
break;
|
||||
case JOINTTYPE_UNIVERSAL:
|
||||
break;
|
||||
case JOINTTYPE_HINGE2:
|
||||
break;
|
||||
case JOINTTYPE_FIXED:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// store the physics engine data into the entity
|
||||
|
||||
btTransform trans;
|
||||
body->getMotionState()->getWorldTransform(trans);
|
||||
// o = dBodyGetPosition(body);
|
||||
// r = dBodyGetRotation(body);
|
||||
// vel = dBodyGetLinearVel(body);
|
||||
// avel = dBodyGetAngularVel(body);
|
||||
// VectorCopy(o, origin);
|
||||
// forward[0] = r[0];
|
||||
// forward[1] = r[4];
|
||||
// forward[2] = r[8];
|
||||
// left[0] = r[1];
|
||||
// left[1] = r[5];
|
||||
// left[2] = r[9];
|
||||
// up[0] = r[2];
|
||||
// up[1] = r[6];
|
||||
// up[2] = r[10];
|
||||
vel = body->getLinearVelocity();
|
||||
avel = body->getAngularVelocity();
|
||||
VectorCopy(vel, velocity);
|
||||
VectorCopy(avel, spinvelocity);
|
||||
trans.getBasis().getOpenGLSubMatrix(bodymatrix);
|
||||
foo Matrix4x4_RM_FromVectors(bodymatrix, forward, left, up, origin);
|
||||
foo Matrix4_Multiply(ed->rbe.offsetimatrix, bodymatrix, entitymatrix);
|
||||
foo Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin);
|
||||
|
||||
VectorAngles(forward, up, angles);
|
||||
angles[0]*=-1;
|
||||
|
||||
avelocity[PITCH] = RAD2DEG(spinvelocity[PITCH]);
|
||||
avelocity[YAW] = RAD2DEG(spinvelocity[ROLL]);
|
||||
avelocity[ROLL] = RAD2DEG(spinvelocity[YAW]);
|
||||
|
||||
if (ed->v->modelindex)
|
||||
{
|
||||
model = world->Get_CModel(world, ed->v->modelindex);
|
||||
if (!model || model->type == mod_alias)
|
||||
{
|
||||
angles[PITCH] *= -1;
|
||||
avelocity[PITCH] *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy(origin, ed->v->origin);
|
||||
VectorCopy(velocity, ed->v->velocity);
|
||||
//VectorCopy(forward, ed->xv->axis_forward);
|
||||
//VectorCopy(left, ed->xv->axis_left);
|
||||
//VectorCopy(up, ed->xv->axis_up);
|
||||
//VectorCopy(spinvelocity, ed->xv->spinvelocity);
|
||||
VectorCopy(angles, ed->v->angles);
|
||||
VectorCopy(avelocity, ed->v->avelocity);
|
||||
|
||||
// values for BodyFromEntity to check if the qc modified anything later
|
||||
VectorCopy(origin, ed->rbe.origin);
|
||||
VectorCopy(velocity, ed->rbe.velocity);
|
||||
VectorCopy(angles, ed->rbe.angles);
|
||||
VectorCopy(avelocity, ed->rbe.avelocity);
|
||||
// ed->rbe.gravity = (qboolean)dBodyGetGravityMode(body);
|
||||
|
||||
World_LinkEdict(world, ed, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static bool NegativeMeshPitch(world_t *world, wedict_t *ent)
|
||||
{
|
||||
if (ent->v->modelindex)
|
||||
|
@ -340,10 +234,10 @@ static btTransform transformFromQuake(world_t *world, wedict_t *ent)
|
|||
|
||||
static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
||||
{
|
||||
bulletcontext_t *rbe = (bulletcontext_t*)world->rbe;
|
||||
btTypedConstraint *j = NULL;
|
||||
btRigidBody *b1 = NULL;
|
||||
btRigidBody *b2 = NULL;
|
||||
auto rbe = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
btTypedConstraint *j = nullptr;
|
||||
btRigidBody *b1 = nullptr;
|
||||
btRigidBody *b2 = nullptr;
|
||||
int movetype = 0;
|
||||
int jointtype = 0;
|
||||
int enemy = 0, aiment = 0;
|
||||
|
@ -352,8 +246,8 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
|||
vec_t Stop;
|
||||
// vec_t Vel;
|
||||
vec3_t forward;
|
||||
movetype = (int)ed->v->movetype;
|
||||
jointtype = (int)ed->xv->jointtype;
|
||||
movetype = ed->v->movetype;
|
||||
jointtype = ed->xv->jointtype;
|
||||
enemy = ed->v->enemy;
|
||||
aiment = ed->v->aiment;
|
||||
btVector3 origin(ed->v->origin[0], ed->v->origin[1], ed->v->origin[2]);
|
||||
|
@ -407,7 +301,7 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
|||
{
|
||||
j = (btTypedConstraint*)ed->rbe.joint.joint;
|
||||
rbe->dworld->removeConstraint(j);
|
||||
ed->rbe.joint.joint = NULL;
|
||||
ed->rbe.joint.joint = nullptr;
|
||||
delete j;
|
||||
}
|
||||
if (!jointtype)
|
||||
|
@ -427,7 +321,7 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
|||
VectorCopy(ed->v->angles, ed->rbe.joint_angles);
|
||||
VectorCopy(movedir, ed->rbe.joint_movedir);
|
||||
|
||||
rbefuncs->AngleVectors(ed->v->angles, forward, NULL, NULL);
|
||||
rbefuncs->AngleVectors(ed->v->angles, forward, nullptr, nullptr);
|
||||
|
||||
//Con_Printf("making new joint %i\n", (int) (ed - prog->edicts));
|
||||
switch(jointtype)
|
||||
|
@ -530,7 +424,7 @@ static void World_Bullet_Frame_JointFromEntity(world_t *world, wedict_t *ed)
|
|||
break;
|
||||
case 0:
|
||||
default:
|
||||
j = NULL;
|
||||
j = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -546,9 +440,9 @@ static void MatToTransform(const float *mat, btTransform &tr)
|
|||
{
|
||||
tr.setBasis(btMatrix3x3(
|
||||
mat[0], mat[1], mat[2],
|
||||
mat[3], mat[4], mat[5],
|
||||
mat[6], mat[7], mat[8]));
|
||||
tr.setOrigin(btVector3(mat[9], mat[10], mat[11]));
|
||||
mat[4], mat[5], mat[6],
|
||||
mat[8], mat[9], mat[10]));
|
||||
tr.setOrigin(btVector3(mat[3], mat[7], mat[11]));
|
||||
}
|
||||
static void MatFromTransform(float *mat, const btTransform &tr)
|
||||
{
|
||||
|
@ -560,31 +454,32 @@ static void MatFromTransform(float *mat, const btTransform &tr)
|
|||
mat[0] = r0[0];
|
||||
mat[1] = r0[1];
|
||||
mat[2] = r0[2];
|
||||
mat[3] = r1[0];
|
||||
mat[4] = r1[1];
|
||||
mat[5] = r1[2];
|
||||
mat[6] = r2[0];
|
||||
mat[7] = r2[1];
|
||||
mat[8] = r2[2];
|
||||
mat[9] = o[0];
|
||||
mat[10] = o[1];
|
||||
mat[11] = o[2];
|
||||
mat[3] =o[0];
|
||||
mat[4] = r1[0];
|
||||
mat[5] = r1[1];
|
||||
mat[6] = r1[2];
|
||||
mat[7] =o[1];
|
||||
mat[8] = r2[0];
|
||||
mat[9] = r2[1];
|
||||
mat[10]= r2[2];
|
||||
mat[11]=o[2];
|
||||
}
|
||||
static qboolean QDECL World_Bullet_RagMatrixToBody(rbebody_t *bodyptr, float *mat)
|
||||
{ //mat is a 4*3 matrix
|
||||
btTransform tr;
|
||||
btRigidBody *body = (btRigidBody*)bodyptr->body;
|
||||
auto body = reinterpret_cast<btRigidBody*>(bodyptr->body);
|
||||
MatToTransform(mat, tr);
|
||||
body->setWorldTransform(tr);
|
||||
return qtrue;
|
||||
}
|
||||
static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *bodyptr, rbebodyinfo_t *bodyinfo, float *mat, wedict_t *ent)
|
||||
{
|
||||
btRigidBody *body = NULL;
|
||||
btCollisionShape *geom = NULL;
|
||||
btRigidBody *body = nullptr;
|
||||
btCollisionShape *geom = nullptr;
|
||||
float radius;
|
||||
float threshold;
|
||||
// float length;
|
||||
bulletcontext_t *ctx = (bulletcontext_t*)world->rbe;
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
// int axisindex;
|
||||
ctx->hasextraobjs = true;
|
||||
|
||||
|
@ -630,10 +525,13 @@ static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *body
|
|||
Con_DPrintf("World_Bullet_RagCreateBody: unsupported geomshape %i\n", bodyinfo->geomshape);
|
||||
case GEOMTYPE_BOX:
|
||||
geom = new btBoxShape(btVector3(bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]) * 0.5);
|
||||
radius = sqrt(DotProduct(bodyinfo->dimensions,bodyinfo->dimensions));
|
||||
threshold = min(bodyinfo->dimensions[0], min(bodyinfo->dimensions[1], bodyinfo->dimensions[2]));
|
||||
break;
|
||||
|
||||
case GEOMTYPE_SPHERE:
|
||||
geom = new btSphereShape(bodyinfo->dimensions[0] * 0.5f);
|
||||
threshold = radius = bodyinfo->dimensions[0] * 0.5f;
|
||||
geom = new btSphereShape(radius);
|
||||
break;
|
||||
|
||||
case GEOMTYPE_CAPSULE:
|
||||
|
@ -642,6 +540,8 @@ static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *body
|
|||
case GEOMTYPE_CAPSULE_Z:
|
||||
radius = (bodyinfo->dimensions[0]+bodyinfo->dimensions[1]) * 0.5f;
|
||||
geom = new btCapsuleShapeZ(radius, bodyinfo->dimensions[2]);
|
||||
threshold = min(radius, bodyinfo->dimensions[2]*0.5);
|
||||
radius = max(radius, bodyinfo->dimensions[2]*0.5);
|
||||
break;
|
||||
|
||||
case GEOMTYPE_CYLINDER:
|
||||
|
@ -650,6 +550,8 @@ static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *body
|
|||
case GEOMTYPE_CYLINDER_Z:
|
||||
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5;
|
||||
geom = new btCylinderShapeZ(btVector3(radius, radius, bodyinfo->dimensions[2])*0.5);
|
||||
threshold = min(radius, bodyinfo->dimensions[2]*0.5);
|
||||
radius = max(radius, bodyinfo->dimensions[2]*0.5);
|
||||
break;
|
||||
}
|
||||
bodyptr->geom = geom;
|
||||
|
@ -657,20 +559,21 @@ static qboolean QDECL World_Bullet_RagCreateBody(world_t *world, rbebody_t *body
|
|||
//now create the body too
|
||||
|
||||
btVector3 fallInertia(0, 0, 0);
|
||||
((btCollisionShape*)geom)->calculateLocalInertia(bodyinfo->mass, fallInertia);
|
||||
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(bodyinfo->mass, NULL, (btCollisionShape*)geom, fallInertia);
|
||||
geom->calculateLocalInertia(bodyinfo->mass, fallInertia);
|
||||
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(bodyinfo->mass, nullptr, geom, fallInertia);
|
||||
MatToTransform(mat, fallRigidBodyCI.m_startWorldTransform);
|
||||
body = new btRigidBody(fallRigidBodyCI);
|
||||
body->setUserPointer(ent);
|
||||
bodyptr->body = (void*)body;
|
||||
bodyptr->body = reinterpret_cast<void*>(body);
|
||||
|
||||
//motion threshhold should be speed/physicsframerate.
|
||||
//FIXME: recalculate...
|
||||
body->setCcdMotionThreshold((bodyinfo->dimensions[0]+bodyinfo->dimensions[1]+bodyinfo->dimensions[2])*(4/3));
|
||||
body->setCcdMotionThreshold(threshold/64);
|
||||
//radius should be the body's radius
|
||||
body->setCcdSweptSphereRadius((bodyinfo->dimensions[0]+bodyinfo->dimensions[1]+bodyinfo->dimensions[2])*(0.5/3));
|
||||
|
||||
ctx->dworld->addRigidBody(body, ent->xv->dimension_solid, ent->xv->dimension_hit);
|
||||
body->setCcdSweptSphereRadius(radius);
|
||||
|
||||
ctx->dworld->addRigidBody(body, ent?ent->xv->dimension_solid:~0, ent?ent->xv->dimension_hit:~0);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
@ -766,47 +669,77 @@ static void QDECL World_Bullet_RagMatrixFromJoint(rbejoint_t *joint, rbejointinf
|
|||
|
||||
static void QDECL World_Bullet_RagMatrixFromBody(world_t *world, rbebody_t *bodyptr, float *mat)
|
||||
{
|
||||
// bulletcontext_t *ctx = (bulletcontext_t*)world->rbe;
|
||||
btRigidBody *body = (btRigidBody*)bodyptr->body;
|
||||
//auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
auto body = reinterpret_cast<btRigidBody*>(bodyptr->body);
|
||||
MatFromTransform(mat, body->getCenterOfMassTransform());
|
||||
}
|
||||
static void QDECL World_Bullet_RagEnableJoint(rbejoint_t *joint, qboolean enabled)
|
||||
{
|
||||
/*
|
||||
if (enabled)
|
||||
dJointEnable(joint->ode_joint);
|
||||
else
|
||||
dJointDisable(joint->ode_joint);
|
||||
*/
|
||||
auto j = reinterpret_cast<btTypedConstraint*>(joint->joint);
|
||||
j->setEnabled(enabled);
|
||||
}
|
||||
static void QDECL World_Bullet_RagCreateJoint(world_t *world, rbejoint_t *joint, rbejointinfo_t *info, rbebody_t *body1, rbebody_t *body2, vec3_t aaa2[3])
|
||||
{
|
||||
/*
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
btTypedConstraint *j;
|
||||
btVector3 org(aaa2[0][0], aaa2[0][1], aaa2[0][2]);
|
||||
btVector3 axis1(aaa2[1][0], aaa2[1][1], aaa2[1][2]);
|
||||
btVector3 axis2(aaa2[2][0], aaa2[2][1], aaa2[2][2]);
|
||||
auto rb1 = reinterpret_cast<btRigidBody*>(body1->body);
|
||||
auto rb2 = reinterpret_cast<btRigidBody*>(body2->body);
|
||||
|
||||
switch(info->type)
|
||||
{
|
||||
case JOINTTYPE_POINT:
|
||||
joint->ode_joint = dJointCreateBall(world->rbe.world, 0);
|
||||
{
|
||||
auto point = new btPoint2PointConstraint(*rb1, *rb2, rb1->getWorldTransform().getOrigin()-org, rb2->getWorldTransform().getOrigin()-org);
|
||||
// point->setParam(BT_P2P_FLAGS_ERP, info->ERP);
|
||||
// point->setParam(BT_P2P_FLAGS_CFM, info->CFM);
|
||||
j = point;
|
||||
}
|
||||
break;
|
||||
case JOINTTYPE_HINGE:
|
||||
joint->ode_joint = dJointCreateHinge(world->rbe.world, 0);
|
||||
break;
|
||||
case JOINTTYPE_SLIDER:
|
||||
joint->ode_joint = dJointCreateSlider(world->rbe.world, 0);
|
||||
{
|
||||
auto hinge = new btHingeConstraint(*rb1, *rb2, org, org, axis1, axis2);
|
||||
hinge->setLimit(info->LoStop, info->HiStop /*other stuff!*/);
|
||||
// hinge->setParam(BT_HINGE_FLAGS_CFM_NORM, info->CFM);
|
||||
// hinge->setParam(BT_HINGE_FLAGS_CFM_STOP, info->CFM2);
|
||||
// hinge->setParam(BT_HINGE_FLAGS_ERP_NORM, info->ERP);
|
||||
// hinge->setParam(BT_HINGE_FLAGS_ERP_STOP, info->ERP2);
|
||||
j = hinge;
|
||||
}
|
||||
break;
|
||||
// case JOINTTYPE_SLIDER:
|
||||
// j = btSliderConstraint(rb1, rb2, tr1, tr2, false);
|
||||
// break;
|
||||
case JOINTTYPE_UNIVERSAL:
|
||||
joint->ode_joint = dJointCreateUniversal(world->rbe.world, 0);
|
||||
{
|
||||
auto uni = new btUniversalConstraint(*rb1, *rb2, org, axis1, axis2);
|
||||
// uni->setParam(BT_6DOF_FLAGS_CFM_NORM, info->CFM);
|
||||
// uni->setParam(BT_6DOF_FLAGS_CFM_STOP, info->CFM2);
|
||||
// uni->setParam(BT_6DOF_FLAGS_ERP_STOP, info->ERP);
|
||||
uni->setUpperLimit(info->HiStop, info->HiStop2);
|
||||
uni->setLowerLimit(info->LoStop, info->LoStop2);
|
||||
j = uni;
|
||||
}
|
||||
break;
|
||||
case JOINTTYPE_HINGE2:
|
||||
joint->ode_joint = dJointCreateHinge2(world->rbe.world, 0);
|
||||
break;
|
||||
case JOINTTYPE_FIXED:
|
||||
joint->ode_joint = dJointCreateFixed(world->rbe.world, 0);
|
||||
{
|
||||
auto hinge2 = new btHinge2Constraint(*rb1, *rb2, org, axis1, axis2);
|
||||
hinge2->setUpperLimit(info->HiStop);
|
||||
hinge2->setLowerLimit(info->LoStop);
|
||||
j = hinge2;
|
||||
}
|
||||
break;
|
||||
// case JOINTTYPE_FIXED:
|
||||
// j = btFixedConstraint(rb1, rb2, tr1, tr2);
|
||||
// break;
|
||||
default:
|
||||
joint->ode_joint = NULL;
|
||||
Con_Printf("Bullet: joint type %i not supported\n", info->type);
|
||||
j = nullptr;
|
||||
break;
|
||||
}
|
||||
if (joint->ode_joint)
|
||||
/* if (joint->ode_joint)
|
||||
{
|
||||
//Con_Printf("made new joint %i\n", (int) (ed - prog->edicts));
|
||||
// dJointSetData(joint->ode_joint, NULL);
|
||||
|
@ -876,16 +809,19 @@ static void QDECL World_Bullet_RagCreateJoint(world_t *world, rbejoint_t *joint,
|
|||
}
|
||||
}
|
||||
*/
|
||||
if (j)
|
||||
ctx->dworld->addConstraint(j, true);
|
||||
joint->joint = reinterpret_cast<void*>(j);
|
||||
}
|
||||
|
||||
static void QDECL World_Bullet_RagDestroyBody(world_t *world, rbebody_t *bodyptr)
|
||||
{
|
||||
bulletcontext_t *ctx = (bulletcontext_t*)world->rbe;
|
||||
btRigidBody *body = (btRigidBody*)bodyptr->body;
|
||||
btCollisionShape *geom = (btCollisionShape*)bodyptr->geom;
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
auto body = reinterpret_cast<btRigidBody*>(bodyptr->body);
|
||||
auto geom = reinterpret_cast<btCollisionShape*>(bodyptr->geom);
|
||||
|
||||
bodyptr->body = NULL;
|
||||
bodyptr->geom = NULL;
|
||||
bodyptr->body = nullptr;
|
||||
bodyptr->geom = nullptr;
|
||||
|
||||
if (body)
|
||||
{
|
||||
|
@ -898,11 +834,14 @@ static void QDECL World_Bullet_RagDestroyBody(world_t *world, rbebody_t *bodyptr
|
|||
|
||||
static void QDECL World_Bullet_RagDestroyJoint(world_t *world, rbejoint_t *joint)
|
||||
{
|
||||
/*
|
||||
if (joint->ode_joint)
|
||||
dJointDestroy(joint->ode_joint);
|
||||
joint->ode_joint = NULL;
|
||||
*/
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
auto j = reinterpret_cast<btTypedConstraint*>(joint->joint);
|
||||
if (j)
|
||||
{
|
||||
ctx->dworld->removeConstraint(j);
|
||||
delete j;
|
||||
}
|
||||
joint->joint = nullptr;
|
||||
}
|
||||
|
||||
//bullet gives us a handy way to get/set motion states. we can cheesily update entity fields this way.
|
||||
|
@ -980,8 +919,8 @@ public:
|
|||
|
||||
static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
||||
{
|
||||
bulletcontext_t *ctx = (bulletcontext_t*)world->rbe;
|
||||
btRigidBody *body = NULL;
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
btRigidBody *body = nullptr;
|
||||
// btScalar mass;
|
||||
float test;
|
||||
// void *dataID;
|
||||
|
@ -1013,16 +952,16 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
|||
// vec_t spinlimit;
|
||||
qboolean gravity;
|
||||
|
||||
geomtype = (int)ed->xv->geomtype;
|
||||
solid = (int)ed->v->solid;
|
||||
movetype = (int)ed->v->movetype;
|
||||
geomtype = ed->xv->geomtype;
|
||||
solid = ed->v->solid;
|
||||
movetype = ed->v->movetype;
|
||||
scale = ed->xv->scale?ed->xv->scale:1;
|
||||
modelindex = 0;
|
||||
model = NULL;
|
||||
model = nullptr;
|
||||
|
||||
if (!geomtype)
|
||||
{
|
||||
switch((int)ed->v->solid)
|
||||
switch(solid)
|
||||
{
|
||||
case SOLID_NOT: geomtype = GEOMTYPE_NONE; break;
|
||||
case SOLID_TRIGGER: geomtype = GEOMTYPE_NONE; break;
|
||||
|
@ -1039,11 +978,11 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
|||
switch(geomtype)
|
||||
{
|
||||
case GEOMTYPE_TRIMESH:
|
||||
modelindex = (int)ed->v->modelindex;
|
||||
modelindex = ed->v->modelindex;
|
||||
model = world->Get_CModel(world, modelindex);
|
||||
if (!model || model->loadstate != MLS_LOADED)
|
||||
{
|
||||
model = NULL;
|
||||
model = nullptr;
|
||||
modelindex = 0;
|
||||
}
|
||||
if (model)
|
||||
|
@ -1122,7 +1061,7 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
|||
{
|
||||
case GEOMTYPE_TRIMESH:
|
||||
// foo Matrix4x4_Identity(ed->rbe.offsetmatrix);
|
||||
geom = NULL;
|
||||
geom = nullptr;
|
||||
if (!model)
|
||||
{
|
||||
Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
|
||||
|
@ -1283,7 +1222,7 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ed->rbe.body.body == NULL)
|
||||
if (ed->rbe.body.body == nullptr)
|
||||
{
|
||||
btRigidBody::btRigidBodyConstructionInfo rbci(ed->rbe.mass, new QCMotionState(ed,world), (btCollisionShape*)ed->rbe.body.geom, btVector3(0, 0, 0));
|
||||
body = new btRigidBody(rbci);
|
||||
|
@ -1432,7 +1371,7 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|
|||
// r[1][2] = up[1];
|
||||
// r[2][2] = up[2];
|
||||
|
||||
QCMotionState *ms = (QCMotionState*)body->getMotionState();
|
||||
auto ms = (QCMotionState*)body->getMotionState();
|
||||
ms->ReloadMotionState();
|
||||
body->setMotionState(ms);
|
||||
body->setLinearVelocity(btVector3(velocity[0], velocity[1], velocity[2]));
|
||||
|
@ -1616,7 +1555,7 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
|
|||
|
||||
static void QDECL World_Bullet_Frame(world_t *world, double frametime, double gravity)
|
||||
{
|
||||
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
if (world->rbe_hasphysicsents || ctx->hasextraobjs)
|
||||
{
|
||||
int iters;
|
||||
|
@ -1631,23 +1570,23 @@ static void QDECL World_Bullet_Frame(world_t *world, double frametime, double gr
|
|||
// copy physics properties from entities to physics engine
|
||||
for (i = 0;i < world->num_edicts;i++)
|
||||
{
|
||||
ed = (wedict_t*)EDICT_NUM_PB(world->progs, i);
|
||||
ed = WEDICT_NUM_PB(world->progs, i);
|
||||
if (!ED_ISFREE(ed))
|
||||
World_Bullet_Frame_BodyFromEntity(world, ed);
|
||||
}
|
||||
// oh, and it must be called after all bodies were created
|
||||
for (i = 0;i < world->num_edicts;i++)
|
||||
{
|
||||
ed = (wedict_t*)EDICT_NUM_PB(world->progs, i);
|
||||
ed = WEDICT_NUM_PB(world->progs, i);
|
||||
if (!ED_ISFREE(ed))
|
||||
World_Bullet_Frame_JointFromEntity(world, ed);
|
||||
}
|
||||
while(ctx->cmdqueuehead)
|
||||
{
|
||||
rbecommandqueue_t *cmd = ctx->cmdqueuehead;
|
||||
auto cmd = ctx->cmdqueuehead;
|
||||
ctx->cmdqueuehead = cmd->next;
|
||||
if (!cmd->next)
|
||||
ctx->cmdqueuetail = NULL;
|
||||
ctx->cmdqueuetail = nullptr;
|
||||
World_Bullet_RunCmd(world, cmd);
|
||||
Z_Free(cmd);
|
||||
}
|
||||
|
@ -1676,23 +1615,12 @@ static void QDECL World_Bullet_Frame(world_t *world, double frametime, double gr
|
|||
|
||||
// clear the JointGroup now that we're done with it
|
||||
// dJointGroupEmpty(world->rbe.contactgroup);
|
||||
|
||||
if (world->rbe_hasphysicsents)
|
||||
{
|
||||
// copy physics properties from physics engine to entities
|
||||
for (i = 1;i < world->num_edicts;i++)
|
||||
{
|
||||
ed = (wedict_t*)EDICT_NUM_PB(world->progs, i);
|
||||
if (!ED_ISFREE(ed))
|
||||
World_Bullet_Frame_BodyToEntity(world, ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd)
|
||||
{
|
||||
btRigidBody *body = (btRigidBody*)(cmd->edict->rbe.body.body);
|
||||
auto body = (btRigidBody*)(cmd->edict->rbe.body.body);
|
||||
switch(cmd->command)
|
||||
{
|
||||
case RBECMD_ENABLE:
|
||||
|
@ -1725,15 +1653,15 @@ static void World_Bullet_RunCmd(world_t *world, rbecommandqueue_t *cmd)
|
|||
|
||||
static void QDECL World_Bullet_PushCommand(world_t *world, rbecommandqueue_t *val)
|
||||
{
|
||||
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
||||
rbecommandqueue_t *cmd = (rbecommandqueue_t*)BZ_Malloc(sizeof(*cmd));
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
auto cmd = (rbecommandqueue_t*)BZ_Malloc(sizeof(rbecommandqueue_t));
|
||||
world->rbe_hasphysicsents = qtrue; //just in case.
|
||||
memcpy(cmd, val, sizeof(*cmd));
|
||||
cmd->next = NULL;
|
||||
cmd->next = nullptr;
|
||||
//add on the end of the queue, so that order is preserved.
|
||||
if (ctx->cmdqueuehead)
|
||||
{
|
||||
rbecommandqueue_t *ot = ctx->cmdqueuetail;
|
||||
auto ot = ctx->cmdqueuetail;
|
||||
ot->next = ctx->cmdqueuetail = cmd;
|
||||
}
|
||||
else
|
||||
|
@ -1742,8 +1670,8 @@ static void QDECL World_Bullet_PushCommand(world_t *world, rbecommandqueue_t *va
|
|||
|
||||
static void QDECL World_Bullet_TraceEntity(world_t *world, wedict_t *ed, vec3_t start, vec3_t end, trace_t *trace)
|
||||
{
|
||||
struct bulletcontext_s *ctx = (struct bulletcontext_s*)world->rbe;
|
||||
btCollisionShape *shape = (btCollisionShape*)ed->rbe.body.geom;
|
||||
auto ctx = reinterpret_cast<bulletcontext_t*>(world->rbe);
|
||||
auto shape = (btCollisionShape*)ed->rbe.body.geom;
|
||||
|
||||
//btCollisionAlgorithm
|
||||
class myConvexResultCallback : public btCollisionWorld::ConvexResultCallback
|
||||
|
@ -1764,7 +1692,7 @@ static void QDECL World_Bullet_TraceEntity(world_t *world, wedict_t *ed, vec3_t
|
|||
return 0;
|
||||
}
|
||||
} result;
|
||||
result.m_impactent = NULL;
|
||||
result.m_impactent = nullptr;
|
||||
result.m_closestHitFraction = trace->fraction;
|
||||
|
||||
btTransform from(btMatrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1), btVector3(start[0], start[1], start[2]));
|
||||
|
@ -1785,14 +1713,14 @@ static void QDECL World_Bullet_TraceEntity(world_t *world, wedict_t *ed, vec3_t
|
|||
|
||||
static void QDECL World_Bullet_Start(world_t *world)
|
||||
{
|
||||
struct bulletcontext_s *ctx;
|
||||
bulletcontext_t *ctx;
|
||||
if (world->rbe)
|
||||
return; //no thanks, we already have one. somehow.
|
||||
|
||||
if (!physics_bullet_enable->value)
|
||||
return;
|
||||
|
||||
ctx = (struct bulletcontext_s*)BZ_Malloc(sizeof(*ctx));
|
||||
ctx = reinterpret_cast<bulletcontext_t*>(BZ_Malloc(sizeof(*ctx)));
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->gworld = world;
|
||||
ctx->funcs.End = World_Bullet_End;
|
||||
|
@ -1869,7 +1797,7 @@ static bool World_Bullet_DoInit(void)
|
|||
{
|
||||
if (!rbefuncs || !rbefuncs->RegisterPhysicsEngine)
|
||||
{
|
||||
rbefuncs = NULL;
|
||||
rbefuncs = nullptr;
|
||||
Con_Printf("Bullet plugin failed: Engine doesn't support physics engine plugins.\n");
|
||||
}
|
||||
else if (!rbefuncs->RegisterPhysicsEngine("Bullet", World_Bullet_Start))
|
||||
|
|
Loading…
Reference in a new issue