Merge branch 'master' of git://github.com/zinnschlag/openmw

This commit is contained in:
lazydev 2013-02-27 01:47:30 +04:00
commit f717fe0254
37 changed files with 300 additions and 202 deletions

View file

@ -382,7 +382,7 @@ namespace MWClass
const MWMechanics::MagicEffects &mageffects = npcdata->mCreatureStats.getMagicEffects(); const MWMechanics::MagicEffects &mageffects = npcdata->mCreatureStats.getMagicEffects();
const float encumbranceTerm = fJumpEncumbranceBase->getFloat() + const float encumbranceTerm = fJumpEncumbranceBase->getFloat() +
fJumpEncumbranceMultiplier->getFloat() * fJumpEncumbranceMultiplier->getFloat() *
(Npc::getEncumbrance(ptr)/Npc::getCapacity(ptr)); (1.0f - Npc::getEncumbrance(ptr)/Npc::getCapacity(ptr));
float a = npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified(); float a = npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified();
float b = 0.0f; float b = 0.0f;

View file

@ -88,7 +88,7 @@ void LocalMapBase::applyFogOfWar()
+ boost::lexical_cast<std::string>(my); + boost::lexical_cast<std::string>(my);
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_" std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1))); + boost::lexical_cast<std::string>(mCurY + (-1*(my-1)));
MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx]; MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
fog->setImageTexture(mFogOfWar ? fog->setImageTexture(mFogOfWar ?
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog" ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
@ -127,7 +127,7 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
{ {
// map // map
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_" std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1))); + boost::lexical_cast<std::string>(y + (-1*(my-1)));
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_" std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
+ boost::lexical_cast<std::string>(my); + boost::lexical_cast<std::string>(my);
@ -173,7 +173,7 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
} }
else else
{ {
Ogre::Vector2 position (marker.x, -marker.y); Ogre::Vector2 position (marker.x, marker.y);
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy); MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8); widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8);
@ -394,10 +394,10 @@ void MapWindow::globalMapUpdatePlayer ()
{ {
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition (); Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation (); Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
Ogre::Vector2 dir (orient.yAxis ().x, -orient.yAxis().z); Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
float worldX, worldY; float worldX, worldY;
mGlobalMapRender->worldPosToImageSpace (pos.x, pos.z, worldX, worldY); mGlobalMapRender->worldPosToImageSpace (pos.x, pos.y, worldX, worldY);
worldX *= mGlobalMapRender->getWidth(); worldX *= mGlobalMapRender->getWidth();
worldY *= mGlobalMapRender->getHeight(); worldY *= mGlobalMapRender->getHeight();

View file

@ -1,6 +1,8 @@
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
#include "messagebox.hpp" #include "messagebox.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
using namespace MWGui; using namespace MWGui;
@ -375,6 +377,7 @@ void InteractiveMessageBox::enterPressed()
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok) if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
{ {
buttonActivated(*button); buttonActivated(*button);
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
break; break;
} }
} }

View file

@ -61,7 +61,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair); nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu4", "Race")); setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu5", "Race"));
getWidget(mRaceList, "RaceList"); getWidget(mRaceList, "RaceList");
mRaceList->setScrollVisible(true); mRaceList->setScrollVisible(true);
mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);

View file

@ -87,10 +87,12 @@ namespace MWInput
std::string("false"))); std::string("false")));
pl.insert(std::make_pair(std::string("x11_keyboard_grab"), pl.insert(std::make_pair(std::string("x11_keyboard_grab"),
std::string("false"))); std::string("false")));
pl.insert(std::make_pair(std::string("XAutoRepeatOn"),
std::string("true")));
#endif #endif
} }
#if defined OIS_LINUX_PLATFORM
pl.insert(std::make_pair(std::string("XAutoRepeatOn"),
std::string("true")));
#endif
#if defined(__APPLE__) && !defined(__LP64__) #if defined(__APPLE__) && !defined(__LP64__)
// Give the application window focus to receive input events // Give the application window focus to receive input events
@ -177,6 +179,11 @@ namespace MWInput
case A_Activate: case A_Activate:
resetIdleTime(); resetIdleTime();
activate(); activate();
if( MWBase::Environment::get().getWindowManager()->isGuiMode()
&& MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) {
// Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button
MWBase::Environment::get().getWindowManager()->enterPressed();
}
break; break;
case A_Journal: case A_Journal:
toggleJournal (); toggleJournal ();

View file

@ -28,8 +28,8 @@ Actors::~Actors()
} }
} }
void Actors::setMwRoot(Ogre::SceneNode* root) void Actors::setRootNode(Ogre::SceneNode* root)
{ mMwRoot = root; } { mRootNode = root; }
void Actors::insertBegin(const MWWorld::Ptr &ptr) void Actors::insertBegin(const MWWorld::Ptr &ptr)
{ {
@ -40,7 +40,7 @@ void Actors::insertBegin(const MWWorld::Ptr &ptr)
else else
{ {
//Create the scenenode and put it in the map //Create the scenenode and put it in the map
cellnode = mMwRoot->createChildSceneNode(); cellnode = mRootNode->createChildSceneNode();
mCellSceneNodes[ptr.getCell()] = cellnode; mCellSceneNodes[ptr.getCell()] = cellnode;
} }
@ -159,7 +159,7 @@ void Actors::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
node = celliter->second; node = celliter->second;
else else
{ {
node = mMwRoot->createChildSceneNode(); node = mRootNode->createChildSceneNode();
mCellSceneNodes[newCell] = node; mCellSceneNodes[newCell] = node;
} }
node->addChild(cur.getRefData().getBaseNode()); node->addChild(cur.getRefData().getBaseNode());

View file

@ -20,7 +20,7 @@ namespace MWRender
typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap; typedef std::map<MWWorld::Ptr,Animation*> PtrAnimationMap;
OEngine::Render::OgreRenderer &mRend; OEngine::Render::OgreRenderer &mRend;
Ogre::SceneNode* mMwRoot; Ogre::SceneNode* mRootNode;
CellSceneNodeMap mCellSceneNodes; CellSceneNodeMap mCellSceneNodes;
PtrAnimationMap mAllActors; PtrAnimationMap mAllActors;
@ -29,7 +29,7 @@ namespace MWRender
Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {} Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {}
~Actors(); ~Actors();
void setMwRoot(Ogre::SceneNode* root); void setRootNode(Ogre::SceneNode* root);
void insertBegin (const MWWorld::Ptr& ptr); void insertBegin (const MWWorld::Ptr& ptr);
void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv); void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv);
void insertCreature (const MWWorld::Ptr& ptr); void insertCreature (const MWWorld::Ptr& ptr);

View file

@ -161,6 +161,7 @@ namespace MWRender
void RaceSelectionPreview::update(float angle) void RaceSelectionPreview::update(float angle)
{ {
mAnimation->runAnimation(0.0f);
mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL); mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL);
mNode->setVisible (true); mNode->setVisible (true);
@ -175,4 +176,9 @@ namespace MWRender
rebuild(); rebuild();
update(0); update(0);
} }
void RaceSelectionPreview::onSetup ()
{
mAnimation->play("idle", "start", "stop", false);
}
} }

View file

@ -85,6 +85,8 @@ namespace MWRender
public: public:
RaceSelectionPreview(); RaceSelectionPreview();
virtual void onSetup();
void update(float angle); void update(float angle);
const ESM::NPC &getPrototype() const { const ESM::NPC &getPrototype() const {

View file

@ -150,9 +150,9 @@ ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid)
return result; return result;
} }
Debugging::Debugging(SceneNode *mwRoot, OEngine::Physic::PhysicEngine *engine) : Debugging::Debugging(SceneNode *root, OEngine::Physic::PhysicEngine *engine) :
mMwRoot(mwRoot), mEngine(engine), mRootNode(root), mEngine(engine),
mSceneMgr(mwRoot->getCreator()), mSceneMgr(root->getCreator()),
mPathgridEnabled(false), mPathgridEnabled(false),
mInteriorPathgridNode(NULL), mPathGridRoot(NULL), mInteriorPathgridNode(NULL), mPathGridRoot(NULL),
mGridMatsCreated(false) mGridMatsCreated(false)
@ -208,7 +208,7 @@ void Debugging::togglePathgrid()
createGridMaterials(); createGridMaterials();
// add path grid meshes to already loaded cells // add path grid meshes to already loaded cells
mPathGridRoot = mMwRoot->createChildSceneNode(); mPathGridRoot = mRootNode->createChildSceneNode();
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it) for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); ++it)
{ {
enableCellPathgrid(*it); enableCellPathgrid(*it);

View file

@ -54,7 +54,7 @@ namespace MWRender
typedef std::vector<MWWorld::CellStore *> CellList; typedef std::vector<MWWorld::CellStore *> CellList;
CellList mActiveCells; CellList mActiveCells;
Ogre::SceneNode *mMwRoot; Ogre::SceneNode *mRootNode;
Ogre::SceneNode *mPathGridRoot; Ogre::SceneNode *mPathGridRoot;
@ -78,7 +78,7 @@ namespace MWRender
Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid); Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid);
Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid); Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid);
public: public:
Debugging(Ogre::SceneNode* mwRoot, OEngine::Physic::PhysicEngine *engine); Debugging(Ogre::SceneNode* root, OEngine::Physic::PhysicEngine *engine);
~Debugging(); ~Debugging();
bool toggleRenderMode (int mode); bool toggleRenderMode (int mode);

View file

@ -190,7 +190,7 @@ namespace MWRender
{ {
imageX = float(x / 8192.f - mMinX) / (mMaxX - mMinX + 1); imageX = float(x / 8192.f - mMinX) / (mMaxX - mMinX + 1);
imageY = 1.f-float(-z / 8192.f - mMinY) / (mMaxY - mMinY + 1); imageY = 1.f-float(z / 8192.f - mMinY) / (mMaxY - mMinY + 1);
} }
void GlobalMap::cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY) void GlobalMap::cellTopLeftCornerToImageSpace(int x, int y, float& imageX, float& imageY)

View file

@ -28,9 +28,6 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag
mCellCamera = mRendering->getScene()->createCamera("CellCamera"); mCellCamera = mRendering->getScene()->createCamera("CellCamera");
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
// look down -y
const float sqrt0pt5 = 0.707106781;
mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
mCameraNode->attachObject(mCellCamera); mCameraNode->attachObject(mCellCamera);
} }
@ -82,8 +79,8 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
} }
else else
{ {
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
Vector2 length = max-min; Vector2 length = max-min;
// divide into segments // divide into segments
@ -107,6 +104,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
mInterior = false; mInterior = false;
mCameraRotNode->setOrientation(Quaternion::IDENTITY); mCameraRotNode->setOrientation(Quaternion::IDENTITY);
mCellCamera->setOrientation(Quaternion(Ogre::Math::Cos(Ogre::Degree(0)/2.f), 0, 0, -Ogre::Math::Sin(Ogre::Degree(0)/2.f)));
int x = cell->mCell->getGridX(); int x = cell->mCell->getGridX();
int y = cell->mCell->getGridY(); int y = cell->mCell->getGridY();
@ -115,7 +113,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
mCameraPosNode->setPosition(Vector3(0,0,0)); mCameraPosNode->setPosition(Vector3(0,0,0));
render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name); render((x+0.5)*sSize, (y+0.5)*sSize, -10000, 10000, sSize, sSize, name);
} }
void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell, void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
@ -124,40 +122,44 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
mInterior = true; mInterior = true;
mBounds = bounds; mBounds = bounds;
Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y); float zMin = mBounds.getMinimum().z;
float zMax = mBounds.getMaximum().z;
const Vector2& north = MWBase::Environment::get().getWorld()->getNorthVector(cell); const Vector2& north = MWBase::Environment::get().getWorld()->getNorthVector(cell);
Radian angle(std::atan2(-north.x, -north.y)); Radian angle = Ogre::Math::ATan2 (north.x, north.y);
mAngle = angle.valueRadians(); mAngle = angle.valueRadians();
mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0));
mCellCamera->setOrientation(Quaternion::IDENTITY);
mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, 0, -Math::Sin(angle/2.f)));
// rotate the cell and merge the rotated corners to the bounding box // rotate the cell and merge the rotated corners to the bounding box
Vector2 _center(bounds.getCenter().x, bounds.getCenter().z); Vector2 _center(bounds.getCenter().x, bounds.getCenter().y);
Vector3 _c1 = bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM); Vector3 _c1 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM);
Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM); Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM);
Vector3 _c3 = bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM); Vector3 _c3 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_TOP);
Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM); Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_TOP);
Vector2 c1(_c1.x, _c1.z);
Vector2 c2(_c2.x, _c2.z); Vector2 c1(_c1.x, _c1.y);
Vector2 c3(_c3.x, _c3.z); Vector2 c2(_c2.x, _c2.y);
Vector2 c4(_c4.x, _c4.z); Vector2 c3(_c3.x, _c3.y);
Vector2 c4(_c4.x, _c4.y);
c1 = rotatePoint(c1, _center, mAngle); c1 = rotatePoint(c1, _center, mAngle);
c2 = rotatePoint(c2, _center, mAngle); c2 = rotatePoint(c2, _center, mAngle);
c3 = rotatePoint(c3, _center, mAngle); c3 = rotatePoint(c3, _center, mAngle);
c4 = rotatePoint(c4, _center, mAngle); c4 = rotatePoint(c4, _center, mAngle);
mBounds.merge(Vector3(c1.x, 0, c1.y)); mBounds.merge(Vector3(c1.x, c1.y, 0));
mBounds.merge(Vector3(c2.x, 0, c2.y)); mBounds.merge(Vector3(c2.x, c2.y, 0));
mBounds.merge(Vector3(c3.x, 0, c3.y)); mBounds.merge(Vector3(c3.x, c3.y, 0));
mBounds.merge(Vector3(c4.x, 0, c4.y)); mBounds.merge(Vector3(c4.x, c4.y, 0));
Vector2 center(mBounds.getCenter().x, mBounds.getCenter().z); Vector2 center(mBounds.getCenter().x, mBounds.getCenter().y);
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
Vector2 length = max-min; Vector2 length = max-min;
mCameraPosNode->setPosition(Vector3(center.x, 0, center.y)); mCameraPosNode->setPosition(Vector3(center.x, center.y, 0));
// divide into segments // divide into segments
const int segsX = std::ceil( length.x / sSize ); const int segsX = std::ceil( length.x / sSize );
@ -172,7 +174,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
Vector2 start = min + Vector2(sSize*x,sSize*y); Vector2 start = min + Vector2(sSize*x,sSize*y);
Vector2 newcenter = start + 4096; Vector2 newcenter = start + 4096;
render(newcenter.x - center.x, newcenter.y - center.y, z.y, z.x, sSize, sSize, render(newcenter.x - center.x, newcenter.y - center.y, zMin, zMax, sSize, sSize,
cell->mCell->mName + "_" + coordStr(x,y)); cell->mCell->mName + "_" + coordStr(x,y));
} }
} }
@ -193,7 +195,7 @@ void LocalMap::render(const float x, const float y,
mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
mRenderingManager->disableLights(); mRenderingManager->disableLights();
mCameraNode->setPosition(Vector3(x, zhigh+100000, y)); mCameraNode->setPosition(Vector3(x, y, zhigh+100000));
//mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
mCellCamera->setFarClipDistance(0); // infinite mCellCamera->setFarClipDistance(0); // infinite
@ -272,15 +274,15 @@ void LocalMap::render(const float x, const float y,
void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y)
{ {
pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle); pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().y), mAngle);
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
x = std::ceil((pos.x - min.x)/sSize)-1; x = std::ceil((pos.x - min.x)/sSize)-1;
y = std::ceil((pos.y - min.y)/sSize)-1; y = std::ceil((pos.y - min.y)/sSize)-1;
nX = (pos.x - min.x - sSize*x)/sSize; nX = (pos.x - min.x - sSize*x)/sSize;
nY = (pos.y - min.y - sSize*y)/sSize; nY = 1.0-(pos.y - min.y - sSize*y)/sSize;
} }
bool LocalMap::isPositionExplored (float nX, float nY, int x, int y, bool interior) bool LocalMap::isPositionExplored (float nX, float nY, int x, int y, bool interior)
@ -311,19 +313,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
int x,y; int x,y;
float u,v; float u,v;
Vector2 pos(position.x, position.z); Vector2 pos(position.x, position.y);
if (mInterior) if (mInterior)
getInteriorMapPosition(pos, u,v, x,y); getInteriorMapPosition(pos, u,v, x,y);
Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).yAxis();
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
if (!mInterior) if (!mInterior)
{ {
x = std::ceil(pos.x / sSize)-1; x = std::ceil(pos.x / sSize)-1;
y = std::ceil(-pos.y / sSize)-1; y = std::ceil(pos.y / sSize)-1;
mCellX = x; mCellX = x;
mCellY = y; mCellY = y;
} }
@ -337,7 +339,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
if (!mInterior) if (!mInterior)
{ {
u = std::abs((pos.x - (sSize*x))/sSize); u = std::abs((pos.x - (sSize*x))/sSize);
v = 1-std::abs((pos.y + (sSize*y))/sSize); v = 1.0-std::abs((pos.y - (sSize*y))/sSize);
texBaseName = "Cell_"; texBaseName = "Cell_";
} }
else else
@ -346,15 +348,13 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
} }
MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v); MWBase::Environment::get().getWindowManager()->setPlayerPos(u, v);
MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, -playerdirection.z); MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, playerdirection.y);
// explore radius (squared) // explore radius (squared)
const float sqrExploreRadius = (mInterior ? 0.01 : 0.09) * sFogOfWarResolution*sFogOfWarResolution; const float sqrExploreRadius = (mInterior ? 0.01 : 0.09) * sFogOfWarResolution*sFogOfWarResolution;
const float exploreRadius = (mInterior ? 0.1 : 0.3) * sFogOfWarResolution; // explore radius from 0 to sFogOfWarResolution const float exploreRadius = (mInterior ? 0.1 : 0.3) * sFogOfWarResolution; // explore radius from 0 to sFogOfWarResolution
const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space) const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space)
int intExtMult = mInterior ? 1 : -1; // interior and exterior have reversed Y coordinates (interior: top to bottom)
// change the affected fog of war textures (in a 3x3 grid around the player) // change the affected fog of war textures (in a 3x3 grid around the player)
for (int mx = -1; mx<2; ++mx) for (int mx = -1; mx<2; ++mx)
{ {
@ -375,7 +375,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
if (!affected) if (!affected)
continue; continue;
std::string texName = texBaseName + coordStr(x+mx,y+my*intExtMult); std::string texName = texBaseName + coordStr(x+mx,y+my*-1);
TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog");
if (!tex.isNull()) if (!tex.isNull())

View file

@ -57,14 +57,14 @@ void Objects::clearSceneNode (Ogre::SceneNode *node)
} }
} }
void Objects::setMwRoot(Ogre::SceneNode* root) void Objects::setRootNode(Ogre::SceneNode* root)
{ {
mMwRoot = root; mRootNode = root;
} }
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_) void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
{ {
Ogre::SceneNode* root = mMwRoot; Ogre::SceneNode* root = mRootNode;
Ogre::SceneNode* cellnode; Ogre::SceneNode* cellnode;
if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end()) if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
{ {
@ -390,9 +390,9 @@ void Objects::enableLights()
std::vector<LightInfo>::iterator it = mLights.begin(); std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end()) while (it != mLights.end())
{ {
if (mMwRoot->getCreator()->hasLight(it->name)) if (mRootNode->getCreator()->hasLight(it->name))
{ {
mMwRoot->getCreator()->getLight(it->name)->setVisible(true); mRootNode->getCreator()->getLight(it->name)->setVisible(true);
++it; ++it;
} }
else else
@ -405,9 +405,9 @@ void Objects::disableLights()
std::vector<LightInfo>::iterator it = mLights.begin(); std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end()) while (it != mLights.end())
{ {
if (mMwRoot->getCreator()->hasLight(it->name)) if (mRootNode->getCreator()->hasLight(it->name))
{ {
mMwRoot->getCreator()->getLight(it->name)->setVisible(false); mRootNode->getCreator()->getLight(it->name)->setVisible(false);
++it; ++it;
} }
else else
@ -460,9 +460,9 @@ void Objects::update(const float dt)
std::vector<LightInfo>::iterator it = mLights.begin(); std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end()) while (it != mLights.end())
{ {
if (mMwRoot->getCreator()->hasLight(it->name)) if (mRootNode->getCreator()->hasLight(it->name))
{ {
Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name); Ogre::Light* light = mRootNode->getCreator()->getLight(it->name);
float brightness; float brightness;
float cycle_time; float cycle_time;
@ -550,7 +550,7 @@ void Objects::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
MWWorld::CellStore *newCell = cur.getCell(); MWWorld::CellStore *newCell = cur.getCell();
if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) { if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
node = mMwRoot->createChildSceneNode(); node = mRootNode->createChildSceneNode();
mCellSceneNodes[newCell] = node; mCellSceneNodes[newCell] = node;
} else { } else {
node = mCellSceneNodes[newCell]; node = mCellSceneNodes[newCell];

View file

@ -53,7 +53,7 @@ class Objects{
std::map<MWWorld::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall; std::map<MWWorld::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
std::map<MWWorld::CellStore *, Ogre::AxisAlignedBox> mBounds; std::map<MWWorld::CellStore *, Ogre::AxisAlignedBox> mBounds;
std::vector<LightInfo> mLights; std::vector<LightInfo> mLights;
Ogre::SceneNode* mMwRoot; Ogre::SceneNode* mRootNode;
bool mIsStatic; bool mIsStatic;
static int uniqueID; static int uniqueID;
@ -90,7 +90,7 @@ public:
void removeCell(MWWorld::CellStore* store); void removeCell(MWWorld::CellStore* store);
void buildStaticGeometry(MWWorld::CellStore &cell); void buildStaticGeometry(MWWorld::CellStore &cell);
void setMwRoot(Ogre::SceneNode* root); void setRootNode(Ogre::SceneNode* root);
void rebuildStaticGeometry(); void rebuildStaticGeometry();

View file

@ -113,11 +113,6 @@ namespace MWRender
Ogre::Vector3 dir = mCamera->getRealDirection(); Ogre::Vector3 dir = mCamera->getRealDirection();
Ogre::Vector3 up = mCamera->getRealUp(); Ogre::Vector3 up = mCamera->getRealUp();
Ogre::Real xch;
xch = pos.y, pos.y = -pos.z, pos.z = xch;
xch = dir.y, dir.y = -dir.z, dir.z = xch;
xch = up.y, up.y = -up.z, up.z = xch;
MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up); MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir, up);
} }
@ -323,10 +318,8 @@ namespace MWRender
bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera) bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera)
{ {
float xch;
mCamera->getParentSceneNode ()->needUpdate(true); mCamera->getParentSceneNode ()->needUpdate(true);
camera = mCamera->getRealPosition(); camera = mCamera->getRealPosition();
xch = camera.z, camera.z = camera.y, camera.y = -xch;
player = mPlayerNode->getPosition(); player = mPlayerNode->getPosition();
return mFirstPersonView && !mVanity.enabled && !mPreviewMode; return mFirstPersonView && !mVanity.enabled && !mPreviewMode;

View file

@ -141,26 +141,20 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
applyCompositors(); applyCompositors();
// Turn the entire scene (represented by the 'root' node) -90
// degrees around the x axis. This makes Z go upwards, and Y go into
// the screen (when x is to the right.) This is the orientation that
// Morrowind uses, and it automagically makes everything work as it
// should.
SceneNode *rt = mRendering.getScene()->getRootSceneNode(); SceneNode *rt = mRendering.getScene()->getRootSceneNode();
mMwRoot = rt->createChildSceneNode("mwRoot"); mRootNode = rt;
mMwRoot->pitch(Degree(-90));
mObjects.setMwRoot(mMwRoot); mObjects.setRootNode(mRootNode);
mActors.setMwRoot(mMwRoot); mActors.setRootNode(mRootNode);
Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player"); Ogre::SceneNode *playerNode = mRootNode->createChildSceneNode ("player");
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mShadows = new Shadows(&mRendering); mShadows = new Shadows(&mRendering);
mTerrainManager = new TerrainManager(mRendering.getScene(), this); mTerrainManager = new TerrainManager(mRendering.getScene(), this);
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera()); mSkyManager = new SkyManager(mRootNode, mRendering.getCamera());
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
@ -169,7 +163,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mSun = 0; mSun = 0;
mDebugging = new Debugging(mMwRoot, engine); mDebugging = new Debugging(mRootNode, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this); mLocalMap = new MWRender::LocalMap(&mRendering, this);
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
@ -322,7 +316,7 @@ void RenderingManager::update (float duration, bool paused)
Ogre::Vector3 orig, dest; Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance(); mPlayer->setCameraDistance();
if (!mPlayer->getPosition(orig, dest)) { if (!mPlayer->getPosition(orig, dest)) {
orig.z += mPlayer->getHeight() * mMwRoot->getScale().z; orig.z += mPlayer->getHeight() * mRootNode->getScale().z;
btVector3 btOrig(orig.x, orig.y, orig.z); btVector3 btOrig(orig.x, orig.y, orig.z);
btVector3 btDest(dest.x, dest.y, dest.z); btVector3 btDest(dest.x, dest.y, dest.z);
@ -366,11 +360,13 @@ void RenderingManager::update (float duration, bool paused)
float *fpos = data.getPosition().pos; float *fpos = data.getPosition().pos;
// only for LocalMap::updatePlayer() // only for LocalMap::updatePlayer()
Ogre::Vector3 pos(fpos[0], -fpos[2], -fpos[1]); Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
Ogre::SceneNode *node = data.getBaseNode(); Ogre::SceneNode *node = data.getBaseNode();
//Ogre::Quaternion orient =
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
Ogre::Quaternion orient = Ogre::Quaternion orient =
node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); node->_getDerivedOrientation();
mLocalMap->updatePlayer(pos, orient); mLocalMap->updatePlayer(pos, orient);
@ -382,7 +378,7 @@ void RenderingManager::update (float duration, bool paused)
mWater->updateUnderwater( mWater->updateUnderwater(
world->isUnderwater( world->isUnderwater(
world->getPlayer().getPlayer().getCell(), world->getPlayer().getPlayer().getCell(),
Ogre::Vector3(cam.x, -cam.z, cam.y)) cam)
); );
mWater->update(duration); mWater->update(duration);
} }
@ -614,8 +610,7 @@ void RenderingManager::sunDisable()
void RenderingManager::setSunDirection(const Ogre::Vector3& direction) 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.y, -direction.z));
if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.z, direction.y));
mSkyManager->setSunDirection(direction); mSkyManager->setSunDirection(direction);
} }

View file

@ -228,10 +228,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
Ogre::ColourValue mAmbientColor; Ogre::ColourValue mAmbientColor;
Ogre::Light* mSun; Ogre::Light* mSun;
/// Root node for all objects added to the scene. This is rotated so Ogre::SceneNode *mRootNode;
/// that the OGRE coordinate system matches that used internally in
/// Morrowind.
Ogre::SceneNode *mMwRoot;
OEngine::Physic::PhysicEngine* mPhysicsEngine; OEngine::Physic::PhysicEngine* mPhysicsEngine;

View file

@ -110,7 +110,7 @@ void BillboardObject::setPosition(const Vector3& pPosition)
Vector3 BillboardObject::getPosition() const Vector3 BillboardObject::getPosition() const
{ {
Vector3 p = mNode->_getDerivedPosition() - mNode->getParentSceneNode()->_getDerivedPosition(); Vector3 p = mNode->_getDerivedPosition() - mNode->getParentSceneNode()->_getDerivedPosition();
return Vector3(p.x, -p.z, p.y); return p;
} }
void BillboardObject::setVisibilityFlags(int flags) void BillboardObject::setVisibilityFlags(int flags)
@ -203,7 +203,7 @@ unsigned int Moon::getPhaseInt() const
return 0; return 0;
} }
SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) SkyManager::SkyManager (SceneNode* root, Camera* pCamera)
: mHour(0.0f) : mHour(0.0f)
, mDay(0) , mDay(0)
, mMonth(0) , mMonth(0)
@ -234,9 +234,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
, mCloudAnimationTimer(0.f) , mCloudAnimationTimer(0.f)
, mMoonRed(false) , mMoonRed(false)
{ {
mSceneMgr = pMwRoot->getCreator(); mSceneMgr = root->getCreator();
mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
mRootNode->setInheritOrientation(false); mRootNode->setInheritOrientation(false);
} }
@ -391,7 +390,6 @@ void SkyManager::update(float duration)
// increase the strength of the sun glare effect depending // increase the strength of the sun glare effect depending
// on how directly the player is looking at the sun // on how directly the player is looking at the sun
Vector3 sun = mSunGlare->getPosition(); Vector3 sun = mSunGlare->getPosition();
sun = Vector3(sun.x, sun.z, -sun.y);
Vector3 cam = mCamera->getRealDirection(); Vector3 cam = mCamera->getRealDirection();
const Degree angle = sun.angleBetween( cam ); const Degree angle = sun.angleBetween( cam );
float val = 1- (angle.valueDegrees() / 180.f); float val = 1- (angle.valueDegrees() / 180.f);

View file

@ -112,7 +112,7 @@ namespace MWRender
class SkyManager class SkyManager
{ {
public: public:
SkyManager(Ogre::SceneNode* pMwRoot, Ogre::Camera* pCamera); SkyManager(Ogre::SceneNode* root, Ogre::Camera* pCamera);
~SkyManager(); ~SkyManager();
void update(float duration); void update(float duration);

View file

@ -26,7 +26,7 @@ namespace MWRender
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) : TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend) :
mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend) mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Y, mLandSize, mWorldSize)), mRendering(rend)
{ {
mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
@ -54,8 +54,8 @@ namespace MWRender
mTerrainGlobals->setCompositeMapDistance(mWorldSize*2); mTerrainGlobals->setCompositeMapDistance(mWorldSize*2);
mTerrainGroup.setOrigin(Vector3(mWorldSize/2, mTerrainGroup.setOrigin(Vector3(mWorldSize/2,
0, mWorldSize/2,
-mWorldSize/2)); 0));
Terrain::ImportData& importSettings = mTerrainGroup.getDefaultImportSettings(); Terrain::ImportData& importSettings = mTerrainGroup.getDefaultImportSettings();

View file

@ -404,6 +404,8 @@ public:
*type = MWSound::SampleType_UInt8; *type = MWSound::SampleType_UInt8;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_S16) else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_S16)
*type = MWSound::SampleType_Int16; *type = MWSound::SampleType_Int16;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
*type = MWSound::SampleType_Float32;
else else
fail(std::string("Unsupported sample format: ")+ fail(std::string("Unsupported sample format: ")+
av_get_sample_fmt_name(mAVStream->codec->sample_fmt)); av_get_sample_fmt_name(mAVStream->codec->sample_fmt));

View file

@ -42,9 +42,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mIsUnderwater = false; mIsUnderwater = false;
mWaterPlane = Plane(Vector3::UNIT_Y, 0); mWaterPlane = Plane(Vector3::UNIT_Z, 0);
MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Z); MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Y);
mWater = mSceneManager->createEntity("water"); mWater = mSceneManager->createEntity("water");
mWater->setVisibilityFlags(RV_Water); mWater->setVisibilityFlags(RV_Water);
@ -168,12 +168,12 @@ void Water::setHeight(const float height)
{ {
mTop = height; mTop = height;
mWaterPlane = Plane(Vector3::UNIT_Y, height); mWaterPlane = Plane(Vector3::UNIT_Z, height);
// small error due to reflection texture size & reflection distortion // small error due to reflection texture size & reflection distortion
mErrorPlane = Plane(Vector3::UNIT_Y, height - 5); mErrorPlane = Plane(Vector3::UNIT_Z, height - 5);
mWaterNode->setPosition(0, height, 0); mWaterNode->setPosition(0, 0, height);
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
} }
@ -199,7 +199,7 @@ Water::updateUnderwater(bool underwater)
Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
{ {
return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2)); return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), gridY * CELL_SIZE + (CELL_SIZE / 2), mTop);
} }
void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
@ -216,7 +216,7 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
mReflectionRenderActive = true; mReflectionRenderActive = true;
Vector3 pos = mCamera->getRealPosition(); Vector3 pos = mCamera->getRealPosition();
pos.y = mTop*2 - pos.y; pos.z = mTop*2 - pos.z;
mSky->setSkyPosition(pos); mSky->setSkyPosition(pos);
mReflectionCamera->enableReflection(mWaterPlane); mReflectionCamera->enableReflection(mWaterPlane);
} }

View file

@ -134,6 +134,18 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
return dec; return dec;
} }
static AVSampleFormat ffmpegNonPlanarSampleFormat (AVSampleFormat format)
{
switch (format)
{
case AV_SAMPLE_FMT_U8P: return AV_SAMPLE_FMT_U8;
case AV_SAMPLE_FMT_S16P: return AV_SAMPLE_FMT_S16;
case AV_SAMPLE_FMT_S32P: return AV_SAMPLE_FMT_S32;
case AV_SAMPLE_FMT_FLTP: return AV_SAMPLE_FMT_FLT;
case AV_SAMPLE_FMT_DBLP: return AV_SAMPLE_FMT_DBL;
default:return format;
}
}
void FFmpeg_Decoder::open(const std::string &fname) void FFmpeg_Decoder::open(const std::string &fname)
{ {
@ -153,10 +165,6 @@ void FFmpeg_Decoder::open(const std::string &fname)
try try
{ {
for(size_t j = 0;j < mFormatCtx->nb_streams;j++)
if(mFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
mFormatCtx->streams[j]->codec->request_sample_fmt = AV_SAMPLE_FMT_S16;
if(avformat_find_stream_info(mFormatCtx, NULL) < 0) if(avformat_find_stream_info(mFormatCtx, NULL) < 0)
fail("Failed to find stream info in "+fname); fail("Failed to find stream info in "+fname);
@ -164,7 +172,6 @@ void FFmpeg_Decoder::open(const std::string &fname)
{ {
if(mFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO) if(mFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{ {
mFormatCtx->streams[j]->codec->request_sample_fmt = AV_SAMPLE_FMT_S16;
mStream = &mFormatCtx->streams[j]; mStream = &mFormatCtx->streams[j];
break; break;
} }
@ -172,6 +179,8 @@ void FFmpeg_Decoder::open(const std::string &fname)
if(!mStream) if(!mStream)
fail("No audio streams in "+fname); fail("No audio streams in "+fname);
(*mStream)->codec->request_sample_fmt = ffmpegNonPlanarSampleFormat ((*mStream)->codec->sample_fmt);
AVCodec *codec = avcodec_find_decoder((*mStream)->codec->codec_id); AVCodec *codec = avcodec_find_decoder((*mStream)->codec->codec_id);
if(!codec) if(!codec)
{ {
@ -224,6 +233,8 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
*type = SampleType_UInt8; *type = SampleType_UInt8;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16) else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16)
*type = SampleType_Int16; *type = SampleType_Int16;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
*type = SampleType_Float32;
else else
fail(std::string("Unsupported sample format: ")+ fail(std::string("Unsupported sample format: ")+
av_get_sample_fmt_name((*mStream)->codec->sample_fmt)); av_get_sample_fmt_name((*mStream)->codec->sample_fmt));

View file

@ -88,6 +88,51 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
} }
} }
} }
if(alIsExtensionPresent("AL_EXT_FLOAT32"))
{
static const struct {
char name[32];
ChannelConfig chans;
SampleType type;
} fltfmtlist[] = {
{ "AL_FORMAT_MONO_FLOAT32", ChannelConfig_Mono, SampleType_Float32 },
{ "AL_FORMAT_STEREO_FLOAT32", ChannelConfig_Stereo, SampleType_Float32 },
};
static const size_t fltfmtlistsize = sizeof(fltfmtlist)/sizeof(fltfmtlist[0]);
for(size_t i = 0;i < fltfmtlistsize;i++)
{
if(fltfmtlist[i].chans == chans && fltfmtlist[i].type == type)
{
ALenum format = alGetEnumValue(fltfmtlist[i].name);
if(format != 0 && format != -1)
return format;
}
}
if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
{
static const struct {
char name[32];
ChannelConfig chans;
SampleType type;
} fltmcfmtlist[] = {
{ "AL_FORMAT_QUAD32", ChannelConfig_Quad, SampleType_Float32 },
{ "AL_FORMAT_51CHN32", ChannelConfig_5point1, SampleType_Float32 },
{ "AL_FORMAT_71CHN32", ChannelConfig_7point1, SampleType_Float32 },
};
static const size_t fltmcfmtlistsize = sizeof(fltmcfmtlist)/sizeof(fltmcfmtlist[0]);
for(size_t i = 0;i < fltmcfmtlistsize;i++)
{
if(fltmcfmtlist[i].chans == chans && fltmcfmtlist[i].type == type)
{
ALenum format = alGetEnumValue(fltmcfmtlist[i].name);
if(format != 0 && format != -1)
return format;
}
}
}
}
fail(std::string("Unsupported sound format (")+getChannelConfigName(chans)+", "+getSampleTypeName(type)+")"); fail(std::string("Unsupported sound format (")+getChannelConfigName(chans)+", "+getSampleTypeName(type)+")");
return AL_NONE; return AL_NONE;

View file

@ -9,7 +9,8 @@ namespace MWSound
{ {
enum SampleType { enum SampleType {
SampleType_UInt8, SampleType_UInt8,
SampleType_Int16 SampleType_Int16,
SampleType_Float32
}; };
const char *getSampleTypeName(SampleType type); const char *getSampleTypeName(SampleType type);

View file

@ -607,6 +607,7 @@ namespace MWSound
{ {
case SampleType_UInt8: return "U8"; case SampleType_UInt8: return "U8";
case SampleType_Int16: return "S16"; case SampleType_Int16: return "S16";
case SampleType_Float32: return "Float32";
} }
return "(unknown sample type)"; return "(unknown sample type)";
} }
@ -638,6 +639,7 @@ namespace MWSound
{ {
case SampleType_UInt8: frames *= 1; break; case SampleType_UInt8: frames *= 1; break;
case SampleType_Int16: frames *= 2; break; case SampleType_Int16: frames *= 2; break;
case SampleType_Float32: frames *= 4; break;
} }
return frames; return frames;
} }

View file

@ -264,9 +264,8 @@ namespace MWWorld
Ogre::Vector3 to = ray.getPoint(queryDistance); Ogre::Vector3 to = ray.getPoint(queryDistance);
btVector3 _from, _to; btVector3 _from, _to;
// OGRE to MW coordinates _from = btVector3(from.x, from.y, from.z);
_from = btVector3(from.x, -from.z, from.y); _to = btVector3(to.x, to.y, to.z);
_to = btVector3(to.x, -to.z, to.y);
std::vector < std::pair <float, std::string> > results; std::vector < std::pair <float, std::string> > results;
/* auto */ results = mEngine->rayTest2(_from,_to); /* auto */ results = mEngine->rayTest2(_from,_to);
@ -287,7 +286,7 @@ namespace MWWorld
Ray centerRay = mRender.getCamera()->getCameraToViewportRay( Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
mRender.getViewport()->getWidth()/2, mRender.getViewport()->getWidth()/2,
mRender.getViewport()->getHeight()/2); mRender.getViewport()->getHeight()/2);
btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y); btVector3 result(centerRay.getPoint(extent).x,centerRay.getPoint(extent).y,centerRay.getPoint(extent).z);
return result; return result;
} }
@ -295,7 +294,7 @@ namespace MWWorld
{ {
//get a ray pointing to the center of the viewport //get a ray pointing to the center of the viewport
Ray centerRay = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY); Ray centerRay = mRender.getCamera()->getCameraToViewportRay(mouseX, mouseY);
btVector3 result(centerRay.getPoint(extent).x,-centerRay.getPoint(extent).z,centerRay.getPoint(extent).y); btVector3 result(centerRay.getPoint(extent).x,centerRay.getPoint(extent).y,centerRay.getPoint(extent).z);
return result; return result;
} }
@ -335,9 +334,8 @@ namespace MWWorld
Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable
btVector3 _from, _to; btVector3 _from, _to;
// OGRE to MW coordinates _from = btVector3(from.x, from.y, from.z);
_from = btVector3(from.x, -from.z, from.y); _to = btVector3(to.x, to.y, to.z);
_to = btVector3(to.x, -to.z, to.y);
std::pair<std::string, float> result = mEngine->rayTest(_from, _to); std::pair<std::string, float> result = mEngine->rayTest(_from, _to);

View file

@ -1024,7 +1024,6 @@ namespace MWWorld
// currently its here because we need to access the physics system // currently its here because we need to access the physics system
float* p = mPlayer->getPlayer().getRefData().getPosition().pos; float* p = mPlayer->getPlayer().getRefData().getPosition().pos;
Vector3 sun = mRendering->getSkyManager()->getRealSunPos(); Vector3 sun = mRendering->getSkyManager()->getRealSunPos();
sun = Vector3(sun.x, -sun.z, sun.y);
mRendering->getSkyManager()->setGlare(!mPhysics->castRay(Ogre::Vector3(p[0], p[1], p[2]), sun)); mRendering->getSkyManager()->setGlare(!mPhysics->castRay(Ogre::Vector3(p[0], p[1], p[2]), sun));
} }
@ -1122,7 +1121,7 @@ namespace MWWorld
} }
else else
p = mPhysics->getRayPoint(results.front().first); p = mPhysics->getRayPoint(results.front().first);
Ogre::Vector3 pos(p.x(), p.z(), -p.y()); Ogre::Vector3 pos(p.x(), p.y(), p.z());
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
//std::cout << "Num facing 1 : " << mFaced1Name << std::endl; //std::cout << "Num facing 1 : " << mFaced1Name << std::endl;
@ -1150,7 +1149,7 @@ namespace MWWorld
} }
else else
p = mPhysics->getRayPoint(results.at (1).first); p = mPhysics->getRayPoint(results.at (1).first);
Ogre::Vector3 pos(p.x(), p.z(), -p.y()); Ogre::Vector3 pos(p.x(), p.y(), p.z());
Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode(); Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode();
Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode(); Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode();
@ -1228,8 +1227,8 @@ namespace MWWorld
if (!ref) if (!ref)
return Vector2(0, 1); return Vector2(0, 1);
Ogre::SceneNode* node = ref->mData.getBaseNode(); Ogre::SceneNode* node = ref->mData.getBaseNode();
Vector3 dir = node->_getDerivedOrientation().yAxis(); Vector3 dir = node->_getDerivedOrientation() * Ogre::Vector3(0,1,0);
Vector2 d = Vector2(dir.x, dir.z); Vector2 d = Vector2(dir.x, dir.y);
return d; return d;
} }
@ -1299,7 +1298,7 @@ namespace MWWorld
if (isCellExterior()) if (isCellExterior())
{ {
int cellX, cellY; int cellX, cellY;
positionToIndex(result.second[0], -result.second[2], cellX, cellY); positionToIndex(result.second[0], result.second[1], cellX, cellY);
cell = mCells.getExterior(cellX, cellY); cell = mCells.getExterior(cellX, cellY);
} }
else else
@ -1307,8 +1306,8 @@ namespace MWWorld
ESM::Position pos = getPlayer().getPlayer().getRefData().getPosition(); ESM::Position pos = getPlayer().getPlayer().getRefData().getPosition();
pos.pos[0] = result.second[0]; pos.pos[0] = result.second[0];
pos.pos[1] = -result.second[2]; pos.pos[1] = result.second[1];
pos.pos[2] = result.second[1]; pos.pos[2] = result.second[2];
Ptr dropped = copyObjectToCell(object, *cell, pos); Ptr dropped = copyObjectToCell(object, *cell, pos);
PCDropped(dropped); PCDropped(dropped);

View file

@ -602,7 +602,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
Nif::NiSourceTexture *st = t->textures[0].texture.getPtr(); Nif::NiSourceTexture *st = t->textures[0].texture.getPtr();
if (st->external) if (st->external)
{ {
/* Bethesda at some at some point converted all their BSA /* Bethesda at some point converted all their BSA
* textures from tga to dds for increased load speed, but all * textures from tga to dds for increased load speed, but all
* texture file name references were kept as .tga. * texture file name references were kept as .tga.
*/ */
@ -621,6 +621,17 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName)) if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
texName = path + st->filename; texName = path + st->filename;
} }
else if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
{
// workaround for Better Heads addon
size_t lastSlash = st->filename.rfind('\\');
if (lastSlash != std::string::npos && lastSlash + 1 != st->filename.size()) {
texName = path + st->filename.substr(lastSlash + 1);
// workaround for Better Bodies addon
if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
texName = st->filename;
}
}
} }
else warn("Found internal texture, ignoring."); else warn("Found internal texture, ignoring.");
} }
@ -683,7 +694,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
new sh::Vector4(diffuse.x, diffuse.y, diffuse.z, alpha))); new sh::Vector4(diffuse.x, diffuse.y, diffuse.z, alpha)));
instance->setProperty ("specular", sh::makeProperty<sh::Vector4> ( instance->setProperty ("specular", sh::makeProperty<sh::Vector4> (
new sh::Vector4(specular.x, specular.y, specular.z, glossiness))); new sh::Vector4(specular.x, specular.y, specular.z, glossiness*255.0f)));
instance->setProperty ("emissive", sh::makeProperty<sh::Vector3> ( instance->setProperty ("emissive", sh::makeProperty<sh::Vector3> (
new sh::Vector3(emissive.x, emissive.y, emissive.z))); new sh::Vector3(emissive.x, emissive.y, emissive.z)));
@ -1031,6 +1042,10 @@ public:
void createMeshes(const Nif::Node *node, MeshInfoList &meshes, int flags=0) void createMeshes(const Nif::Node *node, MeshInfoList &meshes, int flags=0)
{ {
// Do not create meshes for the collision shape (includes all children)
if(node->recType == Nif::RC_RootCollisionNode)
return;
flags |= node->flags; flags |= node->flags;
// Marker objects: just skip the entire node // Marker objects: just skip the entire node

View file

@ -12,65 +12,75 @@ Marc Zinnschlag (Zini) - Lead Programmer/Project Manager
Adam Hogan (aurix) Adam Hogan (aurix)
Aleksandar Jovanov Aleksandar Jovanov
Alexander Nadeau (wareya)
Alexander Olofsson (Ace) Alexander Olofsson (Ace)
Artem Kotsynyak (greye) Artem Kotsynyak (greye)
athile athile
BrotherBrick BrotherBrick
Chris Robinson Chris Robinson (KittyCat)
Cory F. Cohen (cfcohen) Cory F. Cohen (cfcohen)
Cris Mihalache (Mirceam) Cris Mihalache (Mirceam)
Douglas Diniz (Dgdiniz) Douglas Diniz (Dgdiniz)
Douglas Mencken (dougmencken)
Edmondo Tommasina (edmondo)
Eduard Cot (trombonecot) Eduard Cot (trombonecot)
Eli2 Eli2
Emanuel "potatoesmaster" Guével Emanuel Guével (potatoesmaster)
gugus / gus gugus/gus
Jacob Essex (Yacoby) Jacob Essex (Yacoby)
Jannik Heller (scrawl) Jannik Heller (scrawl)
Jason Hooks (jhooks) Jason Hooks (jhooks)
Joel Graff (graffy) Joel Graff (graffy)
Jordan Milne
Julien Voisin (jvoisin/ap0)
Karl-Felix Glatzer (k1ll) Karl-Felix Glatzer (k1ll)
Lars Söderberg (Lazaroth) Lars Söderberg (Lazaroth)
lazydev lazydev
Leon Saunders (emoose) Leon Saunders (emoose)
Lukasz Gromanowski (lgro) Lukasz Gromanowski (lgro)
Marcin Hulist (Gohan) Marcin Hulist (Gohan)
Mark Siewert (mark76)
Manuel Edelmann (vorenon)
Michael Mc Donnell Michael Mc Donnell
Michael Papageorgiou (werdanith) Michael Papageorgiou (werdanith)
Nathan Jeffords (blunted2night) Nathan Jeffords (blunted2night)
Nikolay Kasyanov (corristo) Nikolay Kasyanov (corristo)
Nolan Poe (nopoe)
Paul McElroy (Greendogo)
Pieter van der Kloet (pvdk) Pieter van der Kloet (pvdk)
Radu-Marius Popovici (rpopovici)
Roman Melnik (Kromgart) Roman Melnik (Kromgart)
Sandy Carter (bwrsandman)
Sebastian Wick (swick) Sebastian Wick (swick)
Sergey Shambir Sergey Shambir
Sylvain T. (Garvek) Sylvain Thesnieres (Garvek)
Tom Mason (wheybags) Tom Mason (wheybags)
Packagers: Packagers:
Alexander Olofsson (Ace) - Windows Alexander Olofsson (Ace) - Windows
BrotherBrick - Ubuntu Linux BrotherBrick - Ubuntu Linux
Edmondo Tommasina - Gentoo Linux Edmondo Tommasina (edmondo) - Gentoo Linux
Julian Ospald (hasufell) - Gentoo Linux
Karl-Felix Glatzer (k1ll) - Linux Binaries
Kenny Armstrong (artorius) - Fedora Linux Kenny Armstrong (artorius) - Fedora Linux
Nikolay Kasyanov (corristo) - Mac OS X Nikolay Kasyanov (corristo) - Mac OS X
Sandy Carter (bwrsandman) - Arch Linux Sandy Carter (bwrsandman) - Arch Linux
Public Relations: Public Relations and Translations:
ElderTroll - Release Manager Artem Kotsynyak (greye) - Russian News Writer
sir_herrbatka - News Writer Julien Voisin (jvoisin/ap0) - French News Writer
Mickey Lyle (raevol) - Release Manager
Pithorn - Chinese News Writer
sir_herrbatka - English/Polish News Writer
WeirdSexy - Podcaster WeirdSexy - Podcaster
Website: Website:
juanmnzsk8 - Spanish News Writer
Julien Voisin (jvoisin/ap0) - French News Writer
Kingpix - Italian News Writer
Lukasz Gromanowski (lgro) - Website Administrator Lukasz Gromanowski (lgro) - Website Administrator
Nikolay Kasyanov (corristo) - Russian News Writer
Okulo - Dutch News Writer
penguinroad - Indonesian News Writer
Ryan Sardonic (Wry) - Wiki Editor Ryan Sardonic (Wry) - Wiki Editor
sir_herrbatka - Forum Admin/Polish News Writer sir_herrbatka - Forum Administrator
spyboot - German News Writer
Formula Research: Formula Research:
@ -86,20 +96,32 @@ Sadler
Artwork: Artwork:
Necrod - OpenMW Logo Necrod - OpenMW Logo
raevol - Wordpress Theme Mickey Lyle (raevol) - Wordpress Theme
Okulo - OpenMW Editor Icons
Inactive Contributors: Inactive Contributors:
Ardekantur Ardekantur
Armin Preiml Armin Preiml
Carl Maxwell
Diggory Hardy Diggory Hardy
Jan Borsodi Dmitry Marakasov (AMDmi3)
ElderTroll
guidoj
Jan-Peter Nilsson (peppe) Jan-Peter Nilsson (peppe)
Jan Borsodi
Josua Grawitter Josua Grawitter
juanmnzsk8
Kingpix
Lordrea Lordrea
Michal Sciubidlo
Nicolay Korslund Nicolay Korslund
pchan3
penguinroad
psi29a
sergoz sergoz
spyboot
Star-Demon Star-Demon
Thoronador
Yuri Krupenin Yuri Krupenin
@ -117,7 +139,7 @@ Thanks to Kevin Ryan,
for creating the icon used for the Data Files tab of the OpenMW Launcher. for creating the icon used for the Data Files tab of the OpenMW Launcher.
Thanks to Georg Duffner, Thanks to Georg Duffner,
for the open-source EB Garamond fontface. for his EB Garamond fontface, see OFL.txt for his license terms.
Thanks to Dongle, Thanks to Dongle,
for his Daedric fontface, see Daedric Font License.txt for his license terms. for his Daedric fontface, see Daedric Font License.txt for his license terms.

View file

@ -225,9 +225,9 @@
float3 waterEyePos = float3(1,1,1); float3 waterEyePos = float3(1,1,1);
// NOTE: this calculation would be wrong for non-uniform scaling // NOTE: this calculation would be wrong for non-uniform scaling
float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0));
waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,1,0), waterLevel); waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel);
caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed); caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed);
if (worldPos.y >= waterLevel || waterEnabled != 1.f) if (worldPos.z >= waterLevel || waterEnabled != 1.f)
caustics = float3(1,1,1); caustics = float3(1,1,1);
#endif #endif
@ -269,7 +269,7 @@
#if UNDERWATER #if UNDERWATER
// regular fog only if fragment is above water // regular fog only if fragment is above water
if (worldPos.y > waterLevel || waterEnabled != 1.f) if (worldPos.z > waterLevel || waterEnabled != 1.f)
#endif #endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
#endif #endif
@ -278,7 +278,7 @@
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0)); shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER #if UNDERWATER
float fogAmount = (cameraPos.y > waterLevel) float fogAmount = (cameraPos.z > waterLevel)
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY) ? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY); : shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
@ -292,14 +292,14 @@
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
float3 watercolour = ( gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; float3 watercolour = ( gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0;
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; watercolour = (cameraPos.z <= waterLevel) ? watercolour : watercolour*0.3;
float darkness = VISIBILITY*2.0; float darkness = VISIBILITY*2.0;
darkness = clamp((waterEyePos.y - waterLevel + darkness)/darkness,0.2,1.0); darkness = clamp((waterEyePos.z - waterLevel + darkness)/darkness,0.2,1.0);
watercolour *= darkness; watercolour *= darkness;
float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0; float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0;
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled);
#endif #endif

View file

@ -88,8 +88,8 @@
float toMorph = -min(0, sign(uv1.y - lodMorph.y)); float toMorph = -min(0, sign(uv1.y - lodMorph.y));
// morph // morph
// this assumes XZ terrain alignment // this assumes XY terrain alignment
worldPos.y += uv1.x * toMorph * lodMorph.x; worldPos.z += uv1.x * toMorph * lodMorph.x;
shOutputPosition = shMatrixMult(viewProjMatrix, worldPos); shOutputPosition = shMatrixMult(viewProjMatrix, worldPos);
@ -233,9 +233,9 @@
float3 waterEyePos = float3(1,1,1); float3 waterEyePos = float3(1,1,1);
// NOTE: this calculation would be wrong for non-uniform scaling // NOTE: this calculation would be wrong for non-uniform scaling
float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0));
waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,1,0), waterLevel); waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel);
caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed); caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed);
if (worldPos.y >= waterLevel) if (worldPos.z >= waterLevel)
caustics = float3(1,1,1); caustics = float3(1,1,1);
@ -341,7 +341,7 @@
#if UNDERWATER #if UNDERWATER
// regular fog only if fragment is above water // regular fog only if fragment is above water
if (worldPos.y > waterLevel) if (worldPos.z > waterLevel)
#endif #endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
#endif #endif
@ -350,7 +350,7 @@
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0)); shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER #if UNDERWATER
float fogAmount = (cameraPos.y > waterLevel) float fogAmount = (cameraPos.z > waterLevel)
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY) ? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY); : shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
@ -365,14 +365,14 @@
float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0;
float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; watercolour = (cameraPos.z <= waterLevel) ? watercolour : watercolour*0.3;
float darkness = VISIBILITY*2.0; float darkness = VISIBILITY*2.0;
darkness = clamp((waterEyePos.y - waterLevel + darkness)/darkness,0.2,1.0); darkness = clamp((waterEyePos.z - waterLevel + darkness)/darkness,0.2,1.0);
watercolour *= darkness; watercolour *= darkness;
float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0; float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0;
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
#endif #endif

View file

@ -79,9 +79,9 @@ float3 perturb(shTexture2D tex, float2 coords, float bend, float2 windDir, float
float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 waterEyePos, float3 worldNormal, float3 lightDirectionWS0, float waterLevel, float waterTimer, float3 windDir_windSpeed) float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 waterEyePos, float3 worldNormal, float3 lightDirectionWS0, float waterLevel, float waterTimer, float3 windDir_windSpeed)
{ {
float waterDepth = shSaturate((waterEyePos.y - worldPos.y) / 50.0); float waterDepth = shSaturate((waterEyePos.z - worldPos.z) / 50.0);
float3 causticPos = intercept(worldPos.xyz, lightDirectionWS0.xyz, float3(0,1,0), waterLevel); float3 causticPos = intercept(worldPos.xyz, lightDirectionWS0.xyz, float3(0,0,1), waterLevel);
///\ todo clean this up ///\ todo clean this up
float causticdepth = length(causticPos-worldPos.xyz); float causticdepth = length(causticPos-worldPos.xyz);
@ -91,20 +91,21 @@ float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 waterEyePos,
// NOTE: the original shader calculated a tangent space basis here, // NOTE: the original shader calculated a tangent space basis here,
// but using only the world normal is cheaper and i couldn't see a visual difference // but using only the world normal is cheaper and i couldn't see a visual difference
// also, if this effect gets moved to screen-space some day, it's unlikely to have tangent information // also, if this effect gets moved to screen-space some day, it's unlikely to have tangent information
float3 causticNorm = worldNormal.xyz * perturb(causticMap, causticPos.xz, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).xzy * 2 - 1; float3 causticNorm = worldNormal.xyz * perturb(causticMap, causticPos.xy, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).xyz * 2 - 1;
causticNorm = float3(causticNorm.x, causticNorm.y, -causticNorm.z);
//float fresnel = pow(clamp(dot(LV,causticnorm),0.0,1.0),2.0); //float fresnel = pow(clamp(dot(LV,causticnorm),0.0,1.0),2.0);
float NdotL = max(dot(worldNormal.xyz, lightDirectionWS0.xyz),0.0); float NdotL = max(dot(worldNormal.xyz, lightDirectionWS0.xyz),0.0);
float causticR = 1.0-perturb(causticMap, causticPos.xz, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z; float causticR = 1.0-perturb(causticMap, causticPos.xy, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
/// \todo sunFade /// \todo sunFade
// float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*sunFade*causticdepth; // float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*sunFade*causticdepth;
float3 caustics = clamp(pow(float3(causticR,causticR,causticR)*5.5,float3(5.5*causticdepth,5.5*causticdepth,5.5*causticdepth)),0.0,1.0)*NdotL*causticdepth; float3 caustics = clamp(pow(float3(causticR,causticR,causticR)*5.5,float3(5.5*causticdepth,5.5*causticdepth,5.5*causticdepth)),0.0,1.0)*NdotL*causticdepth;
float causticG = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z; float causticG = 1.0-perturb(causticMap,causticPos.xy+(1.0-causticdepth)*ABBERATION, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
float causticB = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION*2.0, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z; float causticB = 1.0-perturb(causticMap,causticPos.xy+(1.0-causticdepth)*ABBERATION*2.0, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
//caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*sunFade*causticdepth; //caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*sunFade*causticdepth;
caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth,5.5*causticdepth,5.5*causticdepth)))*NdotL*causticdepth; caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth,5.5*causticdepth,5.5*causticdepth)))*NdotL*causticdepth;

View file

@ -122,7 +122,7 @@
#define REFL_BUMP 0.08 // reflection distortion amount #define REFL_BUMP 0.08 // reflection distortion amount
#define REFR_BUMP 0.06 // refraction distortion amount #define REFR_BUMP 0.06 // refraction distortion amount
#define SCATTER_AMOUNT 3.0 // amount of sunlight scattering #define SCATTER_AMOUNT 0.3 // amount of sunlight scattering
#define SCATTER_COLOUR gammaCorrectRead(float3(0.0,1.0,0.95)) // colour of sunlight scattering #define SCATTER_COLOUR gammaCorrectRead(float3(0.0,1.0,0.95)) // colour of sunlight scattering
#define SUN_EXT gammaCorrectRead(float3(0.45, 0.55, 0.68)) //sunlight extinction #define SUN_EXT gammaCorrectRead(float3(0.45, 0.55, 0.68)) //sunlight extinction
@ -219,25 +219,27 @@
float3 normal = (normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y + float3 normal = (normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y +
normal2 * MID_WAVES_X + normal3 * MID_WAVES_Y + normal2 * MID_WAVES_X + normal3 * MID_WAVES_Y +
normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y).xzy; normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y).xyz;
normal = normalize(float3(normal.x * BUMP, normal.y, normal.z * BUMP)); normal = normalize(float3(normal.x * BUMP, normal.y * BUMP, normal.z));
normal = float3(normal.x, normal.y, -normal.z);
// normal for sunlight scattering // normal for sunlight scattering
float3 lNormal = (normal0 * BIG_WAVES_X*0.5 + normal1 * BIG_WAVES_Y*0.5 + float3 lNormal = (normal0 * BIG_WAVES_X*0.5 + normal1 * BIG_WAVES_Y*0.5 +
normal2 * MID_WAVES_X*0.2 + normal3 * MID_WAVES_Y*0.2 + normal2 * MID_WAVES_X*0.2 + normal3 * MID_WAVES_Y*0.2 +
normal4 * SMALL_WAVES_X*0.1 + normal5 * SMALL_WAVES_Y*0.1).xzy; normal4 * SMALL_WAVES_X*0.1 + normal5 * SMALL_WAVES_Y*0.1).xyz;
lNormal = normalize(float3(lNormal.x * BUMP, lNormal.y, lNormal.z * BUMP)); lNormal = normalize(float3(lNormal.x * BUMP, lNormal.y * BUMP, lNormal.z));
lNormal = float3(lNormal.x, lNormal.y, -lNormal.z);
float3 lVec = normalize(sunPosition.xyz); float3 lVec = normalize(sunPosition.xyz);
float3 vVec = normalize(position.xyz - cameraPos.xyz); float3 vVec = normalize(position.xyz - cameraPos.xyz);
float isUnderwater = (cameraPos.y > 0) ? 0.0 : 1.0; float isUnderwater = (cameraPos.z > 0) ? 0.0 : 1.0;
// sunlight scattering // sunlight scattering
float3 pNormal = float3(0,1,0); float3 pNormal = float3(0,0,1);
float3 lR = reflect(lVec, lNormal); float3 lR = reflect(lVec, lNormal);
float3 llR = reflect(lVec, pNormal); float3 llR = reflect(lVec, pNormal);
@ -246,13 +248,13 @@
float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*gammaCorrectRead(float3(1.0,0.4,0.0)), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*gammaCorrectRead(float3(1.0,0.4,0.0)), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
// fresnel // fresnel
float ior = (cameraPos.y>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air float ior = (cameraPos.z>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air
float fresnel = fresnel_dielectric(-vVec, normal, ior); float fresnel = fresnel_dielectric(-vVec, normal, ior);
fresnel = shSaturate(fresnel); fresnel = shSaturate(fresnel);
// reflection // reflection
float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb); float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xy*REFL_BUMP)).rgb);
// refraction // refraction
float3 R = reflect(vVec, normal); float3 R = reflect(vVec, normal);
@ -260,13 +262,13 @@
// check the depth at the refracted coords, and don't do any normal distortion for the refraction if the object to refract // check the depth at the refracted coords, and don't do any normal distortion for the refraction if the object to refract
// is actually above the water (objectDepth < waterDepth) // is actually above the water (objectDepth < waterDepth)
// this solves silhouettes around objects above the water // this solves silhouettes around objects above the water
float refractDepth = shSample(depthMap, screenCoords-(shoreFade * normal.xz*REFR_BUMP)).x * far - depthPassthrough; float refractDepth = shSample(depthMap, screenCoords-(shoreFade * normal.xy*REFR_BUMP)).x * far - depthPassthrough;
float doRefraction = (refractDepth < 0) ? 0.f : 1.f; float doRefraction = (refractDepth < 0) ? 0.f : 1.f;
float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP * doRefraction))*1.0).rgb); float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(shoreFade * normal.xy*REFR_BUMP * doRefraction))*1.0).rgb);
// brighten up the refraction underwater // brighten up the refraction underwater
refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction; refraction = (cameraPos.z < 0) ? shSaturate(refraction * 1.5) : refraction;
// specular // specular
float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS); float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS);
@ -290,7 +292,7 @@
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
float darkness = VISIBILITY*2.0; float darkness = VISIBILITY*2.0;
darkness = clamp((cameraPos.y+darkness)/darkness,0.2,1.0); darkness = clamp((cameraPos.z+darkness)/darkness,0.2,1.0);
float fog = shSaturate(length(cameraPos.xyz-position.xyz) / VISIBILITY); float fog = shSaturate(length(cameraPos.xyz-position.xyz) / VISIBILITY);

View file

@ -193,7 +193,6 @@ namespace Physic
if(!isDebugCreated) if(!isDebugCreated)
{ {
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
node->pitch(Ogre::Degree(-90));
mDebugDrawer = new BtOgre::DebugDrawer(node, dynamicsWorld); mDebugDrawer = new BtOgre::DebugDrawer(node, dynamicsWorld);
dynamicsWorld->setDebugDrawer(mDebugDrawer); dynamicsWorld->setDebugDrawer(mDebugDrawer);
isDebugCreated = true; isDebugCreated = true;

View file

@ -9,7 +9,7 @@ Website: http://www.openmw.org
Font Licenses: Font Licenses:
EBGaramond-Regular.ttf: OFL (see OFL.txt for more information) EBGaramond-Regular.ttf: OFL (see OFL.txt for more information)
VeraMono.ttf: custom (see Bitstream Vera License.txt for more information) DejaVuLGCSansMono.ttf: custom (see DejaVu Font License.txt for more information)