OpenMW: create a window and render the starting cell(s)

c++11
scrawl 10 years ago
parent a0b43f426e
commit c92592493e

@ -127,8 +127,7 @@ int main(int argc, char** argv)
osg::Group* newNode = new osg::Group;
NifOsg::Loader loader;
Resource::TextureManager texMgr(&resourceMgr);
loader.mTextureManager = &texMgr;
newNode->addChild(loader.load(nif));
newNode->addChild(loader.load(nif, &texMgr));
osg::PositionAttitudeTransform* trans = new osg::PositionAttitudeTransform;
root->addChild(trans);

@ -20,8 +20,8 @@ set(GAME_HEADER
source_group(game FILES ${GAME} ${GAME_HEADER})
add_openmw_dir (mwrender
actors objects
# renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
actors objects renderingmanager animation
# debugging sky camera npcanimation creatureanimation activatoranimation
# renderinginterface localmap occlusionquery water shadows
# characterpreview globalmap ripplesimulation refraction
# terrainstorage renderconst effectmanager weaponanimation
@ -129,6 +129,7 @@ target_link_libraries(openmw
${OENGINE_LIBRARY}
${OGRE_LIBRARIES}
${OGRE_STATIC_PLUGINS}
${OPENSCENEGRAPH_LIBRARIES}
${Boost_LIBRARIES}
${OPENAL_LIBRARY}
${SOUND_INPUT_LIBRARY}

@ -3,15 +3,23 @@
#include <stdexcept>
#include <iomanip>
#include <OgreRoot.h>
#include <OgreRenderWindow.h>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgUtil/IncrementalCompileOperation>
#include <MyGUI_WidgetManager.h>
#include <SDL.h>
// TODO: move to component
#include <openengine/misc/rng.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/registerarchives.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/compiler/extensions0.hpp>
#include <components/files/configurationmanager.hpp>
@ -172,8 +180,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
}
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
: mOgre (0)
, mVerboseScripts (false)
: mVerboseScripts (false)
, mSkipMenu (false)
, mUseSound (true)
, mCompileAll (false)
@ -220,10 +227,6 @@ void OMW::Engine::addResourcesDirectory (const boost::filesystem::path& path)
{
}
void OMW::Engine::addZipResource (const boost::filesystem::path& path)
{
}
void OMW::Engine::enableFSStrict(bool fsStrict)
{
mFSStrict = fsStrict;
@ -318,21 +321,27 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
addResourcesDirectory(mResDir / "shadows");
addResourcesDirectory(mResDir / "materials");
OEngine::Render::WindowSettings windowSettings;
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
windowSettings.window_border = settings.getBool("window border", "Video");
windowSettings.window_x = settings.getInt("resolution x", "Video");
windowSettings.window_y = settings.getInt("resolution y", "Video");
windowSettings.screen = settings.getInt("screen", "Video");
windowSettings.vsync = settings.getBool("vsync", "Video");
windowSettings.icon = "openmw.png";
std::string aa = settings.getString("antialiasing", "Video");
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
//OEngine::Render::WindowSettings windowSettings;
//windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
//windowSettings.window_border = settings.getBool("window border", "Video");
//windowSettings.vsync = settings.getBool("vsync", "Video");
//windowSettings.icon = "openmw.png";
//std::string aa = settings.getString("antialiasing", "Video");
//windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,
settings.getBool("minimize on focus loss", "Video") ? "1" : "0");
//Bsa::registerResources (mFileCollections, mArchives, true, mFSStrict);
// not handling fullscreen yet, we should figure this out when adding SDL to the mix
mViewer.setUpViewInWindow(0, 0, settings.getInt("resolution x", "Video"), settings.getInt("resolution y", "Video"), settings.getInt("screen", "Video"));
osg::ref_ptr<osg::Group> rootNode (new osg::Group);
mViewer.setSceneData(rootNode);
mVFS.reset(new VFS::Manager(mFSStrict));
VFS::registerArchives(mVFS.get(), mFileCollections, mArchives, true);
mResourceSystem.reset(new Resource::ResourceSystem(mVFS.get()));
// Create input and UI first to set up a bootstrapping environment for
// showing a loading screen and keeping the window responsive while doing so
@ -378,8 +387,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
}
// Create the world
mEnvironment.setWorld( new MWWorld::World (mFileCollections, mContentFiles,
mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap,
mEnvironment.setWorld( new MWWorld::World (mViewer, rootNode, mResourceSystem.get(),
mFileCollections, mContentFiles, mEncoder, mFallbackMap,
mActivationDistanceOverride, mCellName, mStartupScript));
MWBase::Environment::get().getWorld()->setupPlayer();
//input->setPlayer(&mEnvironment.getWorld()->getPlayer());
@ -460,7 +469,7 @@ void OMW::Engine::go()
{
MWBase::Environment::get().getStateManager()->loadGame(mSaveGameFile);
}
else if (!mSkipMenu)
else if (0)// !mSkipMenu)
{
// start in main menu
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
@ -481,6 +490,22 @@ void OMW::Engine::go()
}
// Start the main rendering loop
mViewer.setCameraManipulator(new osgGA::TrackballManipulator);
mViewer.addEventHandler(new osgViewer::StatsHandler);
osg::Timer timer;
//osgUtil::IncrementalCompileOperation* ico = new osgUtil::IncrementalCompileOperation;
//ico->compileAllForNextFrame(1);
//mViewer.setRealizeOperation(ico);
mViewer.realize();
std::cout << "realize took " << timer.time_m() << std::endl;
while (!mViewer.done())
{
MWBase::Environment::get().getWorld()->update(0.f, false);
mViewer.frame(/*simulationTime*/);
}
/*
Ogre::Timer timer;
while (!MWBase::Environment::get().getStateManager()->hasQuitRequest())

@ -9,11 +9,23 @@
#include <components/settings/settings.hpp>
#include <components/nifcache/nifcache.hpp>
#include <osgViewer/Viewer>
#include "mwbase/environment.hpp"
#include "mwworld/ptr.hpp"
namespace Resource
{
class ResourceSystem;
}
namespace VFS
{
class Manager;
}
namespace Compiler
{
class Context;
@ -39,19 +51,6 @@ namespace MWGui
class WindowManager;
}
namespace OEngine
{
namespace GUI
{
class MyGUIManager;
}
namespace Render
{
class OgreRenderer;
}
}
namespace Files
{
struct ConfigurationManager;
@ -62,13 +61,15 @@ namespace OMW
/// \brief Main engine class, that brings together all the components of OpenMW
class Engine : private Ogre::FrameListener
{
std::auto_ptr<VFS::Manager> mVFS;
std::auto_ptr<Resource::ResourceSystem> mResourceSystem;
MWBase::Environment mEnvironment;
ToUTF8::FromType mEncoding;
ToUTF8::Utf8Encoder* mEncoder;
Files::PathContainer mDataDirs;
std::vector<std::string> mArchives;
boost::filesystem::path mResDir;
OEngine::Render::OgreRenderer *mOgre;
osgViewer::Viewer mViewer;
std::string mCellName;
std::vector<std::string> mContentFiles;
bool mVerboseScripts;
@ -108,9 +109,6 @@ namespace OMW
/// \note This function works recursively.
void addResourcesDirectory (const boost::filesystem::path& path);
/// add a .zip resource
void addZipResource (const boost::filesystem::path& path);
void executeLocalScripts();
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);

@ -16,7 +16,7 @@
#include "../mwworld/failedaction.hpp"
#include "../mwworld/nullaction.hpp"
#include "../mwrender/actors.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwgui/tooltips.hpp"
@ -34,8 +34,7 @@ namespace MWClass
void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
if (!model.empty()) {
MWRender::Actors& actors = renderingInterface.getActors();
actors.insertActivator(ptr, model);
renderingInterface.getObjects().insertModel(ptr, model, true);
}
}

@ -23,7 +23,7 @@
#include "../mwgui/tooltips.hpp"
#include "../mwrender/actors.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwmechanics/npcstats.hpp"
@ -93,8 +93,7 @@ namespace MWClass
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
if (!model.empty()) {
MWRender::Actors& actors = renderingInterface.getActors();
actors.insertActivator(ptr, model);
renderingInterface.getObjects().insertModel(ptr, model, true);
}
}

@ -29,7 +29,7 @@
#include "../mwworld/cellstore.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/actors.hpp"
#include "../mwrender/objects.hpp"
#include "../mwgui/tooltips.hpp"
@ -163,10 +163,10 @@ namespace MWClass
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
//MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
//MWRender::Actors& actors = renderingInterface.getActors();
//actors.insertCreature(ptr, model, (ref->mBase->mFlags & ESM::Creature::Weapon) != 0);
MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertCreature(ptr, model, (ref->mBase->mFlags & ESM::Creature::Weapon) != 0);
}
void Creature::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const

@ -24,7 +24,7 @@
#include "../mwgui/tooltips.hpp"
#include "../mwrender/actors.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
namespace
@ -52,8 +52,7 @@ namespace MWClass
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
if (!model.empty()) {
MWRender::Actors& actors = renderingInterface.getActors();
actors.insertActivator(ptr, model);
renderingInterface.getObjects().insertModel(ptr, model, true);
}
}

@ -23,7 +23,6 @@
#include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/actors.hpp"
#include "../mwrender/renderinginterface.hpp"
namespace MWClass
@ -39,8 +38,7 @@ namespace MWClass
ptr.get<ESM::Light>();
// Insert even if model is empty, so that the light is added
MWRender::Actors& actors = renderingInterface.getActors();
actors.insertActivator(ptr, model, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
renderingInterface.getObjects().insertModel(ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault));
}
void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const

@ -35,7 +35,7 @@
#include "../mwworld/physicssystem.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwrender/actors.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwgui/tooltips.hpp"
@ -409,7 +409,7 @@ namespace MWClass
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
renderingInterface.getActors().insertNPC(ptr);
renderingInterface.getObjects().insertNPC(ptr);
}
void Npc::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const

@ -1702,6 +1702,7 @@ namespace MWGui
void WindowManager::playVideo(const std::string &name, bool allowSkipping)
{
return;
mVideoWidget->playVideo("video\\" + name);
mVideoWidget->eventKeyButtonPressed.clear();

@ -474,7 +474,7 @@ namespace MWMechanics
Ogre::Vector3 dir = playerPos - actorPos;
Ogre::Radian faceAngle = Ogre::Math::ATan2(dir.x,dir.y);
Ogre::Radian actorAngle = actor.getRefData().getBaseNode()->getOrientation().getRoll();
Ogre::Radian actorAngle = actor.getRefData().getBaseNodeOld()->getOrientation().getRoll();
// an attempt at reducing the turning animation glitch
if( Ogre::Math::Abs( faceAngle - actorAngle ) >= Ogre::Degree(5) ) // TODO: is there a better way?
{

@ -75,7 +75,7 @@ namespace MWMechanics
return false;
Ogre::Degree angle = signedAngle (Ogre::Vector3(attacker.getRefData().getPosition().pos) - Ogre::Vector3(blocker.getRefData().getPosition().pos),
blocker.getRefData().getBaseNode()->getOrientation().yAxis(), Ogre::Vector3(0,0,1));
blocker.getRefData().getBaseNodeOld()->getOrientation().yAxis(), Ogre::Vector3(0,0,1));
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
if (angle.valueDegrees() < gmst.find("fCombatBlockLeftAngle")->getFloat())

@ -3,6 +3,8 @@
#include <openengine/misc/rng.hpp>
#include <iostream>
#include "../mwworld/ptr.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/manualref.hpp"

@ -1385,7 +1385,7 @@ namespace MWMechanics
static float fSneakViewMult = store.find("fSneakViewMult")->getFloat();
float y = 0;
Ogre::Vector3 vec = pos1 - pos2;
Ogre::Radian angle = observer.getRefData().getBaseNode()->getOrientation().yAxis().angleBetween(vec);
Ogre::Radian angle = observer.getRefData().getBaseNodeOld()->getOrientation().yAxis().angleBetween(vec);
if (angle < Ogre::Degree(90))
y = obsTerm * observerStats.getFatigueTerm() * fSneakNoViewMult;
else

@ -418,7 +418,7 @@ namespace MWMechanics
absorbed = (OEngine::Misc::Rng::roll0to99() < absorb);
if (absorbed)
{
const ESM::Static* absorbStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Absorb");
//const ESM::Static* absorbStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Absorb");
//MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect(
// "meshes\\" + absorbStatic->mModel, ESM::MagicEffect::SpellAbsorption, false, "");
// Magicka is increased by cost of spell
@ -466,7 +466,7 @@ namespace MWMechanics
bool isReflected = (OEngine::Misc::Rng::roll0to99() < reflect);
if (isReflected)
{
const ESM::Static* reflectStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Reflect");
//const ESM::Static* reflectStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find ("VFX_Reflect");
//MWBase::Environment::get().getWorld()->getAnimation(target)->addEffect(
// "meshes\\" + reflectStatic->mModel, ESM::MagicEffect::Reflect, false, "");
reflectedEffects.mList.push_back(*effectIt);
@ -565,7 +565,7 @@ namespace MWMechanics
}
// Add VFX
const ESM::Static* castStatic;
/*const ESM::Static* castStatic;
if (!magicEffect->mHit.empty())
castStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find (magicEffect->mHit);
else
@ -574,9 +574,10 @@ namespace MWMechanics
// TODO: VFX are no longer active after saving/reloading the game
bool loop = (magicEffect->mData.mFlags & ESM::MagicEffect::ContinuousVfx) != 0;
// Note: in case of non actor, a free effect should be fine as well
//MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(target);
//if (anim)
// anim->addEffect("meshes\\" + castStatic->mModel, magicEffect->mIndex, loop, "");
MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(target);
if (anim)
anim->addEffect("meshes\\" + castStatic->mModel, magicEffect->mIndex, loop, "");
*/
}
}
}

@ -1,8 +1,6 @@
#ifndef GAME_RENDER_ACTORS_H
#define GAME_RENDER_ACTORS_H
//#include <openengine/ogre/renderer.hpp>
#include <string>
namespace OEngine

File diff suppressed because it is too large Load Diff

@ -4,15 +4,20 @@
#include <OgreController.h>
#include <OgreVector3.h>
#include <components/nifogre/ogrenifloader.hpp>
#include "../mwworld/ptr.hpp"
#include <components/nifosg/controller.hpp>
namespace ESM
{
struct Light;
}
namespace Resource
{
class ResourceSystem;
}
namespace MWRender
{
class Camera;
@ -69,20 +74,18 @@ protected:
virtual void setValue(Ogre::Real value);
};
class NullAnimationTime : public Ogre::ControllerValue<Ogre::Real>
class NullAnimationTime : public NifOsg::ControllerSource
{
public:
virtual Ogre::Real getValue() const
{ return 0.0f; }
virtual void setValue(Ogre::Real value)
{ }
virtual float getValue(osg::NodeVisitor *nv)
{
return 0.f;
}
};
struct AnimSource : public Ogre::AnimationAlloc {
NifOgre::TextKeyMap mTextKeys;
//NifOgre::TextKeyMap mTextKeys;
std::vector<Ogre::Controller<Ogre::Real> > mControllers[sNumGroups];
};
typedef std::vector< Ogre::SharedPtr<AnimSource> > AnimSourceList;
@ -113,106 +116,71 @@ protected:
typedef std::map<Ogre::MovableObject*,std::string> ObjectAttachMap;
struct EffectParams
{
std::string mModelName; // Just here so we don't add the same effect twice
NifOgre::ObjectScenePtr mObjects;
int mEffectId;
bool mLoop;
std::string mBoneName;
};
osg::ref_ptr<osg::Group> mInsert;
std::vector<EffectParams> mEffects;
osg::ref_ptr<osg::Node> mObjectRoot;
MWWorld::Ptr mPtr;
Ogre::Light* mGlowLight;
Ogre::SceneNode *mInsert;
Ogre::Entity *mSkelBase;
NifOgre::ObjectScenePtr mObjectRoot;
AnimSourceList mAnimSources;
Ogre::Node *mAccumRoot;
Ogre::Node *mNonAccumRoot;
NifOgre::NodeTargetValue<Ogre::Real> *mNonAccumCtrl;
Ogre::Vector3 mAccumulate;
AnimStateMap mStates;
Ogre::SharedPtr<AnimationTime> mAnimationTimePtr[sNumGroups];
Ogre::SharedPtr<NullAnimationTime> mNullAnimationTimePtr;
ObjectAttachMap mAttachedObjects;
Resource::ResourceSystem* mResourceSystem;
/* Sets the appropriate animations on the bone groups based on priority.
*/
void resetActiveGroups();
//void resetActiveGroups();
static size_t detectAnimGroup(const Ogre::Node *node);
//static size_t detectAnimGroup(const Ogre::Node *node);
/*
static float calcAnimVelocity(const NifOgre::TextKeyMap &keys,
NifOgre::NodeTargetValue<Ogre::Real> *nonaccumctrl,
const Ogre::Vector3 &accum,
const std::string &groupname);
/* Updates a skeleton instance so that all bones matching the source skeleton (based on
* bone names) are positioned identically. */
void updateSkeletonInstance(const Ogre::SkeletonInstance *skelsrc, Ogre::SkeletonInstance *skel);
*/
/* Updates the position of the accum root node for the given time, and
* returns the wanted movement vector from the previous time. */
void updatePosition(float oldtime, float newtime, Ogre::Vector3 &position);
//void updatePosition(float oldtime, float newtime, Ogre::Vector3 &position);
static NifOgre::TextKeyMap::const_iterator findGroupStart(const NifOgre::TextKeyMap &keys, const std::string &groupname);
//static NifOgre::TextKeyMap::const_iterator findGroupStart(const NifOgre::TextKeyMap &keys, const std::string &groupname);
/* Resets the animation to the time of the specified start marker, without
* moving anything, and set the end time to the specified stop marker. If
* the marker is not found, or if the markers are the same, it returns
* false.
*/
bool reset(AnimState &state, const NifOgre::TextKeyMap &keys,
const std::string &groupname, const std::string &start, const std::string &stop,
float startpoint, bool loopfallback);
//bool reset(AnimState &state, const NifOgre::TextKeyMap &keys,
// const std::string &groupname, const std::string &start, const std::string &stop,
// float startpoint, bool loopfallback);
void handleTextKey(AnimState &state, const std::string &groupname, const NifOgre::TextKeyMap::const_iterator &key,
const NifOgre::TextKeyMap& map);
//void handleTextKey(AnimState &state, const std::string &groupname, const NifOgre::TextKeyMap::const_iterator &key,
// const NifOgre::TextKeyMap& map);
/* Sets the root model of the object. If 'baseonly' is true, then any meshes or particle
* systems in the model are ignored (useful for NPCs, where only the skeleton is needed for
* the root).
/* Sets the root model of the object.
*
* Note that you must make sure all animation sources are cleared before reseting the object
* root. All nodes previously retrieved with getNode will also become invalidated.
*/
void setObjectRoot(const std::string &model, bool baseonly);
void setObjectRoot(const std::string &model);
/* Adds the keyframe controllers in the specified model as a new animation source. Note that
* the filename portion of the provided model name will be prepended with 'x', and the .nif
* 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::ObjectScenePtr objlist, const ESM::Light *light);
void clearAnimSources();
//void addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScenePtr objlist, const ESM::Light *light);
// TODO: Should not be here
Ogre::Vector3 getEnchantmentColor(MWWorld::Ptr item);
//void clearAnimSources();
public:
// FIXME: Move outside of this class
static void setRenderProperties(NifOgre::ObjectScenePtr objlist, Ogre::uint32 visflags, Ogre::uint8 solidqueue,
Ogre::uint8 transqueue, Ogre::Real dist=0.0f,
bool enchantedGlow=false, Ogre::Vector3* glowColor=NULL);
/// Returns the name of the .nif file that makes up this animation's base skeleton.
/// If there is no skeleton, returns "".
std::string getObjectRootName() const;
Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node);
Animation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> node, Resource::ResourceSystem* resourceSystem);
virtual ~Animation();
osg::Group* getOrCreateObjectRoot();
osg::Group* getObjectRoot();
/**
* @brief Add an effect mesh attached to a bone or the insert scene node
* @param model
@ -223,25 +191,18 @@ public:
* @param texture override the texture specified in the model's materials
* @note Will not add an effect twice.
*/
void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", std::string texture = "");
void removeEffect (int effectId);
void getLoopingEffects (std::vector<int>& out);
//void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", std::string texture = "");
//void removeEffect (int effectId);
//void getLoopingEffects (std::vector<int>& out);
/// Prepare this animation for being rendered with \a camera (rotates billboard nodes)
virtual void preRender (Ogre::Camera* camera);
//void updatePtr(const MWWorld::Ptr &ptr);
virtual void setAlpha(float alpha) {}
virtual void setVampire(bool vampire) {}
public:
void updatePtr(const MWWorld::Ptr &ptr);
bool hasAnimation(const std::string &anim);
//bool hasAnimation(const std::string &anim);
// Specifies the axis' to accumulate on. Non-accumulated axis will just
// move visually, but not affect the actual movement. Each x/y/z value
// should be on the scale of 0 to 1.
void setAccumulation(const Ogre::Vector3 &accum);
//void setAccumulation(const Ogre::Vector3 &accum);
/** Plays an animation.
* \param groupname Name of the animation group to play.
@ -263,23 +224,23 @@ public:
* \param loopFallback Allow looping an animation that has no loop keys, i.e. fall back to use
* the "start" and "stop" keys for looping?
*/
void play(const std::string &groupname, int priority, int groups, bool autodisable,
float speedmult, const std::string &start, const std::string &stop,
float startpoint, size_t loops, bool loopfallback=false);
//void play(const std::string &groupname, int priority, int groups, bool autodisable,
// float speedmult, const std::string &start, const std::string &stop,
// float startpoint, size_t loops, bool loopfallback=false);
/** If the given animation group is currently playing, set its remaining loop count to '0'.
*/
void stopLooping(const std::string& groupName);
//void stopLooping(const std::string& groupName);
/** Adjust the speed multiplier of an already playing animation.
*/
void adjustSpeedMult (const std::string& groupname, float speedmult);
//void adjustSpeedMult (const std::string& groupname, float speedmult);
/** Returns true if the named animation group is playing. */
bool isPlaying(const std::string &groupname) const;
//bool isPlaying(const std::string &groupname) const;
/// Returns true if no important animations are currently playing on the upper body.
bool upperBodyReady() const;
//bool upperBodyReady() const;
/** Gets info about the given animation group.
* \param groupname Animation group to check.
@ -287,71 +248,32 @@ public:
* \param speedmult Stores the animation speed multiplier
* \return True if the animation is active, false otherwise.
*/
bool getInfo(const std::string &groupname, float *complete=NULL, float *speedmult=NULL) const;
//bool getInfo(const std::string &groupname, float *complete=NULL, float *speedmult=NULL) const;
/// Get the absolute position in the animation track of the first text key with the given group.
float getStartTime(const std::string &groupname) const;
//float getStartTime(const std::string &groupname) const;
/// Get the absolute position in the animation track of the text key
float getTextKeyTime(const std::string &textKey) const;
//float getTextKeyTime(const std::string &textKey) const;
/// Get the current absolute position in the animation track for the animation that is currently playing from the given group.
float getCurrentTime(const std::string& groupname) const;
//float getCurrentTime(const std::string& groupname) const;
/** Disables the specified animation group;
* \param groupname Animation group to disable.
*/
void disable(const std::string &groupname);
void changeGroups(const std::string &groupname, int group);
virtual void setWeaponGroup(const std::string& group) {}
//void disable(const std::string &groupname);
//void changeGroups(const std::string &groupname, int group);
/** Retrieves the velocity (in units per second) that the animation will move. */
float getVelocity(const std::string &groupname) const;
/// A relative factor (0-1) that decides if and how much the skeleton should be pitched
/// to indicate the facing orientation of the character.
virtual void setPitchFactor(float factor) {}
virtual void setHeadPitch(Ogre::Radian factor) {}
virtual void setHeadYaw(Ogre::Radian factor) {}
virtual Ogre::Radian getHeadPitch() const { return Ogre::Radian(0.f); }
virtual Ogre::Radian getHeadYaw() const { return Ogre::Radian(0.f); }
virtual Ogre::Vector3 runAnimation(float duration);
/// This is typically called as part of runAnimation, but may be called manually if needed.
void updateEffects(float duration);
// TODO: move outside of this class
/// Makes this object glow, by placing a Light in its center.
/// @param effect Controls the radius and intensity of the light.
void setLightEffect(float effect);
virtual void showWeapons(bool showWeapon);
virtual void showCarriedLeft(bool show) {}
virtual void attachArrow() {}
virtual void releaseArrow() {}
void enableLights(bool enable);
virtual void enableHeadAnimation(bool enable) {}
Ogre::AxisAlignedBox getWorldBounds();
Ogre::Node *getNode(const std::string &name);
Ogre::Node *getNode(int handle);
// Attaches the given object to a bone on this object's base skeleton. If the bone doesn't
// exist, the object isn't attached and NULL is returned. The returned TagPoint is only
// valid until the next setObjectRoot call.
Ogre::TagPoint *attachObjectToBone(const Ogre::String &bonename, Ogre::MovableObject *obj);
void detachObjectFromBone(Ogre::MovableObject *obj);
//float getVelocity(const std::string &groupname) const;
virtual osg::Vec3f runAnimation(float duration);
};
class ObjectAnimation : public Animation {
public:
ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model);
bool canBatch() const;
void fillBatch(Ogre::StaticGeometry *sg);
ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model, Resource::ResourceSystem* resourceSystem);
};
}

@ -2,110 +2,204 @@
#include <cmath>
#include <OgreSceneNode.h>
#include <OgreSceneManager.h>
#include <OgreEntity.h>
#include <OgreLight.h>
#include <OgreSubEntity.h>
#include <OgreParticleSystem.h>
#include <OgreParticleEmitter.h>
#include <OgreStaticGeometry.h>
#include <osg/io_utils>
#include <osg/Group>
#include <osg/Geode>
#include <osg/PositionAttitudeTransform>
#include <osg/ComputeBoundsVisitor>
#include <components/esm/loadligh.hpp>
#include <components/esm/loadstat.hpp>
#include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleProcessor>
//#include <components/nifogre/ogrenifloader.hpp>
#include <components/settings/settings.hpp>
// light
#include <components/sceneutil/lightmanager.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/sceneutil/util.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/cellstore.hpp"
#include "renderconst.hpp"
//#include "animation.hpp"
#include "animation.hpp"
namespace
{
/// Removes all particle systems and related nodes in a subgraph.
class RemoveParticlesVisitor : public osg::NodeVisitor
{
public:
RemoveParticlesVisitor()
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
{ }
virtual void apply(osg::Node &node)
{
if (dynamic_cast<osgParticle::ParticleSystem*>(&node) || dynamic_cast<osgParticle::ParticleProcessor*>(&node))
mToRemove.push_back(&node);
traverse(node);
}
using namespace MWRender;
void remove()
{
for (std::vector<osg::ref_ptr<osg::Node> >::iterator it = mToRemove.begin(); it != mToRemove.end(); ++it)
{
osg::Node* node = *it;
if (node->getNumParents())
node->getParent(0)->removeChild(node);
}
mToRemove.clear();
}
int Objects::uniqueID = 0;
private:
std::vector<osg::ref_ptr<osg::Node> > mToRemove;
};
}
void Objects::setRootNode(Ogre::SceneNode* root)
namespace MWRender
{
Objects::Objects(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> rootNode)
: mResourceSystem(resourceSystem)
, mRootNode(rootNode)
{
mRootNode = root;
}
Objects::~Objects()
{
for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();++iter)
delete iter->second;
mObjects.clear();
for (CellMap::iterator iter = mCellSceneNodes.begin(); iter != mCellSceneNodes.end(); ++iter)
iter->second->getParent(0)->removeChild(iter->second);
mCellSceneNodes.clear();
}
void Objects::insertBegin(const MWWorld::Ptr& ptr)
{
Ogre::SceneNode* root = mRootNode;
Ogre::SceneNode* cellnode;
if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
osg::ref_ptr<osg::Group> cellnode;
CellMap::iterator found = mCellSceneNodes.find(ptr.getCell());
if (found == mCellSceneNodes.end())
{
//Create the scenenode and put it in the map
cellnode = root->createChildSceneNode();
cellnode = new osg::Group;
mRootNode->addChild(cellnode);
mCellSceneNodes[ptr.getCell()] = cellnode;
}
else
{
cellnode = mCellSceneNodes[ptr.getCell()];
}
cellnode = found->second;
Ogre::SceneNode* insert = cellnode->createChildSceneNode();
const float *f = ptr.getRefData().getPosition().pos;
osg::ref_ptr<osg::PositionAttitudeTransform> insert (new osg::PositionAttitudeTransform);
cellnode->addChild(insert);
insert->setPosition(f[0], f[1], f[2]);
insert->setScale(ptr.getCellRef().getScale(), ptr.getCellRef().getScale(), ptr.getCellRef().getScale());
const float *f = ptr.getRefData().getPosition().pos;
insert->setPosition(osg::Vec3(f[0], f[1], f[2]));
insert->setScale(osg::Vec3(ptr.getCellRef().getScale(), ptr.getCellRef().getScale(), ptr.getCellRef().getScale()));
// Convert MW rotation to a quaternion:
f = ptr.getCellRef().getPosition().rot;
// Rotate around X axis
Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X);
osg::Quat xr(-f[0], osg::Vec3(1,0,0));
// Rotate around Y axis
Ogre::Quaternion yr(Ogre::Radian(-f[1]), Ogre::Vector3::UNIT_Y);
osg::Quat yr(-f[1], osg::Vec3(0,1,0));
// Rotate around Z axis
Ogre::Quaternion zr(Ogre::Radian(-f[2]), Ogre::Vector3::UNIT_Z);
osg::Quat zr(-f[2], osg::Vec3(0,0,1));
// Rotates first around z, then y, then x
insert->setOrientation(xr*yr*zr);
insert->setAttitude(zr*yr*xr);
// TODO: actors rotate around z only
ptr.getRefData().setBaseNode(insert);
}
void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool batch)
void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool animated, bool allowLight)
{
insertBegin(ptr);
/*
std::auto_ptr<ObjectAnimation> anim(new ObjectAnimation(ptr, mesh));
if (!mesh.empty())
std::auto_ptr<ObjectAnimation> anim (new ObjectAnimation(ptr, mesh, mResourceSystem));
if (ptr.getTypeName() == typeid(ESM::Light).name() && allowLight)
{
Ogre::AxisAlignedBox bounds = anim->getWorldBounds();
Ogre::Vector3 extents = bounds.getSize();
extents *= ptr.getRefData().getBaseNode()->getScale();
float size = std::max(std::max(extents.x, extents.y), extents.z);
SceneUtil::FindByNameVisitor visitor("AttachLight");
ptr.getRefData().getBaseNode()->accept(visitor);
osg::Vec3f lightOffset (0.f, 0.f, 0.f);
osg::Group* attachTo = NULL;
if (visitor.mFoundNode)
{
attachTo = visitor.mFoundNode;
}
else
{
osg::ComputeBoundsVisitor computeBound;
osg::Group* objectRoot = anim->getOrCreateObjectRoot();
objectRoot->accept(computeBound);
bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) &&
Settings::Manager::getBool("limit small object distance", "Viewing distance");
// do not fade out doors. that will cause holes and look stupid
if(ptr.getTypeName().find("Door") != std::string::npos)
small = false;
lightOffset = computeBound.getBoundingBox().center();
if (mBounds.find(ptr.getCell()) == mBounds.end())
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
mBounds[ptr.getCell()].merge(bounds);
attachTo = objectRoot;
}
const ESM::Light* esmLight = ptr.get<ESM::Light>()->mBase;
osg::ref_ptr<SceneUtil::LightSource> lightSource = new SceneUtil::LightSource;
osg::Light* light = new osg::Light;
lightSource->setLight(light);
light->setPosition(osg::Vec4f(lightOffset.x(), lightOffset.y(), lightOffset.z(), 1.f));
float realRadius = esmLight->mData.mRadius * 2;
lightSource->setRadius(realRadius);
light->setLinearAttenuation(10.f/realRadius);
//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;
anim->getObjectRoot()->accept(visitor);
visitor.remove();
}
if(anim.get() != NULL)
mObjects.insert(std::make_pair(ptr, anim.release()));
*/
mObjects.insert(std::make_pair(ptr, anim.release()));
}
void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, bool weaponsShields)
{
insertBegin(ptr);
// CreatureAnimation
std::auto_ptr<ObjectAnimation> anim (new ObjectAnimation(ptr, mesh, mResourceSystem));
mObjects.insert(std::make_pair(ptr, anim.release()));
}
void Objects::insertNPC(const MWWorld::Ptr &ptr)
{
}
bool Objects::deleteObject (const MWWorld::Ptr& ptr)
{
/*
if(!ptr.getRefData().getBaseNode())
return true;
@ -115,18 +209,16 @@ bool Objects::deleteObject (const MWWorld::Ptr& ptr)
delete iter->second;
mObjects.erase(iter);
mRenderer.getScene()->destroySceneNode(ptr.getRefData().getBaseNode());
ptr.getRefData().setBaseNode(0);
ptr.getRefData().getBaseNode()->getParent(0)->removeChild(ptr.getRefData().getBaseNode());
ptr.getRefData().setBaseNode(NULL);
return true;
}
*/
return false;
}
void Objects::removeCell(MWWorld::CellStore* store)
void Objects::removeCell(const MWWorld::CellStore* store)
{
/*
for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();)
{
if(iter->first.getCell() == store)
@ -138,46 +230,19 @@ void Objects::removeCell(MWWorld::CellStore* store)
++iter;
}
std::map<MWWorld::CellStore*,Ogre::StaticGeometry*>::iterator geom = mStaticGeometry.find(store);
if(geom != mStaticGeometry.end())
{
Ogre::StaticGeometry *sg = geom->second;
mStaticGeometry.erase(geom);
mRenderer.getScene()->destroyStaticGeometry(sg);
}
geom = mStaticGeometrySmall.find(store);
if(geom != mStaticGeometrySmall.end())
{
Ogre::StaticGeometry *sg = geom->second;
mStaticGeometrySmall.erase(store);
mRenderer.getScene()->destroyStaticGeometry(sg);
}
mBounds.erase(store);
std::map<MWWorld::CellStore*,Ogre::SceneNode*>::iterator cell = mCellSceneNodes.find(store);
CellMap::iterator cell = mCellSceneNodes.find(store);
if(cell != mCellSceneNodes.end())
{
cell->second->removeAndDestroyAllChildren();
mRenderer.getScene()->destroySceneNode(cell->second);
cell->second->getParent(0)->removeChild(cell->second);
mCellSceneNodes.erase(cell);
}
*/
}
Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::CellStore* cell)
{
return mBounds[cell];
}
void Objects::update(float dt, Ogre::Camera* camera)
{
/*
PtrAnimationMap::const_iterator it = mObjects.begin();
for(;it != mObjects.end();++it)
it->second->runAnimation(dt);
*/
}
void Objects::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
@ -206,13 +271,13 @@ void Objects::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
*/
}
ObjectAnimation* Objects::getAnimation(const MWWorld::Ptr &ptr)
Animation* Objects::getAnimation(const MWWorld::Ptr &ptr)
{
/*
PtrAnimationMap::const_iterator iter = mObjects.find(ptr);
if(iter != mObjects.end())
return iter->second;
*/
return NULL;
}
}

@ -1,10 +1,16 @@
#ifndef GAME_RENDER_OBJECTS_H
#define GAME_RENDER_OBJECTS_H
#include <OgreColourValue.h>
#include <OgreAxisAlignedBox.h>
#include <openengine/ogre/renderer.hpp>
#include <components/resource/resourcesystem.hpp>
#include <osg/ref_ptr>
namespace osg
{
class Group;
}
namespace MWWorld
{
@ -14,53 +20,52 @@ namespace MWWorld
namespace MWRender{
class ObjectAnimation;
class Animation;
class Objects{
typedef std::map<MWWorld::Ptr,ObjectAnimation*> PtrAnimationMap;
OEngine::Render::OgreRenderer &mRenderer;
class Objects{
typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap;
std::map<MWWorld::CellStore*,Ogre::SceneNode*> mCellSceneNodes;
std::map<MWWorld::CellStore*,Ogre::StaticGeometry*> mStaticGeometry;
std::map<MWWorld::CellStore*,Ogre::StaticGeometry*> mStaticGeometrySmall;
std::map<MWWorld::CellStore*,Ogre::AxisAlignedBox> mBounds;
typedef std::map<const MWWorld::CellStore*, osg::ref_ptr<osg::Group> > CellMap;
CellMap mCellSceneNodes;
PtrAnimationMap mObjects;
Ogre::SceneNode* mRootNode;
static int uniqueID;
osg::ref_ptr<osg::Group> mRootNode;
void insertBegin(const MWWorld::Ptr& ptr);
Resource::ResourceSystem* mResourceSystem;
public:
Objects(OEngine::Render::OgreRenderer &renderer)
: mRenderer(renderer)
, mRootNode(NULL)
{}
~Objects(){}
void insertModel(const MWWorld::Ptr& ptr, const std::string &model, bool batch=false);
Objects(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> rootNode);
~Objects();
/// @param animated Attempt to load separate keyframes from a .kf file matching the model file?
/// @param allowLight If false, no lights will be created, and particles systems will be cleared then frozen.
void insertModel(const MWWorld::Ptr& ptr, const std::string &model, bool animated=false, bool allowLight=true);
ObjectAnimation* getAnimation(const MWWorld::Ptr &ptr);
void insertNPC(const MWWorld::Ptr& ptr);
void insertCreature (const MWWorld::Ptr& ptr, const std::string& model, bool weaponsShields);
Animation* getAnimation(const MWWorld::Ptr &ptr);
void update (float dt, Ogre::Camera* camera);
///< per-frame update
Ogre::AxisAlignedBox getDimensions(MWWorld::CellStore*);
//Ogre::AxisAlignedBox getDimensions(MWWorld::CellStore*);
///< get a bounding box that encloses all objects in the specified cell
bool deleteObject (const MWWorld::Ptr& ptr);
///< \return found?
void removeCell(MWWorld::CellStore* store);
void setRootNode(Ogre::SceneNode* root);
void rebuildStaticGeometry();
void removeCell(const MWWorld::CellStore* store);
/// Updates containing cell for object rendering data
void updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur);
private:
void operator = (const Objects&);
Objects(const Objects&);
};
}
#endif

File diff suppressed because it is too large Load Diff

@ -1,270 +1,61 @@
#ifndef GAME_RENDERING_MANAGER_H
#define GAME_RENDERING_MANAGER_H
#ifndef OPENMW_MWRENDER_RENDERINGMANAGER_H
#define OPENMW_MWRENDER_RENDERINGMANAGER_H
#include "sky.hpp"
#include "debugging.hpp"
#include <osg/ref_ptr>
#include <osg/Light>
#include <components/settings/settings.hpp>
#include <boost/filesystem.hpp>
#include <OgreRenderTargetListener.h>
#include "objects.hpp"
#include "renderinginterface.hpp"
#include "objects.hpp"
#include "actors.hpp"
#include "camera.hpp"
#include "occlusionquery.hpp"
namespace Ogre
namespace osg
{
class SceneNode;
class Group;
}
namespace MWWorld
namespace Resource
{
class Ptr;
class CellStore;
class ResourceSystem;
}
namespace sh
namespace osgViewer
{
class Factory;
class Viewer;
}
namespace Terrain
namespace ESM
{
class World;
struct Cell;
}
namespace MWRender
{
class Shadows;
class LocalMap;
class Water;
class GlobalMap;
class Animation;
class EffectManager;
class RenderingManager: private RenderingInterface, public Ogre::RenderTargetListener, public OEngine::Render::WindowSizeListener
{
private:
virtual MWRender::Objects& getObjects();
virtual MWRender::Actors& getActors();
public:
RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir,
const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine,
MWWorld::Fallback* fallback);
virtual ~RenderingManager();
void togglePOV()
{ mCamera->toggleViewMode(); }
void togglePreviewMode(bool enable)
{ mCamera->togglePreviewMode(enable); }
bool toggleVanityMode(bool enable)
{ return mCamera->toggleVanityMode(enable); }
void allowVanityMode(bool allow)
{ mCamera->allowVanityMode(allow); }
void togglePlayerLooking(bool enable)
{ mCamera->togglePlayerLooking(enable); }
void changeVanityModeScale(float factor)
class RenderingManager : public MWRender::RenderingInterface
{
if(mCamera->isVanityOrPreviewModeEnabled())
mCamera->setCameraDistance(-factor/120.f*10, true, true);
}
void resetCamera();
bool vanityRotateCamera(const float *rot);
void setCameraDistance(float dist, bool adjust = false, bool override = true);
float getCameraDistance() const;
void setupPlayer(const MWWorld::Ptr &ptr);
void renderPlayer(const MWWorld::Ptr &ptr);
SkyManager* getSkyManager();
MWRender::Camera* getCamera() const;
bool toggleRenderMode(int mode);
void removeCell (MWWorld::CellStore *store);
/// \todo this function should be removed later. Instead the rendering subsystems should track
/// when rebatching is needed and update automatically at the end of each frame.
void cellAdded (MWWorld::CellStore *store);
/// Clear all savegame-specific data (i.e. fog of war textures)
void clear();
void enableTerrain(bool enable);
void removeWater();
/// Write current fog of war for this cell to the CellStore
void writeFog (MWWorld::CellStore* store);
void addObject (const MWWorld::Ptr& ptr, const std::string& model);
void removeObject (const MWWorld::Ptr& ptr);
void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position);
void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale);
/// Updates an object's rotation
void rotateObject (const MWWorld::Ptr& ptr);
void setWaterHeight(float height);
void setWaterEnabled(bool enabled);
bool toggleWater();
bool toggleWorld();
/// Updates object rendering after cell change
/// \param old Object reference in previous cell
/// \param cur Object reference in new cell
void updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur);
/// Specifies an updated Ptr object for the player (used on cell change).
void updatePlayerPtr(const MWWorld::Ptr &ptr);
/// Currently for NPCs only. Rebuilds the NPC, updating their root model, animation sources,
/// and equipment.
void rebuildPtr(const MWWorld::Ptr &ptr);
void update (float duration, bool paused);
void setAmbientColour(const Ogre::ColourValue& colour);
void setSunColour(const Ogre::ColourValue& colour);
void setSunDirection(const Ogre::Vector3& direction, bool is_night);
void sunEnable(bool real); ///< @param real whether or not to really disable the sunlight (otherwise just set diffuse to 0)
void sunDisable(bool real);
void disableLights(bool sun); ///< @param sun whether or not to really disable the sunlight (otherwise just set diffuse to 0)
void enableLights(bool sun);
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); }
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; }
float getTerrainHeightAt (Ogre::Vector3 worldPos);
void notifyWorldSpaceChanged();
void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches);
void setGlare(bool glare);
void skyEnable ();
void skyDisable ();
void skySetHour (double hour);
void skySetDate (int day, int month);
int skyGetMasserPhase() const;
int skyGetSecundaPhase() const;
void skySetMoonColour (bool red);
void configureAmbient(MWWorld::CellStore &mCell);
void addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f);
void removeWaterRippleEmitter (const MWWorld::Ptr& ptr);
void updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr);
void updateTerrain ();
///< update the terrain according to the player position. Usually done automatically, but should be done manually
/// before calling requestMap
void requestMap (MWWorld::CellStore* cell);
///< request the local map for a cell
/// configure fog according to cell
void configureFog(const MWWorld::CellStore &mCell);
/// configure fog manually
void configureFog(const float density, const Ogre::ColourValue& colour);
Ogre::Vector4 boundingBoxToScreen(Ogre::AxisAlignedBox bounds);
///< transform the specified bounding box (in world coordinates) into screen coordinates.
/// @return packed vector4 (min_x, min_y, max_x, max_y)
void processChangedSettings(const Settings::CategorySettingVector& settings);
Ogre::Viewport* getViewport() { return mRendering.getViewport(); }
void worldToInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y);
///< see MWRender::LocalMap::worldToInteriorMapPosition
Ogre::Vector2 interiorMapToWorldPosition (float nX, float nY, int x, int y);
///< see MWRender::LocalMap::interiorMapToWorldPosition
bool isPositionExplored (float nX, float nY, int x, int y, bool interior);
///< see MWRender::LocalMap::isPositionExplored
Animation* getAnimation(const MWWorld::Ptr &ptr);
void frameStarted(float dt, bool paused);
void screenshot(Ogre::Image& image, int w, int h);
void spawnEffect (const std::string& model, const std::string& texture, const Ogre::Vector3& worldPosition, float scale=1.f);
protected:
virtual void windowResized(int x, int y);
private:
sh::Factory* mFactory;
void setAmbientMode();
void applyFog(bool underwater);
void attachCameraTo(const MWWorld::Ptr& ptr);
void setMenuTransparency(float val);
bool mSunEnabled;
MWWorld::Fallback* mFallback;
SkyManager* mSkyManager;
OcclusionQuery* mOcclusionQuery;
Terrain::World* mTerrain;
MWRender::Water *mWater;
GlobalMap* mGlobalMap;
OEngine::Render::OgreRenderer &mRendering;
MWRender::Objects* mObjects;
MWRender::Actors* mActors;
MWRender::EffectManager* mEffectManager;
public:
RenderingManager(osgViewer::Viewer& viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem);
MWRender::NpcAnimation *mPlayerAnimation;
MWRender::Objects& getObjects();
MWRender::Actors& getActors();
Ogre::ColourValue mAmbientColor;
Ogre::Light* mSun;
Resource::ResourceSystem* getResourceSystem();
Ogre::SceneNode *mRootNode;
void configureAmbient(const ESM::Cell* cell);
Ogre::ColourValue mFogColour;
float mFogStart;
float mFogEnd;
void removeCell(const MWWorld::CellStore* store);
OEngine::Physic::PhysicEngine* mPhysicsEngine;
osg::Vec3f getEyePos();
MWRender::Camera *mCamera;
private:
osgViewer::Viewer& mViewer;
osg::ref_ptr<osg::Group> mRootNode;
Resource::ResourceSystem* mResourceSystem;
MWRender::LocalMap* mLocalMap;
osg::ref_ptr<osg::Light> mSunLight;
bool mRenderWorld;
};
std::auto_ptr<Objects> mObjects;
};
}

@ -686,10 +686,10 @@ namespace MWScript
else
throw std::runtime_error ("invalid movement axis: " + axis);
if (!ptr.getRefData().getBaseNode())
if (!ptr.getRefData().getBaseNodeOld())
return;
Ogre::Vector3 diff = ptr.getRefData().getBaseNode()->getOrientation() * posChange;
Ogre::Vector3 diff = ptr.getRefData().getBaseNodeOld()->getOrientation() * posChange;
Ogre::Vector3 worldPos(ptr.getRefData().getPosition().pos);
worldPos += diff;
MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x, worldPos.y, worldPos.z);

@ -20,11 +20,11 @@ namespace MWWorld
bool operator() (MWWorld::Ptr ptr)
{
Ogre::SceneNode* handle = ptr.getRefData().getBaseNode();
Ogre::SceneNode* handle = ptr.getRefData().getBaseNodeOld();
if (handle)
mHandles.push_back (handle);
ptr.getRefData().setBaseNode(0);
ptr.getRefData().setBaseNodeOld(0);
return true;
}
};

@ -242,7 +242,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
MWWorld::Ptr item = *it;
// we may have copied an item from the world, so reset a few things first
item.getRefData().setBaseNode(NULL); // Especially important, otherwise scripts on the item could think that it's actually in a cell
item.getRefData().setBaseNodeOld(NULL); // Especially important, otherwise scripts on the item could think that it's actually in a cell
ESM::Position pos;
pos.rot[0] = 0;
pos.rot[1] = 0;

@ -653,7 +653,7 @@ namespace MWWorld
std::vector<std::string> PhysicsSystem::getCollisions(const Ptr &ptr, int collisionGroup, int collisionMask)
{
return mEngine->getCollisions(ptr.getRefData().getBaseNode()->getName(), collisionGroup, collisionMask);
return mEngine->getCollisions(ptr.getRefData().getBaseNodeOld()->getName(), collisionGroup, collisionMask);
}
Ogre::Vector3 PhysicsSystem::traceDown(const MWWorld::Ptr &ptr, float maxHeight)
@ -675,7 +675,7 @@ namespace MWWorld
void PhysicsSystem::addObject (const Ptr& ptr, const std::string& mesh, bool placeable)
{
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
Ogre::SceneNode* node = ptr.getRefData().getBaseNodeOld();
handleToMesh[node->getName()] = mesh;
mEngine->createAndAdjustRigidBody(
mesh, node->getName(), ptr.getCellRef().getScale(), node->getPosition(), node->getOrientation(), 0, 0, false, placeable);
@ -685,7 +685,7 @@ namespace MWWorld
void PhysicsSystem::addActor (const Ptr& ptr, const std::string& mesh)
{
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
Ogre::SceneNode* node = ptr.getRefData().getBaseNodeOld();
//TODO:optimize this. Searching the std::map isn't very efficient i think.
mEngine->addCharacter(node->getName(), mesh, node->getPosition(), node->getScale().x, node->getOrientation());
}
@ -699,7 +699,7 @@ namespace MWWorld
void PhysicsSystem::moveObject (const Ptr& ptr)
{
Ogre::SceneNode *node = ptr.getRefData().getBaseNode();
Ogre::SceneNode *node = ptr.getRefData().getBaseNodeOld();
const std::string &handle = node->getName();
const Ogre::Vector3 &position = node->getPosition();
@ -722,7 +722,7 @@ namespace MWWorld
void PhysicsSystem::rotateObject (const Ptr& ptr)
{
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
Ogre::SceneNode* node = ptr.getRefData().getBaseNodeOld();
const std::string &handle = node->getName();
const Ogre::Quaternion &rotation = node->getOrientation();
@ -751,7 +751,7 @@ namespace MWWorld
void PhysicsSystem::scaleObject (const Ptr& ptr)
{
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
Ogre::SceneNode* node = ptr.getRefData().getBaseNodeOld();
const std::string &handle = node->getName();
if(handleToMesh.find(handle) != handleToMesh.end())
{

@ -134,14 +134,23 @@ namespace MWWorld
return mBaseNode->getName();
}
Ogre::SceneNode* RefData::getBaseNode()
Ogre::SceneNode* RefData::getBaseNodeOld()
{
return mBaseNode;
}
void RefData::setBaseNode(Ogre::SceneNode* base)
void RefData::setBaseNodeOld(Ogre::SceneNode* base)
{
mBaseNode = base;
}
void RefData::setBaseNode(osg::PositionAttitudeTransform *base)
{
mBase = base;
}
osg::PositionAttitudeTransform* RefData::getBaseNode()
{
return mBase;
}
int RefData::getCount() const

@ -10,6 +10,11 @@ namespace Ogre
class SceneNode;
}
namespace osg
{
class PositionAttitudeTransform;
}
namespace ESM
{
class Script;
@ -28,7 +33,7 @@ namespace MWWorld
class RefData
{
Ogre::SceneNode* mBaseNode;
osg::PositionAttitudeTransform* mBase;
MWScript::Locals mLocals; // if we find the overhead of heaving a locals
// object in the refdata of refs without a script,
@ -78,10 +83,18 @@ namespace MWWorld
const std::string &getHandle();
/// Return OGRE base node (can be a null pointer).
Ogre::SceneNode* getBaseNode();
/// obsolete
Ogre::SceneNode* getBaseNodeOld();
/// Return base node (can be a null pointer).
osg::PositionAttitudeTransform* getBaseNode();
/// Set OGRE base node (can be a null pointer).
void setBaseNode (Ogre::SceneNode* base);
/// obsolete
void setBaseNodeOld (Ogre::SceneNode* base);
/// Set base node (can be a null pointer).
void setBaseNode (osg::PositionAttitudeTransform* base);
int getCount() const;

@ -6,12 +6,16 @@
#include <components/misc/resourcehelpers.hpp>
#include <components/settings/settings.hpp>
#include <osg/PositionAttitudeTransform>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwrender/renderingmanager.hpp"
//#include "physicssystem.hpp"
#include "player.hpp"
#include "localscripts.hpp"
@ -20,19 +24,20 @@
#include "cellfunctors.hpp"
#include "cellstore.hpp"
#include <osg/Timer>
namespace
{
#if 0
void addObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics,
void addObject(const MWWorld::Ptr& ptr, //MWWorld::PhysicsSystem& physics,
MWRender::RenderingManager& rendering)
{
std::string model = Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getModel(ptr));
std::string model = Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getModel(ptr), rendering.getResourceSystem()->getVFS());
std::string id = ptr.getClass().getId(ptr);
if (id == "prisonmarker" || id == "divinemarker" || id == "templemarker" || id == "northmarker")
model = ""; // marker objects that have a hardcoded function in the game logic, should be hidden from the player
rendering.addObject(ptr, model);
ptr.getClass().insertObject (ptr, model, physics);
ptr.getClass().insertObjectRendering(ptr, model, rendering);
//ptr.getClass().insertObject (ptr, model, physics);
}
void updateObjectLocalRotation (const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics,
@ -40,22 +45,21 @@ namespace
{
if (ptr.getRefData().getBaseNode() != NULL)
{
Ogre::Quaternion worldRotQuat(Ogre::Radian(ptr.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z);
osg::Quat worldRotQuat(ptr.getRefData().getPosition().rot[2], osg::Vec3(0,0,-1));
if (!ptr.getClass().isActor())
worldRotQuat = Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X)*
Ogre::Quaternion(Ogre::Radian(ptr.getRefData().getPosition().rot[1]), Ogre::Vector3::NEGATIVE_UNIT_Y)* worldRotQuat;
worldRotQuat = worldRotQuat * osg::Quat(ptr.getRefData().getPosition().rot[1], osg::Vec3(0,-1,0)) *
osg::Quat(ptr.getRefData().getPosition().rot[0], osg::Vec3(-1,0,0));
float x = ptr.getRefData().getLocalRotation().rot[0];
float y = ptr.getRefData().getLocalRotation().rot[1];
float z = ptr.getRefData().getLocalRotation().rot[2];
Ogre::Quaternion rot(Ogre::Radian(z), Ogre::Vector3::NEGATIVE_UNIT_Z);
osg::Quat rot(z, osg::Vec3(0,0,-1));
if (!ptr.getClass().isActor())
rot = Ogre::Quaternion(Ogre::Radian(x), Ogre::Vector3::NEGATIVE_UNIT_X)*
Ogre::Quaternion(Ogre::Radian(y), Ogre::Vector3::NEGATIVE_UNIT_Y)*rot;
rot = rot * osg::Quat(y, osg::Vec3(0,-1,0)) * osg::Quat(x, osg::Vec3(-1,0,0));
ptr.getRefData().getBaseNode()->setOrientation(worldRotQuat*rot);
physics.rotateObject(ptr);
ptr.getRefData().getBaseNode()->setAttitude(rot * worldRotQuat);
//physics.rotateObject(ptr);
}
}
@ -64,20 +68,21 @@ namespace
MWWorld::CellStore& mCell;
bool mRescale;
Loading::Listener& mLoadingListener;
MWWorld::PhysicsSystem& mPhysics;
//MWWorld::PhysicsSystem& mPhysics;
MWRender::RenderingManager& mRendering;
InsertFunctor (MWWorld::CellStore& cell, bool rescale, Loading::Listener& loadingListener,
MWWorld::PhysicsSystem& physics, MWRender::RenderingManager& rendering);
/*MWWorld::PhysicsSystem& physics, */MWRender::RenderingManager& rendering);
bool operator() (const MWWorld::Ptr& ptr);
};
InsertFunctor::InsertFunctor (MWWorld::CellStore& cell, bool rescale,
Loading::Listener& loadingListener, MWWorld::PhysicsSystem& physics,
Loading::Listener& loadingListener, /*MWWorld::PhysicsSystem& physics,*/
MWRender::RenderingManager& rendering)
: mCell (cell), mRescale (rescale), mLoadingListener (loadingListener),
mPhysics (physics), mRendering (rendering)
//mPhysics (physics),
mRendering (rendering)
{}
bool InsertFunctor::operator() (const MWWorld::Ptr& ptr)
@ -94,13 +99,13 @@ namespace
{
try
{
addObject(ptr, mPhysics, mRendering);
updateObjectLocalRotation(ptr, mPhysics, mRendering);
addObject(ptr, /*mPhysics, */mRendering);
//updateObjectLocalRotation(ptr, mPhysics, mRendering);
if (ptr.getRefData().getBaseNode())
{
float scale = ptr.getCellRef().getScale();
ptr.getClass().adjustScale(ptr, scale);
mRendering.scaleObject(ptr, Ogre::Vector3(scale));
//mRendering.scaleObject(ptr, Ogre::Vector3(scale));
}
ptr.getClass().adjustPosition (ptr, false);
}
@ -115,7 +120,6 @@ namespace
return true;
}
#endif
}
@ -129,7 +133,7 @@ namespace MWWorld
void Scene::updateObjectRotation (const Ptr& ptr)
{
if(ptr.getRefData().getBaseNode() != 0)
if(ptr.getRefData().getBaseNodeOld() != 0)
{
//mRendering.rotateObject(ptr);
//mPhysics->rotateObject(ptr);
@ -190,23 +194,24 @@ namespace MWWorld
for (std::vector<Ogre::SceneNode*>::const_iterator iter2 (functor.mHandles.begin());
iter2!=functor.mHandles.end(); ++iter2)
{
Ogre::SceneNode* node = *iter2;
//Ogre::SceneNode* node = *iter2;
//mPhysics->removeObject (node->getName());
}
}
if ((*iter)->getCell()->isExterior())
{
ESM::Land* land =
/*ESM::Land* land =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Land>().search(
(*iter)->getCell()->getGridX(),
(*iter)->getCell()->getGridY()
);
//if (land && land->mDataTypes&ESM::Land::DATA_VHGT)
//mPhysics->removeHeightField ((*iter)->getCell()->getGridX(), (*iter)->getCell()->getGridY());
if (land && land->mDataTypes&ESM::Land::DATA_VHGT)
mPhysics->removeHeightField ((*iter)->getCell()->getGridX(), (*iter)->getCell()->getGridY());
*/
}
//mRendering.removeCell(*iter);
mRendering.removeCell(*iter);
MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter);
@ -224,8 +229,8 @@ namespace MWWorld
{
std::cout << "loading cell " << cell->getCell()->getDescription() << std::endl;
float verts = ESM::Land::LAND_SIZE;
float worldsize = ESM::Land::REAL_SIZE;
//float verts = ESM::Land::LAND_SIZE;
//float worldsize = ESM::Land::REAL_SIZE;
#if 0
// Load terrain physics first...
@ -271,9 +276,9 @@ namespace MWWorld
}
else
mPhysics->disableWater();
mRendering.configureAmbient(*cell);
#endif
if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))
mRendering.configureAmbient(cell->getCell());
}
// register local scripts
@ -290,7 +295,7 @@ namespace MWWorld
mCurrentCell = NULL;
}
void Scene::playerMoved(const Ogre::Vector3 &pos)
void Scene::playerMoved(const osg::Vec3f &pos)
{
if (!mCurrentCell || !mCurrentCell->isExterior())
return;
@ -301,12 +306,14 @@ namespace MWWorld
float centerX, centerY;
MWBase::Environment::get().getWorld()->indexToPosition(cellX, cellY, centerX, centerY, true);
const float maxDistance = 8192/2 + 1024; // 1/2 cell size + threshold
float distance = std::max(std::abs(centerX-pos.x), std::abs(centerY-pos.y));
float distance = std::max(std::abs(centerX-pos.x()), std::abs(centerY-pos.y()));
if (distance > maxDistance)
{
int newX, newY;
MWBase::Environment::get().getWorld()->positionToIndex(pos.x, pos.y, newX, newY);
MWBase::Environment::get().getWorld()->positionToIndex(pos.x(), pos.y(), newX, newY);
osg::Timer timer;
changeCellGrid(newX, newY);
std::cout << "changeCellGrid took " << timer.time_m() << std::endl;
//mRendering.updateTerrain();
}
}
@ -435,7 +442,7 @@ namespace MWWorld
//We need the ogre renderer and a scene node.
Scene::Scene (MWRender::RenderingManager& rendering, PhysicsSystem *physics)
: mCurrentCell (0), mCellChanged (false), /*mPhysics(physics), mRendering(rendering),*/ mNeedMapUpdate(false)
: mCurrentCell (0), mCellChanged (false), /*mPhysics(physics),*/ mRendering(rendering), mNeedMapUpdate(false)
{
}
@ -545,15 +552,15 @@ namespace MWWorld
void Scene::insertCell (CellStore &cell, bool rescale, Loading::Listener* loadingListener)
{
//InsertFunctor functor (cell, rescale, *loadingListener, *mPhysics, mRendering);
//cell.forEach (functor);
InsertFunctor functor (cell, rescale, *loadingListener, /* *mPhysics, */mRendering);
cell.forEach (functor);
}
void Scene::addObjectToScene (const Ptr& ptr)
{
try
{
//addObject(ptr, *mPhysics, mRendering);
addObject(ptr, /* *mPhysics, */mRendering);
//MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
//MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale());
}

@ -8,6 +8,11 @@
#include <set>
namespace osg
{
class Vec3f;
}
namespace Ogre
{
class Vector3;
@ -59,7 +64,7 @@ namespace MWWorld
CellStoreCollection mActiveCells;
bool mCellChanged;
//PhysicsSystem *mPhysics;
//MWRender::RenderingManager& mRendering;
MWRender::RenderingManager& mRendering;
bool mNeedMapUpdate;
@ -80,7 +85,7 @@ namespace MWWorld
void loadCell (CellStore *cell, Loading::Listener* loadingListener);
void playerMoved (const Ogre::Vector3& pos);
void playerMoved (const osg::Vec3f& pos);
void changePlayerCell (CellStore* newCell, const ESM::Position& position, bool adjustPlayerPos);

@ -11,6 +11,8 @@
#include "../mwscript/globalscripts.hpp"
#include <OgreSceneNode.h>
#include <osg/Group>
#include <libs/openengine/bullet/trace.h>
#include <libs/openengine/bullet/physic.hpp>
@ -37,6 +39,7 @@
#include "../mwmechanics/aiavoiddoor.hpp" //Used to tell actors to avoid doors
//#include "../mwrender/animation.hpp"
#include "../mwrender/renderingmanager.hpp"
#include "../mwscript/interpretercontext.hpp"
@ -143,9 +146,11 @@ namespace MWWorld
}
World::World (
osgViewer::Viewer& viewer,
osg::ref_ptr<osg::Group> rootNode,
Resource::ResourceSystem* resourceSystem,
const Files::Collections& fileCollections,
const std::vector<std::string>& contentFiles,
const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap,
int activationDistanceOverride, const std::string& startCell, const std::string& startupScript)
: mPlayer (0), mLocalScripts (mStore),
@ -162,7 +167,7 @@ namespace MWWorld
#if 0
mProjectileManager.reset(new ProjectileManager(renderer.getScene(), *mPhysEngine));
#endif
//mRendering = new MWRender::RenderingManager(renderer, resDir, cacheDir, mPhysEngine,&mFallback);
mRendering = new MWRender::RenderingManager(viewer, rootNode, resourceSystem);
//mPhysEngine->setSceneManager(renderer.getScene());
@ -476,7 +481,7 @@ namespace MWWorld
#endif
//delete mWeatherManager;
delete mWorldScene;
//delete mRendering;
delete mRendering;
//delete mPhysics;
delete mPlayer;
@ -1184,7 +1189,7 @@ namespace MWWorld
MWWorld::Ptr newPtr = ptr.getClass()
.copyToCell(ptr, *newCell);
newPtr.getRefData().setBaseNode(0);
newPtr.getRefData().setBaseNodeOld(0);
}
else if (!currCellActive && !newCellActive)
ptr.getClass().copyToCell(ptr, *newCell);
@ -1194,7 +1199,7 @@ namespace MWWorld
ptr.getClass().copyToCell(ptr, *newCell, pos);
//mRendering->updateObjectCell(ptr, copy);
ptr.getRefData().setBaseNode(NULL);
ptr.getRefData().setBaseNodeOld(NULL);
MWBase::Environment::get().getSoundManager()->updatePtr (ptr, copy);
MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager();
@ -1213,14 +1218,14 @@ namespace MWWorld
ptr.getRefData().setCount(0);
}
}
if (haveToMove && ptr.getRefData().getBaseNode())
if (haveToMove && ptr.getRefData().getBaseNodeOld())
{
//mRendering->moveObject(ptr, vec);
//mPhysics->moveObject (ptr);
}
if (isPlayer)
{
mWorldScene->playerMoved (vec);
//mWorldScene->playerMoved (vec);
}
}
@ -1252,7 +1257,7 @@ namespace MWWorld
ptr.getCellRef().setScale(scale);
ptr.getClass().adjustScale(ptr,scale);
if(ptr.getRefData().getBaseNode() == 0)
if(ptr.getRefData().getBaseNodeOld() == 0)
return;
//mRendering->scaleObject(ptr, Vector3(scale,scale,scale));
//mPhysics->scaleObject(ptr);
@ -1303,7 +1308,7 @@ namespace MWWorld
ptr.getRefData().setPosition(pos);
if(ptr.getRefData().getBaseNode() == 0)
if(ptr.getRefData().getBaseNodeOld() == 0)
return;
if (ptr.getClass().isActor())
@ -1325,7 +1330,7 @@ namespace MWWorld
ptr.getRefData().setLocalRotation(rot);
if (ptr.getRefData().getBaseNode() != 0)
if (ptr.getRefData().getBaseNodeOld() != 0)
{
mWorldScene->updateObjectLocalRotation(ptr);
}
@ -1335,7 +1340,7 @@ namespace MWWorld
{
ESM::Position pos (ptr.getRefData().getPosition());
if(!ptr.getRefData().getBaseNode())
if(!ptr.getRefData().getBaseNodeOld())
{
// will be adjusted when Ptr's cell becomes active
return;
@ -1352,9 +1357,9 @@ namespace MWWorld
if (force || !isFlying(ptr))
{
Ogre::Vector3 traced;// = mPhysics->traceDown(ptr, 500);
if (traced.z < pos.pos[2])
pos.pos[2] = traced.z;
//Ogre::Vector3 traced = mPhysics->traceDown(ptr, 500);
//if (traced.z < pos.pos[2])
// pos.pos[2] = traced.z;
}
moveObject(ptr, ptr.getCell(), pos.pos[0], pos.pos[1], pos.pos[2]);
@ -1599,13 +1604,14 @@ namespace MWWorld
void World::update (float duration, bool paused)
{
/*
if (mGoToJail && !paused)
goToJail();
updateWeather(duration, paused);
//if (!paused)
// doPhysics (duration);
if (!paused)
doPhysics (duration);
mWorldScene->update (duration, paused);
@ -1620,11 +1626,14 @@ namespace MWWorld
ESM::Position pos = mPlayer->getPlayer().getRefData().getPosition();
mPlayer->setLastKnownExteriorPosition(Ogre::Vector3(pos.pos));
}
*/
//mWorldScene->playerMoved(mRendering->getEyePos());
}
void World::updateSoundListener()
{
Ogre::Vector3 playerPos = mPlayer->getPlayer().getRefData().getBaseNode()->getPosition();
Ogre::Vector3 playerPos = mPlayer->getPlayer().getRefData().getBaseNodeOld()->getPosition();
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(getPlayerPtr().getRefData().getHandle());
if(actor) playerPos.z += 1.85f * actor->getHalfExtents().z;
Ogre::Quaternion playerOrient = Ogre::Quaternion(Ogre::Radian(getPlayerPtr().getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
@ -1644,7 +1653,7 @@ namespace MWWorld
// retrieve object dimensions so we know where to place the floating label
if (!object.isEmpty ())
{
Ogre::SceneNode* node = object.getRefData().getBaseNode();
Ogre::SceneNode* node = object.getRefData().getBaseNodeOld();
Ogre::AxisAlignedBox bounds = node->_getWorldAABB();
if (bounds.isFinite())
{
@ -2341,7 +2350,7 @@ namespace MWWorld
bool operator() (Ptr ptr)
{
Ogre::SceneNode* handle = ptr.getRefData().getBaseNode();
Ogre::SceneNode* handle = ptr.getRefData().getBaseNodeOld();
if (handle)
mHandles.push_back(handle->getName());
return true;
@ -2366,7 +2375,7 @@ namespace MWWorld
{
if (!targetActor.getRefData().isEnabled() || !actor.getRefData().isEnabled())
return false; // cannot get LOS unless both NPC's are enabled
if (!targetActor.getRefData().getBaseNode() || !targetActor.getRefData().getBaseNode())
if (!targetActor.getRefData().getBaseNodeOld() || !targetActor.getRefData().getBaseNodeOld())
return false; // not in active cell
OEngine::Physic::PhysicActor* actor1 = mPhysEngine->getCharacter(actor.getRefData().getHandle());

@ -5,6 +5,8 @@
#include <boost/shared_ptr.hpp>
#include <osg/ref_ptr>
#include "ptr.hpp"
#include "scene.hpp"
#include "esmstore.hpp"
@ -21,6 +23,21 @@
#include <components/settings/settings.hpp>
namespace osg
{
class Group;
}
namespace osgViewer
{
class Viewer;
}
namespace Resource
{
class ResourceSystem;
}
namespace Ogre
{
class Vector3;
@ -155,9 +172,11 @@ namespace MWWorld
public:
World (
osgViewer::Viewer& viewer,
osg::ref_ptr<osg::Group> rootNode,
Resource::ResourceSystem* resourceSystem,
const Files::Collections& fileCollections,
const std::vector<std::string>& contentFiles,
const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir,
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap,
int activationDistanceOverride, const std::string& startCell, const std::string& startupScript);

@ -74,6 +74,16 @@ namespace SceneUtil
if (lights.size())
{
static std::map<osg::Node*, osg::ref_ptr<osg::StateSet> > statesets;
std::map<osg::Node*, osg::ref_ptr<osg::StateSet> >::iterator found = statesets.find(node);
osg::ref_ptr<osg::StateSet> stateset;
if (found != statesets.end())
{
stateset = found->second;
}
else{
// we do the intersections in view space
osg::BoundingSphere nodeBound = node->getBound();
osg::Matrixf mat = *cv->getModelViewMatrix();
@ -89,26 +99,33 @@ namespace SceneUtil
if (lightList.empty())
{
statesets[node] = NULL;
traverse(node, nv);
return;
}
if (lightList.size() > 8)
unsigned int maxLights = static_cast<unsigned int> (8 - mLightManager->getStartLight());
if (lightList.size() > maxLights)
{
//std::cerr << "More than 8 lights!" << std::endl;
// TODO: sort lights by certain criteria
while (lightList.size() > 8)
while (lightList.size() > maxLights)
lightList.pop_back();
}
osg::ref_ptr<osg::StateSet> stateset = mLightManager->getLightListStateSet(lightList);
stateset = mLightManager->getLightListStateSet(lightList);
statesets[node] = stateset;
}
if (stateset)
cv->pushStateSet(stateset);
traverse(node, nv);
if (stateset)
cv->popStateSet();
}
else
@ -174,7 +191,7 @@ namespace SceneUtil
throw std::runtime_error("can't find parent LightManager");
}
mLightManager->addLight(static_cast<LightSource*>(node), osg::computeLocalToWorld(nv->getNodePath()));
//mLightManager->addLight(static_cast<LightSource*>(node), osg::computeLocalToWorld(nv->getNodePath()));
traverse(node, nv);
}
@ -208,6 +225,7 @@ namespace SceneUtil
LightManager::LightManager()
: mLightsInViewSpace(false)
, mDecorated(false)
, mStartLight(0)
{
setUpdateCallback(new LightManagerUpdateCallback);
}
@ -216,6 +234,7 @@ namespace SceneUtil
: osg::Group(copy, copyop)
, mLightsInViewSpace(false)
, mDecorated(copy.mDecorated)
, mStartLight(copy.mStartLight)
{
}
@ -284,11 +303,14 @@ namespace SceneUtil
osg::ref_ptr<LightStateAttribute> clonedLight = new LightStateAttribute(*light, osg::CopyOp::DEEP_COPY_ALL);
clonedLight->setPosition(mLights[lightIndex].mWorldMatrix.preMult(light->getPosition()));
clonedLight->setLightNum(i);
clonedLight->setLightNum(i+mStartLight);
// don't use setAttributeAndModes, that does not support light indices!
stateset->setAttribute(clonedLight, osg::StateAttribute::ON);
stateset->setAssociatedModes(clonedLight, osg::StateAttribute::ON);
//stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
}
mStateSetCache.insert(std::make_pair(hash, stateset));
return stateset;
@ -300,6 +322,16 @@ namespace SceneUtil
return mLights;
}
void LightManager::setStartLight(int start)
{
mStartLight = start;
}
int LightManager::getStartLight() const
{
return mStartLight;
}
LightSource::LightSource()
: mRadius(0.f)
{

@ -87,6 +87,11 @@ namespace SceneUtil
osg::ref_ptr<osg::StateSet> getLightListStateSet(const LightList& lightList);
/// Set the first light index that should be used by this manager, typically the number of directional lights in the scene.
void setStartLight(int start);
int getStartLight() const;
private:
// Lights collected from the scene graph. Only valid during the cull traversal.
std::vector<LightSourceTransform> mLights;
@ -98,6 +103,8 @@ namespace SceneUtil
LightStateSetMap mStateSetCache;
bool mDecorated;
int mStartLight;
};
}

@ -129,15 +129,6 @@ local map hud widget size = 256
exterior grid size = 3
[Viewing distance]
# Limit the rendering distance of small objects
limit small object distance = false
# Size below which an object is considered as small
small object size = 250
# Rendering distance for small objects
small object distance = 3500
# Viewing distance at normal weather conditions
# The maximum distance with no pop-in will be: (see RenderingManager::configureFog)
# viewing distance / minimum weather fog depth (.69) * view frustum factor <= cell size (8192) - loading threshold (1024)

Loading…
Cancel
Save