summaryrefslogtreecommitdiffstats
path: root/rwsdk/include/d3d8/baaplylt.c
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2019-05-18 12:39:39 +0200
committeraap <aap@papnet.eu>2019-05-18 12:39:39 +0200
commit9e496100b7baff8834658f577d3138d9f8fc3765 (patch)
treea725be9b0dba9a4ce76c19a6629ef62c36e46814 /rwsdk/include/d3d8/baaplylt.c
parentfixed pathfind (diff)
downloadre3-9e496100b7baff8834658f577d3138d9f8fc3765.tar
re3-9e496100b7baff8834658f577d3138d9f8fc3765.tar.gz
re3-9e496100b7baff8834658f577d3138d9f8fc3765.tar.bz2
re3-9e496100b7baff8834658f577d3138d9f8fc3765.tar.lz
re3-9e496100b7baff8834658f577d3138d9f8fc3765.tar.xz
re3-9e496100b7baff8834658f577d3138d9f8fc3765.tar.zst
re3-9e496100b7baff8834658f577d3138d9f8fc3765.zip
Diffstat (limited to 'rwsdk/include/d3d8/baaplylt.c')
-rw-r--r--rwsdk/include/d3d8/baaplylt.c793
1 files changed, 793 insertions, 0 deletions
diff --git a/rwsdk/include/d3d8/baaplylt.c b/rwsdk/include/d3d8/baaplylt.c
new file mode 100644
index 00000000..ad518e6a
--- /dev/null
+++ b/rwsdk/include/d3d8/baaplylt.c
@@ -0,0 +1,793 @@
+
+/* If this file is used outside of the core RW SDK,
+ * the following things need to be defined
+ */
+#if (!defined(RWASSERT))
+#define RWASSERT(_assertval) /* No op */
+#endif
+#if (!defined(RWFUNCTION))
+#define RWFUNCTION(_rwfunctionstring) /* No op */
+#endif
+#if (!defined(RWRETURN))
+#define RWRETURN(_rwreturnval) return(_rwreturnval)
+#endif
+#if (!defined(RWRETURNVOID))
+#define RWRETURNVOID() return
+#endif
+
+/* These are used by specular lighting,
+ * sorry I have to leave them in here... IDBS
+ * I'll make it neater when I have time.
+ */
+#if (!defined(FALLOFFAMBIENT))
+#define FALLOFFAMBIENT() /* No op */
+#endif
+#if (!defined(FALLOFFDIRECTIONAL))
+#define FALLOFFDIRECTIONAL() /* No op */
+#endif
+#if (!defined(FALLOFFPOINT))
+#define FALLOFFPOINT() /* No op */
+#endif
+#if (!defined(FALLOFFSPOT))
+#define FALLOFFSPOT() /* No op */
+#endif
+#if (!defined(FALLOFFSOFTSPOT))
+#define FALLOFFSOFTSPOT() /* No op */
+#endif
+
+/***************************************************************************
+ _rwApplyAmbientLight
+
+ On entry : Instanced data
+ : Light
+ : Optional inverse object matrix
+ : (to transform light to object space)
+ : Inverse scale of object
+ : Surface properties of the light
+ On exit :
+ */
+
+static void
+_rwApplyAmbientLight(VERTSARG,
+ const void *voidLight,
+ const RwMatrix * __RWUNUSED__ inverseMat,
+ RwReal __RWUNUSED__ invScale,
+ const RwSurfaceProperties * surfaceProps)
+{
+ CAMVERTDECL;
+ NUMVERTDECL;
+ const RpLight *light = (const RpLight *) voidLight;
+ RwReal scale;
+ RwV3d vertToLight;
+
+ RWFUNCTION(RWSTRING("_rwApplyAmbientLight"));
+ RWASSERT(light);
+ RWASSERT(surfaceProps);
+
+ CAMVERTINIT();
+ NUMVERTINIT();
+
+ /* No directional component:
+ * (this is used in CAMVERTADDRGBA in a specular lighting node) */
+ vertToLight.x = 0;
+ vertToLight.y = 0;
+ vertToLight.z = 0;
+
+ /* rpLIGHTAMBIENT - Constant illumination on all vertices
+ */
+ if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
+ {
+ scale = 255.0f * light->color.red * surfaceProps->ambient;
+
+ /* Ambient light affects all vertices the same */
+ while (numVert--)
+ {
+ RwReal lum = scale;
+
+#undef FALLOFFCALC
+#define FALLOFFCALC FALLOFFAMBIENT
+ CAMVERTADDRGBA(1, 1, 1, 0);
+ CAMVERTINC();
+ }
+ }
+ else
+ /* perform for coloured lights */
+ {
+ scale = 255.0f * surfaceProps->ambient;
+
+ /* Ambient light affects all vertices the same */
+ while (numVert--)
+ {
+ RwReal lum = scale;
+
+#undef FALLOFFCALC
+#define FALLOFFCALC FALLOFFAMBIENT
+ CAMVERTADDRGBA(light->color.red, light->color.green,
+ light->color.blue, 0);
+ CAMVERTINC();
+ }
+ }
+ RWRETURNVOID();
+}
+
+/***************************************************************************
+ _rwApplyDirectionalLight
+
+ On entry : Instanced data
+ : Light
+ : Optional inverse object matrix
+ : (to transform light to object space)
+ : Inverse scale of object
+ : Surface properties of the light
+ On exit :
+ */
+
+static void
+_rwApplyDirectionalLight(VERTSARG,
+ const void *voidLight,
+ const RwMatrix * inverseMat,
+ RwReal __RWUNUSED__ invScale,
+ const RwSurfaceProperties * surfaceProps)
+{
+ OBJCAMVERTDECL;
+ NUMVERTDECL;
+ const RpLight *light = (const RpLight *) voidLight;
+ RwV3d vertToLight;
+ RwReal scale;
+ RwReal dot;
+ RwFrame *lightFrame;
+
+ RWFUNCTION(RWSTRING("_rwApplyDirectionalLight"));
+ RWASSERT(light);
+ RWASSERT(surfaceProps);
+
+ OBJCAMVERTINIT();
+ NUMVERTINIT();
+
+ /* rpLIGHTDIRECTIONAL - Lighting scaled by dot product
+ * of vertex normal and light lookAt vector.
+ */
+ /* This may not have a frame - we need to check */
+ lightFrame = RpLightGetFrame(light);
+ if (lightFrame)
+ {
+ vertToLight = RwFrameGetLTM(lightFrame)->at;
+
+ /* Transform the light into object space if necessary */
+ if (inverseMat)
+ {
+ RwV3dTransformVectors(&vertToLight, &vertToLight, 1, inverseMat);
+ _rwV3dNormalize(&vertToLight, &vertToLight);
+ }
+
+ /* Vert TO light */
+ RwV3dScale(&vertToLight, &vertToLight, -1);
+
+ /* Optimise for grey lights? */
+ if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
+ {
+ /* Use one of the light colour intensities as general intensity */
+ /* light vector tests are to be identical to others */
+ scale = 255.0f * light->color.red * surfaceProps->diffuse;
+
+ /* Loop through each of the vertices */
+ while (numVert--)
+ {
+ RwV3d objNormal;
+
+ OBJVERTGETNORMAL(&objNormal);
+ /* Calculate angle between vertex normal and light vector */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+
+ /* Ensure vector is facing light,
+ * don't light areas not facing */
+
+ if (dot > 0.0f)
+ {
+ RwReal lum = dot * scale;
+
+#undef FALLOFFCALC
+#define FALLOFFCALC FALLOFFDIRECTIONAL
+ CAMVERTADDRGBA(1, 1, 1, 0);
+ }
+
+ /* Next vertex */
+ OBJCAMVERTINC();
+ }
+ }
+ else
+ /* perform for coloured lights */
+ {
+ scale = 255.0f * surfaceProps->diffuse;
+
+ /* Loop through each of the vertices */
+ while (numVert--)
+ {
+ RwV3d objNormal;
+
+ OBJVERTGETNORMAL(&objNormal);
+ /* Calculate angle between vertex normal and light vector */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+
+ /* Ensure vector is facing light,
+ * don't light areas not facing */
+
+ if (dot > 0.0f)
+ {
+ RwReal lum = dot * scale;
+
+#define FALLOFFCALC FALLOFFDIRECTIONAL
+ CAMVERTADDRGBA(light->color.red, light->color.green,
+ light->color.blue, 0);
+ }
+
+ /* Next vertex */
+ OBJCAMVERTINC();
+ }
+ }
+ }
+
+ RWRETURNVOID();
+}
+
+/***************************************************************************
+ _rwApplyPointLight
+
+ On entry : Instanced data
+ : Light
+ : Optional inverse object matrix
+ : (to transform light to object space)
+ : Inverse scale of object
+ : Surface properties of the light
+ On exit :
+ */
+
+static void
+_rwApplyPointLight(VERTSARG, const void *voidLight,
+ const RwMatrix * inverseMat,
+ RwReal invScale, const RwSurfaceProperties * surfaceProps)
+{
+ OBJCAMVERTDECL;
+ NUMVERTDECL;
+ const RpLight *light = (const RpLight *) voidLight;
+ RwReal scale, recipRad;
+ RwV3d lightPos, vertToLight;
+ RwReal radSquared;
+
+ RWFUNCTION(RWSTRING("_rwApplyPointLight"));
+ RWASSERT(light);
+ RWASSERT(surfaceProps);
+
+ OBJCAMVERTINIT();
+ NUMVERTINIT();
+
+ /* rpLIGHTPOINT - Linear falloff with distance, scaled by
+ * dot product of vertex normal and light to vertex vector.
+ */
+ lightPos = RwFrameGetLTM(RpLightGetFrame(light))->pos;
+
+ if (inverseMat)
+ {
+ RwReal scaledRad;
+
+ scaledRad = ((light->radius) * (invScale));
+ radSquared = ((scaledRad) * (scaledRad));
+ recipRad = (((RwReal) (1)) / (scaledRad));
+
+ /* Transform light into object space */
+ RwV3dTransformPoints(&lightPos, &lightPos, 1, inverseMat);
+ }
+ else
+ {
+ radSquared = ((light->radius) * (light->radius));
+ recipRad = (((RwReal) (1)) / (light->radius));
+ }
+
+ if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
+ {
+ /* The scale encapsulates the common elements to do
+ * with light intensity and surface lighting properties
+ */
+ scale =
+ ((((RwReal) (255)) * (light->color.red))) *
+ (surfaceProps->diffuse);
+
+ while (numVert--)
+ {
+ RwV3d objVertex, objNormal;
+ RwReal dot, dist2;
+
+ OBJVERTGETPOS(&objVertex);
+ OBJVERTGETNORMAL(&objNormal);
+
+ /* Discover the vector between vertex and light and it's length */
+ RwV3dSub(&vertToLight, &lightPos, &objVertex);
+
+ /* Ensure that this vertex is facing the light source */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+ if (dot > 0.0f)
+ {
+ /* Ensure vertex lies within the light's radius */
+ dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
+ if (dist2 < radSquared)
+ {
+ RwReal lum;
+ RwReal recipDist;
+ RwReal dist;
+
+ rwSqrt(&dist, dist2);
+ recipDist =
+ (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
+
+ /*
+ * The following simplifies down to:
+ *
+ * -scale *
+ * (dot/dist) *
+ * (1 - dist/lightRadius)
+ *
+ * Where
+ * scale
+ * takes care of the light intensity and
+ * diffuse lighting coefficient
+ * (dot/dist)
+ * is a normalised dot product of
+ * light->vertex vector and vertex normal
+ * (1 - dist/lightRadius)
+ * is a linear falloff factor
+ */
+ lum = scale * dot * (recipDist - recipRad);
+
+ /* Calculate the luminance at vertex */
+#undef FALLOFFCALC
+#define FALLOFFCALC FALLOFFPOINT
+ CAMVERTADDRGBA(1, 1, 1, 0);
+ }
+ }
+
+ OBJCAMVERTINC();
+ }
+ }
+ else
+ {
+ scale = (((RwReal) (255)) * (surfaceProps->diffuse));
+
+ while (numVert--)
+ {
+ RwV3d objVertex, objNormal;
+ RwReal dot, dist2;
+
+ OBJVERTGETPOS(&objVertex);
+ OBJVERTGETNORMAL(&objNormal);
+
+ /* Discover the vector between vertex and light and it's length */
+ RwV3dSub(&vertToLight, &lightPos, &objVertex);
+
+ /* Ensure that this vertex is facing the light source */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+ if (dot > 0.0f)
+ {
+ dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
+
+ /* Ensure vertex lies within the light's radius */
+ if (dist2 < radSquared)
+ {
+ RwReal lum;
+ RwReal recipDist;
+ RwReal dist;
+
+ /* Only now calculate the actual length of vector */
+ rwSqrt(&dist, dist2);
+ recipDist =
+ (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
+
+ lum = scale * dot * (recipDist - recipRad);
+ /* Alter the luminance according to light colour */
+#define FALLOFFCALC FALLOFFPOINT
+ CAMVERTADDRGBA(light->color.red, light->color.green,
+ light->color.blue, 0);
+ }
+ }
+
+ /* Next point */
+ OBJCAMVERTINC();
+ }
+ }
+ RWRETURNVOID();
+}
+
+/***************************************************************************
+ _rwApplySpotLight
+
+ On entry : Instanced data
+ : Light
+ : Optional inverse object matrix
+ : (to transform light to object space)
+ : Inverse scale of object
+ : Surface properties of the light
+ On exit :
+ */
+
+static void
+_rwApplySpotLight(VERTSARG,
+ const void *voidLight,
+ const RwMatrix * inverseMat,
+ RwReal invScale, const RwSurfaceProperties * surfaceProps)
+{
+ OBJCAMVERTDECL;
+ NUMVERTDECL;
+ const RpLight *light = (const RpLight *) voidLight;
+ RwReal recipRad;
+ RwReal radSquared;
+ RwV3d lightPos, at;
+
+ RWFUNCTION(RWSTRING("_rwApplySpotLight"));
+ RWASSERT(light);
+ RWASSERT(surfaceProps);
+
+ OBJCAMVERTINIT();
+ NUMVERTINIT();
+
+ /* rpLIGHTSPOT - Linear falloff with distance, cone to restrict
+ * angle that light has effect, constant intensity across cone,
+ * scaled by dot product of vertex normal and light to vertex vector.
+ */
+
+ lightPos = RwFrameGetLTM(RpLightGetFrame(light))->pos;
+ at = RwFrameGetLTM(RpLightGetFrame(light))->at;
+
+ if (inverseMat)
+ {
+ RwReal scaledRad;
+
+ scaledRad = ((light->radius) * (invScale));
+ recipRad = (((RwReal) (1)) / (scaledRad));
+ radSquared = ((scaledRad) * (scaledRad));
+
+ /* Transform light into object space */
+ /* The at is required to ensure within cone */
+ RwV3dTransformPoints(&lightPos, &lightPos, 1, inverseMat);
+ RwV3dTransformVectors(&at, &at, 1, inverseMat);
+ _rwV3dNormalize(&at, &at);
+ }
+ else
+ {
+ recipRad = (((RwReal) (1)) / (light->radius));
+ radSquared = ((light->radius) * (light->radius));
+ }
+
+ if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
+ {
+ RwReal scale =
+
+ ((RwReal) 255) * (light->color.red) * (surfaceProps->diffuse);
+
+ while (numVert--)
+ {
+ RwV3d vertToLight, objVertex, objNormal;
+ RwReal dot;
+
+ OBJVERTGETPOS(&objVertex);
+ OBJVERTGETNORMAL(&objNormal);
+
+ /* Find the squared distance from light point to vertex */
+ RwV3dSub(&vertToLight, &lightPos, &objVertex);
+
+ /* Ensure that this vertex is facing the light source */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+ if (dot > 0.0f)
+ {
+ RwReal dist2;
+
+ /* Ensure vertex lies within the light's radius */
+ dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
+ if (dist2 < radSquared)
+ {
+ RwReal dist;
+ RwReal compare;
+ RwReal proj;
+
+ rwSqrt(&dist, dist2);
+ compare = dist * light->minusCosAngle;
+ proj = RwV3dDotProduct(&vertToLight, &at);
+
+ if (proj < compare)
+ {
+ RwReal lum;
+ RwReal recipDist;
+
+ /* Get the real distance from the light
+ * to the vertex (not squared) */
+ recipDist =
+ (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
+
+ /* This model is the same as the point source
+ * inside the cone, zero outside the cone */
+ lum = scale * dot * (recipDist - recipRad);
+#undef FALLOFFCALC
+#define FALLOFFCALC FALLOFFSPOT
+ CAMVERTADDRGBA(1, 1, 1, 0);
+ }
+ }
+ /* Next vertex */
+ OBJCAMVERTINC();
+ }
+ }
+ }
+ else
+ {
+ RwReal scale =
+
+ (((RwReal) (255)) * (surfaceProps->diffuse));
+
+ while (numVert--)
+ {
+ RwV3d vertToLight, objVertex, objNormal;
+ RwReal dot;
+
+ OBJVERTGETPOS(&objVertex);
+ OBJVERTGETNORMAL(&objNormal);
+
+ /* Find the squared distance from light point to vertex */
+ RwV3dSub(&vertToLight, &lightPos, &objVertex);
+
+ /* Ensure that this vertex is facing the light source */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+ if (dot > 0.0f)
+ {
+ RwReal dist2;
+
+ /* Ensure vertex lies within the light's radius */
+ dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
+ if (dist2 < radSquared)
+ {
+ RwReal dist;
+ RwReal compare;
+ RwReal proj;
+
+ rwSqrt(&dist, dist2);
+ compare = dist * light->minusCosAngle;
+ proj = RwV3dDotProduct(&vertToLight, &at);
+
+ if (proj < compare)
+ {
+ RwReal lum;
+ RwReal recipDist;
+
+ recipDist =
+ (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
+
+ /* This model is the same as the point source
+ * inside the cone, zero outside the cone */
+ lum = scale * dot * (recipDist - recipRad);
+
+ /* Introduce the light colours as a
+ * scaling factor for luminance */
+#define FALLOFFCALC FALLOFFSPOT
+ CAMVERTADDRGBA(light->color.red,
+ light->color.green, light->color.blue,
+ 0);
+ }
+ }
+ }
+
+ /* Next */
+ OBJCAMVERTINC();
+ }
+ }
+
+ RWRETURNVOID();
+}
+
+/***************************************************************************
+ _rwApplySpotSoftLight
+
+ On entry : Instanced data
+ : Light
+ : Optional inverse object matrix
+ : (to transform light to object space)
+ : Inverse scale of object
+ : Surface properties of the light
+ On exit :
+ */
+
+static void
+_rwApplySpotSoftLight(VERTSARG, const void *voidLight,
+ const RwMatrix * inverseMat, RwReal invScale,
+ const RwSurfaceProperties * surfaceProps)
+{
+ OBJCAMVERTDECL;
+ NUMVERTDECL;
+ const RpLight *light = (const RpLight *) voidLight;
+ RwReal recipRad;
+ RwReal radSquared;
+ RwV3d lightPos, at;
+
+ RWFUNCTION(RWSTRING("_rwApplySpotSoftLight"));
+ RWASSERT(light);
+ RWASSERT(surfaceProps);
+
+ OBJCAMVERTINIT();
+ NUMVERTINIT();
+
+ /* rpLIGHTSPOTSOFT - Linear falloff with distance, cone to restrict
+ * angle that light has effect, falloff to edge of cone, scaled by
+ * dot product of vertex normal and light to vertex vector.
+ */
+
+ lightPos = RwFrameGetLTM(RpLightGetFrame(light))->pos;
+ at = RwFrameGetLTM(RpLightGetFrame(light))->at;
+
+ if (inverseMat)
+ {
+ RwReal scaledRad;
+
+ scaledRad = ((light->radius) * (invScale));
+ recipRad = (((RwReal) (1)) / (scaledRad));
+ radSquared = ((scaledRad) * (scaledRad));
+
+ /* Transform light into object space */
+ /* The at is required to ensure within cone */
+ RwV3dTransformPoints(&lightPos, &lightPos, 1, inverseMat);
+ RwV3dTransformVectors(&at, &at, 1, inverseMat);
+ _rwV3dNormalize(&at, &at);
+ }
+ else
+ {
+ recipRad = 1.0f / light->radius;
+ radSquared = light->radius * light->radius;
+ }
+
+ if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
+ {
+ RwReal scale =
+
+ ((RwReal) 255) * (light->color.red) * (surfaceProps->diffuse);
+
+ while (numVert--)
+ {
+ RwV3d vertToLight, objVertex, objNormal;
+ RwReal dot;
+
+ OBJVERTGETPOS(&objVertex);
+ OBJVERTGETNORMAL(&objNormal);
+
+ /* Find the squared distance from light point to vertex */
+ RwV3dSub(&vertToLight, &lightPos, &objVertex);
+
+ /* Ensure that this vertex is facing the light source */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+ if (dot > 0.0f)
+ {
+ RwReal dist2;
+
+ /* Ensure vertex lies within the light's radius */
+ dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
+ if (dist2 < radSquared)
+ {
+ RwReal dist;
+ RwReal compare;
+ RwReal proj;
+
+ rwSqrt(&dist, dist2);
+ compare = dist * light->minusCosAngle;
+ proj = RwV3dDotProduct(&vertToLight, &at);
+
+ if (proj < compare)
+ {
+ RwReal lum;
+ RwReal recipDist;
+ RwReal normalise;
+
+ recipDist =
+ (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
+
+ /* This model is the same as the point source
+ * inside the cone, zero outside the cone */
+ lum = scale * dot * (recipDist - recipRad);
+
+ /* It has an extra term for quadratic falloff
+ * across the cone though */
+ normalise = (dist + compare);
+ RWASSERT(normalise >= 0.0f);
+ if (normalise > 0.0f)
+ {
+ normalise = (dist + proj) / normalise;
+
+ normalise *= normalise;
+ lum *= (((RwReal) 1) - normalise);
+ }
+
+#undef FALLOFFCALC
+#define FALLOFFCALC FALLOFFSOFTSPOT
+ CAMVERTADDRGBA(1, 1, 1, 0);
+ }
+ }
+ }
+
+ /* Next */
+ OBJCAMVERTINC();
+ }
+ }
+
+ else
+ {
+ RwReal scale = 255.0f * surfaceProps->diffuse;
+
+ while (numVert--)
+ {
+ RwV3d vertToLight, objVertex, objNormal;
+ RwReal dot;
+
+ OBJVERTGETPOS(&objVertex);
+ OBJVERTGETNORMAL(&objNormal);
+
+ /* Find the squared distance from light point to vertex */
+ RwV3dSub(&vertToLight, &lightPos, &objVertex);
+
+ /* Ensure that this vertex is facing the light source */
+ dot = RwV3dDotProduct(&vertToLight, &objNormal);
+ if (dot > 0.0f)
+ {
+ RwReal dist2;
+
+ /* Ensure vertex lies within the light's radius */
+ dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
+ if (dist2 < radSquared)
+ {
+ RwReal dist;
+ RwReal compare;
+ RwReal proj;
+
+ rwSqrt(&dist, dist2);
+ compare = dist * light->minusCosAngle;
+ proj = RwV3dDotProduct(&vertToLight, &at);
+
+ if (proj < compare)
+ {
+
+ RwReal lum;
+ RwReal normalise;
+ RwReal recipDist;
+
+ /* Get the real distance from the light
+ * to the vertex (not squared) */
+ recipDist =
+ (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
+
+ /* This model is the same as the point source
+ * inside the cone, zero outside the cone */
+ lum = scale * dot * (recipDist - recipRad);
+
+ /* It has an extra term for quadratic falloff
+ * across the cone though */
+ /* It has an extra term for quadratic falloff
+ * across the cone though */
+ normalise = (dist + compare);
+ RWASSERT(normalise >= 0.0f);
+ if (normalise > 0.0f)
+ {
+ normalise = (dist + proj) / normalise;
+
+ normalise *= normalise;
+ lum *= (((RwReal) 1) - normalise);
+
+ }
+ /* Introduce the light colours as a
+ * scaling factor for luminance */
+#undef FALLOFFCALC
+#define FALLOFFCALC FALLOFFSOFTSPOT
+ CAMVERTADDRGBA(light->color.red,
+ light->color.green,
+ light->color.blue, 0);
+ }
+ }
+ }
+
+ /* Next */
+ OBJCAMVERTINC();
+ }
+ }
+
+ RWRETURNVOID();
+}