3 #include "cl_collision.h"
11 // LordHavoc: vertex arrays
13 float *aliasvertcolorbuf;
14 float *aliasvertcolor; // this may point at aliasvertcolorbuf or at vertex arrays in the mesh backend
15 float *aliasvert_svectors;
16 float *aliasvert_tvectors;
17 float *aliasvert_normals;
19 float *aliasvertcolor2;
21 zymbonematrix *zymbonepose;
23 mempool_t *gl_models_mempool;
25 void gl_models_start(void)
27 // allocate vertex processing arrays
28 gl_models_mempool = Mem_AllocPool("GL_Models");
29 aliasvertcolor = aliasvertcolorbuf = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
30 aliasvert_svectors = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
31 aliasvert_tvectors = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
32 aliasvert_normals = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
33 aliasvertcolor2 = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); // used temporarily for tinted coloring
34 zymbonepose = Mem_Alloc(gl_models_mempool, sizeof(zymbonematrix[256]));
35 aliasvertusage = Mem_Alloc(gl_models_mempool, sizeof(int[MD2MAX_VERTS]));
38 void gl_models_shutdown(void)
40 Mem_FreePool(&gl_models_mempool);
43 void gl_models_newmap(void)
47 void GL_Models_Init(void)
49 R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap);
52 void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float *normals, float *svectors, float *tvectors)
55 float lerp1, lerp2, lerp3, lerp4;
56 const aliasvertex_t *verts1, *verts2, *verts3, *verts4;
59 Host_Error("R_Model_Alias_GetVerts: vertices == NULL.\n");
60 if (svectors != NULL && (tvectors == NULL || normals == NULL))
61 Host_Error("R_Model_Alias_GetVerts: svectors requires tvectors and normals.\n");
62 if (tvectors != NULL && (svectors == NULL || normals == NULL))
63 Host_Error("R_Model_Alias_GetVerts: tvectors requires svectors and normals.\n");
65 vertcount = ent->model->numverts;
66 verts1 = ent->model->mdlmd2data_pose + ent->frameblend[0].frame * vertcount;
67 lerp1 = ent->frameblend[0].lerp;
68 if (ent->frameblend[1].lerp)
70 verts2 = ent->model->mdlmd2data_pose + ent->frameblend[1].frame * vertcount;
71 lerp2 = ent->frameblend[1].lerp;
72 if (ent->frameblend[2].lerp)
74 verts3 = ent->model->mdlmd2data_pose + ent->frameblend[2].frame * vertcount;
75 lerp3 = ent->frameblend[2].lerp;
76 if (ent->frameblend[3].lerp)
78 verts4 = ent->model->mdlmd2data_pose + ent->frameblend[3].frame * vertcount;
79 lerp4 = ent->frameblend[3].lerp;
83 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++, verts4++)
85 VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices);
86 VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normals);
87 VectorMAMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, lerp4, verts4->svector, svectors);
88 CrossProduct(svectors, normals, tvectors);
91 else if (normals != NULL)
93 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++, verts4++)
95 VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices);
96 VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normals);
100 for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++, verts4++)
101 VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices);
106 if (svectors != NULL)
108 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++)
110 VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices);
111 VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normals);
112 VectorMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, svectors);
113 CrossProduct(svectors, normals, tvectors);
116 else if (normals != NULL)
118 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++)
120 VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices);
121 VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normals);
125 for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++)
126 VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices);
132 if (svectors != NULL)
134 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++)
136 VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices);
137 VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normals);
138 VectorMAM(lerp1, verts1->svector, lerp2, verts2->svector, svectors);
139 CrossProduct(svectors, normals, tvectors);
142 else if (normals != NULL)
144 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++)
146 VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices);
147 VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normals);
151 for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++)
152 VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices);
158 if (svectors != NULL)
160 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++)
162 VectorM(lerp1, verts1->origin, vertices);
163 VectorM(lerp1, verts1->normal, normals);
164 VectorM(lerp1, verts1->svector, svectors);
165 CrossProduct(svectors, normals, tvectors);
168 else if (normals != NULL)
170 for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++)
172 VectorM(lerp1, verts1->origin, vertices);
173 VectorM(lerp1, verts1->normal, normals);
177 for (i = 0;i < vertcount;i++, vertices += 4, verts1++)
178 VectorM(lerp1, verts1->origin, vertices);
182 skinframe_t *R_FetchSkinFrame(const entity_render_t *ent)
184 model_t *model = ent->model;
185 int s = ent->skinnum;
186 if ((unsigned int)s >= (unsigned int)model->numskins)
188 if (model->skinscenes[s].framecount > 1)
189 return &model->skinframes[model->skinscenes[s].firstframe + (int) (cl.time * 10) % model->skinscenes[s].framecount];
191 return &model->skinframes[model->skinscenes[s].firstframe];
194 aliasskin_t *R_FetchAliasSkin(const entity_render_t *ent, const aliasmesh_t *mesh)
196 model_t *model = ent->model;
197 int s = ent->skinnum;
198 if ((unsigned int)s >= (unsigned int)model->numskins)
200 if (model->skinscenes[s].framecount > 1)
201 s = model->skinscenes[s].firstframe + (int) (cl.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
203 s = model->skinscenes[s].firstframe;
204 if (s > mesh->num_skins)
205 return mesh->data_skins;
206 return mesh->data_skins + s;
209 void R_DrawAliasModelCallback (const void *calldata1, int calldata2)
211 int c, fullbright, layernum;
212 float tint[3], fog, ifog, colorscale;
216 const entity_render_t *ent = calldata1;
217 aliasmesh_t *mesh = ent->model->mdlmd2data_meshes + calldata2;
221 R_Mesh_Matrix(&ent->matrix);
226 VectorSubtract(ent->origin, r_origin, diff);
227 fog = DotProduct(diff,diff);
230 fog = exp(fogdensity/fog);
235 // fog method: darken, additive fog
236 // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
237 // 2. render fog as additive
241 memset(&m, 0, sizeof(m));
242 skin = R_FetchAliasSkin(ent, mesh);
243 R_Mesh_ResizeCheck(mesh->num_vertices);
244 R_Model_Alias_GetVerts(ent, varray_vertex, aliasvert_normals, NULL, NULL);
245 memcpy(varray_texcoord[0], mesh->data_texcoords, mesh->num_vertices * sizeof(float[4]));
246 for (layernum = 0, layer = skin->data_layers;layernum < skin->num_layers;layernum++, layer++)
248 if (((layer->flags & ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED) && ent->colormap < 0)
249 || ((layer->flags & ALIASLAYER_NODRAW_IF_COLORMAPPED) && ent->colormap >= 0)
250 || (layer->flags & ALIASLAYER_DRAW_PER_LIGHT))
252 if (layer->flags & ALIASLAYER_FOG)
254 m.blendfunc1 = GL_SRC_ALPHA;
255 m.blendfunc2 = GL_ONE;
256 colorscale = r_colorscale;
257 m.texrgbscale[0] = 1;
258 m.tex[0] = R_GetTexture(layer->texture);
260 GL_Color(fogcolor[0] * fog * colorscale, fogcolor[1] * fog * colorscale, fogcolor[2] * fog * colorscale, ent->alpha);
261 c_alias_polys += mesh->num_triangles;
262 R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_elements);
265 if ((layer->flags & ALIASLAYER_ADD) || ((layer->flags & ALIASLAYER_ALPHA) && (ent->effects & EF_ADDITIVE)))
267 m.blendfunc1 = GL_SRC_ALPHA;
268 m.blendfunc2 = GL_ONE;
270 else if ((layer->flags & ALIASLAYER_ALPHA) || ent->alpha != 1.0)
272 m.blendfunc1 = GL_SRC_ALPHA;
273 m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
277 m.blendfunc1 = GL_ONE;
278 m.blendfunc2 = GL_ZERO;
280 colorscale = r_colorscale;
281 m.texrgbscale[0] = 1;
282 if (gl_combine.integer)
285 m.texrgbscale[0] = 4;
287 m.tex[0] = R_GetTexture(layer->texture);
289 if (layer->flags & ALIASLAYER_COLORMAP_PANTS)
291 // 128-224 are backwards ranges
292 c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
293 bcolor = (qbyte *) (&palette_complete[c]);
294 fullbright = c >= 224;
295 VectorScale(bcolor, (1.0f / 255.0f), tint);
297 else if (layer->flags & ALIASLAYER_COLORMAP_SHIRT)
299 // 128-224 are backwards ranges
300 c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
301 bcolor = (qbyte *) (&palette_complete[c]);
302 fullbright = c >= 224;
303 VectorScale(bcolor, (1.0f / 255.0f), tint);
307 tint[0] = tint[1] = tint[2] = 1;
310 VectorScale(tint, ifog * colorscale, tint);
311 if (!(layer->flags & ALIASLAYER_DIFFUSE))
313 if (ent->effects & EF_FULLBRIGHT)
316 GL_Color(tint[0], tint[1], tint[2], ent->alpha);
318 R_LightModel(ent, mesh->num_vertices, varray_vertex, aliasvert_normals, varray_color, tint[0], tint[1], tint[2], false);
319 c_alias_polys += mesh->num_triangles;
320 R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_elements);
324 void R_Model_Alias_Draw(entity_render_t *ent)
328 if (ent->alpha < (1.0f / 64.0f))
329 return; // basically completely transparent
333 for (meshnum = 0, mesh = ent->model->mdlmd2data_meshes;meshnum < ent->model->mdlmd2num_meshes;meshnum++, mesh++)
335 if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_FetchAliasSkin(ent, mesh)->flags & ALIASSKIN_TRANSPARENT)
336 R_MeshQueue_AddTransparent(ent->origin, R_DrawAliasModelCallback, ent, meshnum);
338 R_DrawAliasModelCallback(ent, meshnum);
342 void R_Model_Alias_DrawFakeShadow (entity_render_t *ent)
348 float *v, planenormal[3], planedist, dist, projection[3], floororigin[3], surfnormal[3], lightdirection[3], v2[3];
350 if ((ent->effects & EF_ADDITIVE) || ent->alpha < 1)
353 lightdirection[0] = 0.5;
354 lightdirection[1] = 0.2;
355 lightdirection[2] = -1;
356 VectorNormalizeFast(lightdirection);
358 VectorMA(ent->origin, 65536.0f, lightdirection, v2);
359 if (CL_TraceLine(ent->origin, v2, floororigin, surfnormal, 0, false, NULL) == 1)
362 R_Mesh_Matrix(&ent->matrix);
364 memset(&m, 0, sizeof(m));
365 m.blendfunc1 = GL_SRC_ALPHA;
366 m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
368 GL_Color(0, 0, 0, 0.5);
370 // put a light direction in the entity's coordinate space
371 Matrix4x4_Transform3x3(&ent->inversematrix, lightdirection, projection);
372 VectorNormalizeFast(projection);
374 // put the plane's normal in the entity's coordinate space
375 Matrix4x4_Transform3x3(&ent->inversematrix, surfnormal, planenormal);
376 VectorNormalizeFast(planenormal);
378 // put the plane's distance in the entity's coordinate space
379 VectorSubtract(floororigin, ent->origin, floororigin);
380 planedist = DotProduct(floororigin, surfnormal) + 2;
382 dist = -1.0f / DotProduct(projection, planenormal);
383 VectorScale(projection, dist, projection);
384 for (meshnum = 0, mesh = ent->model->mdlmd2data_meshes;meshnum < ent->model->mdlmd2num_meshes;meshnum++)
386 skin = R_FetchAliasSkin(ent, mesh);
387 if (skin->flags & ALIASSKIN_TRANSPARENT)
389 R_Mesh_ResizeCheck(mesh->num_vertices);
390 R_Model_Alias_GetVerts(ent, varray_vertex, NULL, NULL, NULL);
391 for (i = 0, v = varray_vertex;i < mesh->num_vertices;i++, v += 4)
393 dist = DotProduct(v, planenormal) - planedist;
395 VectorMA(v, dist, projection, v);
397 c_alias_polys += mesh->num_triangles;
398 R_Mesh_Draw(mesh->num_vertices, mesh->num_triangles, mesh->data_elements);
402 void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
407 float projectdistance;
408 if (ent->effects & EF_ADDITIVE || ent->alpha < 1)
410 projectdistance = lightradius + ent->model->radius - sqrt(DotProduct(relativelightorigin, relativelightorigin));
411 if (projectdistance > 0.1)
413 R_Mesh_Matrix(&ent->matrix);
414 for (meshnum = 0, mesh = ent->model->mdlmd2data_meshes;meshnum < ent->model->mdlmd2num_meshes;meshnum++)
416 skin = R_FetchAliasSkin(ent, mesh);
417 if (skin->flags & ALIASSKIN_TRANSPARENT)
419 R_Mesh_ResizeCheck(mesh->num_vertices * 2);
420 R_Model_Alias_GetVerts(ent, varray_vertex, NULL, NULL, NULL);
421 R_Shadow_Volume(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, mesh->data_neighbors, relativelightorigin, lightradius, projectdistance);
426 void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor)
428 int c, meshnum, layernum;
429 float fog, ifog, lightcolor2[3];
436 if (ent->effects & (EF_ADDITIVE | EF_FULLBRIGHT) || ent->alpha < 1)
439 R_Mesh_Matrix(&ent->matrix);
444 VectorSubtract(ent->origin, r_origin, diff);
445 fog = DotProduct(diff,diff);
448 fog = exp(fogdensity/fog);
453 // fog method: darken, additive fog
454 // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
455 // 2. render fog as additive
459 for (meshnum = 0, mesh = ent->model->mdlmd2data_meshes;meshnum < ent->model->mdlmd2num_meshes;meshnum++, mesh++)
461 skin = R_FetchAliasSkin(ent, mesh);
462 if (skin->flags & ALIASSKIN_TRANSPARENT)
464 R_Mesh_ResizeCheck(mesh->num_vertices);
465 R_Model_Alias_GetVerts(ent, varray_vertex, aliasvert_normals, aliasvert_svectors, aliasvert_tvectors);
466 for (layernum = 0, layer = skin->data_layers;layernum < skin->num_layers;layernum++, layer++)
468 if (!(layer->flags & ALIASLAYER_DRAW_PER_LIGHT)
469 || ((layer->flags & ALIASLAYER_NODRAW_IF_NOTCOLORMAPPED) && ent->colormap < 0)
470 || ((layer->flags & ALIASLAYER_NODRAW_IF_COLORMAPPED) && ent->colormap >= 0))
472 lightcolor2[0] = lightcolor[0] * ifog;
473 lightcolor2[1] = lightcolor[1] * ifog;
474 lightcolor2[2] = lightcolor[2] * ifog;
475 if (layer->flags & ALIASLAYER_SPECULAR)
477 c_alias_polys += mesh->num_triangles;
478 R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, mesh->data_texcoords, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, layer->texture, layer->nmap, NULL);
480 else if (layer->flags & ALIASLAYER_DIFFUSE)
482 if (layer->flags & ALIASLAYER_COLORMAP_PANTS)
484 // 128-224 are backwards ranges
485 c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
486 // fullbright passes were already taken care of, so skip them in realtime lighting passes
489 bcolor = (qbyte *) (&palette_complete[c]);
490 lightcolor2[0] *= bcolor[0] * (1.0f / 255.0f);
491 lightcolor2[1] *= bcolor[1] * (1.0f / 255.0f);
492 lightcolor2[2] *= bcolor[2] * (1.0f / 255.0f);
494 else if (layer->flags & ALIASLAYER_COLORMAP_SHIRT)
496 // 128-224 are backwards ranges
497 c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
498 // fullbright passes were already taken care of, so skip them in realtime lighting passes
501 bcolor = (qbyte *) (&palette_complete[c]);
502 lightcolor2[0] *= bcolor[0] * (1.0f / 255.0f);
503 lightcolor2[1] *= bcolor[1] * (1.0f / 255.0f);
504 lightcolor2[2] *= bcolor[2] * (1.0f / 255.0f);
506 c_alias_polys += mesh->num_triangles;
507 R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_elements, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, mesh->data_texcoords, relativelightorigin, lightradius, lightcolor2, layer->texture, layer->nmap, NULL);
513 float lightcolor2[3];
515 skinframe_t *skinframe;
516 R_Mesh_Matrix(&ent->matrix);
517 R_Mesh_ResizeCheck(ent->model->numverts);
518 R_Model_Alias_GetVerts(ent, varray_vertex, aliasvert_normals, aliasvert_svectors, aliasvert_tvectors);
519 skinframe = R_FetchSkinFrame(ent);
521 // note: to properly handle fog this should scale the lightcolor into lightcolor2 according to 1-fog scaling
523 R_Shadow_SpecularLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, NULL, NULL, NULL);
525 if (!skinframe->base && !skinframe->pants && !skinframe->shirt && !skinframe->glow)
527 R_Shadow_DiffuseLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, lightradius, lightcolor, r_notexture, NULL, NULL);
531 if (!skinframe->merged || (ent->colormap >= 0 && skinframe->base && (skinframe->pants || skinframe->shirt)))
533 // 128-224 are backwards ranges
534 // we only render non-fullbright ranges here
535 if (skinframe->pants && (ent->colormap & 0xF) < 0xE)
537 c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
538 bcolor = (qbyte *) (&palette_complete[c]);
539 lightcolor2[0] = lightcolor[0] * bcolor[0] * (1.0f / 255.0f);
540 lightcolor2[1] = lightcolor[1] * bcolor[1] * (1.0f / 255.0f);
541 lightcolor2[2] = lightcolor[2] * bcolor[2] * (1.0f / 255.0f);
542 R_Shadow_DiffuseLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, lightradius, lightcolor2, skinframe->pants, skinframe->nmap, NULL);
545 // we only render non-fullbright ranges here
546 if (skinframe->shirt && (ent->colormap & 0xF0) < 0xE0)
548 c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
549 bcolor = (qbyte *) (&palette_complete[c]);
550 lightcolor2[0] = lightcolor[0] * bcolor[0] * (1.0f / 255.0f);
551 lightcolor2[1] = lightcolor[1] * bcolor[1] * (1.0f / 255.0f);
552 lightcolor2[2] = lightcolor[2] * bcolor[2] * (1.0f / 255.0f);
553 R_Shadow_DiffuseLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, lightradius, lightcolor2, skinframe->shirt, skinframe->nmap, NULL);
557 R_Shadow_DiffuseLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, lightradius, lightcolor, skinframe->base, skinframe->nmap, NULL);
560 if (skinframe->merged)
561 R_Shadow_DiffuseLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, lightradius, lightcolor, skinframe->merged, skinframe->nmap, NULL);
565 int ZymoticLerpBones(int count, const zymbonematrix *bonebase, const frameblend_t *blend, const zymbone_t *bone)
568 float lerp1, lerp2, lerp3, lerp4;
569 zymbonematrix *out, rootmatrix, m;
570 const zymbonematrix *bone1, *bone2, *bone3, *bone4;
572 rootmatrix.m[0][0] = 1;
573 rootmatrix.m[0][1] = 0;
574 rootmatrix.m[0][2] = 0;
575 rootmatrix.m[0][3] = 0;
576 rootmatrix.m[1][0] = 0;
577 rootmatrix.m[1][1] = 1;
578 rootmatrix.m[1][2] = 0;
579 rootmatrix.m[1][3] = 0;
580 rootmatrix.m[2][0] = 0;
581 rootmatrix.m[2][1] = 0;
582 rootmatrix.m[2][2] = 1;
583 rootmatrix.m[2][3] = 0;
585 bone1 = bonebase + blend[0].frame * count;
586 lerp1 = blend[0].lerp;
589 bone2 = bonebase + blend[1].frame * count;
590 lerp2 = blend[1].lerp;
593 bone3 = bonebase + blend[2].frame * count;
594 lerp3 = blend[2].lerp;
598 bone4 = bonebase + blend[3].frame * count;
599 lerp4 = blend[3].lerp;
600 for (i = 0, out = zymbonepose;i < count;i++, out++)
602 // interpolate matrices
603 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
604 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
605 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
606 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
607 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
608 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
609 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
610 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
611 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
612 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
613 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
614 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
615 if (bone->parent >= 0)
616 R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
618 R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
629 for (i = 0, out = zymbonepose;i < count;i++, out++)
631 // interpolate matrices
632 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
633 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
634 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
635 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
636 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
637 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
638 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
639 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
640 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
641 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
642 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
643 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
644 if (bone->parent >= 0)
645 R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
647 R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
658 for (i = 0, out = zymbonepose;i < count;i++, out++)
660 // interpolate matrices
661 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
662 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
663 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
664 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
665 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
666 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
667 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
668 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
669 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
670 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
671 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
672 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
673 if (bone->parent >= 0)
674 R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
676 R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
689 for (i = 0, out = zymbonepose;i < count;i++, out++)
691 // interpolate matrices
692 m.m[0][0] = bone1->m[0][0] * lerp1;
693 m.m[0][1] = bone1->m[0][1] * lerp1;
694 m.m[0][2] = bone1->m[0][2] * lerp1;
695 m.m[0][3] = bone1->m[0][3] * lerp1;
696 m.m[1][0] = bone1->m[1][0] * lerp1;
697 m.m[1][1] = bone1->m[1][1] * lerp1;
698 m.m[1][2] = bone1->m[1][2] * lerp1;
699 m.m[1][3] = bone1->m[1][3] * lerp1;
700 m.m[2][0] = bone1->m[2][0] * lerp1;
701 m.m[2][1] = bone1->m[2][1] * lerp1;
702 m.m[2][2] = bone1->m[2][2] * lerp1;
703 m.m[2][3] = bone1->m[2][3] * lerp1;
704 if (bone->parent >= 0)
705 R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
707 R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
715 for (i = 0, out = zymbonepose;i < count;i++, out++)
717 if (bone->parent >= 0)
718 R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &bone1->m[0][0], &out->m[0][0]);
720 R_ConcatTransforms(&rootmatrix.m[0][0], &bone1->m[0][0], &out->m[0][0]);
729 void ZymoticTransformVerts(int vertcount, float *vertex, int *bonecounts, zymvertex_t *vert)
733 zymbonematrix *matrix;
737 // FIXME: validate bonecounts at load time (must be >= 1)
738 // FIXME: need 4th component in origin, for how much of the translate to blend in
741 matrix = &zymbonepose[vert->bonenum];
742 out[0] = vert->origin[0] * matrix->m[0][0] + vert->origin[1] * matrix->m[0][1] + vert->origin[2] * matrix->m[0][2] + matrix->m[0][3];
743 out[1] = vert->origin[0] * matrix->m[1][0] + vert->origin[1] * matrix->m[1][1] + vert->origin[2] * matrix->m[1][2] + matrix->m[1][3];
744 out[2] = vert->origin[0] * matrix->m[2][0] + vert->origin[1] * matrix->m[2][1] + vert->origin[2] * matrix->m[2][2] + matrix->m[2][3];
752 matrix = &zymbonepose[vert->bonenum];
753 out[0] += vert->origin[0] * matrix->m[0][0] + vert->origin[1] * matrix->m[0][1] + vert->origin[2] * matrix->m[0][2] + matrix->m[0][3];
754 out[1] += vert->origin[0] * matrix->m[1][0] + vert->origin[1] * matrix->m[1][1] + vert->origin[2] * matrix->m[1][2] + matrix->m[1][3];
755 out[2] += vert->origin[0] * matrix->m[2][0] + vert->origin[1] * matrix->m[2][1] + vert->origin[2] * matrix->m[2][2] + matrix->m[2][3];
763 void ZymoticCalcNormals(int vertcount, float *vertex, float *normals, int shadercount, int *renderlist)
766 float *out, v1[3], v2[3], normal[3], s;
769 memset(normals, 0, sizeof(float) * vertcount * 3);
770 memset(aliasvertusage, 0, sizeof(int) * vertcount);
771 // parse render list and accumulate surface normals
780 v1[0] = vertex[a+0] - vertex[b+0];
781 v1[1] = vertex[a+1] - vertex[b+1];
782 v1[2] = vertex[a+2] - vertex[b+2];
783 v2[0] = vertex[c+0] - vertex[b+0];
784 v2[1] = vertex[c+1] - vertex[b+1];
785 v2[2] = vertex[c+2] - vertex[b+2];
786 CrossProduct(v1, v2, normal);
787 VectorNormalizeFast(normal);
788 // add surface normal to vertices
789 a = renderlist[0] * 3;
790 normals[a+0] += normal[0];
791 normals[a+1] += normal[1];
792 normals[a+2] += normal[2];
793 aliasvertusage[renderlist[0]]++;
794 a = renderlist[1] * 3;
795 normals[a+0] += normal[0];
796 normals[a+1] += normal[1];
797 normals[a+2] += normal[2];
798 aliasvertusage[renderlist[1]]++;
799 a = renderlist[2] * 3;
800 normals[a+0] += normal[0];
801 normals[a+1] += normal[1];
802 normals[a+2] += normal[2];
803 aliasvertusage[renderlist[2]]++;
807 // FIXME: precalc this
808 // average surface normals
825 void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2)
827 float fog, ifog, colorscale;
829 int i, *renderlist, *elements;
832 const entity_render_t *ent = calldata1;
833 int shadernum = calldata2;
834 int numverts, numtriangles;
836 R_Mesh_Matrix(&ent->matrix);
838 // find the vertex index list and texture
839 renderlist = ent->model->zymdata_renderlist;
840 for (i = 0;i < shadernum;i++)
841 renderlist += renderlist[0] * 3 + 1;
842 texture = ent->model->zymdata_textures[shadernum];
844 numverts = ent->model->zymnum_verts;
845 numtriangles = *renderlist++;
846 elements = renderlist;
847 R_Mesh_ResizeCheck(numverts);
852 VectorSubtract(ent->origin, r_origin, diff);
853 fog = DotProduct(diff,diff);
856 fog = exp(fogdensity/fog);
861 // fog method: darken, additive fog
862 // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
863 // 2. render fog as additive
867 memset(&mstate, 0, sizeof(mstate));
868 if (ent->effects & EF_ADDITIVE)
870 mstate.blendfunc1 = GL_SRC_ALPHA;
871 mstate.blendfunc2 = GL_ONE;
873 else if (ent->alpha != 1.0 || R_TextureHasAlpha(texture))
875 mstate.blendfunc1 = GL_SRC_ALPHA;
876 mstate.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
880 mstate.blendfunc1 = GL_ONE;
881 mstate.blendfunc2 = GL_ZERO;
883 colorscale = r_colorscale;
884 if (gl_combine.integer)
886 mstate.texrgbscale[0] = 4;
889 mstate.tex[0] = R_GetTexture(texture);
890 R_Mesh_State(&mstate);
891 ZymoticLerpBones(ent->model->zymnum_bones, (zymbonematrix *) ent->model->zymdata_poses, ent->frameblend, ent->model->zymdata_bones);
892 ZymoticTransformVerts(numverts, varray_vertex, ent->model->zymdata_vertbonecounts, ent->model->zymdata_verts);
893 ZymoticCalcNormals(numverts, varray_vertex, aliasvert_normals, ent->model->zymnum_shaders, ent->model->zymdata_renderlist);
894 memcpy(varray_texcoord[0], ent->model->zymdata_texcoords, ent->model->zymnum_verts * sizeof(float[4]));
896 R_LightModel(ent, numverts, varray_vertex, aliasvert_normals, varray_color, ifog * colorscale, ifog * colorscale, ifog * colorscale, false);
897 R_Mesh_Draw(numverts, numtriangles, elements);
898 c_alias_polys += numtriangles;
902 memset(&mstate, 0, sizeof(mstate));
903 mstate.blendfunc1 = GL_SRC_ALPHA;
904 mstate.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
905 // FIXME: need alpha mask for fogging...
906 //mstate.tex[0] = R_GetTexture(texture);
907 R_Mesh_State(&mstate);
908 GL_Color(fogcolor[0] * r_colorscale, fogcolor[1] * r_colorscale, fogcolor[2] * r_colorscale, ent->alpha * fog);
909 R_Mesh_Draw(numverts, numtriangles, elements);
910 c_alias_polys += numtriangles;
914 void R_Model_Zymotic_Draw(entity_render_t *ent)
918 if (ent->alpha < (1.0f / 64.0f))
919 return; // basically completely transparent
923 for (i = 0;i < ent->model->zymnum_shaders;i++)
925 if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_TextureHasAlpha(ent->model->zymdata_textures[i]))
926 R_MeshQueue_AddTransparent(ent->origin, R_DrawZymoticModelMeshCallback, ent, i);
928 R_DrawZymoticModelMeshCallback(ent, i);
932 void R_Model_Zymotic_DrawFakeShadow(entity_render_t *ent)
937 void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor)
942 void R_Model_Zymotic_DrawOntoLight(entity_render_t *ent)