diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index cffbc60c7..047cea760 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows - compositors + compositors characterpreview ) add_openmw_dir (mwinput diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 19405fb7a..5ecd1b1b9 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -271,6 +271,8 @@ namespace MWBase virtual void togglePlayerLooking(bool enable) = 0; virtual void renderPlayer() = 0; + + virtual void updateCharacterPreview(int sizeX, int sizeY) = 0; }; } diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 6dc19944f..cf23ecd8f 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -48,6 +48,7 @@ namespace MWGui static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); getWidget(mAvatar, "Avatar"); + getWidget(mAvatarImage, "AvatarImage"); getWidget(mEncumbranceBar, "EncumbranceBar"); getWidget(mEncumbranceText, "EncumbranceBarT"); getWidget(mFilterAll, "AllButton"); @@ -100,6 +101,13 @@ namespace MWGui _sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15, _sender->getSize().height-44 ); drawItems(); + + MyGUI::IntSize size = mAvatarImage->getSize(); + + std::cout << "dims " << size.width << " " << size.height << std::endl; + MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); + + mAvatarImage->setImageCoord (MyGUI::IntCoord(0,0,size.width, size.height)); } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) @@ -171,14 +179,7 @@ namespace MWGui drawItems(); - // update selected weapon icon - MWWorld::InventoryStore& invStore = MWWorld::Class::get(mPtr).getInventoryStore(mPtr); - MWWorld::ContainerStoreIterator weaponSlot = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if (weaponSlot == invStore.end()) - mWindowManager.unsetSelectedWeapon(); - else - mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability - + notifyContentChanged(); } } @@ -265,6 +266,10 @@ namespace MWGui mWindowManager.unsetSelectedWeapon(); else mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability + + MyGUI::IntSize size = mAvatarImage->getSize(); + mAvatarImage->setImageCoord (MyGUI::IntCoord(0,0,size.width, size.height)); + MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); } void InventoryWindow::pickUpObject (MWWorld::Ptr object) diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index fbdb79977..4a385dd71 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -24,6 +24,7 @@ namespace MWGui protected: MyGUI::Widget* mAvatar; + MyGUI::ImageBox* mAvatarImage; MyGUI::TextBox* mArmorRating; MyGUI::ProgressBar* mEncumbranceBar; MyGUI::TextBox* mEncumbranceText; diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp new file mode 100644 index 000000000..3d3f0a58d --- /dev/null +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -0,0 +1,52 @@ +#include "characterpreview.hpp" + + +#include +#include + + +#include "renderconst.hpp" + +namespace MWRender +{ + + CharacterPreview::CharacterPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node) + : mSceneMgr(sceneMgr) + { + mCamera = mSceneMgr->createCamera ("CharacterPreviewCamera"); + mCamera->setAspectRatio (0.5); + + mNode = node->createChildSceneNode (); + mNode->attachObject (mCamera); + + mNode->setPosition(0, 185, 70); + mNode->roll(Ogre::Degree(180)); + + mNode->pitch(Ogre::Degree(90)); + + mTexture = Ogre::TextureManager::getSingleton().createManual("CharacterPreview", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 1024, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); + + mRenderTarget = mTexture->getBuffer()->getRenderTarget(); + mViewport = mRenderTarget->addViewport(mCamera); + mViewport->setOverlaysEnabled(false); + mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); + mViewport->setShadowsEnabled(false); + mViewport->setMaterialScheme("local_map"); + mViewport->setVisibilityMask (RV_Player); + mRenderTarget->setActive(true); + mRenderTarget->setAutoUpdated (false); + } + + void CharacterPreview::update(int sizeX, int sizeY) + { + bool wasVisible = mNode->getParentSceneNode()->getAttachedObject(0)->getVisible (); + mNode->getParentSceneNode()->setVisible(true, false); + //mViewport->setDimensions (0, 0, float(sizeX) / float(512), float(sizeY) / float(1024)); + + mRenderTarget->update(); + + mNode->getParentSceneNode()->setVisible(wasVisible, false); + } + +} diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp new file mode 100644 index 000000000..e15d6c359 --- /dev/null +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -0,0 +1,29 @@ +#ifndef MWRENDER_CHARACTERPREVIEW_H +#define MWRENDER_CHARACTERPREVIEW_H + +#include + +namespace MWRender +{ + + class CharacterPreview + { + public: + CharacterPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node); + + void update(int sizeX, int sizeY); + + private: + Ogre::TexturePtr mTexture; + Ogre::RenderTarget* mRenderTarget; + Ogre::Viewport* mViewport; + + Ogre::Camera* mCamera; + + Ogre::SceneManager* mSceneMgr; + Ogre::SceneNode* mNode; + }; + +} + +#endif diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 4f98aebc4..392a79c96 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -45,7 +45,7 @@ NpcAnimation::~NpcAnimation() } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv) +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, bool player) : Animation(_rend), mStateID(-1), mInv(_inv), timeToChange(0), robe(mInv.end()), helmet(mInv.end()), shirt(mInv.end()), cuirass(mInv.end()), greaves(mInv.end()), @@ -53,6 +53,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere boots(mInv.end()), leftglove(mInv.end()), rightglove(mInv.end()), skirtiter(mInv.end()), pants(mInv.end()) + , mIsPlayer(player) { MWWorld::LiveCellRef *ref = ptr.get(); @@ -94,7 +95,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere { Ogre::Entity *base = mEntityList.mEntities[i]; - base->setVisibilityFlags(RV_Actors); + base->setVisibilityFlags(mIsPlayer ? RV_Player : RV_Actors); bool transparent = false; for(unsigned int j=0;j < base->getNumSubEntities();++j) { @@ -357,13 +358,13 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, con mInsert, mesh); std::vector &parts = entities.mEntities; for(size_t i = 0;i < parts.size();i++) - parts[i]->setVisibilityFlags(RV_Actors); + parts[i]->setVisibilityFlags(mIsPlayer ? RV_Player : RV_Actors); return entities; } void NpcAnimation::runAnimation(float timepassed) { - if(timeToChange > .2) + //if(timeToChange > .2) { timeToChange = 0; updateParts(); diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index d4b2a5b9e..945dd210e 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -18,6 +18,8 @@ private: int mPartslots[27]; //Each part slot is taken by clothing, armor, or is empty int mPartPriorities[27]; + bool mIsPlayer; + //Bounded Parts NifOgre::EntityList lclavicle; NifOgre::EntityList rclavicle; @@ -66,7 +68,7 @@ private: MWWorld::ContainerStoreIterator skirtiter; public: - NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); + NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, bool player=false); virtual ~NpcAnimation(); NifOgre::EntityList insertBoundedPart(const std::string &mesh, const std::string &bonename); virtual void runAnimation(float timepassed); diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 9f57833bb..194ca9da6 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -41,7 +41,7 @@ enum VisibilityFlags // Water RV_Water = 8, - // Actors (player, npcs, creatures) + // Actors (npcs, creatures) RV_Actors = 16, // Misc objects (containers, dynamic objects) @@ -54,6 +54,8 @@ enum VisibilityFlags RV_OcclusionQuery = 256, + RV_Player = 512, + RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water /// \todo markers (normally hidden) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 70d7de552..acb587d03 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -34,6 +34,7 @@ #include "water.hpp" #include "compositors.hpp" #include "npcanimation.hpp" +#include "characterpreview.hpp" using namespace MWRender; using namespace Ogre; @@ -159,6 +160,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mDebugging = new Debugging(mMwRoot, engine); mLocalMap = new MWRender::LocalMap(&mRendering, this); + mCharacterPreview = new CharacterPreview(mRendering.getScene (), playerNode); + setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); } @@ -175,6 +178,7 @@ RenderingManager::~RenderingManager () delete mOcclusionQuery; delete mCompositors; delete mWater; + delete mCharacterPreview; } MWRender::SkyManager* RenderingManager::getSkyManager() @@ -860,7 +864,7 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) new MWRender::NpcAnimation( ptr, mRendering, - MWWorld::Class::get(ptr).getInventoryStore(ptr) + MWWorld::Class::get(ptr).getInventoryStore(ptr), true ); mPlayer->setAnimation(anim); } @@ -882,4 +886,9 @@ bool RenderingManager::isPositionExplored (float nX, float nY, int x, int y, boo return mLocalMap->isPositionExplored(nX, nY, x, y, interior); } +void RenderingManager::updateCharacterPreview (int sizeX, int sizeY) +{ + mCharacterPreview->update(sizeX, sizeY); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index e5be238bd..fe79c9400 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -43,6 +43,7 @@ namespace MWRender class LocalMap; class Water; class Compositors; + class CharacterPreview; class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { @@ -191,6 +192,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior); ///< see MWRender::LocalMap::isPositionExplored + void updateCharacterPreview(int sizeX, int sizeY); + protected: virtual void windowResized(Ogre::RenderWindow* rw); virtual void windowClosed(Ogre::RenderWindow* rw); @@ -213,6 +216,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList TerrainManager* mTerrainManager; + CharacterPreview* mCharacterPreview; + MWRender::Water *mWater; OEngine::Render::OgreRenderer &mRendering; diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index 3d9f13243..fc28f1cb9 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -111,7 +111,7 @@ void Shadows::recreate() sh::Factory::getInstance ().setSharedParameter ("shadowFar_fadeStart", sh::makeProperty(shadowFar_fadeStart)); // Set visibility mask for the shadow render textures - int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows") + int visibilityMask = (RV_Actors + RV_Player) * Settings::Manager::getBool("actor shadows", "Shadows") + (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows") + RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows"); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 7100540fc..6a3eeb509 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -332,7 +332,7 @@ void Water::applyVisibilityMask() mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") - + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") + + (RV_Actors + RV_Player) * Settings::Manager::getBool("reflect actors", "Water") + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + RV_Sky; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 869ce94d1..f88f5c320 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1222,4 +1222,9 @@ namespace MWWorld { mRendering->renderPlayer(mPlayer->getPlayer()); } + + void World::updateCharacterPreview (int sizeX, int sizeY) + { + mRendering->updateCharacterPreview(sizeX, sizeY); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 6279343d4..5e8bc697e 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -307,6 +307,8 @@ namespace MWWorld } virtual void renderPlayer(); + + virtual void updateCharacterPreview(int sizeX, int sizeY); }; } diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 1ffabe3b6..b9e14fffa 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -12,8 +12,12 @@ - - + + + + + +