float mod_md3_sin[320];
-static size_t Mod_Skeltal_AnimateVertices_maxbonepose = 0;
-static void *Mod_Skeltal_AnimateVertices_bonepose = NULL;
+static size_t Mod_Skeletal_AnimateVertices_maxbonepose = 0;
+static void *Mod_Skeletal_AnimateVertices_bonepose = NULL;
void Mod_Skeletal_FreeBuffers(void)
{
- if(Mod_Skeltal_AnimateVertices_bonepose)
- Mem_Free(Mod_Skeltal_AnimateVertices_bonepose);
- Mod_Skeltal_AnimateVertices_maxbonepose = 0;
- Mod_Skeltal_AnimateVertices_bonepose = NULL;
+ if(Mod_Skeletal_AnimateVertices_bonepose)
+ Mem_Free(Mod_Skeletal_AnimateVertices_bonepose);
+ Mod_Skeletal_AnimateVertices_maxbonepose = 0;
+ Mod_Skeletal_AnimateVertices_bonepose = NULL;
}
void *Mod_Skeletal_AnimateVertices_AllocBuffers(size_t nbytes)
{
- if(Mod_Skeltal_AnimateVertices_maxbonepose < nbytes)
+ if(Mod_Skeletal_AnimateVertices_maxbonepose < nbytes)
{
- if(Mod_Skeltal_AnimateVertices_bonepose)
- Mem_Free(Mod_Skeltal_AnimateVertices_bonepose);
- Mod_Skeltal_AnimateVertices_bonepose = Z_Malloc(nbytes);
- Mod_Skeltal_AnimateVertices_maxbonepose = nbytes;
+ if(Mod_Skeletal_AnimateVertices_bonepose)
+ Mem_Free(Mod_Skeletal_AnimateVertices_bonepose);
+ Mod_Skeletal_AnimateVertices_bonepose = Z_Malloc(nbytes);
+ Mod_Skeletal_AnimateVertices_maxbonepose = nbytes;
}
- return Mod_Skeltal_AnimateVertices_bonepose;
+ return Mod_Skeletal_AnimateVertices_bonepose;
}
void Mod_Skeletal_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
{
+
+ if (!model->surfmesh.num_vertices)
+ return;
+
+ if (!model->num_bones)
+ {
+ if (vertex3f) memcpy(vertex3f, model->surfmesh.data_vertex3f, model->surfmesh.num_vertices*sizeof(float[3]));
+ if (normal3f) memcpy(normal3f, model->surfmesh.data_normal3f, model->surfmesh.num_vertices*sizeof(float[3]));
+ if (svector3f) memcpy(svector3f, model->surfmesh.data_svector3f, model->surfmesh.num_vertices*sizeof(float[3]));
+ if (tvector3f) memcpy(tvector3f, model->surfmesh.data_tvector3f, model->surfmesh.num_vertices*sizeof(float[3]));
+ return;
+ }
+
#ifdef SSE_POSSIBLE
if(r_skeletal_use_sse_defined)
if(r_skeletal_use_sse.integer)
qboolean firstvertex = true;
float dist, yawradius, radius;
float *v;
- float *vertex3f;
- frameblend_t frameblend[MAX_FRAMEBLENDS];
- memset(frameblend, 0, sizeof(frameblend));
- frameblend[0].lerp = 1;
- vertex3f = (float *) Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(float[3]));
VectorClear(loadmodel->normalmins);
VectorClear(loadmodel->normalmaxs);
yawradius = 0;
radius = 0;
- for (frameblend[0].subframe = 0;frameblend[0].subframe < loadmodel->num_poses;frameblend[0].subframe++)
+ if (loadmodel->AnimateVertices)
{
- loadmodel->AnimateVertices(loadmodel, frameblend, NULL, vertex3f, NULL, NULL, NULL);
- for (vnum = 0, v = vertex3f;vnum < loadmodel->surfmesh.num_vertices;vnum++, v += 3)
+ float *vertex3f;
+ frameblend_t frameblend[MAX_FRAMEBLENDS];
+ memset(frameblend, 0, sizeof(frameblend));
+ frameblend[0].lerp = 1;
+ vertex3f = (float *) Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(float[3]));
+ for (frameblend[0].subframe = 0;frameblend[0].subframe < loadmodel->num_poses;frameblend[0].subframe++)
+ {
+ loadmodel->AnimateVertices(loadmodel, frameblend, NULL, vertex3f, NULL, NULL, NULL);
+ for (vnum = 0, v = vertex3f;vnum < loadmodel->surfmesh.num_vertices;vnum++, v += 3)
+ {
+ if (firstvertex)
+ {
+ firstvertex = false;
+ VectorCopy(v, loadmodel->normalmins);
+ VectorCopy(v, loadmodel->normalmaxs);
+ }
+ else
+ {
+ if (loadmodel->normalmins[0] > v[0]) loadmodel->normalmins[0] = v[0];
+ if (loadmodel->normalmins[1] > v[1]) loadmodel->normalmins[1] = v[1];
+ if (loadmodel->normalmins[2] > v[2]) loadmodel->normalmins[2] = v[2];
+ if (loadmodel->normalmaxs[0] < v[0]) loadmodel->normalmaxs[0] = v[0];
+ if (loadmodel->normalmaxs[1] < v[1]) loadmodel->normalmaxs[1] = v[1];
+ if (loadmodel->normalmaxs[2] < v[2]) loadmodel->normalmaxs[2] = v[2];
+ }
+ dist = v[0] * v[0] + v[1] * v[1];
+ if (yawradius < dist)
+ yawradius = dist;
+ dist += v[2] * v[2];
+ if (radius < dist)
+ radius = dist;
+ }
+ }
+ if (vertex3f)
+ Mem_Free(vertex3f);
+ }
+ else
+ {
+ for (vnum = 0, v = loadmodel->surfmesh.data_vertex3f;vnum < loadmodel->surfmesh.num_vertices;vnum++, v += 3)
{
if (firstvertex)
{
radius = dist;
}
}
- if (vertex3f)
- Mem_Free(vertex3f);
radius = sqrt(radius);
yawradius = sqrt(yawradius);
loadmodel->yawmins[0] = loadmodel->yawmins[1] = -yawradius;
texture->currentmaterialflags = texture->basematerialflags;
texture->offsetmapping = OFFSETMAPPING_DEFAULT;
texture->offsetscale = 1;
+ texture->offsetbias = 0;
texture->specularscalemod = 1;
texture->specularpowermod = 1;
texture->surfaceflags = 0;
loadmodel->modeldatatypestring = "MDL";
loadmodel->type = mod_alias;
- loadmodel->AnimateVertices = Mod_MDL_AnimateVertices;
loadmodel->DrawSky = NULL;
loadmodel->DrawAddWaterPlanes = NULL;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->surfmesh.data_neighbor3i = (int *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_triangles * sizeof(int[3]));
}
Mod_MDL_LoadFrames (startframes, numverts, vertremap);
+ loadmodel->AnimateVertices = Mod_MDL_AnimateVertices; // needed during loading, may be cleared by code later in this function
if (loadmodel->surfmesh.data_neighbor3i)
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
Mod_Alias_CalculateBoundingBox();
Mod_Alias_MorphMesh_CompileFrames();
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_MDL_AnimateVertices : NULL;
Mem_Free(vertst);
Mem_Free(vertremap);
surface->num_firstvertex = 0;
surface->num_vertices = loadmodel->surfmesh.num_vertices;
- loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1;
+ loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_MDL_AnimateVertices : NULL;
if (!loadmodel->surfmesh.isanimated)
{
loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
}
+
+ // because shaders can do somewhat unexpected things, check for unusual features now
+ for (i = 0;i < loadmodel->num_textures;i++)
+ {
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_SKY))
+ mod->DrawSky = R_Q1BSP_DrawSky;
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
+ }
}
void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend)
loadmodel->modeldatatypestring = "MD2";
loadmodel->type = mod_alias;
- loadmodel->AnimateVertices = Mod_MDL_AnimateVertices;
loadmodel->DrawSky = NULL;
loadmodel->DrawAddWaterPlanes = NULL;
loadmodel->Draw = R_Q1BSP_Draw;
Mem_Free(vertremap);
+ loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = Mod_MDL_AnimateVertices; // needed during loading, may be cleared by code later in this function
if (loadmodel->surfmesh.data_neighbor3i)
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
Mod_Alias_CalculateBoundingBox();
Mod_Alias_MorphMesh_CompileFrames();
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_MDL_AnimateVertices : NULL;
surface = loadmodel->data_surfaces;
surface->texture = loadmodel->data_textures;
surface->num_firstvertex = 0;
surface->num_vertices = loadmodel->surfmesh.num_vertices;
- loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1;
-
if (!loadmodel->surfmesh.isanimated)
{
Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih);
loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
}
+
+ // because shaders can do somewhat unexpected things, check for unusual features now
+ for (i = 0;i < loadmodel->num_textures;i++)
+ {
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_SKY))
+ mod->DrawSky = R_Q1BSP_DrawSky;
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
+ }
}
void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend)
loadmodel->modeldatatypestring = "MD3";
loadmodel->type = mod_alias;
- loadmodel->AnimateVertices = Mod_MD3_AnimateVertices;
loadmodel->DrawSky = NULL;
loadmodel->DrawAddWaterPlanes = NULL;
loadmodel->Draw = R_Q1BSP_Draw;
if (loadmodel->surfmesh.data_element3s)
for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+ loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = Mod_MD3_AnimateVertices; // needed during loading, may be cleared by code later in this function
if (loadmodel->surfmesh.data_neighbor3i)
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
Mod_Alias_MorphMesh_CompileFrames();
Mod_Alias_CalculateBoundingBox();
Mod_FreeSkinFiles(skinfiles);
Mod_MakeSortedSurfaces(loadmodel);
-
- loadmodel->surfmesh.isanimated = loadmodel->numframes > 1
- || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_MD3_AnimateVertices : NULL;
if (!loadmodel->surfmesh.isanimated)
{
loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
}
+
+ // because shaders can do somewhat unexpected things, check for unusual features now
+ for (i = 0;i < loadmodel->num_textures;i++)
+ {
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_SKY))
+ mod->DrawSky = R_Q1BSP_DrawSky;
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
+ }
}
void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
return;
}
- loadmodel->AnimateVertices = Mod_Skeletal_AnimateVertices;
loadmodel->DrawSky = NULL;
loadmodel->DrawAddWaterPlanes = NULL;
loadmodel->Draw = R_Q1BSP_Draw;
meshvertices = pheader->numverts;
meshtriangles = pheader->numtris;
+ loadmodel->surfmesh.isanimated = loadmodel->num_bones > 1 || loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_Skeletal_AnimateVertices : NULL;
loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
if (loadmodel->surfmesh.data_neighbor3i)
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
- loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1;
-
if (!loadmodel->surfmesh.isanimated)
{
Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih);
loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
}
+
+ // because shaders can do somewhat unexpected things, check for unusual features now
+ for (i = 0;i < loadmodel->num_textures;i++)
+ {
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_SKY))
+ mod->DrawSky = R_Q1BSP_DrawSky;
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
+ }
}
void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
return;
}
- loadmodel->AnimateVertices = Mod_Skeletal_AnimateVertices;
loadmodel->DrawSky = NULL;
loadmodel->DrawAddWaterPlanes = NULL;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->nummodelsurfaces = loadmodel->num_surfaces = pheader->num_meshs;
loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
+ loadmodel->surfmesh.isanimated = loadmodel->num_bones > 1 || loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_Skeletal_AnimateVertices : NULL;
// do most allocations as one merged chunk
data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + (r_enableshadowvolumes.integer ? meshtriangles * sizeof(int[3]) : 0) + meshvertices * (sizeof(float[14]) + sizeof(unsigned short)) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[6]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
if (loadmodel->surfmesh.data_neighbor3i)
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
- loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1;
-
if (!loadmodel->surfmesh.isanimated)
{
Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih);
loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
}
+
+ // because shaders can do somewhat unexpected things, check for unusual features now
+ for (i = 0;i < loadmodel->num_textures;i++)
+ {
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_SKY))
+ mod->DrawSky = R_Q1BSP_DrawSky;
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
+ }
}
// no idea why PSK/PSA files contain weird quaternions but they do...
loadmodel->modeldatatypestring = "PSK";
loadmodel->type = mod_alias;
- loadmodel->AnimateVertices = Mod_Skeletal_AnimateVertices;
loadmodel->DrawSky = NULL;
loadmodel->DrawAddWaterPlanes = NULL;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
loadmodel->surfmesh.num_vertices = meshvertices;
loadmodel->surfmesh.num_triangles = meshtriangles;
+ loadmodel->surfmesh.isanimated = loadmodel->num_bones > 1 || loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_Skeletal_AnimateVertices : NULL;
// do most allocations as one merged chunk
size = loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + loadmodel->surfmesh.num_triangles * sizeof(int[3]) + (r_enableshadowvolumes.integer ? loadmodel->surfmesh.num_triangles * sizeof(int[3]) : 0) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[3]) + loadmodel->surfmesh.num_vertices * sizeof(float[2]) + loadmodel->surfmesh.num_vertices * sizeof(unsigned short) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[6]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t) + ((loadmodel->surfmesh.num_vertices <= 65536) ? (loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3])) : 0);
data = (unsigned char *)Mem_Alloc(loadmodel->mempool, size);
Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
Mod_Alias_CalculateBoundingBox();
- loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1;
-
if (!loadmodel->surfmesh.isanimated)
{
Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih);
loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
}
+
+ // because shaders can do somewhat unexpected things, check for unusual features now
+ for (i = 0;i < loadmodel->num_textures;i++)
+ {
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_SKY))
+ mod->DrawSky = R_Q1BSP_DrawSky;
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
+ }
}
void Mod_INTERQUAKEMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
int *outelements;
const int *inneighbors;
int *outneighbors;
- float *outvertex, *outnormal, *outtexcoord, *outsvector, *outtvector;
+ float *outvertex, *outnormal, *outtexcoord, *outsvector, *outtvector, *outcolor;
// this pointers into the file data are read only through Little* functions so they can be unaligned memory
const float *vnormal = NULL;
const float *vposition = NULL;
const float *vtangent = NULL;
const float *vtexcoord = NULL;
+ const float *vcolor4f = NULL;
const unsigned char *vblendindexes = NULL;
const unsigned char *vblendweights = NULL;
+ const unsigned char *vcolor4ub = NULL;
const unsigned short *framedata = NULL;
// temporary memory allocations (because the data in the file may be misaligned)
iqmanim_t *anims = NULL;
pend = (unsigned char *)bufferend;
if (pbase + sizeof(iqmheader_t) > pend)
- Host_Error ("Mod_INTERQUAKEMODEL_Load: %s is not an Inter-Quake Model %d", loadmodel->name, pend - pbase);
+ Host_Error ("Mod_INTERQUAKEMODEL_Load: %s is not an Inter-Quake Model %d", loadmodel->name, (int)(pend - pbase));
// copy struct (otherwise it may be misaligned)
// LordHavoc: okay it's definitely not misaligned here, but for consistency...
header.num_extensions = LittleLong(header.num_extensions);
header.ofs_extensions = LittleLong(header.ofs_extensions);
- if (header.num_triangles < 1 || header.num_vertexes < 3 || header.num_vertexarrays < 1 || header.num_meshes < 1)
- {
- Con_Printf("%s has no geometry\n", loadmodel->name);
- return;
- }
-
if (header.version == 1)
{
if (pbase + header.ofs_joints + header.num_joints*sizeof(iqmjoint1_t) > pend ||
if (va.format == IQM_UBYTE && va.size == 4)
vblendweights = (const unsigned char *)(pbase + va.offset);
break;
+ case IQM_COLOR:
+ if (va.format == IQM_FLOAT && va.size == 4)
+ vcolor4f = (const float *)(pbase + va.offset);
+ if (va.format == IQM_UBYTE && va.size == 4)
+ vcolor4ub = (const unsigned char *)(pbase + va.offset);
+ break;
}
}
if (header.num_vertexes > 0 && (!vposition || !vtexcoord || ((header.num_frames > 0 || header.num_anims > 0) && (!vblendindexes || !vblendweights))))
text = header.num_text && header.ofs_text ? (const char *)(pbase + header.ofs_text) : "";
- loadmodel->AnimateVertices = Mod_Skeletal_AnimateVertices;
loadmodel->DrawSky = NULL;
loadmodel->DrawAddWaterPlanes = NULL;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->nummodelsurfaces = loadmodel->num_surfaces = header.num_meshes;
loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
+ loadmodel->AnimateVertices = Mod_Skeletal_AnimateVertices; // updated later
meshvertices = header.num_vertexes;
meshtriangles = header.num_triangles;
// do most allocations as one merged chunk
- data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + (r_enableshadowvolumes.integer ? meshtriangles * sizeof(int[3]) : 0) + meshvertices * sizeof(float[14]) + (vblendindexes && vblendweights ? meshvertices * sizeof(unsigned short) : 0) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[6]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
+ data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + (r_enableshadowvolumes.integer ? meshtriangles * sizeof(int[3]) : 0) + meshvertices * (sizeof(float[14]) + (vcolor4f || vcolor4ub ? sizeof(float[4]) : 0)) + (vblendindexes && vblendweights ? meshvertices * sizeof(unsigned short) : 0) + loadmodel->num_poses * loadmodel->num_bones * sizeof(short[6]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
loadmodel->sortedmodelsurfaces = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
loadmodel->surfmesh.data_tvector3f = (float *)data;data += meshvertices * sizeof(float[3]);
loadmodel->surfmesh.data_normal3f = (float *)data;data += meshvertices * sizeof(float[3]);
loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += meshvertices * sizeof(float[2]);
+ if (vcolor4f || vcolor4ub)
+ {
+ loadmodel->surfmesh.data_lightmapcolor4f = (float *)data;data += meshvertices * sizeof(float[4]);
+ }
loadmodel->data_baseboneposeinverse = (float *)data;data += loadmodel->num_bones * sizeof(float[12]);
loadmodel->skinscenes = (animscene_t *)data;data += loadmodel->numskins * sizeof(animscene_t);
loadmodel->data_bones = (aliasbone_t *)data;data += loadmodel->num_bones * sizeof(aliasbone_t);
loadmodel->animscenes[0].framerate = 10;
}
+ loadmodel->surfmesh.isanimated = loadmodel->num_bones > 1 || loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
+ loadmodel->AnimateVertices = loadmodel->surfmesh.isanimated ? Mod_Skeletal_AnimateVertices : NULL;
+
biggestorigin = 0;
if (header.version == 1)
{
+ iqmpose1_t *inpose1 = (iqmpose1_t *)(pbase + header.ofs_poses);
if (header.num_poses)
- {
pose1 = (iqmpose1_t *)Mem_Alloc(loadmodel->mempool, header.num_poses * sizeof(iqmpose1_t));
- memcpy(pose1, pbase + header.ofs_poses, header.num_poses * sizeof(iqmpose1_t));
- }
for (i = 0;i < (int)header.num_poses;i++)
{
float f;
- pose1[i].parent = LittleLong(pose1[i].parent);
- pose1[i].channelmask = LittleLong(pose1[i].channelmask);
+ pose1[i].parent = LittleLong(inpose1[i].parent);
+ pose1[i].channelmask = LittleLong(inpose1[i].channelmask);
for (j = 0;j < 9;j++)
{
- pose1[i].channeloffset[j] = LittleFloat(pose1[i].channeloffset[j]);
- pose1[i].channelscale[j] = LittleFloat(pose1[i].channelscale[j]);
+ pose1[i].channeloffset[j] = LittleFloat(inpose1[i].channeloffset[j]);
+ pose1[i].channelscale[j] = LittleFloat(inpose1[i].channelscale[j]);
}
f = fabs(pose1[i].channeloffset[0]); biggestorigin = max(biggestorigin, f);
f = fabs(pose1[i].channeloffset[1]); biggestorigin = max(biggestorigin, f);
}
else
{
+ iqmpose_t *inpose = (iqmpose_t *)(pbase + header.ofs_poses);
if (header.num_poses)
- {
pose = (iqmpose_t *)Mem_Alloc(loadmodel->mempool, header.num_poses * sizeof(iqmpose_t));
- memcpy(pose, pbase + header.ofs_poses, header.num_poses * sizeof(iqmpose_t));
- }
for (i = 0;i < (int)header.num_poses;i++)
{
float f;
- pose[i].parent = LittleLong(pose[i].parent);
- pose[i].channelmask = LittleLong(pose[i].channelmask);
+ pose[i].parent = LittleLong(inpose[i].parent);
+ pose[i].channelmask = LittleLong(inpose[i].channelmask);
for (j = 0;j < 10;j++)
{
- pose[i].channeloffset[j] = LittleFloat(pose[i].channeloffset[j]);
- pose[i].channelscale[j] = LittleFloat(pose[i].channelscale[j]);
+ pose[i].channeloffset[j] = LittleFloat(inpose[i].channeloffset[j]);
+ pose[i].channelscale[j] = LittleFloat(inpose[i].channelscale[j]);
}
f = fabs(pose[i].channeloffset[0]); biggestorigin = max(biggestorigin, f);
f = fabs(pose[i].channeloffset[1]); biggestorigin = max(biggestorigin, f);
}
}
+ if (vcolor4f)
+ {
+ outcolor = loadmodel->surfmesh.data_lightmapcolor4f;
+ // this unaligned memory access is safe (LittleFloat reads as bytes)
+ for (i = 0;i < (int)header.num_vertexes;i++)
+ {
+ outcolor[0] = LittleFloat(vcolor4f[0]);
+ outcolor[1] = LittleFloat(vcolor4f[1]);
+ outcolor[2] = LittleFloat(vcolor4f[2]);
+ outcolor[3] = LittleFloat(vcolor4f[3]);
+ vcolor4f += 4;
+ outcolor += 4;
+ }
+ }
+ else if (vcolor4ub)
+ {
+ outcolor = loadmodel->surfmesh.data_lightmapcolor4f;
+ // this unaligned memory access is safe (all bytes)
+ for (i = 0;i < (int)header.num_vertexes;i++)
+ {
+ outcolor[0] = vcolor4ub[0] * (1.0f / 255.0f);
+ outcolor[1] = vcolor4ub[1] * (1.0f / 255.0f);
+ outcolor[2] = vcolor4ub[2] * (1.0f / 255.0f);
+ outcolor[3] = vcolor4ub[3] * (1.0f / 255.0f);
+ vcolor4ub += 4;
+ outcolor += 4;
+ }
+ }
+
// load meshes
for (i = 0;i < (int)header.num_meshes;i++)
{
if (!header.ofs_bounds)
Mod_Alias_CalculateBoundingBox();
- loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || loadmodel->animscenes[0].framecount > 1;
-
- if (!loadmodel->surfmesh.isanimated)
+ if (!loadmodel->surfmesh.isanimated && loadmodel->surfmesh.num_triangles >= 1)
{
Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih);
loadmodel->TraceBox = Mod_CollisionBIH_TraceBox;
if (joint1 ) Mem_Free(joint1 );joint1 = NULL;
if (pose ) Mem_Free(pose );pose = NULL;
if (pose1 ) Mem_Free(pose1 );pose1 = NULL;
+
+ // because shaders can do somewhat unexpected things, check for unusual features now
+ for (i = 0;i < loadmodel->num_textures;i++)
+ {
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_SKY))
+ mod->DrawSky = R_Q1BSP_DrawSky;
+ if (loadmodel->data_textures[i].basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA))
+ mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
+ }
}