// blend the vertex bone weights
// special case for the extremely common wf[0] == 1 because it saves 3 multiplies per array when compared to the other case (w[0] is always 1 if only one bone controls this vertex, artists only use multiple bones for certain special cases)
// special case for the first bone because it avoids the need to memset the arrays before filling
+ if (vertex3f)
{
const float *v = model->surfmesh.data_vertex3f;
const int *wi = model->surfmesh.data_vertexweightindex4i;
for (blendnum = 0;blendnum < numblends;blendnum++)
{
const md3vertex_t *verts = model->surfmesh.data_morphmd3vertex + numverts * frameblend[blendnum].subframe;
- float scale = frameblend[blendnum].lerp * (1.0f / 64.0f);
- if (blendnum == 0)
+ if (vertex3f)
{
- for (i = 0;i < numverts;i++)
+ float scale = frameblend[blendnum].lerp * (1.0f / 64.0f);
+ if (blendnum == 0)
{
- vertex3f[i * 3 + 0] = verts[i].origin[0] * scale;
- vertex3f[i * 3 + 1] = verts[i].origin[1] * scale;
- vertex3f[i * 3 + 2] = verts[i].origin[2] * scale;
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] = verts[i].origin[0] * scale;
+ vertex3f[i * 3 + 1] = verts[i].origin[1] * scale;
+ vertex3f[i * 3 + 2] = verts[i].origin[2] * scale;
+ }
}
- }
- else
- {
- for (i = 0;i < numverts;i++)
+ else
{
- vertex3f[i * 3 + 0] += verts[i].origin[0] * scale;
- vertex3f[i * 3 + 1] += verts[i].origin[1] * scale;
- vertex3f[i * 3 + 2] += verts[i].origin[2] * scale;
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] += verts[i].origin[0] * scale;
+ vertex3f[i * 3 + 1] += verts[i].origin[1] * scale;
+ vertex3f[i * 3 + 2] += verts[i].origin[2] * scale;
+ }
}
}
// the yaw and pitch stored in md3 models are 8bit quantized angles
for (blendnum = 0;blendnum < numblends;blendnum++)
{
const trivertx_t *verts = model->surfmesh.data_morphmdlvertex + numverts * frameblend[blendnum].subframe;
- float scale[3];
- if (model->surfmesh.data_morphmd2framesize6f)
- VectorScale(model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6, frameblend[blendnum].lerp, scale);
- else
- VectorScale(model->surfmesh.num_morphmdlframescale, frameblend[blendnum].lerp, scale);
- if (blendnum == 0)
+ if (vertex3f)
{
- for (i = 0;i < numverts;i++)
+ float scale[3];
+ if (model->surfmesh.data_morphmd2framesize6f)
+ VectorScale(model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6, frameblend[blendnum].lerp, scale);
+ else
+ VectorScale(model->surfmesh.num_morphmdlframescale, frameblend[blendnum].lerp, scale);
+ if (blendnum == 0)
{
- vertex3f[i * 3 + 0] = translate[0] + verts[i].v[0] * scale[0];
- vertex3f[i * 3 + 1] = translate[1] + verts[i].v[1] * scale[1];
- vertex3f[i * 3 + 2] = translate[2] + verts[i].v[2] * scale[2];
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] = translate[0] + verts[i].v[0] * scale[0];
+ vertex3f[i * 3 + 1] = translate[1] + verts[i].v[1] * scale[1];
+ vertex3f[i * 3 + 2] = translate[2] + verts[i].v[2] * scale[2];
+ }
}
- }
- else
- {
- for (i = 0;i < numverts;i++)
+ else
{
- vertex3f[i * 3 + 0] += verts[i].v[0] * scale[0];
- vertex3f[i * 3 + 1] += verts[i].v[1] * scale[1];
- vertex3f[i * 3 + 2] += verts[i].v[2] * scale[2];
+ for (i = 0;i < numverts;i++)
+ {
+ vertex3f[i * 3 + 0] += verts[i].v[0] * scale[0];
+ vertex3f[i * 3 + 1] += verts[i].v[1] * scale[1];
+ vertex3f[i * 3 + 2] += verts[i].v[2] * scale[2];
+ }
}
}
// the vertex normals in mdl models are an index into a table of
{
int i, k;
double scale;
- float *basebonepose = (float *) Mem_Alloc(tempmempool, loadmodel->num_bones * sizeof(float[12]));
+ float *basebonepose;
float *in12f = loadmodel->data_poses;
- float *out12f = basebonepose;
+ float *out12f;
float *outinv12f = loadmodel->data_baseboneposeinverse;
+ if (!loadmodel->num_bones)
+ return;
+ out12f = basebonepose = (float *) Mem_Alloc(tempmempool, loadmodel->num_bones * sizeof(float[12]));
for (i = 0;i < loadmodel->num_bones;i++, in12f += 12, out12f += 12, outinv12f += 12)
{
if (loadmodel->data_bones[i].parent >= 0)
{
frameblend[0].subframe = i;
loadmodel->AnimateVertices(loadmodel, frameblend, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_normal3f, NULL, NULL);
- Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer);
+ Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer != 0);
// encode the svector and tvector in 3 byte format for permanent storage
for (j = 0;j < loadmodel->surfmesh.num_vertices;j++)
{
static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, int frame, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
{
int i;
+ vec3_t shiftstart, shiftend;
float segmentmins[3], segmentmaxs[3];
frameblend_t frameblend[MAX_FRAMEBLENDS];
msurface_t *surface;
maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
}
- if (VectorLength2(boxmins) + VectorLength2(boxmaxs) == 0)
+ if (VectorCompare(boxmins, boxmaxs))
{
// line trace
- segmentmins[0] = min(start[0], end[0]) - 1;
- segmentmins[1] = min(start[1], end[1]) - 1;
- segmentmins[2] = min(start[2], end[2]) - 1;
- segmentmaxs[0] = max(start[0], end[0]) + 1;
- segmentmaxs[1] = max(start[1], end[1]) + 1;
- segmentmaxs[2] = max(start[2], end[2]) + 1;
+ VectorAdd(start, boxmins, shiftstart);
+ VectorAdd(end, boxmins, shiftend);
+ segmentmins[0] = min(shiftstart[0], shiftend[0]) - 1;
+ segmentmins[1] = min(shiftstart[1], shiftend[1]) - 1;
+ segmentmins[2] = min(shiftstart[2], shiftend[2]) - 1;
+ segmentmaxs[0] = max(shiftstart[0], shiftend[0]) + 1;
+ segmentmaxs[1] = max(shiftstart[1], shiftend[1]) + 1;
+ segmentmaxs[2] = max(shiftstart[2], shiftend[2]) + 1;
for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
{
model->AnimateVertices(model, frameblend, vertex3f, NULL, NULL, NULL);
- Collision_TraceLineTriangleMeshFloat(trace, start, end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
+ Collision_TraceLineTriangleMeshFloat(trace, shiftstart, shiftend, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
}
}
else
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->numframes = pheader->num_frames;
loadmodel->num_bones = pheader->num_bones;
- loadmodel->num_poses = loadmodel->num_frames;
+ loadmodel->num_poses = loadmodel->numframes;
loadmodel->nummodelsurfaces = loadmodel->num_surfaces = pheader->num_meshs;
loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
loadmodel->num_texturesperskin = loadmodel->num_surfaces;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->Draw = R_Q1BSP_Draw;
loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+ loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
loadmodel->DrawLight = R_Q1BSP_DrawLight;