Code: Select all
vec3_t end, hit, lightspot2;
if (!cl.worldmodel->lightdata)
{
Vector3Set (colour, 1.0f, 1.0f, 1.0f);
return;
}
// offset from mins[2] to enclose the full world
Vector3Set (end, origin[0], origin[1], cl.worldmodel->mins[2] - 10.0f);
if (RecursiveLightPoint (cl.worldmodel->nodes, origin, end, colour) == -1)
{
// copy off end as the hit point if we hit nothing on the world so that a bmodel will always be above it
Vector3Set (colour, 0.0f, 0.0f, 0.0f);
Vector3Copy (hit, end);
}
else
{
// copy off the hit point
Vector3Copy (hit, lightspot);
}
// add inline bmodels
// note - a proper setup would cache the local matrix and use transform/inversetransform like i do in q2;
// this is just a cheap and nasty implementation for non-rotating bmodels in q1. if you're doing shadows
// also copy over lightplane
// find bmodels under the lightpoint - move the point to bmodel space, trace down, then check; if r < 0
// it didn't find a bmodel, otherwise it did (a bmodel under a valid world hit will hit here too)
// fixme: is it possible for a bmodel to not be in the PVS but yet be a valid candidate for this???
for (int i = 0; i < r_numvisedicts; i++)
{
entity_t *e = r_visedicts[i];
model_t *m = e->model;
float estart[3], eend[3], ecolour[3];
// only take inline bmodels
if (!m) continue;
if (m->name[0] != '*') continue;
if (m->type != mod_brush) continue;
// move start and end points into the entity's frame of reference
Vector3Subtract (estart, origin, e->origin);
Vector3Subtract (eend, end, e->origin);
//R_InverseTransform (&e->localmatrix, estart, p);
//R_InverseTransform (&e->localmatrix, eend, end);
// and run the recursive light point on it too
if (RecursiveLightPoint (m->nodes + m->hulls[0].firstclipnode, estart, eend, ecolour) != -1)
{
// this is a potential hit spot
// a bmodel under a valid world hit will hit here too so take the highest lightspot on all hits
// move lightspot back to world space
Vector3Add (lightspot2, lightspot, e->origin);
//R_Transform (&e->localmatrix, lightspot2, lightspot);
if (lightspot2[2] > hit[2])
{
// found a bmodel so copy it over
Vector3Copy (colour, ecolour);
Vector3Copy (hit, lightspot2);
}
}
}
// the final hit point is the valid lightspot
Vector3Copy (lightspot, hit);