ODE support works slightly better now. remember to force fixed-rate tics by setting sv_[min|max]tic to the same value.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3436 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2009-11-12 08:53:10 +00:00
parent b9baebe711
commit 67e90812c2
4 changed files with 175 additions and 93 deletions

View File

@ -42,10 +42,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
cvar_t physics_ode_quadtree_depth = CVARDP4(0, "physics_ode_quadtree_depth","5", "desired subdivision level of quadtree culling space");
cvar_t physics_ode_contactsurfacelayer = CVARDP4(0, "physics_ode_contactsurfacelayer","0", "allows objects to overlap this many units to reduce jitter");
cvar_t physics_ode_worldquickstep = CVARDP4(0, "physics_ode_worldquickstep","1", "use dWorldQuickStep rather than dWorldStepFast1 or dWorldStep");
cvar_t physics_ode_worldquickstep = CVARDP4(0, "physics_ode_worldquickstep","1", "use dWorldQuickStep rather than dWorldStep");
cvar_t physics_ode_worldquickstep_iterations = CVARDP4(0, "physics_ode_worldquickstep_iterations","20", "parameter to dWorldQuickStep");
cvar_t physics_ode_worldstepfast = CVARDP4(0, "physics_ode_worldstepfast","0", "use dWorldStepFast1 rather than dWorldStep");
cvar_t physics_ode_worldstepfast_iterations = CVARDP4(0, "physics_ode_worldstepfast_iterations","20", "parameter to dWorldStepFast1");
//physics_ode_worldstepfast dWorldStepFast1 is not present in more recent versions of ODE. thus we don't use it ever.
cvar_t physics_ode_contact_mu = CVARDP4(0, "physics_ode_contact_mu", "1", "contact solver mu parameter - friction pyramid approximation 1 (see ODE User Guide)");
cvar_t physics_ode_contact_erp = CVARDP4(0, "physics_ode_contact_erp", "0.96", "contact solver erp parameter - Error Restitution Percent (see ODE User Guide)");
cvar_t physics_ode_contact_cfm = CVARDP4(0, "physics_ode_contact_cfm", "0", "contact solver cfm parameter - Constraint Force Mixing (see ODE User Guide)");
@ -234,7 +233,7 @@ typedef struct dContact
}
dContact;
typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
typedef void VARGS dNearCallback (void *data, dGeomID o1, dGeomID o2);
// SAP
// Order XZY or ZXY usually works best, if your Y is up.
@ -290,7 +289,7 @@ void (ODE_API *dWorldSetQuickStepNumIterations)(dWorldID, int num);
//dReal (ODE_API *dWorldGetContactMaxCorrectingVel)(dWorldID);
void (ODE_API *dWorldSetContactSurfaceLayer)(dWorldID, dReal depth);
//dReal (ODE_API *dWorldGetContactSurfaceLayer)(dWorldID);
void (ODE_API *dWorldStepFast1)(dWorldID, dReal stepsize, int maxiterations);
//void (ODE_API *dWorldStepFast1)(dWorldID, dReal stepsize, int maxiterations);
//void (ODE_API *dWorldSetAutoEnableDepthSF1)(dWorldID, int autoEnableDepth);
//int (ODE_API *dWorldGetAutoEnableDepthSF1)(dWorldID);
//dReal (ODE_API *dWorldGetAutoDisableLinearThreshold)(dWorldID);
@ -755,7 +754,7 @@ static dllfunction_t odefuncs[] =
// {"dWorldGetContactMaxCorrectingVel", (void **) &dWorldGetContactMaxCorrectingVel},
{(void **) &dWorldSetContactSurfaceLayer, "dWorldSetContactSurfaceLayer"},
// {"dWorldGetContactSurfaceLayer", (void **) &dWorldGetContactSurfaceLayer},
{(void **) &dWorldStepFast1, "dWorldStepFast1"},
// {(void **) &dWorldStepFast1, "dWorldStepFast1"},
// {"dWorldSetAutoEnableDepthSF1", (void **) &dWorldSetAutoEnableDepthSF1},
// {"dWorldGetAutoEnableDepthSF1", (void **) &dWorldGetAutoEnableDepthSF1},
// {"dWorldGetAutoDisableLinearThreshold", (void **) &dWorldGetAutoDisableLinearThreshold},
@ -1183,8 +1182,6 @@ void World_Physics_Init(void)
Cvar_Register(&physics_ode_contactsurfacelayer, "ODE Physics Library");
Cvar_Register(&physics_ode_worldquickstep, "ODE Physics Library");
Cvar_Register(&physics_ode_worldquickstep_iterations, "ODE Physics Library");
Cvar_Register(&physics_ode_worldstepfast, "ODE Physics Library");
Cvar_Register(&physics_ode_worldstepfast_iterations, "ODE Physics Library");
Cvar_Register(&physics_ode_contact_mu, "ODE Physics Library");
Cvar_Register(&physics_ode_contact_erp, "ODE Physics Library");
Cvar_Register(&physics_ode_contact_cfm, "ODE Physics Library");
@ -1284,6 +1281,9 @@ void World_Physics_RemoveJointFromEntity(world_t *world, wedict_t *ed)
void World_Physics_RemoveFromEntity(world_t *world, wedict_t *ed)
{
if (!ed->ode.ode_physics)
return;
// entity is not physics controlled, free any physics data
ed->ode.ode_physics = false;
if (ed->ode.ode_geom)
@ -1386,9 +1386,9 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, wedict_t *ed)
up[2] = r[10];
VectorCopy(vel, velocity);
VectorCopy(avel, spinvelocity);
Matrix4_FromVectors(bodymatrix, forward, left, up, origin);
Matrix4_Multiply(entitymatrix, bodymatrix, ed->ode.ode_offsetimatrix);
Matrix4_ToVectors(entitymatrix, forward, left, up, origin);
Matrix4Q_FromVectors(bodymatrix, forward, left, up, origin);
Matrix4_Multiply(bodymatrix, ed->ode.ode_offsetimatrix, entitymatrix);
Matrix4Q_ToVectors(entitymatrix, forward, left, up, origin);
VectorAngles(forward, up, angles);
avelocity[PITCH] = RAD2DEG(spinvelocity[PITCH]);
@ -1612,11 +1612,17 @@ static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed
for (sno = 0; sno < mod->nummodelsurfaces; sno++)
{
surf = &mod->surfaces[sno+mod->firstmodelsurface];
mesh = surf->mesh;
if (!mesh)
continue;
numverts += mesh->numvertexes;
numindexes += mesh->numindexes;
if (surf->mesh)
{
mesh = surf->mesh;
numverts += mesh->numvertexes;
numindexes += mesh->numindexes;
}
else
{
numverts += surf->numedges;
numindexes += (surf->numedges-2) * 3;
}
}
if (!numindexes)
{
@ -1625,24 +1631,61 @@ static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed
}
ed->ode.ode_element3i = BZ_Malloc(numindexes*sizeof(index_t));
ed->ode.ode_vertex3f = BZ_Malloc(numverts*sizeof(vec3_t));
numverts = 0;
numindexes = 0;
for (sno = 0; sno < mod->nummodelsurfaces; sno++)
{
surf = &mod->surfaces[sno+mod->firstmodelsurface];
mesh = surf->mesh;
if (!mesh)
continue;
for (i = 0; i < mesh->numvertexes; i++)
VectorSubtract(mesh->xyz_array[i], geomcenter, (ed->ode.ode_vertex3f + numverts+i));
for (i = 0; i < mesh->numindexes; i+=3)
if (surf->mesh)
{
//flip the triangles as we go
ed->ode.ode_element3i[numindexes+i+0] = mesh->indexes[i+2];
ed->ode.ode_element3i[numindexes+i+1] = mesh->indexes[i+1];
ed->ode.ode_element3i[numindexes+i+2] = mesh->indexes[i+0];
mesh = surf->mesh;
for (i = 0; i < mesh->numvertexes; i++)
VectorSubtract(mesh->xyz_array[i], geomcenter, (ed->ode.ode_vertex3f + 3*(numverts+i)));
for (i = 0; i < mesh->numindexes; i+=3)
{
//flip the triangles as we go
ed->ode.ode_element3i[numindexes+i+0] = numverts+mesh->indexes[i+2];
ed->ode.ode_element3i[numindexes+i+1] = numverts+mesh->indexes[i+1];
ed->ode.ode_element3i[numindexes+i+2] = numverts+mesh->indexes[i+0];
}
numverts += mesh->numvertexes;
numindexes += i;
}
else
{
float *vec;
medge_t *edge;
int lindex;
for (i = 0; i < surf->numedges; i++)
{
lindex = mod->surfedges[surf->firstedge + i];
if (lindex > 0)
{
edge = &mod->edges[lindex];
vec = mod->vertexes[edge->v[0]].position;
}
else
{
edge = &mod->edges[-lindex];
vec = mod->vertexes[edge->v[1]].position;
}
VectorSubtract(vec, geomcenter, (ed->ode.ode_vertex3f + 3*(numverts+i)));
}
for (i = 2; i < surf->numedges; i++)
{
//quake is backwards, not ode
ed->ode.ode_element3i[numindexes++] = numverts+i;
ed->ode.ode_element3i[numindexes++] = numverts+i-1;
ed->ode.ode_element3i[numindexes++] = numverts;
}
numverts += surf->numedges;
}
numverts += mesh->numvertexes;
numindexes += mesh->numindexes;
}
ed->ode.ode_numvertices = numverts;
ed->ode.ode_numtriangles = numindexes/3;
return true;
}
@ -1650,7 +1693,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
{
dBodyID body = (dBodyID)ed->ode.ode_body;
dMass mass;
dReal test;
float test;
void *dataID;
dVector3 capsulerot[3];
model_t *model;
@ -1676,7 +1719,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
vec_t massval = 1.0f;
vec_t movelimit;
vec_t radius;
vec_t scale = 1.0f;
vec_t scale;
vec_t spinlimit;
qboolean gravity;
#ifdef ODE_DYNAMIC
@ -1685,7 +1728,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
#endif
solid = (int)ed->v->solid;
movetype = (int)ed->v->movetype;
scale = ed->xv->scale;
scale = ed->xv->scale?ed->xv->scale:1;
modelindex = 0;
model = NULL;
@ -1698,7 +1741,8 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
{
VectorScale(model->mins, scale, entmins);
VectorScale(model->maxs, scale, entmaxs);
massval = ed->xv->mass;
if (ed->xv->mass)
massval = ed->xv->mass;
}
else
{
@ -1707,14 +1751,15 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
}
break;
case SOLID_BBOX:
//case SOLID_SLIDEBOX:
case SOLID_SLIDEBOX:
case SOLID_CORPSE:
case SOLID_PHYSICS_BOX:
case SOLID_PHYSICS_SPHERE:
case SOLID_PHYSICS_CAPSULE:
VectorCopy(ed->v->mins, entmins);
VectorCopy(ed->v->maxs, entmaxs);
massval = ed->xv->mass;
if (ed->xv->mass)
massval = ed->xv->mass;
break;
default:
if (ed->ode.ode_physics)
@ -1771,7 +1816,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
if (!GenerateCollisionMesh(world, model, ed, geomcenter))
break;
Matrix4_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
Matrix4Q_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
// now create the geom
dataID = dGeomTriMeshDataCreate();
dGeomTriMeshDataBuildSingle(dataID, (void*)ed->ode.ode_vertex3f, sizeof(float[3]), ed->ode.ode_numvertices, ed->ode.ode_element3i, ed->ode.ode_numtriangles*3, sizeof(int[3]));
@ -1782,12 +1827,12 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
case SOLID_SLIDEBOX:
case SOLID_CORPSE:
case SOLID_PHYSICS_BOX:
Matrix4_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
Matrix4Q_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
ed->ode.ode_geom = (void *)dCreateBox(world->ode.ode_space, geomsize[0], geomsize[1], geomsize[2]);
dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
break;
case SOLID_PHYSICS_SPHERE:
Matrix4_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
Matrix4Q_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
ed->ode.ode_geom = (void *)dCreateSphere(world->ode.ode_space, geomsize[0] * 0.5f);
dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f);
break;
@ -1821,8 +1866,8 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
default:
Sys_Error("World_Physics_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
}
Matrix4_Invert_Simple(ed->ode.ode_offsetmatrix, ed->ode.ode_offsetimatrix);
ed->ode.ode_massbuf = BZ_Malloc(sizeof(mass));
Matrix4Q_Invert_Simple(ed->ode.ode_offsetmatrix, ed->ode.ode_offsetimatrix);
ed->ode.ode_massbuf = BZ_Malloc(sizeof(dMass));
memcpy(ed->ode.ode_massbuf, &mass, sizeof(dMass));
}
@ -1868,8 +1913,9 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
//val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_up);if (val) VectorCopy(val->vector, up);
//val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.spinvelocity);if (val) VectorCopy(val->vector, spinvelocity);
VectorCopy(ed->v->angles, angles);
angles[0] = 0;
VectorCopy(ed->v->avelocity, avelocity);
if (ed == world->edicts || (ed->xv->gravity && ed->xv->gravity < 0))
if (ed == world->edicts || (ed->xv->gravity && ed->xv->gravity <= 0.01))
gravity = false;
// compatibility for legacy entities
@ -1966,9 +2012,9 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
VectorCopy(avelocity, ed->ode.ode_avelocity);
ed->ode.ode_gravity = gravity;
Matrix4_FromVectors(entitymatrix, forward, left, up, origin);
Matrix4_Multiply(bodymatrix, entitymatrix, ed->ode.ode_offsetmatrix);
Matrix4_ToVectors(bodymatrix, forward, left, up, origin);
Matrix4Q_FromVectors(entitymatrix, forward, left, up, origin);
Matrix4_Multiply(entitymatrix, ed->ode.ode_offsetmatrix, bodymatrix);
Matrix4Q_ToVectors(bodymatrix, forward, left, up, origin);
r[0][0] = forward[0];
r[1][0] = forward[1];
r[2][0] = forward[2];
@ -2038,7 +2084,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
}
#define MAX_CONTACTS 16
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
{
world_t *world = (world_t *)data;
dContact contact[MAX_CONTACTS]; // max contacts per collision pair
@ -2080,6 +2126,28 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
ed1 = (wedict_t *) dGeomGetData(o1);
if(ed1 && ed1->isfree)
ed1 = NULL;
ed2 = (wedict_t *) dGeomGetData(o2);
if(ed2 && ed2->isfree)
ed2 = NULL;
// generate contact points between the two non-space geoms
numcontacts = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(contact[0]));
if (numcontacts)
{
if(ed1 && ed1->v->touch)
{
world->Event_Touch(world, ed1, ed2);
}
if(ed2 && ed2->v->touch)
{
world->Event_Touch(world, ed2, ed1);
}
/* if either ent killed itself, don't collide */
if ((ed1&&ed1->isfree) || (ed2&&ed2->isfree))
return;
}
if(ed1)
{
if (ed1->xv->bouncefactor)
@ -2089,9 +2157,6 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
bouncestop1 = ed1->xv->bouncestop;
}
ed2 = (wedict_t *) dGeomGetData(o2);
if(ed2 && ed2->isfree)
ed2 = NULL;
if(ed2)
{
if (ed2->xv->bouncefactor)
@ -2101,14 +2166,8 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
bouncestop2 = ed2->xv->bouncestop;
}
if(ed1 && ed1->v->touch)
{
world->Event_Touch(world, ed1, ed2);
}
if(ed2 && ed2->v->touch)
{
world->Event_Touch(world, ed2, ed1);
}
if (ed1->v->owner == ed2->entnum || ed2->v->owner == ed1->entnum)
return;
// merge bounce factors and bounce stop
if(bouncefactor2 > 0)
@ -2130,12 +2189,13 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
dWorldGetGravity(world->ode.ode_world, grav);
bouncestop1 *= fabs(grav[2]);
// generate contact points between the two non-space geoms
numcontacts = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(contact[0]));
// add these contact points to the simulation
for (i = 0;i < numcontacts;i++)
{
contact[i].surface.mode = (physics_ode_contact_mu.value != -1 ? dContactApprox1 : 0) | (physics_ode_contact_erp.value != -1 ? dContactSoftERP : 0) | (physics_ode_contact_cfm.value != -1 ? dContactSoftCFM : 0) | (bouncefactor1 > 0 ? dContactBounce : 0);
contact[i].surface.mode = (physics_ode_contact_mu.value != -1 ? dContactApprox1 : 0) |
(physics_ode_contact_erp.value != -1 ? dContactSoftERP : 0) |
(physics_ode_contact_cfm.value != -1 ? dContactSoftCFM : 0) |
(bouncefactor1 > 0 ? dContactBounce : 0);
contact[i].surface.mu = physics_ode_contact_mu.value;
contact[i].surface.soft_erp = physics_ode_contact_erp.value;
contact[i].surface.soft_cfm = physics_ode_contact_cfm.value;
@ -2160,14 +2220,14 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
// copy physics properties from entities to physics engine
for (i = 0;i < world->num_edicts;i++)
{
ed = EDICT_NUM(world->progs, i);
ed = (wedict_t*)EDICT_NUM(world->progs, i);
if (!ed->isfree)
World_Physics_Frame_BodyFromEntity(world, ed);
}
// oh, and it must be called after all bodies were created
for (i = 0;i < world->num_edicts;i++)
{
ed = EDICT_NUM(world->progs, i);
ed = (wedict_t*)EDICT_NUM(world->progs, i);
if (!ed->isfree)
World_Physics_Frame_JointFromEntity(world, ed);
}
@ -2188,8 +2248,6 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
dWorldSetQuickStepNumIterations(world->ode.ode_world, bound(1, physics_ode_worldquickstep_iterations.ival, 200));
dWorldQuickStep(world->ode.ode_world, world->ode.ode_step);
}
else if (physics_ode_worldstepfast.ival)
dWorldStepFast1(world->ode.ode_world, world->ode.ode_step, bound(1, physics_ode_worldstepfast_iterations.ival, 200));
else
dWorldStep(world->ode.ode_world, world->ode.ode_step);
@ -2200,7 +2258,7 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
// copy physics properties from physics engine to entities
for (i = 1;i < world->num_edicts;i++)
{
ed = EDICT_NUM(world->progs, i);
ed = (wedict_t*)EDICT_NUM(world->progs, i);
if (!ed->isfree)
World_Physics_Frame_BodyToEntity(world, ed);
}

View File

@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h>
vec3_t vec3_origin = {0,0,0};
int nanmask = 255<<23;
/*-----------------------------------------------------------------*/
@ -877,7 +876,7 @@ float *Matrix4_NewTranslation(float x, float y, float z)
}
//be aware that this generates two sorts of matricies depending on order of a+b
void Matrix4_Multiply(float *a, float *b, float *out)
void Matrix4_Multiply(const float *a, const float *b, float *out)
{
out[0] = a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3];
out[1] = a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3];
@ -901,7 +900,7 @@ void Matrix4_Multiply(float *a, float *b, float *out)
}
//transform 4d vector by a 4d matrix.
void Matrix4_Transform4(float *matrix, float *vector, float *product)
void Matrix4_Transform4(const float *matrix, const float *vector, float *product)
{
product[0] = matrix[0]*vector[0] + matrix[4]*vector[1] + matrix[8]*vector[2] + matrix[12]*vector[3];
product[1] = matrix[1]*vector[0] + matrix[5]*vector[1] + matrix[9]*vector[2] + matrix[13]*vector[3];
@ -909,7 +908,7 @@ void Matrix4_Transform4(float *matrix, float *vector, float *product)
product[3] = matrix[3]*vector[0] + matrix[7]*vector[1] + matrix[11]*vector[2] + matrix[15]*vector[3];
}
void Matrix4_Transform3(float *matrix, float *vector, float *product)
void Matrix4_Transform3(const float *matrix, const float *vector, float *product)
{
product[0] = matrix[0]*vector[0] + matrix[4]*vector[1] + matrix[8]*vector[2] + matrix[12];
product[1] = matrix[1]*vector[0] + matrix[5]*vector[1] + matrix[9]*vector[2] + matrix[13];
@ -951,6 +950,29 @@ void Matrix4_CreateTranslate (float *out, float x, float y, float z)
memcpy(out, Matrix4_NewTranslation(x, y, z), 16*sizeof(float));
}
void Matrix4Q_CreateTranslate (float *out, float x, float y, float z)
{
out[0] = 1;
out[4] = 0;
out[8] = 0;
out[12] = 0;
out[1] = 0;
out[5] = 1;
out[9] = 0;
out[13] = 0;
out[2] = 0;
out[6] = 0;
out[10] = 1;
out[14] = 0;
out[3] = x;
out[7] = y;
out[11] = z;
out[15] = 1;
}
void Matrix4_ModelViewMatrixFromAxis(float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg)
{
float tempmat[16];
@ -976,7 +998,7 @@ void Matrix4_ModelViewMatrixFromAxis(float *modelview, const vec3_t pn, const ve
}
void Matrix4_ToVectors(const float *in, float vx[3], float vy[3], float vz[3], float t[3])
void Matrix4Q_ToVectors(const float *in, float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = in[0];
vx[1] = in[4];
@ -995,23 +1017,23 @@ void Matrix4_ToVectors(const float *in, float vx[3], float vy[3], float vz[3], f
t [2] = in[11];
}
void Matrix4_FromVectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
void Matrix4Q_FromVectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
{
out[0] = vx[0];
out[4] = vy[0];
out[8] = vz[0];
out[12] = t[0];
out[1] = vx[1];
out[1] = vy[0];
out[2] = vz[0];
out[3] = t[0];
out[4] = vx[1];
out[5] = vy[1];
out[9] = vz[1];
out[13] = t[1];
out[2] = vx[2];
out[6] = vy[2];
out[6] = vz[1];
out[7] = t[1];
out[8] = vx[2];
out[9] = vy[2];
out[10] = vz[2];
out[14] = t[2];
out[3] = 0.0f;
out[7] = 0.0f;
out[11] = 0.0f;
out[11] = t[2];
out[12] = 0.0f;
out[13] = 0.0f;
out[14] = 0.0f;
out[15] = 1.0f;
}
@ -1397,7 +1419,7 @@ qboolean Matrix4_Invert(const float *m, float *out)
#undef SWAP_ROWS
}
void Matrix4_Invert_Simple (const float *in1, float *out)
void Matrix4Q_Invert_Simple (const float *in1, float *out)
{
// we only support uniform scaling, so assume the first row is enough
// (note the lack of sqrt here, because we're trying to undo the scaling,

View File

@ -55,10 +55,10 @@ typedef int fixed16_t;
struct mplane_s;
extern vec3_t vec3_origin;
extern int nanmask;
#define bound(min,num,max) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
#define nanmask (255<<23)
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
@ -131,19 +131,20 @@ float Q_rsqrt(float number);
void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out);
void Matrix4_Identity(float *outm);
qboolean Matrix4_Invert(const float *m, float *out);
void Matrix4_Invert_Simple (const float *in1, float *out);
void Matrix4Q_Invert_Simple (const float *in1, float *out);
void Matrix4_CreateTranslate (float *out, float x, float y, float z);
void Matrix4Q_CreateTranslate (float *out, float x, float y, float z);
void Matrix4_ModelMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg);
void Matrix4_ModelViewMatrix (float *modelview, const vec3_t viewangles, const vec3_t vieworg);
void Matrix4_ModelViewMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg);
void Matrix4_CreateFromQuakeEntity (float *matrix, float x, float y, float z, float pitch, float yaw, float roll, float scale);
void Matrix4_Multiply (float *a, float *b, float *out);
void Matrix4_Multiply (const float *a, const float *b, float *out);
void Matrix4_Project (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy);
void Matrix4_Transform3 (float *matrix, float *vector, float *product);
void Matrix4_Transform4 (float *matrix, float *vector, float *product);
void Matrix4_Transform3 (const float *matrix, const float *vector, float *product);
void Matrix4_Transform4 (const float *matrix, const float *vector, float *product);
void Matrix4_UnProject (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy);
void Matrix4_FromVectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3]);
void Matrix4_ToVectors(const float *in, float vx[3], float vy[3], float vz[3], float t[3]);
void Matrix4Q_FromVectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3]);
void Matrix4Q_ToVectors(const float *in, float vx[3], float vy[3], float vz[3], float t[3]);
#define AngleVectorsFLU(a,f,l,u) do{AngleVectors(a,f,l,u);VectorNegate(l,l);}while(0)

View File

@ -690,6 +690,10 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
}
#ifdef USEODE
World_Physics_End(&sv.world);
#endif
// wipe the entire per-level structure
memset (&sv, 0, sizeof(sv));
@ -826,7 +830,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
Info_SetValueForStarKey(svs.info, "*startspot", "", MAX_SERVERINFO_STRING);
//
// clear physics interaction links
// init physics interaction links
//
World_ClearWorld (&sv.world);
@ -864,9 +868,6 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
Info_RemoveKey(svs.info, "*csqcdebug");
#endif
if (svs.gametype == GT_PROGS)
{
if (svprogfuncs) //we don't want the q1 stuff anymore.