Merge branch 'master' into minimap

Conflicts:
	apps/openmw/mwscript/docs/vmformat.txt
actorid
scrawl 13 years ago
commit e0631dd9be

@ -28,6 +28,7 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries
# Sound source selection
option(USE_FFMPEG "use ffmpeg for sound" OFF)
option(USE_AUDIERE "use audiere for sound" OFF)
option(USE_MPG123 "use mpg123 + libsndfile for sound" ON)
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
@ -133,6 +134,13 @@ if (USE_FFMPEG)
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_FFMPEG)
endif (USE_FFMPEG)
if (USE_AUDIERE)
find_package(Audiere REQUIRED)
set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${AUDIERE_INCLUDE_DIR})
set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${AUDIERE_LIBRARY})
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_AUDIERE)
endif (USE_AUDIERE)
if (USE_MPG123)
find_package(MPG123 REQUIRED)
find_package(SNDFILE REQUIRED)
@ -241,8 +249,14 @@ if (APPLE)
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY)
# prepare plugins
if (${CMAKE_BUILD_TYPE} MATCHES "Release" OR
${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo")
if (${CMAKE_BUILD_TYPE} MATCHES "Release")
set(OPENMW_RELEASE_BUILD 1)
endif()
if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo")
set(OPENMW_RELEASE_BUILD 1)
endif()
if (${OPENMW_RELEASE_BUILD})
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
else()
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})

@ -39,7 +39,7 @@ add_openmw_dir (mwscript
)
add_openmw_dir (mwsound
soundmanager openal_output mpgsnd_decoder ffmpeg_decoder
soundmanager openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder
)
add_openmw_dir (mwworld

@ -82,12 +82,20 @@ void OMW::Engine::updateFocusReport (float duration)
if (!handle.empty())
{
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
// the faced handle is not updated immediately, so on a cell change it might
// point to an object that doesn't exist anymore
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
try
{
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
if (!ptr.isEmpty()){
name = MWWorld::Class::get (ptr).getName (ptr);
if (!ptr.isEmpty()){
name = MWWorld::Class::get (ptr).getName (ptr);
}
}
catch (std::runtime_error& e)
{}
}
if (name!=mFocusName)
@ -420,10 +428,21 @@ void OMW::Engine::activate()
if (handle.empty())
return;
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
// the faced handle is not updated immediately, so on a cell change it might
// point to an object that doesn't exist anymore
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
MWWorld::Ptr ptr;
try
{
ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
if (ptr.isEmpty())
if (ptr.isEmpty())
return;
}
catch (std::runtime_error&)
{
return;
}
MWScript::InterpreterContext interpreterContext (mEnvironment,
&ptr.getRefData().getLocals(), ptr);

@ -2,33 +2,283 @@
#include <assert.h>
#include "OgreRoot.h"
#include "OgreRenderWindow.h"
#include "OgreSceneManager.h"
#include "OgreViewport.h"
#include "OgreCamera.h"
#include "OgreTextureManager.h"
#include <OgreNode.h>
#include <OgreSceneManager.h>
#include <OgreMaterial.h>
#include <OgreMaterialManager.h>
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
#include "../mwworld/environment.hpp"
#include "../mwworld/ptr.hpp"
#include <components/esm/loadstat.hpp>
#include <components/esm/loadpgrd.hpp>
#include "player.hpp"
using namespace MWRender;
using namespace Ogre;
Debugging::Debugging(OEngine::Physic::PhysicEngine* engine){
eng = engine;
namespace MWRender
{
static const std::string PATHGRID_POINT_MATERIAL = "pathgridPointMaterial";
static const std::string PATHGRID_LINE_MATERIAL = "pathgridLineMaterial";
static const std::string DEBUGGING_GROUP = "debugging";
static const int POINT_MESH_BASE = 35;
void Debugging::createGridMaterials()
{
if (mGridMatsCreated) return;
if (MaterialManager::getSingleton().getByName(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP).isNull())
{
MaterialPtr lineMatPtr = MaterialManager::getSingleton().create(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP);
lineMatPtr->setReceiveShadows(false);
lineMatPtr->getTechnique(0)->setLightingEnabled(true);
lineMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,1,0,0);
lineMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,1,0);
lineMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,1,0);
}
if (MaterialManager::getSingleton().getByName(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP).isNull())
{
MaterialPtr pointMatPtr = MaterialManager::getSingleton().create(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP);
pointMatPtr->setReceiveShadows(false);
pointMatPtr->getTechnique(0)->setLightingEnabled(true);
pointMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,0,0,0);
pointMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,0,0);
pointMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,0,0);
}
mGridMatsCreated = true;
}
void Debugging::destroyGridMaterials()
{
if (mGridMatsCreated)
{
MaterialManager::getSingleton().remove(PATHGRID_POINT_MATERIAL);
MaterialManager::getSingleton().remove(PATHGRID_LINE_MATERIAL);
mGridMatsCreated = false;
}
}
ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid)
{
ManualObject *result = mSceneMgr->createManualObject();
result->begin(PATHGRID_LINE_MATERIAL, RenderOperation::OT_LINE_LIST);
for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->edges.begin();
it != pathgrid->edges.end();
it++)
{
const ESM::Pathgrid::Edge &edge = *it;
const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1];
Vector3 direction = (Vector3(p2.x, p2.y, p2.z) - Vector3(p1.x, p1.y, p1.z));
Vector3 lineDisplacement = direction.crossProduct(Vector3::UNIT_Z).normalisedCopy();
lineDisplacement = lineDisplacement * POINT_MESH_BASE +
Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape
result->position(Vector3(p1.x, p1.y, p1.z) + lineDisplacement);
result->position(Vector3(p2.x, p2.y, p2.z) + lineDisplacement);
}
result->end();
return result;
}
ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid)
{
ManualObject *result = mSceneMgr->createManualObject();
const float height = POINT_MESH_BASE * sqrtf(2);
result->begin(PATHGRID_POINT_MATERIAL, RenderOperation::OT_TRIANGLE_STRIP);
bool first = true;
uint32 startIndex = 0;
for(ESM::Pathgrid::PointList::const_iterator it = pathgrid->points.begin();
it != pathgrid->points.end();
it++, startIndex += 6)
{
Vector3 pointPos(it->x, it->y, it->z);
if (!first)
{
// degenerate triangle from previous octahedron
result->index(startIndex - 4); // 2nd point of previous octahedron
result->index(startIndex); // start point of current octahedron
}
result->position(pointPos + Vector3(0, 0, height)); // 0
result->position(pointPos + Vector3(-POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 1
result->position(pointPos + Vector3(POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 2
result->position(pointPos + Vector3(POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 3
result->position(pointPos + Vector3(-POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 4
result->position(pointPos + Vector3(0, 0, -height)); // 5
result->index(startIndex + 0);
result->index(startIndex + 1);
result->index(startIndex + 2);
result->index(startIndex + 5);
result->index(startIndex + 3);
result->index(startIndex + 4);
// degenerates
result->index(startIndex + 4);
result->index(startIndex + 5);
result->index(startIndex + 5);
// end degenerates
result->index(startIndex + 1);
result->index(startIndex + 4);
result->index(startIndex + 0);
result->index(startIndex + 3);
result->index(startIndex + 2);
first = false;
}
result->end();
return result;
}
Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) :
mMwRoot(mwRoot), mEnvironment(env), mEngine(engine),
mSceneMgr(mwRoot->getCreator()),
mPathgridEnabled(false),
mInteriorPathgridNode(NULL), mPathGridRoot(NULL),
mGridMatsCreated(false)
{
ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP);
}
Debugging::~Debugging()
{
if (mPathgridEnabled)
{
togglePathgrid();
}
ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP);
}
bool Debugging::toggleRenderMode (int mode){
switch (mode)
switch (mode)
{
case MWWorld::World::Render_CollisionDebug:
return eng->toggleDebugRendering();
return mEngine->toggleDebugRendering();
case MWWorld::World::Render_Pathgrid:
togglePathgrid();
return mPathgridEnabled;
}
return false;
}
void Debugging::cellAdded(MWWorld::Ptr::CellStore *store)
{
mActiveCells.push_back(store);
if (mPathgridEnabled)
enableCellPathgrid(store);
}
void Debugging::cellRemoved(MWWorld::Ptr::CellStore *store)
{
mActiveCells.erase(std::remove(mActiveCells.begin(), mActiveCells.end(), store), mActiveCells.end());
if (mPathgridEnabled)
disableCellPathgrid(store);
}
void Debugging::togglePathgrid()
{
mPathgridEnabled = !mPathgridEnabled;
if (mPathgridEnabled)
{
createGridMaterials();
// add path grid meshes to already loaded cells
mPathGridRoot = mMwRoot->createChildSceneNode();
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++)
{
enableCellPathgrid(*it);
}
}
else
{
// remove path grid meshes from already loaded cells
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++)
{
disableCellPathgrid(*it);
}
mPathGridRoot->removeAndDestroyAllChildren();
mSceneMgr->destroySceneNode(mPathGridRoot);
mPathGridRoot = NULL;
destroyGridMaterials();
}
}
void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store)
{
ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell);
if (!pathgrid) return;
Vector3 cellPathGridPos(0, 0, 0);
if (store->cell->isExterior())
{
cellPathGridPos.x = store->cell->data.gridX * ESM::Land::REAL_SIZE;
cellPathGridPos.y = store->cell->data.gridY * ESM::Land::REAL_SIZE;
}
SceneNode *cellPathGrid = mPathGridRoot->createChildSceneNode(cellPathGridPos);
cellPathGrid->attachObject(createPathgridLines(pathgrid));
cellPathGrid->attachObject(createPathgridPoints(pathgrid));
if (store->cell->isExterior())
{
mExteriorPathgridNodes[std::make_pair(store->cell->data.gridX, store->cell->data.gridY)] = cellPathGrid;
}
else
{
assert(mInteriorPathgridNode == NULL);
mInteriorPathgridNode = cellPathGrid;
}
}
void Debugging::disableCellPathgrid(MWWorld::Ptr::CellStore *store)
{
if (store->cell->isExterior())
{
ExteriorPathgridNodes::iterator it =
mExteriorPathgridNodes.find(std::make_pair(store->cell->data.gridX, store->cell->data.gridY));
if (it != mExteriorPathgridNodes.end())
{
destroyCellPathgridNode(it->second);
mExteriorPathgridNodes.erase(it);
}
}
else
{
if (mInteriorPathgridNode)
{
destroyCellPathgridNode(mInteriorPathgridNode);
mInteriorPathgridNode = NULL;
}
}
}
void Debugging::destroyCellPathgridNode(SceneNode *node)
{
mPathGridRoot->removeChild(node);
destroyAttachedObjects(node);
mSceneMgr->destroySceneNode(node);
}
void Debugging::destroyAttachedObjects(SceneNode *node)
{
SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator();
while (objIt.hasMoreElements())
{
MovableObject *mesh = static_cast<MovableObject *>(objIt.getNext());
mSceneMgr->destroyMovableObject(mesh);
}
}
}

@ -4,6 +4,7 @@
#include <utility>
#include <openengine/ogre/renderer.hpp>
#include <openengine/bullet/physic.hpp>
#include "../mwworld/ptr.hpp"
#include <vector>
#include <string>
@ -22,20 +23,58 @@ namespace Ogre
namespace MWWorld
{
class World;
class Environment;
}
namespace MWRender
{
class Player;
class Debugging{
OEngine::Physic::PhysicEngine* eng;
class Debugging
{
OEngine::Physic::PhysicEngine* mEngine;
Ogre::SceneManager *mSceneMgr;
MWWorld::Environment& mEnvironment;
// Path grid stuff
bool mPathgridEnabled;
public:
Debugging(OEngine::Physic::PhysicEngine* engine);
bool toggleRenderMode (int mode);
};
void togglePathgrid();
typedef std::vector<MWWorld::Ptr::CellStore *> CellList;
CellList mActiveCells;
Ogre::SceneNode *mMwRoot;
Ogre::SceneNode *mPathGridRoot;
typedef std::map<std::pair<int,int>, Ogre::SceneNode *> ExteriorPathgridNodes;
ExteriorPathgridNodes mExteriorPathgridNodes;
Ogre::SceneNode *mInteriorPathgridNode;
void enableCellPathgrid(MWWorld::Ptr::CellStore *store);
void disableCellPathgrid(MWWorld::Ptr::CellStore *store);
// utility
void destroyCellPathgridNode(Ogre::SceneNode *node);
void destroyAttachedObjects(Ogre::SceneNode *node);
// materials
bool mGridMatsCreated;
void createGridMaterials();
void destroyGridMaterials();
// path grid meshes
Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid);
Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid);
public:
Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine);
~Debugging();
bool toggleRenderMode (int mode);
void cellAdded(MWWorld::Ptr::CellStore* store);
void cellRemoved(MWWorld::Ptr::CellStore* store);
};
}

@ -5,13 +5,14 @@
#include <OgreBillboardSet.h>
#include <OgreHardwareOcclusionQuery.h>
#include <OgreEntity.h>
#include <OgreSubEntity.h>
using namespace MWRender;
using namespace Ogre;
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0),
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false),
mBBNode(0)
{
@ -84,7 +85,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
mRendering->getScene()->addRenderObjectListener(this);
mRendering->getScene()->addRenderQueueListener(this);
mDoQuery = true;
mDoQuery2 = true;
}
OcclusionQuery::~OcclusionQuery()
@ -100,7 +100,7 @@ bool OcclusionQuery::supported()
return mSupported;
}
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
const LightList* pLightList, bool suppressRenderStateChanges)
{
// The following code activates and deactivates the occlusion queries
@ -134,7 +134,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
mActiveQuery = mSingleObjectQuery;
mObjectWasVisible = true;
}
if (mActiveQuery != NULL)
mActiveQuery->beginOcclusionQuery();
}
@ -195,7 +195,6 @@ void OcclusionQuery::update(float duration)
// Stop occlusion queries until we get their information
// (may not happen on the same frame they are requested in)
mDoQuery = false;
mDoQuery2 = false;
if (!mSunTotalAreaQuery->isStillOutstanding()
&& !mSunVisibleAreaQuery->isStillOutstanding()
@ -264,3 +263,40 @@ bool OcclusionQuery::getTestResult()
return mTestResult;
}
bool OcclusionQuery::isPotentialOccluder(Ogre::SceneNode* node)
{
bool result = false;
for (unsigned int i=0; i < node->numAttachedObjects(); ++i)
{
MovableObject* ob = node->getAttachedObject(i);
std::string type = ob->getMovableType();
if (type == "Entity")
{
Entity* ent = static_cast<Entity*>(ob);
for (unsigned int j=0; j < ent->getNumSubEntities(); ++j)
{
// if any sub entity has a material with depth write off,
// consider the object as not an occluder
MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements())
{
Technique* tech = techIt.getNext();
Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
{
Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
return false;
else
result = true;
}
}
}
}
}
return result;
}

@ -46,6 +46,14 @@ namespace MWRender
*/
bool occlusionTestPending();
/**
* Checks if the objects held by this scenenode
* can be considered as potential occluders
* (which might not be the case when transparency is involved)
* @param Scene node
*/
bool isPotentialOccluder(Ogre::SceneNode* node);
/**
* @return true if the object tested in the last request was occluded
*/

@ -20,7 +20,7 @@ using namespace Ogre;
namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment)
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mDebugging(engine)
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0)
{
mRendering.createScene("PlayerCam", 55, 5);
mTerrainManager = new TerrainManager(mRendering.getScene(),
@ -52,7 +52,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode();
Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode();
cameraPitchNode->attachObject(mRendering.getCamera());
//mSkyManager = 0;
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera(), &environment);
@ -63,6 +63,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mSun = 0;
mDebugging = new Debugging(mMwRoot, environment, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, &environment);
}
@ -71,6 +72,7 @@ RenderingManager::~RenderingManager ()
//TODO: destroy mSun?
delete mPlayer;
delete mSkyManager;
delete mDebugging;
delete mTerrainManager;
delete mLocalMap;
delete mOcclusionQuery;
@ -101,6 +103,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
{
mObjects.removeCell(store);
mActors.removeCell(store);
mDebugging->cellRemoved(store);
if (store->cell->isExterior())
mTerrainManager->cellRemoved(store);
}
@ -122,6 +125,7 @@ void RenderingManager::toggleWater()
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
{
mObjects.buildStaticGeometry (*store);
mDebugging->cellAdded(store);
if (store->cell->isExterior())
mTerrainManager->cellAdded(store);
}
@ -188,7 +192,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
}
else
removeWater();
}
void RenderingManager::setWaterHeight(const float height)
@ -226,7 +230,7 @@ void RenderingManager::skySetDate (int day, int month)
int RenderingManager::skyGetMasserPhase() const
{
return mSkyManager->getMasserPhase();
}
@ -242,8 +246,8 @@ void RenderingManager::skySetMoonColour (bool red){
bool RenderingManager::toggleRenderMode(int mode)
{
if (mode == MWWorld::World::Render_CollisionDebug)
return mDebugging.toggleRenderMode(mode);
if (mode != MWWorld::World::Render_Wireframe)
return mDebugging->toggleRenderMode(mode);
else // if (mode == MWWorld::World::Render_Wireframe)
{
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
@ -268,10 +272,10 @@ void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
}
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
{
{
/// \todo make the viewing distance and fog start/end configurable
// right now we load 3x3 cells, so the maximum viewing distance we
// right now we load 3x3 cells, so the maximum viewing distance we
// can allow (to prevent objects suddenly popping up) equals:
// 8192 * 0.69
// ^ cell size ^ minimum density value used (clear weather)
@ -279,7 +283,7 @@ void RenderingManager::configureFog(const float density, const Ogre::ColourValue
float high = 5652.48 / density;
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
mRendering.getCamera()->setFarClipDistance ( high );
mRendering.getViewport()->setBackgroundColour (colour);
}
@ -382,10 +386,10 @@ void RenderingManager::sunDisable()
void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
{
// direction * -1 (because 'direction' is camera to sun vector and not sun to camera),
// direction * -1 (because 'direction' is camera to sun vector and not sun to camera),
// then convert from MW to ogre coordinates (swap y,z and make y negative)
if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.z, direction.y));
mSkyManager->setSunDirection(direction);
}

@ -174,7 +174,8 @@ class RenderingManager: private RenderingInterface {
OEngine::Physic::PhysicEngine* mPhysicsEngine;
MWRender::Player *mPlayer;
MWRender::Debugging mDebugging;
MWRender::Debugging *mDebugging;
MWRender::LocalMap* mLocalMap;
};

@ -128,4 +128,5 @@ op 0x2000142: SetWaterLevel
op 0x2000143: ModWaterLevel
op 0x2000144: ToggleWater, twa
op 0x2000145: ToggleFogOfWar (tfow)
opcodes 0x2000146-0x3ffffff unused
op 0x2000146: TogglePathgrid
opcodes 0x2000147-0x3ffffff unused

@ -106,7 +106,7 @@ namespace MWScript
"Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off");
}
};
class OpToggleWireframe : public Interpreter::Opcode0
{
public:
@ -123,7 +123,23 @@ namespace MWScript
"Wireframe Rendering -> On" : "Wireframe Rendering -> Off");
}
};
class OpTogglePathgrid : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
bool enabled =
context.getWorld().toggleRenderMode (MWWorld::World::Render_Pathgrid);
context.report (enabled ?
"Path Grid rendering -> On" : "Path Grid Rendering -> Off");
}
};
class OpFadeIn : public Interpreter::Opcode0
{
public:
@ -135,11 +151,11 @@ namespace MWScript
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
context.getWorld().getFader()->fadeIn(time);
}
};
class OpFadeOut : public Interpreter::Opcode0
{
public:
@ -151,11 +167,11 @@ namespace MWScript
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
context.getWorld().getFader()->fadeOut(time);
}
};
class OpFadeTo : public Interpreter::Opcode0
{
public:
@ -167,10 +183,10 @@ namespace MWScript
Interpreter::Type_Float alpha = runtime[0].mFloat;
runtime.pop();
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
context.getWorld().getFader()->fadeTo(alpha, time);
}
};
@ -201,6 +217,7 @@ namespace MWScript
const int opcodeFadeOut = 0x200013d;
const int opcodeFadeTo = 0x200013e;
const int opcodeToggleWater = 0x2000144;
const int opcodeTogglePathgrid = 0x2000146;
void registerExtensions (Compiler::Extensions& extensions)
{
@ -220,6 +237,8 @@ namespace MWScript
extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
extensions.registerInstruction ("togglewater", "", opcodeToggleWater);
extensions.registerInstruction ("twa", "", opcodeToggleWater);
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
@ -236,6 +255,7 @@ namespace MWScript
interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn);
interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut);
interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo);
interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid);
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
}
}

@ -0,0 +1,122 @@
#ifdef OPENMW_USE_AUDIERE
#include <stdexcept>
#include <iostream>
#include "audiere_decoder.hpp"
static void fail(const std::string &msg)
{ throw std::runtime_error("Audiere exception: "+msg); }
namespace MWSound
{
class OgreFile : public audiere::File
{
Ogre::DataStreamPtr mStream;
ADR_METHOD(int) read(void* buffer, int size)
{
return mStream->read(buffer, size);
}
ADR_METHOD(bool) seek(int position, SeekMode mode)
{
if(mode == CURRENT)
mStream->seek(mStream->tell()+position);
else if(mode == BEGIN)
mStream->seek(position);
else if(mode == END)
mStream->seek(mStream->size()+position);
else
return false;
return true;
}
ADR_METHOD(int) tell()
{
return mStream->tell();
}
size_t refs;
virtual void ref() { ++refs; }
virtual void unref()
{
if(--refs == 0)
delete this;
}
public:
OgreFile(const Ogre::DataStreamPtr &stream)
: mStream(stream), refs(1)
{ }
virtual ~OgreFile() { }
};
void Audiere_Decoder::open(const std::string &fname)
{
close();
audiere::FilePtr file(new OgreFile(mResourceMgr.openResource(fname)));
mSoundSource = audiere::OpenSampleSource(file);
int channels, srate;
audiere::SampleFormat format;
mSoundSource->getFormat(channels, srate, format);
if(format == audiere::SF_S16)
mSampleType = SampleType_Int16;
else if(format == audiere::SF_U8)
mSampleType = SampleType_UInt8;
else
fail("Unsupported sample type");
if(channels == 1)
mChannelConfig = ChannelConfig_Mono;
else if(channels == 2)
mChannelConfig = ChannelConfig_Stereo;
else
fail("Unsupported channel count");
mSampleRate = srate;
}
void Audiere_Decoder::close()
{
mSoundSource = NULL;
}
void Audiere_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
{
*samplerate = mSampleRate;
*chans = mChannelConfig;
*type = mSampleType;
}
size_t Audiere_Decoder::read(char *buffer, size_t bytes)
{
int size = bytesToFrames(bytes, mChannelConfig, mSampleType);
size = mSoundSource->read(size, buffer);
return framesToBytes(size, mChannelConfig, mSampleType);
}
void Audiere_Decoder::rewind()
{
mSoundSource->reset();
}
Audiere_Decoder::Audiere_Decoder()
{
}
Audiere_Decoder::~Audiere_Decoder()
{
close();
}
}
#endif

@ -0,0 +1,42 @@
#ifndef GAME_SOUND_AUDIERE_DECODER_H
#define GAME_SOUND_AUDIERE_DECODER_H
#include <OgreDataStream.h>
#include "audiere.h"
#include "sound_decoder.hpp"
namespace MWSound
{
class Audiere_Decoder : public Sound_Decoder
{
audiere::SampleSourcePtr mSoundSource;
int mSampleRate;
SampleType mSampleType;
ChannelConfig mChannelConfig;
virtual void open(const std::string &fname);
virtual void close();
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
virtual size_t read(char *buffer, size_t bytes);
virtual void rewind();
Audiere_Decoder& operator=(const Audiere_Decoder &rhs);
Audiere_Decoder(const Audiere_Decoder &rhs);
Audiere_Decoder();
public:
virtual ~Audiere_Decoder();
friend class SoundManager;
};
#ifndef DEFAULT_DECODER
#define DEFAULT_DECODER (::MWSound::Audiere_Decoder)
#endif
};
#endif

@ -18,8 +18,8 @@
#include "openal_output.hpp"
#define SOUND_OUT "OpenAL"
/* Set up the sound manager to use FFMPEG or MPG123+libsndfile for input. The
* OPENMW_USE_x macros are set in CMakeLists.txt.
/* Set up the sound manager to use FFMPEG, MPG123+libsndfile, or Audiere for
* input. The OPENMW_USE_x macros are set in CMakeLists.txt.
*/
#ifdef OPENMW_USE_FFMPEG
#include "ffmpeg_decoder.hpp"
@ -28,6 +28,13 @@
#endif
#endif
#ifdef OPENMW_USE_AUDIERE
#include "audiere_decoder.hpp"
#ifndef SOUND_IN
#define SOUND_IN "Audiere"
#endif
#endif
#ifdef OPENMW_USE_MPG123
#include "mpgsnd_decoder.hpp"
#ifndef SOUND_IN
@ -407,7 +414,7 @@ namespace MWSound
if(!isMusicPlaying())
startRandomTitle();
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
const ESM::Cell *cell = mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell;
Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera();
Ogre::Vector3 nPos, nDir, nUp;
nPos = cam->getRealPosition();
@ -415,7 +422,7 @@ namespace MWSound
nUp = cam->getRealUp();
Environment env = Env_Normal;
if(nPos.y < current->cell->water)
if((cell->data.flags&cell->HasWater) && nPos.y < cell->water)
env = Env_Underwater;
// The output handler is expecting vectors oriented like the game

@ -34,7 +34,7 @@ const float WeatherGlobals::mThunderFrequency = .4;
const float WeatherGlobals::mThunderThreshold = 0.6;
const float WeatherGlobals::mThunderSoundDelay = 0.25;
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) :
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::Environment* env) :
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
{

@ -543,7 +543,7 @@ namespace MWWorld
if (ptr==mPlayer->getPlayer())
{
//std::cout << "X:" << ptr.getRefData().getPosition().pos[0] << " Z: " << ptr.getRefData().getPosition().pos[1] << "\n";
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
if (currentCell)
{
@ -750,15 +750,16 @@ namespace MWWorld
// figure out which object we want to test against
std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects();
// ignore the player
for (std::vector < std::pair < float, std::string > >::iterator it = results.begin();
it != results.end(); ++it)
// ignore the player and other things we're not interested in
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
while (it != results.end())
{
if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle() )
if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() )
{
results.erase(it);
break;
it = results.erase(it);
}
else
++it;
}
if (results.size() == 0)
@ -774,6 +775,10 @@ namespace MWWorld
btVector3 p = mPhysics->getRayPoint(results.front().first);
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
//std::cout << "Num facing 1 : " << mFaced1Name << std::endl;
//std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl;
query->occlusionTest(pos, node);
}
else
@ -786,8 +791,33 @@ namespace MWWorld
btVector3 p = mPhysics->getRayPoint(results[1].first);
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
Ogre::SceneNode* node = mFaced2.getRefData().getBaseNode();
query->occlusionTest(pos, node);
Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode();
Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode();
// no need to test if the first node is not occluder
if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos))
{
mFacedHandle = mFaced1Name;
//std::cout << "node1 Not an occluder" << std::endl;
return;
}
// no need to test if the second object is static (thus cannot be activated)
if (mFaced2.getTypeName().find("Static") != std::string::npos)
{
mFacedHandle = mFaced1Name;
return;
}
// work around door problems
if (mFaced1.getTypeName().find("Static") != std::string::npos
&& mFaced2.getTypeName().find("Door") != std::string::npos)
{
mFacedHandle = mFaced2Name;
return;
}
query->occlusionTest(pos, node2);
}
}
}

@ -63,13 +63,14 @@ namespace MWWorld
enum RenderMode
{
Render_CollisionDebug,
Render_Wireframe
Render_Wireframe,
Render_Pathgrid
};
private:
MWRender::RenderingManager* mRendering;
MWWorld::WeatherManager* mWeatherManager;
MWWorld::Scene *mWorldScene;
@ -112,7 +113,7 @@ namespace MWWorld
Environment& environment, const std::string& encoding);
~World();
OEngine::Render::Fader* getFader();
Ptr::CellStore *getExterior (int x, int y);
@ -121,7 +122,7 @@ namespace MWWorld
void setWaterHeight(const float height);
void toggleWater();
void adjustSky();
MWWorld::Player& getPlayer();
@ -134,7 +135,7 @@ namespace MWWorld
bool hasCellChanged() const;
///< Has the player moved to a different cell, since the last frame?
bool isCellExterior() const;
bool isCellQuasiExterior() const;
@ -175,9 +176,9 @@ namespace MWWorld
bool toggleSky();
///< \return Resulting mode
void changeWeather(const std::string& region, const unsigned int id);
int getCurrentWeather() const;
int getMasserPhase() const;

@ -457,7 +457,7 @@ namespace ESMS
}
}
Pathgrid *find(int cellX, int cellY, std::string cellName) const
Pathgrid *find(int cellX, int cellY, const std::string &cellName) const
{
Pathgrid *result = search(cellX, cellY, cellName);
if (!result)
@ -467,7 +467,7 @@ namespace ESMS
return result;
}
Pathgrid *search(int cellX, int cellY, std::string cellName) const
Pathgrid *search(int cellX, int cellY, const std::string &cellName) const
{
Pathgrid *result = NULL;
if (cellX == 0 && cellY == 0) // possibly interior

Loading…
Cancel
Save