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

actorid
lazydev 12 years ago
commit f717fe0254

@ -382,7 +382,7 @@ namespace MWClass
const MWMechanics::MagicEffects &mageffects = npcdata->mCreatureStats.getMagicEffects();
const float encumbranceTerm = fJumpEncumbranceBase->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 b = 0.0f;

@ -88,7 +88,7 @@ void LocalMapBase::applyFogOfWar()
+ boost::lexical_cast<std::string>(my);
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];
fog->setImageTexture(mFogOfWar ?
((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
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) + "_"
+ boost::lexical_cast<std::string>(my);
@ -173,7 +173,7 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
}
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);
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::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;
mGlobalMapRender->worldPosToImageSpace (pos.x, pos.z, worldX, worldY);
mGlobalMapRender->worldPosToImageSpace (pos.x, pos.y, worldX, worldY);
worldX *= mGlobalMapRender->getWidth();
worldY *= mGlobalMapRender->getHeight();

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

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

@ -87,10 +87,12 @@ namespace MWInput
std::string("false")));
pl.insert(std::make_pair(std::string("x11_keyboard_grab"),
std::string("false")));
pl.insert(std::make_pair(std::string("XAutoRepeatOn"),
std::string("true")));
#endif
}
#if defined OIS_LINUX_PLATFORM
pl.insert(std::make_pair(std::string("XAutoRepeatOn"),
std::string("true")));
#endif
#if defined(__APPLE__) && !defined(__LP64__)
// Give the application window focus to receive input events
@ -177,6 +179,11 @@ namespace MWInput
case A_Activate:
resetIdleTime();
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;
case A_Journal:
toggleJournal ();

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

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

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

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

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

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

@ -190,7 +190,7 @@ namespace MWRender
{
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)

@ -28,9 +28,6 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag
mCellCamera = mRendering->getScene()->createCamera("CellCamera");
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
// look down -y
const float sqrt0pt5 = 0.707106781;
mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
mCameraNode->attachObject(mCellCamera);
}
@ -82,8 +79,8 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
}
else
{
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
Vector2 length = max-min;
// divide into segments
@ -107,6 +104,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
mInterior = false;
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 y = cell->mCell->getGridY();
@ -115,7 +113,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
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,
@ -124,40 +122,44 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
mInterior = true;
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);
Radian angle(std::atan2(-north.x, -north.y));
Radian angle = Ogre::Math::ATan2 (north.x, north.y);
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
Vector2 _center(bounds.getCenter().x, bounds.getCenter().z);
Vector3 _c1 = bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM);
Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM);
Vector3 _c3 = bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM);
Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM);
Vector2 c1(_c1.x, _c1.z);
Vector2 c2(_c2.x, _c2.z);
Vector2 c3(_c3.x, _c3.z);
Vector2 c4(_c4.x, _c4.z);
Vector2 _center(bounds.getCenter().x, bounds.getCenter().y);
Vector3 _c1 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM);
Vector3 _c2 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM);
Vector3 _c3 = bounds.getCorner(AxisAlignedBox::FAR_LEFT_TOP);
Vector3 _c4 = bounds.getCorner(AxisAlignedBox::FAR_RIGHT_TOP);
Vector2 c1(_c1.x, _c1.y);
Vector2 c2(_c2.x, _c2.y);
Vector2 c3(_c3.x, _c3.y);
Vector2 c4(_c4.x, _c4.y);
c1 = rotatePoint(c1, _center, mAngle);
c2 = rotatePoint(c2, _center, mAngle);
c3 = rotatePoint(c3, _center, mAngle);
c4 = rotatePoint(c4, _center, mAngle);
mBounds.merge(Vector3(c1.x, 0, c1.y));
mBounds.merge(Vector3(c2.x, 0, c2.y));
mBounds.merge(Vector3(c3.x, 0, c3.y));
mBounds.merge(Vector3(c4.x, 0, c4.y));
mBounds.merge(Vector3(c1.x, c1.y, 0));
mBounds.merge(Vector3(c2.x, c2.y, 0));
mBounds.merge(Vector3(c3.x, c3.y, 0));
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 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
Vector2 length = max-min;
mCameraPosNode->setPosition(Vector3(center.x, 0, center.y));
mCameraPosNode->setPosition(Vector3(center.x, center.y, 0));
// divide into segments
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 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));
}
}
@ -193,7 +195,7 @@ void LocalMap::render(const float x, const float y,
mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
mRenderingManager->disableLights();
mCameraNode->setPosition(Vector3(x, zhigh+100000, y));
mCameraNode->setPosition(Vector3(x, y, zhigh+100000));
//mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
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)
{
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;
y = std::ceil((pos.y - min.y)/sSize)-1;
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)
@ -311,19 +313,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
int x,y;
float u,v;
Vector2 pos(position.x, position.z);
Vector2 pos(position.x, position.y);
if (mInterior)
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)
{
x = std::ceil(pos.x / sSize)-1;
y = std::ceil(-pos.y / sSize)-1;
y = std::ceil(pos.y / sSize)-1;
mCellX = x;
mCellY = y;
}
@ -337,7 +339,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
if (!mInterior)
{
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_";
}
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()->setPlayerDir(playerdirection.x, -playerdirection.z);
MWBase::Environment::get().getWindowManager()->setPlayerDir(playerdirection.x, playerdirection.y);
// explore radius (squared)
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 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)
for (int mx = -1; mx<2; ++mx)
{
@ -375,7 +375,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
if (!affected)
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");
if (!tex.isNull())

@ -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_)
{
Ogre::SceneNode* root = mMwRoot;
Ogre::SceneNode* root = mRootNode;
Ogre::SceneNode* cellnode;
if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
{
@ -390,9 +390,9 @@ void Objects::enableLights()
std::vector<LightInfo>::iterator it = mLights.begin();
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;
}
else
@ -405,9 +405,9 @@ void Objects::disableLights()
std::vector<LightInfo>::iterator it = mLights.begin();
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;
}
else
@ -460,9 +460,9 @@ void Objects::update(const float dt)
std::vector<LightInfo>::iterator it = mLights.begin();
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 cycle_time;
@ -550,7 +550,7 @@ void Objects::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
MWWorld::CellStore *newCell = cur.getCell();
if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
node = mMwRoot->createChildSceneNode();
node = mRootNode->createChildSceneNode();
mCellSceneNodes[newCell] = node;
} else {
node = mCellSceneNodes[newCell];

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

@ -113,11 +113,6 @@ namespace MWRender
Ogre::Vector3 dir = mCamera->getRealDirection();
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);
}
@ -323,10 +318,8 @@ namespace MWRender
bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera)
{
float xch;
mCamera->getParentSceneNode ()->needUpdate(true);
camera = mCamera->getRealPosition();
xch = camera.z, camera.z = camera.y, camera.y = -xch;
player = mPlayerNode->getPosition();
return mFirstPersonView && !mVanity.enabled && !mPreviewMode;

@ -141,26 +141,20 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
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();
mMwRoot = rt->createChildSceneNode("mwRoot");
mMwRoot->pitch(Degree(-90));
mRootNode = rt;
mObjects.setMwRoot(mMwRoot);
mActors.setMwRoot(mMwRoot);
mObjects.setRootNode(mRootNode);
mActors.setRootNode(mRootNode);
Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player");
Ogre::SceneNode *playerNode = mRootNode->createChildSceneNode ("player");
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mShadows = new Shadows(&mRendering);
mTerrainManager = new TerrainManager(mRendering.getScene(), this);
mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera());
mSkyManager = new SkyManager(mRootNode, mRendering.getCamera());
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
@ -169,7 +163,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mSun = 0;
mDebugging = new Debugging(mMwRoot, engine);
mDebugging = new Debugging(mRootNode, engine);
mLocalMap = new MWRender::LocalMap(&mRendering, this);
setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI"));
@ -322,7 +316,7 @@ void RenderingManager::update (float duration, bool paused)
Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance();
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 btDest(dest.x, dest.y, dest.z);
@ -366,11 +360,13 @@ void RenderingManager::update (float duration, bool paused)
float *fpos = data.getPosition().pos;
// 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::Quaternion orient =
//node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
Ogre::Quaternion orient =
node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
node->_getDerivedOrientation();
mLocalMap->updatePlayer(pos, orient);
@ -382,7 +378,7 @@ void RenderingManager::update (float duration, bool paused)
mWater->updateUnderwater(
world->isUnderwater(
world->getPlayer().getPlayer().getCell(),
Ogre::Vector3(cam.x, -cam.z, cam.y))
cam)
);
mWater->update(duration);
}
@ -614,8 +610,7 @@ void RenderingManager::sunDisable()
void RenderingManager::setSunDirection(const Ogre::Vector3& direction)
{
// 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));
if (mSun) mSun->setDirection(Vector3(-direction.x, -direction.y, -direction.z));
mSkyManager->setSunDirection(direction);
}

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

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

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

@ -26,7 +26,7 @@ namespace MWRender
//----------------------------------------------------------------------------------------------
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();
@ -54,8 +54,8 @@ namespace MWRender
mTerrainGlobals->setCompositeMapDistance(mWorldSize*2);
mTerrainGroup.setOrigin(Vector3(mWorldSize/2,
0,
-mWorldSize/2));
mWorldSize/2,
0));
Terrain::ImportData& importSettings = mTerrainGroup.getDefaultImportSettings();

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

@ -42,9 +42,9 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
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->setVisibilityFlags(RV_Water);
@ -168,12 +168,12 @@ void Water::setHeight(const float height)
{
mTop = height;
mWaterPlane = Plane(Vector3::UNIT_Y, height);
mWaterPlane = Plane(Vector3::UNIT_Z, height);
// 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)));
}
@ -199,7 +199,7 @@ Water::updateUnderwater(bool underwater)
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)
@ -216,7 +216,7 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
mReflectionRenderActive = true;
Vector3 pos = mCamera->getRealPosition();
pos.y = mTop*2 - pos.y;
pos.z = mTop*2 - pos.z;
mSky->setSkyPosition(pos);
mReflectionCamera->enableReflection(mWaterPlane);
}

@ -134,6 +134,18 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
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)
{
@ -153,10 +165,6 @@ void FFmpeg_Decoder::open(const std::string &fname)
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)
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)
{
mFormatCtx->streams[j]->codec->request_sample_fmt = AV_SAMPLE_FMT_S16;
mStream = &mFormatCtx->streams[j];
break;
}
@ -172,6 +179,8 @@ void FFmpeg_Decoder::open(const std::string &fname)
if(!mStream)
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);
if(!codec)
{
@ -224,6 +233,8 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
*type = SampleType_UInt8;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16)
*type = SampleType_Int16;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
*type = SampleType_Float32;
else
fail(std::string("Unsupported sample format: ")+
av_get_sample_fmt_name((*mStream)->codec->sample_fmt));

@ -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)+")");
return AL_NONE;

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

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

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

@ -1024,7 +1024,6 @@ namespace MWWorld
// currently its here because we need to access the physics system
float* p = mPlayer->getPlayer().getRefData().getPosition().pos;
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));
}
@ -1122,7 +1121,7 @@ namespace MWWorld
}
else
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();
//std::cout << "Num facing 1 : " << mFaced1Name << std::endl;
@ -1150,7 +1149,7 @@ namespace MWWorld
}
else
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* node2 = mFaced2.getRefData().getBaseNode();
@ -1228,8 +1227,8 @@ namespace MWWorld
if (!ref)
return Vector2(0, 1);
Ogre::SceneNode* node = ref->mData.getBaseNode();
Vector3 dir = node->_getDerivedOrientation().yAxis();
Vector2 d = Vector2(dir.x, dir.z);
Vector3 dir = node->_getDerivedOrientation() * Ogre::Vector3(0,1,0);
Vector2 d = Vector2(dir.x, dir.y);
return d;
}
@ -1299,7 +1298,7 @@ namespace MWWorld
if (isCellExterior())
{
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);
}
else
@ -1307,8 +1306,8 @@ namespace MWWorld
ESM::Position pos = getPlayer().getPlayer().getRefData().getPosition();
pos.pos[0] = result.second[0];
pos.pos[1] = -result.second[2];
pos.pos[2] = result.second[1];
pos.pos[1] = result.second[1];
pos.pos[2] = result.second[2];
Ptr dropped = copyObjectToCell(object, *cell, pos);
PCDropped(dropped);

@ -602,7 +602,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
Nif::NiSourceTexture *st = t->textures[0].texture.getPtr();
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
* 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))
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.");
}
@ -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)));
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> (
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)
{
// Do not create meshes for the collision shape (includes all children)
if(node->recType == Nif::RC_RootCollisionNode)
return;
flags |= node->flags;
// Marker objects: just skip the entire node

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

@ -225,9 +225,9 @@
float3 waterEyePos = float3(1,1,1);
// NOTE: this calculation would be wrong for non-uniform scaling
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);
if (worldPos.y >= waterLevel || waterEnabled != 1.f)
if (worldPos.z >= waterLevel || waterEnabled != 1.f)
caustics = float3(1,1,1);
#endif
@ -269,7 +269,7 @@
#if UNDERWATER
// regular fog only if fragment is above water
if (worldPos.y > waterLevel || waterEnabled != 1.f)
if (worldPos.z > waterLevel || waterEnabled != 1.f)
#endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
#endif
@ -278,7 +278,7 @@
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER
float fogAmount = (cameraPos.y > waterLevel)
float fogAmount = (cameraPos.z > waterLevel)
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
@ -292,14 +292,14 @@
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;
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;
darkness = clamp((waterEyePos.y - waterLevel + darkness)/darkness,0.2,1.0);
darkness = clamp((waterEyePos.z - waterLevel + darkness)/darkness,0.2,1.0);
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);
#endif

@ -88,8 +88,8 @@
float toMorph = -min(0, sign(uv1.y - lodMorph.y));
// morph
// this assumes XZ terrain alignment
worldPos.y += uv1.x * toMorph * lodMorph.x;
// this assumes XY terrain alignment
worldPos.z += uv1.x * toMorph * lodMorph.x;
shOutputPosition = shMatrixMult(viewProjMatrix, worldPos);
@ -233,9 +233,9 @@
float3 waterEyePos = float3(1,1,1);
// NOTE: this calculation would be wrong for non-uniform scaling
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);
if (worldPos.y >= waterLevel)
if (worldPos.z >= waterLevel)
caustics = float3(1,1,1);
@ -341,7 +341,7 @@
#if UNDERWATER
// regular fog only if fragment is above water
if (worldPos.y > waterLevel)
if (worldPos.z > waterLevel)
#endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
#endif
@ -350,7 +350,7 @@
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
#if UNDERWATER
float fogAmount = (cameraPos.y > waterLevel)
float fogAmount = (cameraPos.z > waterLevel)
? shSaturate(length(waterEyePos-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 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 = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
watercolour = (cameraPos.z <= waterLevel) ? watercolour : watercolour*0.3;
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;
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);
#endif

@ -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)
{
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
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,
// 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
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 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
// 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;
float causticG = 1.0-perturb(causticMap,causticPos.xz+(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 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.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,5.5*causticdepth,5.5*causticdepth)))*NdotL*causticdepth;

@ -122,7 +122,7 @@
#define REFL_BUMP 0.08 // reflection 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 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 +
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
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 +
normal4 * SMALL_WAVES_X*0.1 + normal5 * SMALL_WAVES_Y*0.1).xzy;
lNormal = normalize(float3(lNormal.x * BUMP, lNormal.y, lNormal.z * BUMP));
normal4 * SMALL_WAVES_X*0.1 + normal5 * SMALL_WAVES_Y*0.1).xyz;
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 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
float3 pNormal = float3(0,1,0);
float3 pNormal = float3(0,0,1);
float3 lR = reflect(lVec, lNormal);
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)));
// 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);
fresnel = shSaturate(fresnel);
// reflection
float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb);
float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xy*REFL_BUMP)).rgb);
// refraction
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
// is actually above the water (objectDepth < waterDepth)
// 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;
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
refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction;
refraction = (cameraPos.z < 0) ? shSaturate(refraction * 1.5) : refraction;
// specular
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)));
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);

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

@ -9,7 +9,7 @@ Website: http://www.openmw.org
Font Licenses:
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)

Loading…
Cancel
Save