diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 2febf9c9a..e4c05bc1e 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -14,6 +15,8 @@ #include #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -178,6 +181,48 @@ namespace MWRender return result; } + void Animation::addExtraLight(osg::ref_ptr parent, const ESM::Light *esmLight) + { + SceneUtil::FindByNameVisitor visitor("AttachLight"); + parent->accept(visitor); + + osg::Group* attachTo = NULL; + if (visitor.mFoundNode) + { + attachTo = visitor.mFoundNode; + } + else + { + osg::ComputeBoundsVisitor computeBound; + parent->accept(computeBound); + + // PositionAttitudeTransform seems to be slightly faster than MatrixTransform + osg::ref_ptr trans(new osg::PositionAttitudeTransform); + trans->setPosition(computeBound.getBoundingBox().center()); + + parent->addChild(trans); + + attachTo = trans; + } + + osg::ref_ptr lightSource = new SceneUtil::LightSource; + osg::Light* light = new osg::Light; + lightSource->setLight(light); + + float realRadius = esmLight->mData.mRadius; + + lightSource->setRadius(realRadius); + light->setLinearAttenuation(10.f/(esmLight->mData.mRadius*2.f)); + //light->setLinearAttenuation(0.05); + light->setConstantAttenuation(0.f); + + light->setDiffuse(SceneUtil::colourFromRGB(esmLight->mData.mColor)); + light->setAmbient(osg::Vec4f(0,0,0,1)); + light->setSpecular(osg::Vec4f(0,0,0,0)); + + attachTo->addChild(lightSource); + } + void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, std::string texture) { // Early out if we already have this effect @@ -307,7 +352,7 @@ namespace MWRender // -------------------------------------------------------------------------------- - ObjectAnimation::ObjectAnimation(const MWWorld::Ptr &ptr, const std::string &model, Resource::ResourceSystem* resourceSystem) + ObjectAnimation::ObjectAnimation(const MWWorld::Ptr &ptr, const std::string &model, Resource::ResourceSystem* resourceSystem, bool allowLight) : Animation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), resourceSystem) { if (!model.empty()) @@ -316,6 +361,9 @@ namespace MWRender if (!ptr.getClass().getEnchantment(ptr).empty()) addGlow(mObjectRoot, getEnchantmentColor(ptr)); + + if (ptr.getTypeName() == typeid(ESM::Light).name() && allowLight) + addExtraLight(getOrCreateObjectRoot(), ptr.get()->mBase); } } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index ccc4bfa23..797c215c5 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -206,8 +206,8 @@ protected: * extension will be replaced with .kf. */ //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::ObjectScenePtr objlist, const ESM::Light *light); + /** Adds an additional light to the given node using the specified ESM record. */ + void addExtraLight(osg::ref_ptr parent, const ESM::Light *light); //void clearAnimSources(); @@ -319,7 +319,7 @@ public: class ObjectAnimation : public Animation { public: - ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model, Resource::ResourceSystem* resourceSystem); + ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model, Resource::ResourceSystem* resourceSystem, bool allowLight); }; } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 6a6b8a315..56f12da13 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -431,7 +431,7 @@ void NpcAnimation::updateParts() const ESM::Light *light = part.get()->mBase; addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, "meshes\\"+light->mModel); - //addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], light); + addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), light); } } @@ -837,9 +837,8 @@ void NpcAnimation::showCarriedLeft(bool show) if (addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor)) { - // TODO - //if (iter->getTypeName() == typeid(ESM::Light).name()) - //addExtraLight(mInsert->getCreator(), mObjectParts[ESM::PRT_Shield], iter->get()->mBase); + if (iter->getTypeName() == typeid(ESM::Light).name()) + addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), iter->get()->mBase); } } else diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 3d11662aa..1d28291de 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -17,7 +16,6 @@ #include #include -#include #include "../mwworld/ptr.hpp" #include "../mwworld/class.hpp" @@ -120,9 +118,10 @@ void Objects::insertBegin(const MWWorld::Ptr& ptr) osg::Quat zr(-f[2], osg::Vec3(0,0,1)); // Rotates first around z, then y, then x - insert->setAttitude(zr*yr*xr); - - // TODO: actors rotate around z only + if (ptr.getClass().isActor()) + insert->setAttitude(zr); + else + insert->setAttitude(zr*yr*xr); ptr.getRefData().setBaseNode(insert); } @@ -131,55 +130,11 @@ void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool { insertBegin(ptr); - std::auto_ptr anim (new ObjectAnimation(ptr, mesh, mResourceSystem)); + std::auto_ptr anim (new ObjectAnimation(ptr, mesh, mResourceSystem, allowLight)); if (anim->getObjectRoot()) anim->getObjectRoot()->addCullCallback(new SceneUtil::LightListCallback); - if (ptr.getTypeName() == typeid(ESM::Light).name() && allowLight) - { - SceneUtil::FindByNameVisitor visitor("AttachLight"); - ptr.getRefData().getBaseNode()->accept(visitor); - - osg::Group* attachTo = NULL; - if (visitor.mFoundNode) - { - attachTo = visitor.mFoundNode; - } - else - { - osg::ComputeBoundsVisitor computeBound; - osg::Group* objectRoot = anim->getOrCreateObjectRoot(); - objectRoot->accept(computeBound); - - // PositionAttitudeTransform seems to be slightly faster than MatrixTransform - osg::ref_ptr trans(new osg::PositionAttitudeTransform); - trans->setPosition(computeBound.getBoundingBox().center()); - - objectRoot->addChild(trans); - - attachTo = trans; - } - - const ESM::Light* esmLight = ptr.get()->mBase; - - osg::ref_ptr lightSource = new SceneUtil::LightSource; - osg::Light* light = new osg::Light; - lightSource->setLight(light); - - float realRadius = esmLight->mData.mRadius; - - lightSource->setRadius(realRadius); - light->setLinearAttenuation(10.f/(esmLight->mData.mRadius*2.f)); - //light->setLinearAttenuation(0.05); - light->setConstantAttenuation(0.f); - - light->setDiffuse(SceneUtil::colourFromRGB(esmLight->mData.mColor)); - light->setAmbient(osg::Vec4f(0,0,0,1)); - light->setSpecular(osg::Vec4f(0,0,0,0)); - - attachTo->addChild(lightSource); - } if (!allowLight) { RemoveParticlesVisitor visitor; @@ -202,6 +157,9 @@ void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, b else anim.reset(new CreatureAnimation(ptr, mesh, mResourceSystem)); + if (anim->getObjectRoot()) + anim->getObjectRoot()->addCullCallback(new SceneUtil::LightListCallback); + mObjects.insert(std::make_pair(ptr, anim.release())); } @@ -210,6 +168,10 @@ void Objects::insertNPC(const MWWorld::Ptr &ptr) insertBegin(ptr); std::auto_ptr anim (new NpcAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), mResourceSystem, 0)); + + if (anim->getObjectRoot()) + anim->getObjectRoot()->addCullCallback(new SceneUtil::LightListCallback); + mObjects.insert(std::make_pair(ptr, anim.release())); }