mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
OpenMW: create a window and render the starting cell(s)
This commit is contained in:
parent
a0b43f426e
commit
c92592493e
36 changed files with 665 additions and 3202 deletions
|
@ -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 addExtraLight(Ogre::SceneManager *sceneMgr, NifOgre::ObjectScenePtr objlist, const ESM::Light *light);
|
||||
|
||||
void clearAnimSources();
|
||||
|
||||
// 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;
|
||||
//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);
|
||||
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"
|
||||
|
||||
using namespace MWRender;
|
||||
|
||||
int Objects::uniqueID = 0;
|
||||
|
||||
void Objects::setRootNode(Ogre::SceneNode* root)
|
||||
namespace
|
||||
{
|
||||
mRootNode = root;
|
||||
|
||||
/// 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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<osg::ref_ptr<osg::Node> > mToRemove;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
Objects::Objects(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> rootNode)
|
||||
: mResourceSystem(resourceSystem)
|
||||
, mRootNode(rootNode)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> insert (new osg::PositionAttitudeTransform);
|
||||
cellnode->addChild(insert);
|
||||
|
||||
Ogre::SceneNode* insert = cellnode->createChildSceneNode();
|
||||
const float *f = ptr.getRefData().getPosition().pos;
|
||||
|
||||
insert->setPosition(f[0], f[1], f[2]);
|
||||
insert->setScale(ptr.getCellRef().getScale(), ptr.getCellRef().getScale(), ptr.getCellRef().getScale());
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
osg::Vec3f lightOffset (0.f, 0.f, 0.f);
|
||||
|
||||
if (mBounds.find(ptr.getCell()) == mBounds.end())
|
||||
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
|
||||
mBounds[ptr.getCell()].merge(bounds);
|
||||
osg::Group* attachTo = NULL;
|
||||
if (visitor.mFoundNode)
|
||||
{
|
||||
attachTo = visitor.mFoundNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::ComputeBoundsVisitor computeBound;
|
||||
osg::Group* objectRoot = anim->getOrCreateObjectRoot();
|
||||
objectRoot->accept(computeBound);
|
||||
|
||||
lightOffset = computeBound.getBoundingBox().center();
|
||||
|
||||
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()));
|
||||
*/
|
||||
}
|
||||
|
||||
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;
|
||||
typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap;
|
||||
|
||||
OEngine::Render::OgreRenderer &mRenderer;
|
||||
|
||||
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();
|
||||
|
||||
ObjectAnimation* getAnimation(const MWWorld::Ptr &ptr);
|
||||
/// @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);
|
||||
|
||||
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,269 +1,60 @@
|
|||
#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
|
||||
class RenderingManager : public MWRender::RenderingInterface
|
||||
{
|
||||
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();
|
||||
RenderingManager(osgViewer::Viewer& viewer, osg::ref_ptr<osg::Group> rootNode, Resource::ResourceSystem* resourceSystem);
|
||||
|
||||
void togglePOV()
|
||||
{ mCamera->toggleViewMode(); }
|
||||
MWRender::Objects& getObjects();
|
||||
MWRender::Actors& getActors();
|
||||
|
||||
void togglePreviewMode(bool enable)
|
||||
{ mCamera->togglePreviewMode(enable); }
|
||||
Resource::ResourceSystem* getResourceSystem();
|
||||
|
||||
bool toggleVanityMode(bool enable)
|
||||
{ return mCamera->toggleVanityMode(enable); }
|
||||
void configureAmbient(const ESM::Cell* cell);
|
||||
|
||||
void allowVanityMode(bool allow)
|
||||
{ mCamera->allowVanityMode(allow); }
|
||||
void removeCell(const MWWorld::CellStore* store);
|
||||
|
||||
void togglePlayerLooking(bool enable)
|
||||
{ mCamera->togglePlayerLooking(enable); }
|
||||
|
||||
void changeVanityModeScale(float factor)
|
||||
{
|
||||
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);
|
||||
osg::Vec3f getEyePos();
|
||||
|
||||
private:
|
||||
sh::Factory* mFactory;
|
||||
osgViewer::Viewer& mViewer;
|
||||
osg::ref_ptr<osg::Group> mRootNode;
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
|
||||
void setAmbientMode();
|
||||
void applyFog(bool underwater);
|
||||
osg::ref_ptr<osg::Light> mSunLight;
|
||||
|
||||
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;
|
||||
|
||||
MWRender::NpcAnimation *mPlayerAnimation;
|
||||
|
||||
Ogre::ColourValue mAmbientColor;
|
||||
Ogre::Light* mSun;
|
||||
|
||||
Ogre::SceneNode *mRootNode;
|
||||
|
||||
Ogre::ColourValue mFogColour;
|
||||
float mFogStart;
|
||||
float mFogEnd;
|
||||
|
||||
OEngine::Physic::PhysicEngine* mPhysicsEngine;
|
||||
|
||||
MWRender::Camera *mCamera;
|
||||
|
||||
MWRender::LocalMap* mLocalMap;
|
||||
|
||||
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…
Reference in a new issue