Add a light for torches

actorid
Chris Robinson 12 years ago
parent 57fb065a86
commit e976bb16c5

@ -16,6 +16,7 @@
#include "../mwmechanics/character.hpp" #include "../mwmechanics/character.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/fallback.hpp"
namespace MWRender namespace MWRender
{ {
@ -36,7 +37,13 @@ void Animation::AnimationValue::setValue(Ogre::Real)
void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects) void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects)
{ {
for(size_t i = 0;i < objects.mLights.size();i++) for(size_t i = 0;i < objects.mLights.size();i++)
sceneMgr->destroyLight(objects.mLights[i]); {
Ogre::Light *light = objects.mLights[i];
// If parent is a scene node, it was created specifically for this light. Destroy it now.
if(light->isAttached() && !light->isParentTagPoint())
sceneMgr->destroySceneNode(light->getParentSceneNode());
sceneMgr->destroyLight(light);
}
for(size_t i = 0;i < objects.mParticles.size();i++) for(size_t i = 0;i < objects.mParticles.size();i++)
sceneMgr->destroyParticleSystem(objects.mParticles[i]); sceneMgr->destroyParticleSystem(objects.mParticles[i]);
for(size_t i = 0;i < objects.mEntities.size();i++) for(size_t i = 0;i < objects.mEntities.size();i++)
@ -257,6 +264,83 @@ void Animation::clearAnimSources()
} }
void Animation::addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objlist, const ESM::Light *light)
{
const MWWorld::Fallback *fallback = MWBase::Environment::get().getWorld()->getFallback();
const int clr = light->mData.mColor;
Ogre::ColourValue color(((clr >> 0) & 0xFF) / 255.0f,
((clr >> 8) & 0xFF) / 255.0f,
((clr >> 16) & 0xFF) / 255.0f);
const float radius = float(light->mData.mRadius);
if((light->mData.mFlags&ESM::Light::Negative))
color *= -1;
objlist.mLights.push_back(sceneMgr->createLight());
Ogre::Light *olight = objlist.mLights.back();
olight->setDiffuseColour(color);
bool interior = !(mPtr.isInCell() && mPtr.getCell()->mCell->isExterior());
// TODO: Create Controllers for these
#if 0
// randomize lights animations
info.time = Ogre::Math::RangeRandom(-500, +500);
info.phase = Ogre::Math::RangeRandom(-500, +500);
if((light->mData.mFlags&ESM::Light::Flicker))
info.type = LT_Flicker;
else if((light->mData.mFlags&ESM::Light::FlickerSlow))
info.type = LT_FlickerSlow;
else if((light->mData.mFlags&ESM::Light::Pulse))
info.type = LT_Pulse;
else if((light->mData.mFlags&ESM::Light::PulseSlow))
info.type = LT_PulseSlow;
else
info.type = LT_Normal;
#endif
bool quadratic = fallback->getFallbackBool("LightAttenuation_OutQuadInLin") ?
!interior : fallback->getFallbackBool("LightAttenuation_UseQuadratic");
// 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.
const float threshold = 0.03;
if (!quadratic)
{
float r = radius * fallback->getFallbackFloat("LightAttenuation_LinearRadiusMult");
float attenuation = fallback->getFallbackFloat("LightAttenuation_LinearValue") / r;
float activationRange = 1.0f / (threshold * attenuation);
olight->setAttenuation(activationRange, 0, attenuation, 0);
}
else
{
float r = radius * fallback->getFallbackFloat("LightAttenuation_QuadraticRadiusMult");
float attenuation = fallback->getFallbackFloat("LightAttenuation_QuadraticValue") / std::pow(r, 2);
float activationRange = std::sqrt(1.0f / (threshold * attenuation));
olight->setAttenuation(activationRange, 0, 0, attenuation);
}
// 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"))
objlist.mSkelBase->attachObjectToBone("AttachLight", olight);
else
{
Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
for(size_t i = 0;i < objlist.mEntities.size();i++)
{
Ogre::Entity *ent = objlist.mEntities[i];
bounds.merge(ent->getBoundingBox());
}
Ogre::SceneNode *node = mInsert->createChildSceneNode(bounds.getCenter());
node->attachObject(olight);
}
}
Ogre::Node *Animation::getNode(const std::string &name) Ogre::Node *Animation::getNode(const std::string &name)
{ {
if(mSkelBase) if(mSkelBase)

@ -158,6 +158,9 @@ protected:
* extension will be replaced with .kf. */ * extension will be replaced with .kf. */
void addAnimSource(const std::string &model); void addAnimSource(const std::string &model);
/** Adds an additional light to the given object list using the specified ESM record. */
void addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objlist, const ESM::Light *light);
static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects); static void destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects);
static void setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue); static void setRenderProperties(const NifOgre::ObjectList &objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue, Ogre::uint8 transqueue);

@ -276,6 +276,14 @@ void NpcAnimation::updateParts(bool forceupdate)
const ESM::Light *light = part.get<ESM::Light>()->mBase; const ESM::Light *light = part.get<ESM::Light>()->mBase;
addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft,
1, "meshes\\"+light->mModel); 1, "meshes\\"+light->mModel);
for(size_t i = 0;i < sPartListSize;i++)
{
if(ESM::PRT_Shield == sPartList[i].type)
{
addExtraLight(mInsert->getCreator(), mObjectParts[i], light);
break;
}
}
} }
} }

Loading…
Cancel
Save