mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-30 02:56:44 +00:00 
			
		
		
		
	Merge branch 'master' of git://github.com/zinnschlag/openmw
This commit is contained in:
		
						commit
						f717fe0254
					
				
					 37 changed files with 300 additions and 202 deletions
				
			
		|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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 (); | ||||||
|  |  | ||||||
|  | @ -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()); | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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 { | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  |  | ||||||
|  | @ -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()) | ||||||
|  |  | ||||||
|  | @ -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]; | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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)); | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -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)); | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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
 | ||||||
|  |  | ||||||
							
								
								
									
										62
									
								
								credits.txt
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								credits.txt
									
									
									
									
									
								
							|  | @ -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. | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue