Mod_BuildTextureVectorsAndNormals(0, mesh->num_vertices, mesh->num_triangles, mesh->data_vertex3f, mesh->data_texcoordtexture2f, mesh->data_element3i, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f, true);
}
-static void Mod_MDLMD2MD3_TraceBox(model_t *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
+static void Mod_MDLMD2MD3_TraceBox(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, linetrace;
+ int i;
float segmentmins[3], segmentmaxs[3];
frameblend_t frameblend[4];
msurface_t *surface;
surfmesh_t *mesh;
- colbrushf_t *thisbrush_start = NULL, *thisbrush_end = NULL;
- matrix4x4_t startmatrix, endmatrix;
+ static int maxvertices = 0;
+ static float *vertex3f = NULL;
memset(trace, 0, sizeof(*trace));
trace->fraction = 1;
trace->realfraction = 1;
trace->hitsupercontentsmask = hitsupercontentsmask;
- segmentmins[0] = min(boxstartmins[0], boxendmins[0]);
- segmentmins[1] = min(boxstartmins[1], boxendmins[1]);
- segmentmins[2] = min(boxstartmins[2], boxendmins[2]);
- segmentmaxs[0] = max(boxstartmaxs[0], boxendmaxs[0]);
- segmentmaxs[1] = max(boxstartmaxs[1], boxendmaxs[1]);
- segmentmaxs[2] = max(boxstartmaxs[2], boxendmaxs[2]);
- linetrace = VectorCompare(boxstartmins, boxstartmaxs) && VectorCompare(boxendmins, boxendmaxs);
- if (!linetrace)
- {
- // box trace, performed as brush trace
- startmatrix = identitymatrix;
- endmatrix = identitymatrix;
- thisbrush_start = Collision_BrushForBox(&startmatrix, boxstartmins, boxstartmaxs);
- thisbrush_end = Collision_BrushForBox(&endmatrix, boxendmins, boxendmaxs);
- }
memset(frameblend, 0, sizeof(frameblend));
frameblend[0].frame = frame;
frameblend[0].lerp = 1;
- for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+ if (VectorLength2(boxmins) + VectorLength2(boxmaxs) == 0)
+ {
+ // 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;
+ for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+ {
+ mesh = surface->groupmesh;
+ if (maxvertices < mesh->num_vertices)
+ {
+ if (vertex3f)
+ Z_Free(vertex3f);
+ maxvertices = (mesh->num_vertices + 255) & ~255;
+ vertex3f = Z_Malloc(maxvertices * sizeof(float[3]));
+ }
+ Mod_Alias_GetMesh_Vertex3f(model, frameblend, mesh, vertex3f);
+ Collision_TraceLineTriangleMeshFloat(trace, start, end, mesh->num_triangles, mesh->data_element3i, vertex3f, SUPERCONTENTS_SOLID, segmentmins, segmentmaxs);
+ }
+ }
+ else
{
- mesh = surface->groupmesh;
- Mod_Alias_GetMesh_Vertex3f(model, frameblend, mesh, varray_vertex3f);
- if (linetrace)
- Collision_TraceLineTriangleMeshFloat(trace, boxstartmins, boxendmins, mesh->num_triangles, mesh->data_element3i, varray_vertex3f, SUPERCONTENTS_SOLID, segmentmins, segmentmaxs);
- else
- Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, mesh->num_triangles, mesh->data_element3i, varray_vertex3f, SUPERCONTENTS_SOLID, segmentmins, segmentmaxs);
+ // box trace, performed as brush trace
+ colbrushf_t *thisbrush_start, *thisbrush_end;
+ vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
+ segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1;
+ segmentmins[1] = min(start[1], end[1]) + boxmins[1] - 1;
+ segmentmins[2] = min(start[2], end[2]) + boxmins[2] - 1;
+ segmentmaxs[0] = max(start[0], end[0]) + boxmaxs[0] + 1;
+ segmentmaxs[1] = max(start[1], end[1]) + boxmaxs[1] + 1;
+ segmentmaxs[2] = max(start[2], end[2]) + boxmaxs[2] + 1;
+ VectorAdd(start, boxmins, boxstartmins);
+ VectorAdd(start, boxmaxs, boxstartmaxs);
+ VectorAdd(end, boxmins, boxendmins);
+ VectorAdd(end, boxmaxs, boxendmaxs);
+ thisbrush_start = Collision_BrushForBox(&identitymatrix, boxstartmins, boxstartmaxs);
+ thisbrush_end = Collision_BrushForBox(&identitymatrix, boxendmins, boxendmaxs);
+ for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+ {
+ mesh = surface->groupmesh;
+ if (maxvertices < mesh->num_vertices)
+ {
+ if (vertex3f)
+ Z_Free(vertex3f);
+ maxvertices = (mesh->num_vertices + 255) & ~255;
+ vertex3f = Z_Malloc(maxvertices * sizeof(float[3]));
+ }
+ Mod_Alias_GetMesh_Vertex3f(model, frameblend, mesh, vertex3f);
+ Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, mesh->num_triangles, mesh->data_element3i, vertex3f, SUPERCONTENTS_SOLID, segmentmins, segmentmaxs);
+ }
}
}
Host_Error ("Mod_ZYMOTICMODEL_Load: only type 1 (skeletal pose) models are currently supported (name = %s)", loadmodel->name);
loadmodel->type = mod_alias;
- loadmodel->DrawSky = NULL;
- loadmodel->Draw = R_Q1BSP_Draw;
- loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
- loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
- loadmodel->DrawLight = R_Q1BSP_DrawLight;
- loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
loadmodel->flags = 0; // there are no flags on zym models
loadmodel->synctype = ST_RAND;
pheader->lump_trizone.start = BigLong(pinmodel->lump_trizone.start);
pheader->lump_trizone.length = BigLong(pinmodel->lump_trizone.length);
+ if (pheader->numtris < 1 || pheader->numverts < 3 || pheader->numshaders < 1)
+ {
+ Con_Printf("%s has no geometry\n");
+ return;
+ }
+ if (pheader->numscenes < 1 || pheader->lump_poses.length < (int)sizeof(float[3][4]))
+ {
+ Con_Printf("%s has no animations\n");
+ return;
+ }
+
+ loadmodel->DrawSky = NULL;
+ loadmodel->Draw = R_Q1BSP_Draw;
+ loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
+ loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
+ loadmodel->DrawLight = R_Q1BSP_DrawLight;
+ loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+
loadmodel->numframes = pheader->numscenes;
loadmodel->num_surfaces = pheader->numshaders;
Mem_Free(vertbonecounts);
Mem_Free(verts);
Mem_Free(outtexcoord2f);
+ Mod_FreeSkinFiles(skinfiles);
}
void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
Host_Error ("Mod_DARKPLACESMODEL_Load: only type 2 (hierarchical skeletal pose) models are currently supported (name = %s)", loadmodel->name);
loadmodel->type = mod_alias;
- loadmodel->DrawSky = NULL;
- loadmodel->Draw = R_Q1BSP_Draw;
- loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
- loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
- loadmodel->DrawLight = R_Q1BSP_DrawLight;
- loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
loadmodel->flags = 0; // there are no flags on zym models
loadmodel->synctype = ST_RAND;
pheader->ofs_meshs = BigLong(pheader->ofs_meshs);
pheader->ofs_frames = BigLong(pheader->ofs_frames);
+ if (pheader->num_bones < 1 || pheader->num_meshs < 1)
+ {
+ Con_Printf("%s has no geometry\n");
+ return;
+ }
+ if (pheader->num_frames < 1)
+ {
+ Con_Printf("%s has no frames\n");
+ return;
+ }
+
+ loadmodel->DrawSky = NULL;
+ loadmodel->Draw = R_Q1BSP_Draw;
+ loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
+ loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
+ loadmodel->DrawLight = R_Q1BSP_DrawLight;
+ loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+
// model bbox
for (i = 0;i < 3;i++)
{
dpmmesh++;
}
+ Mod_FreeSkinFiles(skinfiles);
}
static void Mod_PSKMODEL_AnimKeyToMatrix(float *origin, float *quat, matrix4x4_t *m)
Mod_Alias_Mesh_CompileFrameZero(mesh);
Mem_Free(animfilebuffer);
+ Mod_FreeSkinFiles(skinfiles);
}