1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 21:53:51 +00:00

Handle Quadratic and Linear attenuation independently (Fixes #1456)

This commit is contained in:
scrawl 2014-06-11 02:24:17 +02:00
parent 7eee0855f7
commit 14a9f0ebf8

View file

@ -356,28 +356,40 @@ void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScene
objlist->mControllers.push_back(Ogre::Controller<Ogre::Real>(src, dest, func)); objlist->mControllers.push_back(Ogre::Controller<Ogre::Real>(src, dest, func));
bool interior = !(mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior()); bool interior = !(mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior());
bool quadratic = fallback->getFallbackBool("LightAttenuation_OutQuadInLin") ?
!interior : fallback->getFallbackBool("LightAttenuation_UseQuadratic"); static bool outQuadInLin = fallback->getFallbackBool("LightAttenuation_OutQuadInLin");
static bool useQuadratic = fallback->getFallbackBool("LightAttenuation_UseQuadratic");
static float quadraticValue = fallback->getFallbackFloat("LightAttenuation_QuadraticValue");
static float quadraticRadiusMult = fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
static bool useLinear = fallback->getFallbackBool("LightAttenuation_UseLinear");
static float linearRadiusMult = fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
static float linearValue = fallback->getFallbackFloat("LightAttenuation_LinearValue");
bool quadratic = useQuadratic && (!outQuadInLin || !interior);
// with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero, // with the standard 1 / (c + d*l + d*d*q) equation the attenuation factor never becomes zero,
// so we ignore lights if their attenuation falls below this factor. // so we ignore lights if their attenuation falls below this factor.
const float threshold = 0.03; const float threshold = 0.03;
if (!quadratic) float quadraticAttenuation = 0;
float linearAttenuation = 0;
float activationRange = 0;
if (quadratic)
{ {
float r = radius * fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult"); float r = radius * quadraticRadiusMult;
float attenuation = fallback->getFallbackFloat("LightAttenuation_LinearValue") / r; quadraticAttenuation = quadraticValue / std::pow(r, 2);
float activationRange = 1.0f / (threshold * attenuation); activationRange = std::sqrt(1.0f / (threshold * quadraticAttenuation));
olight->setAttenuation(activationRange, 0, attenuation, 0);
} }
else if (useLinear)
{ {
float r = radius * fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult"); float r = radius * linearRadiusMult;
float attenuation = fallback->getFallbackFloat("LightAttenuation_QuadraticValue") / std::pow(r, 2); linearAttenuation = linearValue / r;
float activationRange = std::sqrt(1.0f / (threshold * attenuation)); activationRange = std::max(activationRange, 1.0f / (threshold * linearAttenuation));
olight->setAttenuation(activationRange, 0, 0, attenuation);
} }
olight->setAttenuation(activationRange, 0, linearAttenuation, quadraticAttenuation);
// If there's an AttachLight bone, attach the light to that, otherwise put it in the center, // If there's an AttachLight bone, attach the light to that, otherwise put it in the center,
if(objlist->mSkelBase && objlist->mSkelBase->getSkeleton()->hasBone("AttachLight")) if(objlist->mSkelBase && objlist->mSkelBase->getSkeleton()->hasBone("AttachLight"))
objlist->mSkelBase->attachObjectToBone("AttachLight", olight); objlist->mSkelBase->attachObjectToBone("AttachLight", olight);