- sl = cl.worldmodel->lights + i;
- if (d_lightstylevalue[sl->style] > 0)
- {
- VectorSubtract (p, sl->origin, v);
- f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract);
- if (f > 0 && CL_TraceLine(p, sl->origin, NULL, NULL, 0, false) == 1)
- {
- f *= d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
- VectorMA(color, f, sl->light, color);
- }
- }
- }
- }
- else
- RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536);
-
- if (dynamic && leaf->dlightframe == r_framecount)
- {
- dlightbits = leaf->dlightbits;
- for (i = 0;i < r_numdlights;i++)
- {
- if (!(dlightbits[i >> 5] & (1 << (i & 31))))
- continue;
- rd = r_dlight + i;
- VectorSubtract (p, rd->origin, v);
- f = DotProduct(v, v);
- if (f < rd->cullradius2)
- {
- f = (1.0f / (f + LIGHTOFFSET)) - rd->subtract;
- VectorMA(color, f, rd->light, color);
- }
- }
- }
-}
-
-void R_ModelLightPoint (entity_render_t *ent, vec3_t color, vec3_t p, int *dlightbits)
-{
- mleaf_t *leaf;
- leaf = Mod_PointInLeaf(p, cl.worldmodel);
- if (leaf->contents == CONTENTS_SOLID)
- {
- color[0] = color[1] = color[2] = 0;
- dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
- return;
- }
-
- if (r_fullbright.integer || !cl.worldmodel->lightdata || ent->effects & EF_FULLBRIGHT)
- {
- color[0] = color[1] = color[2] = 2;
- dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
- return;
- }
-
- color[0] = color[1] = color[2] = r_ambient.value * (2.0f / 128.0f);
- if (!cl.worldmodel->numlights)
- RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536);
-
- if (leaf->dlightframe == r_framecount)
- {
- dlightbits[0] = leaf->dlightbits[0];
- dlightbits[1] = leaf->dlightbits[1];
- dlightbits[2] = leaf->dlightbits[2];
- dlightbits[3] = leaf->dlightbits[3];
- dlightbits[4] = leaf->dlightbits[4];
- dlightbits[5] = leaf->dlightbits[5];
- dlightbits[6] = leaf->dlightbits[6];
- dlightbits[7] = leaf->dlightbits[7];
- }
- else
- dlightbits[0] = dlightbits[1] = dlightbits[2] = dlightbits[3] = dlightbits[4] = dlightbits[5] = dlightbits[6] = dlightbits[7] = 0;
-}
-
-void R_LightModel(entity_render_t *ent, int numverts, float colorr, float colorg, float colorb, int worldcoords)
-{
- int i, j, nearlights = 0, maxnearlights = r_modellights.integer;
- float color[3], basecolor[3], v[3], t, *av, *avn, *avc, a, f, dist2, mscale, dot, stylescale, intensity, ambientcolor[3];
- struct
- {
- vec3_t origin;
- //vec_t cullradius2;
- vec3_t light;
- // how much this light would contribute to ambient if replaced
- vec3_t ambientlight;
- vec_t subtract;
- vec_t falloff;
- vec_t offset;
- // used for choosing only the brightest lights
- vec_t intensity;
- }
- nearlight[MAX_DLIGHTS], *nl;
- int modeldlightbits[8];
- mlight_t *sl;
- rdlight_t *rd;
- a = ent->alpha;
- // scale of the model's coordinate space, to alter light attenuation to match
- // make the mscale squared so it can scale the squared distance results
- mscale = ent->scale * ent->scale;
- if ((maxnearlights != 0) && !r_fullbright.integer && !(ent->effects & EF_FULLBRIGHT))
- {
- R_ModelLightPoint(ent, basecolor, ent->origin, modeldlightbits);
-
- nl = &nearlight[0];
- VectorSubtract(ent->origin, ent->entlightsorigin, v);
- if ((realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f))
- {
- ent->numentlights = 0;
- ent->entlightstime = realtime + 0.2;
- VectorCopy(ent->origin, ent->entlightsorigin);
- for (i = 0, sl = cl.worldmodel->lights;i < cl.worldmodel->numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
- if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, 0, false) == 1)
- ent->entlights[ent->numentlights++] = i;
- }
- for (i = 0;i < ent->numentlights;i++)
- {
- sl = cl.worldmodel->lights + ent->entlights[i];
- stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
- VectorSubtract (ent->origin, sl->origin, v);
- f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale;
- VectorScale(sl->light, f, ambientcolor);
- intensity = DotProduct(ambientcolor, ambientcolor);
- if (f < 0)
- intensity *= -1.0f;
- if (nearlights < maxnearlights)
- j = nearlights++;
- else
- {
- for (j = 0;j < maxnearlights;j++)
- {
- if (nearlight[j].intensity < intensity)
- {
- if (nearlight[j].intensity > 0)
- VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
- break;
- }
- }
- }
- if (j >= maxnearlights)
- {
- // this light is less significant than all others,
- // add it to ambient
- if (intensity > 0)
- VectorAdd(basecolor, ambientcolor, basecolor);
- }
- else
- {
- nl = nearlight + j;
- nl->intensity = intensity;
- // transform the light into the model's coordinate system
- if (worldcoords)
- VectorCopy(sl->origin, nl->origin);
- else
- softwareuntransform(sl->origin, nl->origin);
- // integrate mscale into falloff, for maximum speed
- nl->falloff = sl->falloff * mscale;
- VectorCopy(ambientcolor, nl->ambientlight);
- nl->light[0] = sl->light[0] * stylescale * colorr * 4.0f;
- nl->light[1] = sl->light[1] * stylescale * colorg * 4.0f;
- nl->light[2] = sl->light[2] * stylescale * colorb * 4.0f;
- nl->subtract = sl->subtract;
- nl->offset = sl->distbias;
- }
- }
- for (i = 0;i < r_numdlights;i++)
- {
- if (!(modeldlightbits[i >> 5] & (1 << (i & 31))))
- continue;
- rd = r_dlight + i;
- VectorSubtract (ent->origin, rd->origin, v);
- f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract);
- VectorScale(rd->light, f, ambientcolor);
- intensity = DotProduct(ambientcolor, ambientcolor);
- if (f < 0)
- intensity *= -1.0f;
- if (nearlights < maxnearlights)
- j = nearlights++;
- else
- {
- for (j = 0;j < maxnearlights;j++)
- {
- if (nearlight[j].intensity < intensity)
- {
- if (nearlight[j].intensity > 0)
- VectorAdd(basecolor, nearlight[j].ambientlight, basecolor);
- break;
- }
- }
- }
- if (j >= maxnearlights)
- {
- // this light is less significant than all others,
- // add it to ambient
- if (intensity > 0)
- VectorAdd(basecolor, ambientcolor, basecolor);
- }
- else
- {
- nl = nearlight + j;
- nl->intensity = intensity;
- // transform the light into the model's coordinate system
- if (worldcoords)
- VectorCopy(rd->origin, nl->origin);
- else
- softwareuntransform(rd->origin, nl->origin);
- // integrate mscale into falloff, for maximum speed
- nl->falloff = mscale;
- VectorCopy(ambientcolor, nl->ambientlight);
- nl->light[0] = rd->light[0] * colorr * 4.0f;
- nl->light[1] = rd->light[1] * colorg * 4.0f;
- nl->light[2] = rd->light[2] * colorb * 4.0f;
- nl->subtract = rd->subtract;
- nl->offset = LIGHTOFFSET;
- }
- }
- }
- else
- {
- R_CompleteLightPoint (basecolor, ent->origin, true, NULL);
- }
- basecolor[0] *= colorr;
- basecolor[1] *= colorg;
- basecolor[2] *= colorb;
- avc = aliasvertcolor;
- if (nearlights)
- {
- av = aliasvert;
- avn = aliasvertnorm;
- for (i = 0;i < numverts;i++)
- {
- VectorCopy(basecolor, color);
- for (j = 0, nl = &nearlight[0];j < nearlights;j++, nl++)
- {
- VectorSubtract(nl->origin, av, v);
- // directional shading
- dot = DotProduct(avn,v);
- if (dot > 0)
- {
- // the vertex normal faces the light
-
- // do the distance attenuation
- dist2 = DotProduct(v,v);
- f = (1.0f / (dist2 * nl->falloff + nl->offset)) - nl->subtract;
- if (f > 0)
- {
- #if SLOWMATH
- t = 1.0f / sqrt(dist2);
- #else
- *((int *)&t) = 0x5f3759df - ((* (int *) &dist2) >> 1);
- t = t * (1.5f - (dist2 * 0.5f * t * t));
- #endif
-
- // dot * t is dotproduct with a normalized v.
- // (the result would be -1 to +1, but we already
- // eliminated the <= 0 case, so it is 0 to 1)
-
- // the hardness variables are for backlighting/shinyness
- // these have been hardwired at * 0.5 + 0.5 to match
- // the quake map lighting utility's equations
- f *= dot * t;// * 0.5f + 0.5f;// * hardness + hardnessoffset;
- VectorMA(color, f, nl->light, color);
- }
- }
- }
-
- VectorCopy(color, avc);
- avc[3] = a;
- avc += 4;
- av += 4;
- avn += 3;
- }
- }
- else
- {
- for (i = 0;i < numverts;i++)
- {
- VectorCopy(basecolor, avc);
- avc[3] = a;
- avc += 4;