+static int R_Shadow_ConstructShadowVolume_ZPass(int innumvertices, int innumtris, const int *inelement3i, const int *inneighbor3i, const float *invertex3f, int *outnumvertices, int *outelement3i, float *outvertex3f, const float *projectorigin, const float *projectdirection, float projectdistance, int numshadowmarktris, const int *shadowmarktris)
+{
+ int i, j, k;
+ int outtriangles = 0, outvertices = 0;
+ const int *element;
+ const float *vertex;
+ float ratio, direction[3], projectvector[3];
+ qboolean side[4];
+
+ if (projectdirection)
+ VectorScale(projectdirection, projectdistance, projectvector);
+ else
+ VectorClear(projectvector);
+
+ for (i = 0;i < numshadowmarktris;i++)
+ {
+ int remappedelement[3];
+ int markindex;
+ const int *neighbortriangle;
+
+ markindex = shadowmarktris[i] * 3;
+ neighbortriangle = inneighbor3i + markindex;
+ side[0] = shadowmark[neighbortriangle[0]] == shadowmarkcount;
+ side[1] = shadowmark[neighbortriangle[1]] == shadowmarkcount;
+ side[2] = shadowmark[neighbortriangle[2]] == shadowmarkcount;
+ if (side[0] + side[1] + side[2] == 0)
+ continue;
+
+ side[3] = side[0];
+ element = inelement3i + markindex;
+
+ // create the vertices
+ for (j = 0;j < 3;j++)
+ {
+ if (side[j] + side[j+1] == 0)
+ continue;
+ k = element[j];
+ if (vertexupdate[k] != vertexupdatenum)
+ {
+ vertexupdate[k] = vertexupdatenum;
+ vertexremap[k] = outvertices;
+ vertex = invertex3f + k * 3;
+ VectorCopy(vertex, outvertex3f);
+ if (projectdirection)
+ {
+ // project one copy of the vertex according to projectvector
+ VectorAdd(vertex, projectvector, (outvertex3f + 3));
+ }
+ else
+ {
+ // project one copy of the vertex to the sphere radius of the light
+ // (FIXME: would projecting it to the light box be better?)
+ VectorSubtract(vertex, projectorigin, direction);
+ ratio = projectdistance / VectorLength(direction);
+ VectorMA(projectorigin, ratio, direction, (outvertex3f + 3));
+ }
+ outvertex3f += 6;
+ outvertices += 2;
+ }
+ }
+
+ // output the sides (facing outward from this triangle)
+ if (!side[0])
+ {
+ remappedelement[0] = vertexremap[element[0]];
+ remappedelement[1] = vertexremap[element[1]];
+ outelement3i[0] = remappedelement[1];
+ outelement3i[1] = remappedelement[0];
+ outelement3i[2] = remappedelement[0] + 1;
+ outelement3i[3] = remappedelement[1];
+ outelement3i[4] = remappedelement[0] + 1;
+ outelement3i[5] = remappedelement[1] + 1;
+
+ outelement3i += 6;
+ outtriangles += 2;
+ }
+ if (!side[1])
+ {
+ remappedelement[1] = vertexremap[element[1]];
+ remappedelement[2] = vertexremap[element[2]];
+ outelement3i[0] = remappedelement[2];
+ outelement3i[1] = remappedelement[1];
+ outelement3i[2] = remappedelement[1] + 1;
+ outelement3i[3] = remappedelement[2];
+ outelement3i[4] = remappedelement[1] + 1;
+ outelement3i[5] = remappedelement[2] + 1;
+
+ outelement3i += 6;
+ outtriangles += 2;
+ }
+ if (!side[2])
+ {
+ remappedelement[0] = vertexremap[element[0]];
+ remappedelement[2] = vertexremap[element[2]];
+ outelement3i[0] = remappedelement[0];
+ outelement3i[1] = remappedelement[2];
+ outelement3i[2] = remappedelement[2] + 1;
+ outelement3i[3] = remappedelement[0];
+ outelement3i[4] = remappedelement[2] + 1;
+ outelement3i[5] = remappedelement[0] + 1;
+
+ outelement3i += 6;
+ outtriangles += 2;
+ }
+ }
+ if (outnumvertices)
+ *outnumvertices = outvertices;
+ return outtriangles;
+}
+