void IMU_IntegrateGyros(float dt, vec3 *rates, quat *pGyroFrame) // Integrate gyros into our gyro frame. { // Get rotation axis from gyros, and rate in rads/sec if ((rates->x==0.0f) && (rates->y==0.0f) && (rates->z==0.0f)) return; vec3 axis; float rate = v3normalize(&axis,rates); NANTest("rate",rate); // Get a quat for the displacement this timestep did. quat q_dot; Quat_SetAxisAndAngle( &q_dot, &axis, rate * dt); NANTest("z",q_dot.z); NANTest("x",q_dot.x); NANTest("y",q_dot.y); NANTest("z",q_dot.z); Quat_Multiply(pGyroFrame, pGyroFrame, &q_dot); Quat_Normalize( pGyroFrame); }
/* * Mod_LoadAliasMD3Model */ void Mod_LoadAliasMD3Model( model_t *mod, model_t *parent, void *buffer, bspFormatDesc_t *unused ) { int version, i, j, l; int bufsize, numverts; qbyte *buf; dmd3header_t *pinmodel; dmd3frame_t *pinframe; dmd3tag_t *pintag; dmd3mesh_t *pinmesh; dmd3skin_t *pinskin; dmd3coord_t *pincoord; dmd3vertex_t *pinvert; elem_t *pinelem, *poutelem; maliasvertex_t *poutvert; vec2_t *poutcoord; maliasskin_t *poutskin; maliasmesh_t *poutmesh; maliastag_t *pouttag; maliasframe_t *poutframe; maliasmodel_t *poutmodel; drawSurfaceAlias_t *drawSurf; pinmodel = ( dmd3header_t * )buffer; version = LittleLong( pinmodel->version ); if( version != MD3_ALIAS_VERSION ) ri.Com_Error( ERR_DROP, "%s has wrong version number (%i should be %i)", mod->name, version, MD3_ALIAS_VERSION ); mod->type = mod_alias; mod->extradata = poutmodel = Mod_Malloc( mod, sizeof( maliasmodel_t ) ); mod->radius = 0; mod->registrationSequence = rf.registrationSequence; mod->touch = &Mod_TouchAliasModel; ClearBounds( mod->mins, mod->maxs ); // byte swap the header fields and sanity check poutmodel->numframes = LittleLong( pinmodel->num_frames ); poutmodel->numtags = LittleLong( pinmodel->num_tags ); poutmodel->nummeshes = LittleLong( pinmodel->num_meshes ); poutmodel->numskins = 0; if( poutmodel->numframes <= 0 ) ri.Com_Error( ERR_DROP, "model %s has no frames", mod->name ); // else if( poutmodel->numframes > MD3_MAX_FRAMES ) // ri.Com_Error( ERR_DROP, "model %s has too many frames", mod->name ); if( poutmodel->numtags > MD3_MAX_TAGS ) ri.Com_Error( ERR_DROP, "model %s has too many tags", mod->name ); else if( poutmodel->numtags < 0 ) ri.Com_Error( ERR_DROP, "model %s has invalid number of tags", mod->name ); if( poutmodel->nummeshes < 0 ) ri.Com_Error( ERR_DROP, "model %s has invalid number of meshes", mod->name ); else if( !poutmodel->nummeshes && !poutmodel->numtags ) ri.Com_Error( ERR_DROP, "model %s has no meshes and no tags", mod->name ); // else if( poutmodel->nummeshes > MD3_MAX_MESHES ) // ri.Com_Error( ERR_DROP, "model %s has too many meshes", mod->name ); bufsize = poutmodel->numframes * ( sizeof( maliasframe_t ) + sizeof( maliastag_t ) * poutmodel->numtags ) + poutmodel->nummeshes * sizeof( maliasmesh_t ) + poutmodel->nummeshes * sizeof( drawSurfaceAlias_t ); buf = Mod_Malloc( mod, bufsize ); // // load the frames // pinframe = ( dmd3frame_t * )( ( qbyte * )pinmodel + LittleLong( pinmodel->ofs_frames ) ); poutframe = poutmodel->frames = ( maliasframe_t * )buf; buf += sizeof( maliasframe_t ) * poutmodel->numframes; for( i = 0; i < poutmodel->numframes; i++, pinframe++, poutframe++ ) { for( j = 0; j < 3; j++ ) { poutframe->scale[j] = MD3_XYZ_SCALE; poutframe->translate[j] = LittleFloat( pinframe->translate[j] ); } // never trust the modeler utility and recalculate bbox and radius ClearBounds( poutframe->mins, poutframe->maxs ); } // // load the tags // pintag = ( dmd3tag_t * )( ( qbyte * )pinmodel + LittleLong( pinmodel->ofs_tags ) ); pouttag = poutmodel->tags = ( maliastag_t * )buf; buf += sizeof( maliastag_t ) * poutmodel->numframes * poutmodel->numtags; for( i = 0; i < poutmodel->numframes; i++ ) { for( l = 0; l < poutmodel->numtags; l++, pintag++, pouttag++ ) { mat3_t axis; for( j = 0; j < 3; j++ ) { axis[AXIS_FORWARD+j] = LittleFloat( pintag->axis[0][j] ); axis[AXIS_RIGHT+j] = LittleFloat( pintag->axis[1][j] ); axis[AXIS_UP+j] = LittleFloat( pintag->axis[2][j] ); pouttag->origin[j] = LittleFloat( pintag->origin[j] ); } Quat_FromMatrix3( axis, pouttag->quat ); Quat_Normalize( pouttag->quat ); Q_strncpyz( pouttag->name, pintag->name, MD3_MAX_PATH ); } } // // allocate drawSurfs // drawSurf = poutmodel->drawSurfs = ( drawSurfaceAlias_t * )buf; buf += sizeof( drawSurfaceAlias_t ) * poutmodel->nummeshes; for( i = 0; i < poutmodel->nummeshes; i++, drawSurf++ ) { drawSurf->type = ST_ALIAS; drawSurf->model = mod; drawSurf->mesh = poutmodel->meshes + i; } // // load meshes // pinmesh = ( dmd3mesh_t * )( ( qbyte * )pinmodel + LittleLong( pinmodel->ofs_meshes ) ); poutmesh = poutmodel->meshes = ( maliasmesh_t * )buf; buf += sizeof( maliasmesh_t ) * poutmodel->nummeshes; for( i = 0; i < poutmodel->nummeshes; i++, poutmesh++ ) { if( strncmp( (const char *)pinmesh->id, IDMD3HEADER, 4 ) ) ri.Com_Error( ERR_DROP, "mesh %s in model %s has wrong id (%s should be %s)", pinmesh->name, mod->name, pinmesh->id, IDMD3HEADER ); Q_strncpyz( poutmesh->name, pinmesh->name, MD3_MAX_PATH ); Mod_StripLODSuffix( poutmesh->name ); poutmesh->numtris = LittleLong( pinmesh->num_tris ); poutmesh->numskins = LittleLong( pinmesh->num_skins ); poutmesh->numverts = numverts = LittleLong( pinmesh->num_verts ); /* if( poutmesh->numskins <= 0 ) ri.Com_Error( ERR_DROP, "mesh %i in model %s has no skins", i, mod->name ); else*/ if( poutmesh->numskins > MD3_MAX_SHADERS ) ri.Com_Error( ERR_DROP, "mesh %i in model %s has too many skins", i, mod->name ); if( poutmesh->numtris <= 0 ) ri.Com_Error( ERR_DROP, "mesh %i in model %s has no elements", i, mod->name ); else if( poutmesh->numtris > MD3_MAX_TRIANGLES ) ri.Com_Error( ERR_DROP, "mesh %i in model %s has too many triangles", i, mod->name ); if( poutmesh->numverts <= 0 ) ri.Com_Error( ERR_DROP, "mesh %i in model %s has no vertices", i, mod->name ); else if( poutmesh->numverts > MD3_MAX_VERTS ) ri.Com_Error( ERR_DROP, "mesh %i in model %s has too many vertices", i, mod->name ); bufsize = sizeof( maliasskin_t ) * poutmesh->numskins + poutmesh->numtris * sizeof( elem_t ) * 3 + numverts * ( sizeof( vec2_t ) + sizeof( maliasvertex_t ) * poutmodel->numframes ); buf = Mod_Malloc( mod, bufsize ); // // load the skins // pinskin = ( dmd3skin_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_skins ) ); poutskin = poutmesh->skins = ( maliasskin_t * )buf; buf += sizeof( maliasskin_t ) * poutmesh->numskins; for( j = 0; j < poutmesh->numskins; j++, pinskin++, poutskin++ ) { Q_strncpyz( poutskin->name, pinskin->name, sizeof( poutskin->name ) ); poutskin->shader = R_RegisterSkin( poutskin->name ); } // // load the elems // pinelem = ( elem_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_elems ) ); poutelem = poutmesh->elems = ( elem_t * )buf; buf += poutmesh->numtris * sizeof( elem_t ) * 3; for( j = 0; j < poutmesh->numtris; j++, pinelem += 3, poutelem += 3 ) { poutelem[0] = (elem_t)LittleLong( pinelem[0] ); poutelem[1] = (elem_t)LittleLong( pinelem[1] ); poutelem[2] = (elem_t)LittleLong( pinelem[2] ); } // // load the texture coordinates // pincoord = ( dmd3coord_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_tcs ) ); poutcoord = poutmesh->stArray = ( vec2_t * )buf; buf += poutmesh->numverts * sizeof( vec2_t ); for( j = 0; j < poutmesh->numverts; j++, pincoord++ ) { poutcoord[j][0] = LittleFloat( pincoord->st[0] ); poutcoord[j][1] = LittleFloat( pincoord->st[1] ); } // // load the vertexes and normals // pinvert = ( dmd3vertex_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->ofs_verts ) ); poutvert = poutmesh->vertexes = ( maliasvertex_t * )buf; for( l = 0, poutframe = poutmodel->frames; l < poutmodel->numframes; l++, poutframe++, pinvert += poutmesh->numverts, poutvert += poutmesh->numverts ) { vec3_t v; for( j = 0; j < poutmesh->numverts; j++ ) { poutvert[j].point[0] = LittleShort( pinvert[j].point[0] ); poutvert[j].point[1] = LittleShort( pinvert[j].point[1] ); poutvert[j].point[2] = LittleShort( pinvert[j].point[2] ); poutvert[j].latlong[0] = pinvert[j].norm[0]; poutvert[j].latlong[1] = pinvert[j].norm[1]; VectorCopy( poutvert[j].point, v ); AddPointToBounds( v, poutframe->mins, poutframe->maxs ); } } pinmesh = ( dmd3mesh_t * )( ( qbyte * )pinmesh + LittleLong( pinmesh->meshsize ) ); } // // setup drawSurfs // for( i = 0; i < poutmodel->nummeshes; i++ ) { drawSurf = poutmodel->drawSurfs + i; drawSurf->type = ST_ALIAS; drawSurf->model = mod; drawSurf->mesh = poutmodel->meshes + i; } // // build S and T vectors for frame 0 // Mod_AliasBuildMeshesForFrame0( mod ); // // calculate model bounds // poutframe = poutmodel->frames; for( i = 0; i < poutmodel->numframes; i++, poutframe++ ) { VectorMA( poutframe->translate, MD3_XYZ_SCALE, poutframe->mins, poutframe->mins ); VectorMA( poutframe->translate, MD3_XYZ_SCALE, poutframe->maxs, poutframe->maxs ); poutframe->radius = RadiusFromBounds( poutframe->mins, poutframe->maxs ); AddPointToBounds( poutframe->mins, mod->mins, mod->maxs ); AddPointToBounds( poutframe->maxs, mod->mins, mod->maxs ); mod->radius = max( mod->radius, poutframe->radius ); } }