1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-04 05:45:35 +00:00

Merge remote-tracking branch 'upstream/master' into launcherui

This commit is contained in:
Pieter van der Kloet 2013-03-02 23:01:53 +01:00
commit a3c5c868ec
94 changed files with 1183 additions and 1196 deletions

View file

@ -74,7 +74,6 @@ set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
set(OENGINE_OGRE set(OENGINE_OGRE
${LIBDIR}/openengine/ogre/renderer.cpp ${LIBDIR}/openengine/ogre/renderer.cpp
${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp
${LIBDIR}/openengine/ogre/selectionbuffer.cpp ${LIBDIR}/openengine/ogre/selectionbuffer.cpp
) )
set(OENGINE_GUI set(OENGINE_GUI
@ -297,7 +296,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
"${OpenMW_BINARY_DIR}/openmw.cfg.install") "${OpenMW_BINARY_DIR}/openmw.cfg.install")
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (NOT WIN32 AND NOT APPLE)
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
"${OpenMW_BINARY_DIR}/openmw.desktop") "${OpenMW_BINARY_DIR}/openmw.desktop")
endif() endif()
@ -378,7 +377,7 @@ if(WIN32)
"${OpenMW_SOURCE_DIR}/readme.txt" "${OpenMW_SOURCE_DIR}/readme.txt"
"${OpenMW_SOURCE_DIR}/GPL3.txt" "${OpenMW_SOURCE_DIR}/GPL3.txt"
"${OpenMW_SOURCE_DIR}/OFL.txt" "${OpenMW_SOURCE_DIR}/OFL.txt"
"${OpenMW_SOURCE_DIR}/Bitstream Vera License.txt" "${OpenMW_SOURCE_DIR}/DejaVu Font License.txt"
"${OpenMW_SOURCE_DIR}/Daedric Font License.txt" "${OpenMW_SOURCE_DIR}/Daedric Font License.txt"
"${OpenMW_BINARY_DIR}/launcher.qss" "${OpenMW_BINARY_DIR}/launcher.qss"
"${OpenMW_BINARY_DIR}/settings-default.cfg" "${OpenMW_BINARY_DIR}/settings-default.cfg"
@ -389,7 +388,7 @@ if(WIN32)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
SET(CPACK_GENERATOR "NSIS") SET(CPACK_GENERATOR "NSIS")
SET(CPACK_PACKAGE_NAME "OpenMW ${OPENMW_VERSION}") SET(CPACK_PACKAGE_NAME "OpenMW")
SET(CPACK_PACKAGE_VENDOR "OpenMW.org") SET(CPACK_PACKAGE_VENDOR "OpenMW.org")
SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
@ -404,7 +403,7 @@ if(WIN32)
SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/readme.txt") SET(CPACK_RESOURCE_FILE_README "${OpenMW_SOURCE_DIR}/readme.txt")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW") SET(CPACK_NSIS_DISPLAY_NAME "OpenMW ${OPENMW_VERSION}")
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org") SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org") SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe") SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
@ -657,10 +656,18 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
# Install binaries # Install binaries
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" ) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" ) IF(BUILD_LAUNCHER)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" ) INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" ) ENDIF(BUILD_LAUNCHER)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" ) IF(BUILD_ESMTOOL)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
ENDIF(BUILD_ESMTOOL)
IF(BUILD_MWINIIMPORTER)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
ENDIF(BUILD_MWINIIMPORTER)
IF(BUILD_OPENCS)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" )
ENDIF(BUILD_OPENCS)
# Install icon and .desktop # Install icon and .desktop
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "${ICONDIR}") INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "${ICONDIR}")
@ -674,5 +681,7 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
# Install resources # Install resources
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" ) INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${DATADIR}/resources" ) IF(BUILD_LAUNCHER)
INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${DATADIR}/resources" )
ENDIF(BUILD_LAUNCHER)
endif(NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE) endif(NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)

View file

@ -26,11 +26,11 @@ add_openmw_dir (mwinput
add_openmw_dir (mwgui add_openmw_dir (mwgui
text_input widgets race class birth review windowmanagerimp console dialogue text_input widgets race class birth review windowmanagerimp console dialogue
dialogue_history window_base stats_window messagebox journalwindow charactercreation dialogue_history window_base stats_window messagebox journalwindow charactercreation
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list map_window window_pinnable_base tooltips scrollwindow bookwindow list
formatting inventorywindow container hud countdialog tradewindow settingswindow formatting inventorywindow container hud countdialog tradewindow settingswindow
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue

View file

@ -18,7 +18,6 @@
#include "mwinput/inputmanagerimp.hpp" #include "mwinput/inputmanagerimp.hpp"
#include "mwgui/windowmanagerimp.hpp" #include "mwgui/windowmanagerimp.hpp"
#include "mwgui/cursorreplace.hpp"
#include "mwscript/scriptmanagerimp.hpp" #include "mwscript/scriptmanagerimp.hpp"
#include "mwscript/extensions.hpp" #include "mwscript/extensions.hpp"
@ -333,9 +332,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
loadBSA(); loadBSA();
// cursor replacer (converts the cursor from the bsa so they can be used by mygui)
MWGui::CursorReplace replacer;
// Create the world // Create the world
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins, mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins,
mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoder, mFallbackMap, mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoder, mFallbackMap,

View file

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

View file

@ -2,6 +2,7 @@
#include "dialoguemanagerimp.hpp" #include "dialoguemanagerimp.hpp"
#include <cctype> #include <cctype>
#include <cstdlib>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
@ -251,8 +252,12 @@ namespace MWDialogue
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
if (const ESM::DialInfo *info = filter.search (dialogue, true)) std::vector<const ESM::DialInfo *> infos = filter.list (dialogue, true, true);
if (!infos.empty())
{ {
const ESM::DialInfo* info = infos[std::rand() % infos.size()];
parseText (info->mResponse); parseText (info->mResponse);
if (dialogue.mType==ESM::Dialogue::Persuasion) if (dialogue.mType==ESM::Dialogue::Persuasion)

View file

@ -289,7 +289,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
case SelectWrapper::Function_PcGender: case SelectWrapper::Function_PcGender:
return player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female ? 0 : 1; return player.get<ESM::NPC>()->mBase->isMale() ? 0 : 1;
case SelectWrapper::Function_PcClothingModifier: case SelectWrapper::Function_PcClothingModifier:
{ {
@ -559,8 +559,21 @@ MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedTo
: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer) : mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
{} {}
const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const
{ {
std::vector<const ESM::DialInfo *> suitableInfos = list (dialogue, fallbackToInfoRefusal, false);
if (suitableInfos.empty())
return NULL;
else
return suitableInfos[0];
}
std::vector<const ESM::DialInfo *> MWDialogue::Filter::list (const ESM::Dialogue& dialogue,
bool fallbackToInfoRefusal, bool searchAll) const
{
std::vector<const ESM::DialInfo *> infos;
bool infoRefusal = false; bool infoRefusal = false;
// Iterate over topic responses to find a matching one // Iterate over topic responses to find a matching one
@ -569,14 +582,17 @@ const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
{ {
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter)) if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
{ {
if (testDisposition (*iter)) if (testDisposition (*iter)) {
return &*iter; infos.push_back(&*iter);
if (!searchAll)
break;
}
else else
infoRefusal = true; infoRefusal = true;
} }
} }
if (infoRefusal && fallbackToInfoRefusal) if (infos.empty() && infoRefusal && fallbackToInfoRefusal)
{ {
// No response is valid because of low NPC disposition, // No response is valid because of low NPC disposition,
// search a response in the topic "Info Refusal" // search a response in the topic "Info Refusal"
@ -588,11 +604,14 @@ const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue,
for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin(); for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin();
iter!=infoRefusalDialogue.mInfo.end(); ++iter) iter!=infoRefusalDialogue.mInfo.end(); ++iter)
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter)) if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter)) {
return &*iter; infos.push_back(&*iter);
if (!searchAll)
break;
}
} }
return 0; return infos;
} }
bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const

View file

@ -1,6 +1,8 @@
#ifndef GAME_MWDIALOGUE_FILTER_H #ifndef GAME_MWDIALOGUE_FILTER_H
#define GAME_MWDIALOGUE_FILTER_H #define GAME_MWDIALOGUE_FILTER_H
#include <vector>
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
namespace ESM namespace ESM
@ -51,7 +53,10 @@ namespace MWDialogue
Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
const ESM::DialInfo *search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; std::vector<const ESM::DialInfo *> list (const ESM::Dialogue& dialogue,
bool fallbackToInfoRefusal, bool searchAll) const;
const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
///< Get a matching response for the requested dialogue. ///< Get a matching response for the requested dialogue.
/// Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition. /// Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition.

View file

@ -0,0 +1,130 @@
#include "cursor.hpp"
#include <MyGUI_PointerManager.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_RenderManager.h>
#include <MyGUI_RotatingSkin.h>
#include <MyGUI_Gui.h>
#include <OgreMath.h>
namespace MWGui
{
ResourceImageSetPointerFix::ResourceImageSetPointerFix() :
mImageSet(nullptr)
{
}
ResourceImageSetPointerFix::~ResourceImageSetPointerFix()
{
}
void ResourceImageSetPointerFix::deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version)
{
Base::deserialization(_node, _version);
MyGUI::xml::ElementEnumerator info = _node->getElementEnumerator();
while (info.next("Property"))
{
const std::string& key = info->findAttribute("key");
const std::string& value = info->findAttribute("value");
if (key == "Point")
mPoint = MyGUI::IntPoint::parse(value);
else if (key == "Size")
mSize = MyGUI::IntSize::parse(value);
else if (key == "Rotation")
mRotation = MyGUI::utility::parseInt(value);
else if (key == "Resource")
mImageSet = MyGUI::ResourceManager::getInstance().getByName(value)->castType<MyGUI::ResourceImageSet>();
}
}
int ResourceImageSetPointerFix::getRotation()
{
return mRotation;
}
void ResourceImageSetPointerFix::setImage(MyGUI::ImageBox* _image)
{
if (mImageSet != nullptr)
_image->setItemResourceInfo(mImageSet->getIndexInfo(0, 0));
}
void ResourceImageSetPointerFix::setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point)
{
_image->setCoord(_point.left - mPoint.left, _point.top - mPoint.top, mSize.width, mSize.height);
}
MyGUI::ResourceImageSetPtr ResourceImageSetPointerFix:: getImageSet()
{
return mImageSet;
}
MyGUI::IntPoint ResourceImageSetPointerFix::getHotSpot()
{
return mPoint;
}
MyGUI::IntSize ResourceImageSetPointerFix::getSize()
{
return mSize;
}
// ----------------------------------------------------------------------------------------
Cursor::Cursor()
{
// hide mygui's pointer since we're rendering it ourselves (because mygui's pointer doesn't support rotation)
MyGUI::PointerManager::getInstance().setVisible(false);
MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &Cursor::onCursorChange);
mWidget = MyGUI::Gui::getInstance().createWidget<MyGUI::ImageBox>("RotatingSkin",0,0,0,0,MyGUI::Align::Default,"Pointer","");
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
}
Cursor::~Cursor()
{
}
void Cursor::onCursorChange(const std::string &name)
{
ResourceImageSetPointerFix* imgSetPtr = dynamic_cast<ResourceImageSetPointerFix*>(
MyGUI::PointerManager::getInstance().getByName(name));
assert(imgSetPtr != NULL);
MyGUI::ResourceImageSet* imgSet = imgSetPtr->getImageSet();
std::string texture = imgSet->getIndexInfo(0,0).texture;
mSize = imgSetPtr->getSize();
mHotSpot = imgSetPtr->getHotSpot();
int rotation = imgSetPtr->getRotation();
mWidget->setImageTexture(texture);
MyGUI::ISubWidget* main = mWidget->getSubWidgetMain();
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
rotatingSubskin->setCenter(MyGUI::IntPoint(mSize.width/2,mSize.height/2));
rotatingSubskin->setAngle(Ogre::Degree(rotation).valueRadians());
}
void Cursor::update()
{
MyGUI::IntPoint position = MyGUI::InputManager::getInstance().getMousePosition();
mWidget->setPosition(position - mHotSpot);
mWidget->setSize(mSize);
}
void Cursor::setVisible(bool visible)
{
mWidget->setVisible(visible);
}
}

View file

@ -0,0 +1,62 @@
#ifndef MWGUI_CURSOR_H
#define MWGUI_CURSOR_H
#include <MyGUI_IPointer.h>
#include <MyGUI_ResourceImageSet.h>
#include <MyGUI_RTTI.h>
namespace MWGui
{
/// \brief Allows us to get the members of
/// ResourceImageSetPointer that we need.
/// \example MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
/// MyGUI::ResourceManager::getInstance().load("core.xml");
class ResourceImageSetPointerFix :
public MyGUI::IPointer
{
MYGUI_RTTI_DERIVED( ResourceImageSetPointerFix )
public:
ResourceImageSetPointerFix();
virtual ~ResourceImageSetPointerFix();
virtual void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version);
virtual void setImage(MyGUI::ImageBox* _image);
virtual void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point);
//and now for the whole point of this class, allow us to get
//the hot spot, the image and the size of the cursor.
virtual MyGUI::ResourceImageSetPtr getImageSet();
virtual MyGUI::IntPoint getHotSpot();
virtual MyGUI::IntSize getSize();
virtual int getRotation();
private:
MyGUI::IntPoint mPoint;
MyGUI::IntSize mSize;
MyGUI::ResourceImageSetPtr mImageSet;
int mRotation; // rotation in degrees
};
class Cursor
{
public:
Cursor();
~Cursor();
void update ();
void setVisible (bool visible);
void onCursorChange (const std::string& name);
private:
MyGUI::ImageBox* mWidget;
MyGUI::IntSize mSize;
MyGUI::IntPoint mHotSpot;
};
}
#endif

View file

@ -1,16 +0,0 @@
#include "cursorreplace.hpp"
#include <boost/filesystem.hpp>
#include <openengine/ogre/imagerotate.hpp>
#include <OgreResourceGroupManager.h>
#include <OgreRoot.h>
using namespace MWGui;
CursorReplace::CursorReplace()
{
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90);
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize1.png", -45);
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45);
}

View file

@ -1,16 +0,0 @@
#ifndef GAME_CURSORREPLACE_H
#define GAME_CURSORREPLACE_H
#include <string>
namespace MWGui
{
/// \brief MyGUI does not support rotating cursors, so we have to do it manually
class CursorReplace
{
public:
CursorReplace();
};
}
#endif

View file

@ -106,7 +106,7 @@ namespace MWGui
float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading); float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading);
assert(progress <= 1 && progress >= 0); assert(progress <= 1 && progress >= 0);
mLoadingText->setCaption(stage + "... "); mLoadingText->setCaption(stage);
mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000)); mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000));
static float loadingScreenFps = 30.f; static float loadingScreenFps = 30.f;

View file

@ -5,6 +5,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
namespace MWGui namespace MWGui
{ {
@ -65,6 +66,7 @@ namespace MWGui
void MainMenu::onButtonClicked(MyGUI::Widget *sender) void MainMenu::onButtonClicked(MyGUI::Widget *sender)
{ {
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
if (sender == mButtons["return"]) if (sender == mButtons["return"])
MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu); MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu);
else if (sender == mButtons["options"]) else if (sender == mButtons["options"])

View file

@ -6,6 +6,8 @@
#include <OgreTextureManager.h> #include <OgreTextureManager.h>
#include <OgreSceneNode.h> #include <OgreSceneNode.h>
#include <MyGUI_Gui.h>
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -13,6 +15,8 @@
#include "../mwrender/globalmap.hpp" #include "../mwrender/globalmap.hpp"
#include "widgets.hpp"
using namespace MWGui; using namespace MWGui;
LocalMapBase::LocalMapBase() LocalMapBase::LocalMapBase()
@ -88,7 +92,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"
@ -96,6 +100,7 @@ void LocalMapBase::applyFogOfWar()
: ""); : "");
} }
} }
notifyMapChanged ();
} }
void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2) void LocalMapBase::onMarkerFocused (MyGUI::Widget* w1, MyGUI::Widget* w2)
@ -127,7 +132,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 +178,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 +399,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();
@ -425,3 +430,17 @@ void MapWindow::notifyPlayerUpdate ()
{ {
globalMapUpdatePlayer (); globalMapUpdatePlayer ();
} }
void MapWindow::notifyMapChanged ()
{
// workaround to prevent the map from drawing on top of the button
MyGUI::IntCoord oldCoord = mButton->getCoord ();
MyGUI::Gui::getInstance().destroyWidget (mButton);
mButton = mMainWidget->createWidget<MWGui::Widgets::AutoSizedButton>("MW_Button",
oldCoord, MyGUI::Align::Bottom | MyGUI::Align::Right);
mButton->setProperty ("ExpandDirection", "Left");
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" :
"#{sWorld}");
}

View file

@ -50,6 +50,7 @@ namespace MWGui
void onMarkerUnfocused(MyGUI::Widget* w1, MyGUI::Widget* w2); void onMarkerUnfocused(MyGUI::Widget* w1, MyGUI::Widget* w2);
virtual void notifyPlayerUpdate() {} virtual void notifyPlayerUpdate() {}
virtual void notifyMapChanged() {}
OEngine::GUI::Layout* mLayout; OEngine::GUI::Layout* mLayout;
@ -99,6 +100,8 @@ namespace MWGui
virtual void onPinToggled(); virtual void onPinToggled();
virtual void notifyPlayerUpdate(); virtual void notifyPlayerUpdate();
virtual void notifyMapChanged();
}; };
} }
#endif #endif

View file

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

View file

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

View file

@ -95,31 +95,46 @@ namespace MWGui
// http://www.uesp.net/wiki/Lore:Calendar // http://www.uesp.net/wiki/Lore:Calendar
std::string month; std::string month;
int m = MWBase::Environment::get().getWorld ()->getMonth (); int m = MWBase::Environment::get().getWorld ()->getMonth ();
if (m == 0) switch (m) {
month = "#{sMonthMorningstar}"; case 0:
else if (m == 1) month = "#{sMonthMorningstar}";
month = "#{sMonthSunsdawn}"; break;
else if (m == 2) case 1:
month = "#{sMonthFirstseed}"; month = "#{sMonthSunsdawn}";
else if (m == 3) break;
month = "#{sMonthRainshand}"; case 2:
else if (m == 4) month = "#{sMonthFirstseed}";
month = "#{sMonthSecondseed}"; break;
else if (m == 5) case 3:
month = "#{sMonthMidyear}"; month = "#{sMonthRainshand}";
else if (m == 6) break;
month = "#{sMonthSunsheight}"; case 4:
else if (m == 7) month = "#{sMonthSecondseed}";
month = "#{sMonthLastseed}"; break;
else if (m == 8) case 5:
month = "#{sMonthHeartfire}"; month = "#{sMonthMidyear}";
else if (m == 9) break;
month = "#{sMonthFrostfall}"; case 6:
else if (m == 10) month = "#{sMonthSunsheight}";
month = "#{sMonthSunsdusk}"; break;
else if (m == 11) case 7:
month = "#{sMonthEveningstar}"; month = "#{sMonthLastseed}";
break;
case 8:
month = "#{sMonthHeartfire}";
break;
case 9:
month = "#{sMonthFrostfall}";
break;
case 10:
month = "#{sMonthSunsdusk}";
break;
case 11:
month = "#{sMonthEveningstar}";
break;
default:
break;
}
int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour (); int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour ();
bool pm = hour >= 12; bool pm = hour >= 12;
if (hour >= 13) hour -= 12; if (hour >= 13) hour -= 12;

View file

@ -53,6 +53,7 @@
#include "trainingwindow.hpp" #include "trainingwindow.hpp"
#include "imagebutton.hpp" #include "imagebutton.hpp"
#include "exposedwindow.hpp" #include "exposedwindow.hpp"
#include "cursor.hpp"
using namespace MWGui; using namespace MWGui;
@ -130,6 +131,9 @@ WindowManager::WindowManager(
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ImageButton>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ImageButton>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget"); MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
MyGUI::ResourceManager::getInstance().load("core.xml");
MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag); MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
// Get size info from the Gui object // Get size info from the Gui object
@ -178,6 +182,8 @@ WindowManager::WindowManager(
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows",""); mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
mCursor = new Cursor();
// The HUD is always on // The HUD is always on
mHud->setVisible(true); mHud->setVisible(true);
@ -236,6 +242,7 @@ WindowManager::~WindowManager()
delete mTrainingWindow; delete mTrainingWindow;
delete mCountDialog; delete mCountDialog;
delete mQuickKeysMenu; delete mQuickKeysMenu;
delete mCursor;
cleanupGarbage(); cleanupGarbage();
@ -262,6 +269,8 @@ void WindowManager::update()
mHud->setFPS(mFPS); mHud->setFPS(mFPS);
mHud->setTriangleCount(mTriangleCount); mHud->setTriangleCount(mTriangleCount);
mHud->setBatchCount(mBatchCount); mHud->setBatchCount(mBatchCount);
mCursor->update();
} }
void WindowManager::updateVisible() void WindowManager::updateVisible()
@ -293,7 +302,7 @@ void WindowManager::updateVisible()
mHud->setVisible(true); mHud->setVisible(true);
// Mouse is visible whenever we're not in game mode // Mouse is visible whenever we're not in game mode
MyGUI::PointerManager::getInstance().setVisible(isGuiMode()); mCursor->setVisible(isGuiMode());
bool gameMode = !isGuiMode(); bool gameMode = !isGuiMode();
@ -421,13 +430,19 @@ void WindowManager::updateVisible()
break; break;
case GM_LoadingWallpaper: case GM_LoadingWallpaper:
mHud->setVisible(false); mHud->setVisible(false);
MyGUI::PointerManager::getInstance().setVisible(false); mCursor->setVisible(false);
break; break;
case GM_Loading: case GM_Loading:
MyGUI::PointerManager::getInstance().setVisible(false); // Show the pinned windows
mMap->setVisible(mMap->pinned());
mStatsWindow->setVisible(mStatsWindow->pinned());
mInventoryWindow->setVisible(mInventoryWindow->pinned());
mSpellWindow->setVisible(mSpellWindow->pinned());
mCursor->setVisible(false);
break; break;
case GM_Video: case GM_Video:
MyGUI::PointerManager::getInstance().setVisible(false); mCursor->setVisible(false);
mHud->setVisible(false); mHud->setVisible(false);
break; break;
default: default:
@ -749,7 +764,7 @@ void WindowManager::setSpellVisibility(bool visible)
void WindowManager::setMouseVisible(bool visible) void WindowManager::setMouseVisible(bool visible)
{ {
MyGUI::PointerManager::getInstance().setVisible(visible); mCursor->setVisible(visible);
} }
void WindowManager::setDragDrop(bool dragDrop) void WindowManager::setDragDrop(bool dragDrop)

View file

@ -72,6 +72,7 @@ namespace MWGui
class SpellCreationDialog; class SpellCreationDialog;
class EnchantingDialog; class EnchantingDialog;
class TrainingWindow; class TrainingWindow;
class Cursor;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
{ {
@ -260,6 +261,7 @@ namespace MWGui
EnchantingDialog* mEnchantingDialog; EnchantingDialog* mEnchantingDialog;
TrainingWindow* mTrainingWindow; TrainingWindow* mTrainingWindow;
Translation::Storage& mTranslationDataStorage; Translation::Storage& mTranslationDataStorage;
Cursor* mCursor;
CharacterCreation* mCharGen; CharacterCreation* mCharGen;

View file

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

View file

@ -31,20 +31,18 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
Ogre::Entity *ent = mEntityList.mEntities[i]; Ogre::Entity *ent = mEntityList.mEntities[i];
bool transparent = false; bool transparent = false;
for (unsigned int j=0;j < ent->getNumSubEntities() && !transparent; ++j) for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
{ {
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial(); Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements() && !transparent) while(!transparent && techIt.hasMoreElements())
{ {
Ogre::Technique* tech = techIt.getNext(); Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator(); Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements() && !transparent) while(!transparent && passIt.hasMoreElements())
{ {
Ogre::Pass* pass = passIt.getNext(); Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
} }
} }
} }

View file

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

View file

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

View file

@ -53,8 +53,6 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
if(!mEntityList.mSkelBase) if(!mEntityList.mSkelBase)
return; return;
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
mCurrentAnim = NULL; mCurrentAnim = NULL;
mCurrentKeys = NULL; mCurrentKeys = NULL;
mAnimVelocity = 0.0f; mAnimVelocity = 0.0f;
@ -62,19 +60,14 @@ void Animation::setAnimationSources(const std::vector<std::string> &names)
mNonAccumRoot = NULL; mNonAccumRoot = NULL;
mSkeletonSources.clear(); mSkeletonSources.clear();
std::vector<std::string>::const_iterator nameiter = names.begin(); std::vector<std::string>::const_iterator nameiter;
for(nameiter = names.begin();nameiter != names.end();nameiter++) for(nameiter = names.begin();nameiter != names.end();nameiter++)
{ {
Ogre::SkeletonPtr skel = skelMgr.getByName(*nameiter); Ogre::SkeletonPtr skel = NifOgre::Loader::getSkeleton(*nameiter);
if(skel.isNull()) if(skel.isNull())
{ {
NifOgre::Loader::createSkeleton(*nameiter); std::cerr<< "Failed to get skeleton source "<<*nameiter <<std::endl;
skel = skelMgr.getByName(*nameiter); continue;
if(skel.isNull())
{
std::cerr<< "Failed to get skeleton source "<<*nameiter <<std::endl;
continue;
}
} }
skel->touch(); skel->touch();

View file

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

View file

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

View file

@ -32,20 +32,18 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
ent->setVisibilityFlags(RV_Actors); ent->setVisibilityFlags(RV_Actors);
bool transparent = false; bool transparent = false;
for (unsigned int j=0;j < ent->getNumSubEntities() && !transparent; ++j) for(unsigned int j=0;!transparent && j < ent->getNumSubEntities(); ++j)
{ {
Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial(); Ogre::MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements() && !transparent) while(!transparent && techIt.hasMoreElements())
{ {
Ogre::Technique* tech = techIt.getNext(); Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator(); Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements() && !transparent) while(!transparent && passIt.hasMoreElements())
{ {
Ogre::Pass* pass = passIt.getNext(); Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
} }
} }
} }

View file

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

View file

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

View file

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

View file

@ -28,9 +28,6 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag
mCellCamera = mRendering->getScene()->createCamera("CellCamera"); mCellCamera = mRendering->getScene()->createCamera("CellCamera");
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC); mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
// look down -y
const float sqrt0pt5 = 0.707106781;
mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
mCameraNode->attachObject(mCellCamera); mCameraNode->attachObject(mCellCamera);
} }
@ -82,8 +79,8 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
} }
else else
{ {
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z); Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
Vector2 length = max-min; Vector2 length = max-min;
// divide into segments // divide into segments
@ -107,6 +104,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
mInterior = false; mInterior = false;
mCameraRotNode->setOrientation(Quaternion::IDENTITY); mCameraRotNode->setOrientation(Quaternion::IDENTITY);
mCellCamera->setOrientation(Quaternion(Ogre::Math::Cos(Ogre::Degree(0)/2.f), 0, 0, -Ogre::Math::Sin(Ogre::Degree(0)/2.f)));
int x = cell->mCell->getGridX(); int x = cell->mCell->getGridX();
int y = cell->mCell->getGridY(); int y = cell->mCell->getGridY();
@ -115,49 +113,60 @@ 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,
AxisAlignedBox bounds) AxisAlignedBox bounds)
{ {
// if we're in an empty cell, don't bother rendering anything
if (bounds.isNull ())
return;
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(mAngle/2.f), 0, 0, -Math::Sin(mAngle/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); // apply a little padding
mBounds.scale ((mBounds.getSize ()+Ogre::Vector3(1000,1000,0)) / mBounds.getSize ());
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 center(mBounds.getCenter().x, mBounds.getCenter().y);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().y);
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().y);
Vector2 length = max-min; 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 +181,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 +202,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 +281,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 +320,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 +346,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 +355,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 +382,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
if (!affected) if (!affected)
continue; continue;
std::string texName = texBaseName + coordStr(x+mx,y+my*intExtMult); std::string texName = texBaseName + coordStr(x+mx,y+my*-1);
TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog"); TexturePtr tex = TextureManager::getSingleton().getByName(texName+"_fog");
if (!tex.isNull()) if (!tex.isNull())

View file

@ -107,19 +107,18 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
base->setVisibilityFlags(mVisibilityFlags); base->setVisibilityFlags(mVisibilityFlags);
bool transparent = false; bool transparent = false;
for(unsigned int j=0;j < base->getNumSubEntities();++j) for(unsigned int j=0;!transparent && j < base->getNumSubEntities();++j)
{ {
Ogre::MaterialPtr mat = base->getSubEntity(j)->getMaterial(); Ogre::MaterialPtr mat = base->getSubEntity(j)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements()) while(!transparent && techIt.hasMoreElements())
{ {
Ogre::Technique* tech = techIt.getNext(); Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator(); Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements()) while(!transparent && passIt.hasMoreElements())
{ {
Ogre::Pass* pass = passIt.getNext(); Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false) transparent = pass->isTransparent();
transparent = true;
} }
} }
} }
@ -322,8 +321,26 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int
std::vector<Ogre::Entity*> &parts = entities.mEntities; std::vector<Ogre::Entity*> &parts = entities.mEntities;
for(size_t i = 0;i < parts.size();i++) for(size_t i = 0;i < parts.size();i++)
{ {
parts[i]->setVisibilityFlags(mVisibilityFlags);
parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group)); parts[i]->getUserObjectBindings().setUserAny(Ogre::Any(group));
parts[i]->setVisibilityFlags(mVisibilityFlags);
bool transparent = false;
for(unsigned int j=0;!transparent && j < parts[i]->getNumSubEntities();++j)
{
Ogre::MaterialPtr mat = parts[i]->getSubEntity(j)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
}
}
}
parts[i]->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
} }
if(entities.mSkelBase) if(entities.mSkelBase)
{ {

View file

@ -57,14 +57,14 @@ void Objects::clearSceneNode (Ogre::SceneNode *node)
} }
} }
void Objects::setMwRoot(Ogre::SceneNode* root) void Objects::setRootNode(Ogre::SceneNode* root)
{ {
mMwRoot = root; mRootNode = root;
} }
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_) void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
{ {
Ogre::SceneNode* root = mMwRoot; Ogre::SceneNode* root = mRootNode;
Ogre::SceneNode* cellnode; Ogre::SceneNode* cellnode;
if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end()) if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
{ {
@ -113,12 +113,8 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool
Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL;
NifOgre::EntityList entities = NifOgre::Loader::createEntities(insert, mesh); NifOgre::EntityList entities = NifOgre::Loader::createEntities(insert, mesh);
for(size_t i = 0;i < entities.mEntities.size();i++) for(size_t i = 0;i < entities.mEntities.size();i++)
{ bounds.merge(entities.mEntities[i]->getWorldBoundingBox(true));
const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox();
bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(),
insert->_getDerivedPosition() + tmp.getMaximum())
);
}
Ogre::Vector3 extents = bounds.getSize(); Ogre::Vector3 extents = bounds.getSize();
extents *= insert->getScale(); extents *= insert->getScale();
float size = std::max(std::max(extents.x, extents.y), extents.z); float size = std::max(std::max(extents.x, extents.y), extents.z);
@ -134,23 +130,21 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool
mBounds[ptr.getCell()].merge(bounds); mBounds[ptr.getCell()].merge(bounds);
bool transparent = false; bool transparent = false;
for(size_t i = 0;i < entities.mEntities.size();i++) for(size_t i = 0;!transparent && i < entities.mEntities.size();i++)
{ {
Ogre::Entity *ent = entities.mEntities[i]; Ogre::Entity *ent = entities.mEntities[i];
for (unsigned int i=0; i<ent->getNumSubEntities(); ++i) for(unsigned int i=0;!transparent && i < ent->getNumSubEntities(); ++i)
{ {
Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements()) while(!transparent && techIt.hasMoreElements())
{ {
Ogre::Technique* tech = techIt.getNext(); Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator(); Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements()) while(!transparent && passIt.hasMoreElements())
{ {
Ogre::Pass* pass = passIt.getNext(); Ogre::Pass* pass = passIt.getNext();
transparent = pass->isTransparent();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
} }
} }
} }
@ -390,9 +384,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 +399,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 +454,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 +544,7 @@ void Objects::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
MWWorld::CellStore *newCell = cur.getCell(); MWWorld::CellStore *newCell = cur.getCell();
if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) { if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
node = mMwRoot->createChildSceneNode(); node = mRootNode->createChildSceneNode();
mCellSceneNodes[newCell] = node; mCellSceneNodes[newCell] = node;
} else { } else {
node = mCellSceneNodes[newCell]; node = mCellSceneNodes[newCell];

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -27,13 +27,10 @@ namespace
{ {
const MWWorld::Class& class_ = const MWWorld::Class& class_ =
MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.mList.begin(), &cell)); MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.mList.begin(), &cell));
size_t numRefs = cellRefList.mList.size();
int current = 0; int current = 0;
for (typename T::List::iterator it = cellRefList.mList.begin(); for (typename T::List::iterator it = cellRefList.mList.begin();
it != cellRefList.mList.end(); it++) it != cellRefList.mList.end(); it++)
{ {
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, current, numRefs);
++current; ++current;
if (it->mData.getCount() || it->mData.isEnabled()) if (it->mData.getCount() || it->mData.isEnabled())
@ -55,10 +52,6 @@ namespace
} }
} }
} }
else
{
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, 0, 1);
}
} }
} }
@ -176,12 +169,18 @@ namespace MWWorld
void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos)
{ {
Nif::NIFFile::CacheLock cachelock; Nif::NIFFile::CacheLock cachelock;
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
mRendering.preCellChange(mCurrentCell); mRendering.preCellChange(mCurrentCell);
// remove active // remove active
MWBase::Environment::get().getMechanicsManager()->remove(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); MWBase::Environment::get().getMechanicsManager()->remove(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
std::string loadingExteriorText;
loadingExteriorText = gmst.find ("sLoadingMessage3")->getString();
CellStoreCollection::iterator active = mActiveCells.begin(); CellStoreCollection::iterator active = mActiveCells.begin();
// get the number of cells to unload // get the number of cells to unload
@ -216,8 +215,6 @@ namespace MWWorld
continue; continue;
} }
} }
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload);
unloadCell (active++); unloadCell (active++);
++current; ++current;
} }
@ -266,7 +263,9 @@ namespace MWWorld
{ {
CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y); CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(x, y);
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, current, numLoad); //Loading Exterior loading text
MWBase::Environment::get().getWindowManager ()->setLoadingProgress (loadingExteriorText, 0, current, numLoad);
loadCell (cell); loadCell (cell);
++current; ++current;
} }
@ -325,6 +324,13 @@ namespace MWWorld
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
{ {
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
std::string loadingInteriorText;
loadingInteriorText = gmst.find ("sLoadingMessage2")->getString();
CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName); CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
bool loadcell = (mCurrentCell == NULL); bool loadcell = (mCurrentCell == NULL);
if(!loadcell) if(!loadcell)
@ -360,8 +366,6 @@ namespace MWWorld
active = mActiveCells.begin(); active = mActiveCells.begin();
while (active!=mActiveCells.end()) while (active!=mActiveCells.end())
{ {
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload);
unloadCell (active++); unloadCell (active++);
++current; ++current;
} }
@ -369,7 +373,9 @@ namespace MWWorld
// Load cell. // Load cell.
std::cout << "cellName: " << cell->mCell->mName << std::endl; std::cout << "cellName: " << cell->mCell->mName << std::endl;
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 0, 0, 1); //Loading Interior loading text
MWBase::Environment::get().getWindowManager ()->setLoadingProgress (loadingInteriorText, 0, 0, 1);
loadCell (cell); loadCell (cell);
mCurrentCell = cell; mCurrentCell = cell;

View file

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

View file

@ -2,7 +2,7 @@
macro (add_openmw_dir dir) macro (add_openmw_dir dir)
set (files) set (files)
foreach (u ${ARGN}) foreach (u ${ARGN})
file (GLOB ALL ${CMAKE_CURRENT_SOURCE_DIR} "${dir}/${u}.[ch]pp") file (GLOB ALL "${dir}/${u}.[ch]pp")
foreach (f ${ALL}) foreach (f ${ALL})
list (APPEND files "${f}") list (APPEND files "${f}")
list (APPEND OPENMW_FILES "${f}") list (APPEND OPENMW_FILES "${f}")
@ -14,7 +14,7 @@ endmacro (add_openmw_dir)
macro (add_component_dir dir) macro (add_component_dir dir)
set (files) set (files)
foreach (u ${ARGN}) foreach (u ${ARGN})
file (GLOB ALL ${CMAKE_CURRENT_SOURCE_DIR} "${dir}/${u}.[ch]pp") file (GLOB ALL "${dir}/${u}.[ch]pp")
foreach (f ${ALL}) foreach (f ${ALL})
list (APPEND files "${f}") list (APPEND files "${f}")
list (APPEND COMPONENT_FILES "${f}") list (APPEND COMPONENT_FILES "${f}")
@ -26,12 +26,12 @@ endmacro (add_component_dir)
macro (add_component_qt_dir dir) macro (add_component_qt_dir dir)
set (files) set (files)
foreach (u ${ARGN}) foreach (u ${ARGN})
file (GLOB ALL ${CMAKE_CURRENT_SOURCE_DIR} "${dir}/${u}.[ch]pp") file (GLOB ALL "${dir}/${u}.[ch]pp")
foreach (f ${ALL}) foreach (f ${ALL})
list (APPEND files "${f}") list (APPEND files "${f}")
list (APPEND COMPONENT_FILES "${f}") list (APPEND COMPONENT_FILES "${f}")
endforeach (f) endforeach (f)
file (GLOB MOC_H ${CMAKE_CURRENT_SOURCE_DIR} "${dir}/${u}.hpp") file (GLOB MOC_H "${dir}/${u}.hpp")
foreach (fi ${MOC_H}) foreach (fi ${MOC_H})
list (APPEND COMPONENT_MOC_FILES "${fi}") list (APPEND COMPONENT_MOC_FILES "${fi}")
endforeach (fi) endforeach (fi)

View file

@ -77,8 +77,7 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
// Get the header // Get the header
getHNT(mCtx.header, "HEDR", 300); getHNT(mCtx.header, "HEDR", 300);
if (mCtx.header.version != VER_12 && mCtx.header.version != VER_13) // Some mods abuse the header.version field for the version of the mod instead of the version of the file format, so we can only ignore it.
fail("Unsupported file format version");
while (isNextSub("MAST")) while (isNextSub("MAST"))
{ {

View file

@ -37,14 +37,14 @@ public:
*************************************************************************/ *************************************************************************/
int getVer() const { return mCtx.header.version; } int getVer() const { return mCtx.header.version; }
float getFVer() { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; } float getFVer() const { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; }
int getSpecial() { return mSpf; } int getSpecial() const { return mSpf; }
int getType() { return mCtx.header.type; } int getType() const { return mCtx.header.type; }
const std::string getAuthor() { return mCtx.header.author.toString(); } const std::string getAuthor() const { return mCtx.header.author.toString(); }
const std::string getDesc() { return mCtx.header.desc.toString(); } const std::string getDesc() const { return mCtx.header.desc.toString(); }
const SaveData &getSaveData() const { return mSaveData; } const SaveData &getSaveData() const { return mSaveData; }
const MasterList &getMasters() { return mMasters; } const MasterList &getMasters() const { return mMasters; }
const NAME &retSubName() { return mCtx.subName; } const NAME &retSubName() const { return mCtx.subName; }
uint32_t getSubSize() const { return mCtx.leftSub; } uint32_t getSubSize() const { return mCtx.leftSub; }
/************************************************************************* /*************************************************************************

View file

@ -7,12 +7,27 @@ namespace ESM
{ {
void Apparatus::load(ESMReader &esm) void Apparatus::load(ESMReader &esm)
{ {
mModel = esm.getHNString("MODL"); // we will not treat duplicated subrecords as errors here
mName = esm.getHNString("FNAM"); while (esm.hasMoreSubs())
esm.getHNT(mData, "AADT", 16); {
mScript = esm.getHNOString("SCRI"); esm.getSubName();
mIcon = esm.getHNString("ITEX"); NAME subName = esm.retSubName();
if (subName == "MODL")
mModel = esm.getHString();
else if (subName == "FNAM")
mName = esm.getHString();
else if (subName == "AADT")
esm.getHT(mData);
else if (subName == "SCRI")
mScript = esm.getHString();
else if (subName == "ITEX")
mIcon = esm.getHString();
else
esm.fail("wrong subrecord type " + subName.toString() + " for APPA record");
}
} }
void Apparatus::save(ESMWriter &esm) void Apparatus::save(ESMWriter &esm)
{ {
esm.writeHNCString("MODL", mModel); esm.writeHNCString("MODL", mModel);

View file

@ -112,8 +112,8 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
// instead. // instead.
if (mData.mFlags & QuasiEx) if (mData.mFlags & QuasiEx)
mRegion = esm.getHNOString("RGNN"); mRegion = esm.getHNOString("RGNN");
else else if (esm.isNextSub("AMBI"))
esm.getHNT(mAmbi, "AMBI", 16); esm.getHT(mAmbi);
} }
else else
{ {

View file

@ -1,25 +1,3 @@
/**
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
* engine implementation.
*
* Copyright (C) 2011 Open Morrowind Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file components/files/fixedpath.hpp */
#ifndef COMPONENTS_FILES_FIXEDPATH_HPP #ifndef COMPONENTS_FILES_FIXEDPATH_HPP
#define COMPONENTS_FILES_FIXEDPATH_HPP #define COMPONENTS_FILES_FIXEDPATH_HPP

View file

@ -1,25 +1,3 @@
/**
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
* engine implementation.
*
* Copyright (C) 2011 Open Morrowind Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file components/files/linuxpath.cpp */
#include "linuxpath.hpp" #include "linuxpath.hpp"
#if defined(__linux__) || defined(__FreeBSD__) #if defined(__linux__) || defined(__FreeBSD__)

View file

@ -1,25 +1,3 @@
/**
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
* engine implementation.
*
* Copyright (C) 2011 Open Morrowind Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file components/files/linuxpath.hpp */
#ifndef COMPONENTS_FILES_LINUXPATH_H #ifndef COMPONENTS_FILES_LINUXPATH_H
#define COMPONENTS_FILES_LINUXPATH_H #define COMPONENTS_FILES_LINUXPATH_H

View file

@ -1,25 +1,3 @@
/**
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
* engine implementation.
*
* Copyright (C) 2011 Open Morrowind Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file components/files/macospath.cpp */
#include "macospath.hpp" #include "macospath.hpp"
#if defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) #if defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__)

View file

@ -1,25 +1,3 @@
/**
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
* engine implementation.
*
* Copyright (C) 2011 Open Morrowind Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file components/files/macospath.hpp */
#ifndef COMPONENTS_FILES_MACOSPATH_H #ifndef COMPONENTS_FILES_MACOSPATH_H
#define COMPONENTS_FILES_MACOSPATH_H #define COMPONENTS_FILES_MACOSPATH_H

View file

@ -1,25 +1,3 @@
/**
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
* engine implementation.
*
* Copyright (C) 2011 Open Morrowind Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file components/files/ogreplugin.hpp */
#ifndef COMPONENTS_FILES_OGREPLUGIN_H #ifndef COMPONENTS_FILES_OGREPLUGIN_H
#define COMPONENTS_FILES_OGREPLUGIN_H #define COMPONENTS_FILES_OGREPLUGIN_H

View file

@ -1,25 +1,3 @@
/**
* Open Morrowind - an opensource Elder Scrolls III: Morrowind
* engine implementation.
*
* Copyright (C) 2011 Open Morrowind Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \file components/files/windowspath.hpp */
#ifndef COMPONENTS_FILES_WINDOWSPATH_HPP #ifndef COMPONENTS_FILES_WINDOWSPATH_HPP
#define COMPONENTS_FILES_WINDOWSPATH_HPP #define COMPONENTS_FILES_WINDOWSPATH_HPP

View file

@ -142,20 +142,18 @@ public:
{ {
ShapeData::read(nif); ShapeData::read(nif);
int tris = nif->getUShort(); /*int tris =*/ nif->getUShort();
if(tris)
{ // We have three times as many vertices as triangles, so this
// We have three times as many vertices as triangles, so this // is always equal to tris*3.
// is always equal to tris*3. int cnt = nif->getInt();
int cnt = nif->getInt(); nif->getShorts(triangles, cnt);
nif->getShorts(triangles, cnt);
}
// Read the match list, which lists the vertices that are equal to // Read the match list, which lists the vertices that are equal to
// vertices. We don't actually need need this for anything, so // vertices. We don't actually need need this for anything, so
// just skip it. // just skip it.
int verts = nif->getUShort(); int verts = nif->getUShort();
for(int i=0;i<verts;i++) for(int i=0;i < verts;i++)
{ {
// Number of vertices matching vertex 'i' // Number of vertices matching vertex 'i'
int num = nif->getUShort(); int num = nif->getUShort();

View file

@ -220,11 +220,10 @@ void NIFFile::parse()
for(size_t i = 0;i < recNum;i++) for(size_t i = 0;i < recNum;i++)
{ {
std::string rec = getString();
//cout << i << ": " << rec.toString() << endl;
Record *r = NULL; Record *r = NULL;
std::string rec = getString();
/* These are all the record types we know how to read. /* These are all the record types we know how to read.
This can be heavily optimized later if needed. For example, a This can be heavily optimized later if needed. For example, a
@ -256,6 +255,7 @@ void NIFFile::parse()
else if(rec == "NiDitherProperty") { r = new NiDitherProperty; r->recType = RC_NiDitherProperty; } else if(rec == "NiDitherProperty") { r = new NiDitherProperty; r->recType = RC_NiDitherProperty; }
else if(rec == "NiWireframeProperty") { r = new NiWireframeProperty; r->recType = RC_NiWireframeProperty; } else if(rec == "NiWireframeProperty") { r = new NiWireframeProperty; r->recType = RC_NiWireframeProperty; }
else if(rec == "NiSpecularProperty") { r = new NiSpecularProperty; r->recType = RC_NiSpecularProperty; } else if(rec == "NiSpecularProperty") { r = new NiSpecularProperty; r->recType = RC_NiSpecularProperty; }
else if(rec == "NiStencilProperty") { r = new NiStencilProperty; r->recType = RC_NiStencilProperty; }
// Controllers // Controllers
else if(rec == "NiVisController") { r = new NiVisController; r->recType = RC_NiVisController; } else if(rec == "NiVisController") { r = new NiVisController; r->recType = RC_NiVisController; }

View file

@ -158,6 +158,7 @@ public:
short getShort() { return read_le16(); } short getShort() { return read_le16(); }
unsigned short getUShort() { return read_le16(); } unsigned short getUShort() { return read_le16(); }
int getInt() { return read_le32(); } int getInt() { return read_le32(); }
unsigned int getUInt() { return read_le32(); }
float getFloat() { return read_le32f(); } float getFloat() { return read_le32f(); }
Ogre::Vector2 getVector2() Ogre::Vector2 getVector2()
{ {

View file

@ -257,9 +257,66 @@ struct S_AlphaProperty
} }
}; };
/*
Docs taken from:
http://niftools.sourceforge.net/doc/nif/NiStencilProperty.html
*/
struct S_StencilProperty
{
// Is stencil test enabled?
unsigned char enabled;
/*
0 TEST_NEVER
1 TEST_LESS
2 TEST_EQUAL
3 TEST_LESS_EQUAL
4 TEST_GREATER
5 TEST_NOT_EQUAL
6 TEST_GREATER_EQUAL
7 TEST_ALWAYS
*/
int compareFunc;
unsigned stencilRef;
unsigned stencilMask;
/*
Stencil test fail action, depth test fail action and depth test pass action:
0 ACTION_KEEP
1 ACTION_ZERO
2 ACTION_REPLACE
3 ACTION_INCREMENT
4 ACTION_DECREMENT
5 ACTION_INVERT
*/
int failAction;
int zFailAction;
int zPassAction;
/*
Face draw mode:
0 DRAW_CCW_OR_BOTH
1 DRAW_CCW [default]
2 DRAW_CW
3 DRAW_BOTH
*/
int drawMode;
void read(NIFFile *nif)
{
enabled = nif->getChar();
compareFunc = nif->getInt();
stencilRef = nif->getUInt();
stencilMask = nif->getUInt();
failAction = nif->getInt();
zFailAction = nif->getInt();
zPassAction = nif->getInt();
drawMode = nif->getInt();
}
};
typedef StructPropT<S_AlphaProperty> NiAlphaProperty; typedef StructPropT<S_AlphaProperty> NiAlphaProperty;
typedef StructPropT<S_MaterialProperty> NiMaterialProperty; typedef StructPropT<S_MaterialProperty> NiMaterialProperty;
typedef StructPropT<S_VertexColorProperty> NiVertexColorProperty; typedef StructPropT<S_VertexColorProperty> NiVertexColorProperty;
typedef StructPropT<S_StencilProperty> NiStencilProperty;
} // Namespace } // Namespace
#endif #endif

View file

@ -48,6 +48,7 @@ enum RecordType
RC_NiDitherProperty, RC_NiDitherProperty,
RC_NiWireframeProperty, RC_NiWireframeProperty,
RC_NiSpecularProperty, RC_NiSpecularProperty,
RC_NiStencilProperty,
RC_NiVisController, RC_NiVisController,
RC_NiGeomMorpherController, RC_NiGeomMorpherController,
RC_NiKeyframeController, RC_NiKeyframeController,

View file

@ -452,7 +452,8 @@ void loadResource(Ogre::Resource *resource)
} }
} }
bool createSkeleton(const std::string &name, const std::string &group, const Nif::Node *node)
static Ogre::SkeletonPtr createSkeleton(const std::string &name, const std::string &group, const Nif::Node *node)
{ {
/* We need to be a little aggressive here, since some NIFs have a crap-ton /* We need to be a little aggressive here, since some NIFs have a crap-ton
* of nodes and Ogre only supports 256 bones. We will skip a skeleton if: * of nodes and Ogre only supports 256 bones. We will skip a skeleton if:
@ -463,7 +464,7 @@ bool createSkeleton(const std::string &name, const std::string &group, const Nif
if(!node->boneTrafo) if(!node->boneTrafo)
{ {
if(node->recType == Nif::RC_NiTriShape) if(node->recType == Nif::RC_NiTriShape)
return false; return Ogre::SkeletonPtr();
if(node->controller.empty() && node->name != "AttachLight") if(node->controller.empty() && node->name != "AttachLight")
{ {
if(node->recType == Nif::RC_NiNode || node->recType == Nif::RC_RootCollisionNode) if(node->recType == Nif::RC_NiNode || node->recType == Nif::RC_RootCollisionNode)
@ -474,67 +475,61 @@ bool createSkeleton(const std::string &name, const std::string &group, const Nif
{ {
if(!children[i].empty()) if(!children[i].empty())
{ {
if(createSkeleton(name, group, children[i].getPtr())) Ogre::SkeletonPtr skel = createSkeleton(name, group, children[i].getPtr());
return true; if(!skel.isNull())
return skel;
} }
} }
return false; return Ogre::SkeletonPtr();
} }
} }
} }
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton(); Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
skelMgr.create(name, group, true, &sLoaders[name]); return skelMgr.create(name, group, true, &sLoaders[name]);
return true;
} }
}; };
NIFSkeletonLoader::LoaderMap NIFSkeletonLoader::sLoaders; NIFSkeletonLoader::LoaderMap NIFSkeletonLoader::sLoaders;
// Conversion of blend / test mode from NIF -> OGRE. // Conversion of blend / test mode from NIF
// Not in use yet, so let's comment it out. static const char *getBlendFactor(int mode)
/*
static SceneBlendFactor getBlendFactor(int mode)
{ {
switch(mode) switch(mode)
{ {
case 0: return SBF_ONE; case 0: return "one";
case 1: return SBF_ZERO; case 1: return "zero";
case 2: return SBF_SOURCE_COLOUR; case 2: return "src_colour";
case 3: return SBF_ONE_MINUS_SOURCE_COLOUR; case 3: return "one_minus_src_colour";
case 4: return SBF_DEST_COLOUR; case 4: return "dest_colour";
case 5: return SBF_ONE_MINUS_DEST_COLOUR; case 5: return "one_minus_dest_colour";
case 6: return SBF_SOURCE_ALPHA; case 6: return "src_alpha";
case 7: return SBF_ONE_MINUS_SOURCE_ALPHA; case 7: return "one_minus_src_alpha";
case 8: return SBF_DEST_ALPHA; case 8: return "dest_alpha";
case 9: return SBF_ONE_MINUS_DEST_ALPHA; case 9: return "one_minus_dest_alpha";
// [Comment from Chris Robinson:] Can't handle this mode? :/ case 10: return "src_alpha_saturate";
// case 10: return SBF_SOURCE_ALPHA_SATURATE;
default:
return SBF_SOURCE_ALPHA;
} }
std::cerr<< "Unexpected blend mode: "<<mode <<std::endl;
return "src_alpha";
} }
static const char *getTestMode(int mode)
// This is also unused
static CompareFunction getTestMode(int mode)
{ {
switch(mode) switch(mode)
{ {
case 0: return CMPF_ALWAYS_PASS; case 0: return "always_pass";
case 1: return CMPF_LESS; case 1: return "less";
case 2: return CMPF_EQUAL; case 2: return "equal";
case 3: return CMPF_LESS_EQUAL; case 3: return "less_equal";
case 4: return CMPF_GREATER; case 4: return "greater";
case 5: return CMPF_NOT_EQUAL; case 5: return "not_equal";
case 6: return CMPF_GREATER_EQUAL; case 6: return "greater_equal";
case 7: return CMPF_ALWAYS_FAIL; case 7: return "always_fail";
default:
return CMPF_ALWAYS_PASS;
} }
std::cerr<< "Unexpected test mode: "<<mode <<std::endl;
return "less_equal";
} }
*/
class NIFMaterialLoader { class NIFMaterialLoader {
@ -567,8 +562,8 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
Ogre::Vector3 emissive(0.0f); Ogre::Vector3 emissive(0.0f);
float glossiness = 0.0f; float glossiness = 0.0f;
float alpha = 1.0f; float alpha = 1.0f;
int alphaFlags = -1; int alphaFlags = 0;
// ubyte alphaTest = 0; int alphaTest = 0;
Ogre::String texName; Ogre::String texName;
bool vertexColour = (shape->data->colors.size() != 0); bool vertexColour = (shape->data->colors.size() != 0);
@ -592,6 +587,8 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
m = static_cast<const Nif::NiMaterialProperty*>(pr); m = static_cast<const Nif::NiMaterialProperty*>(pr);
else if (pr->recType == Nif::RC_NiAlphaProperty) else if (pr->recType == Nif::RC_NiAlphaProperty)
a = static_cast<const Nif::NiAlphaProperty*>(pr); a = static_cast<const Nif::NiAlphaProperty*>(pr);
else if (pr->recType == Nif::RC_NiStencilProperty)
/* unused */;
else else
warn("Skipped property type: "+pr->recName); warn("Skipped property type: "+pr->recName);
} }
@ -602,13 +599,18 @@ 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.
*/ */
static const char path[] = "textures\\"; static const char path[] = "textures\\";
texName = path + st->filename; texName = st->filename;
Misc::StringUtils::toLower(texName);
if(texName.compare(0, sizeof(path)-1, path) != 0)
texName = path + texName;
Ogre::String::size_type pos = texName.rfind('.'); Ogre::String::size_type pos = texName.rfind('.');
if(pos != Ogre::String::npos && texName.compare(pos, texName.length() - pos, ".dds") != 0) if(pos != Ogre::String::npos && texName.compare(pos, texName.length() - pos, ".dds") != 0)
{ {
@ -619,7 +621,12 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
// if it turns out that the above wasn't true in all cases (not for vanilla, but maybe mods) // if it turns out that the above wasn't true in all cases (not for vanilla, but maybe mods)
// verify, and revert if false (this call succeeds quickly, but fails slowly) // verify, and revert if false (this call succeeds quickly, but fails slowly)
if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName)) if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
texName = path + st->filename; {
texName = st->filename;
Misc::StringUtils::toLower(texName);
if(texName.compare(0, sizeof(path)-1, path) != 0)
texName = path + texName;
}
} }
} }
else warn("Found internal texture, ignoring."); else warn("Found internal texture, ignoring.");
@ -629,7 +636,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
if (a) if (a)
{ {
alphaFlags = a->flags; alphaFlags = a->flags;
// alphaTest = a->data.threshold; alphaTest = a->data.threshold;
} }
// Material // Material
@ -663,6 +670,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
boost::hash_combine(h, texName); boost::hash_combine(h, texName);
boost::hash_combine(h, vertexColour); boost::hash_combine(h, vertexColour);
boost::hash_combine(h, alphaFlags); boost::hash_combine(h, alphaFlags);
boost::hash_combine(h, alphaTest);
std::map<size_t,std::string>::iterator itr = MaterialMap.find(h); std::map<size_t,std::string>::iterator itr = MaterialMap.find(h);
if (itr != MaterialMap.end()) if (itr != MaterialMap.end())
@ -683,7 +691,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)));
@ -694,58 +702,37 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
instance->setProperty ("has_vertex_colour", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(true))); instance->setProperty ("has_vertex_colour", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(true)));
// Add transparency if NiAlphaProperty was present // Add transparency if NiAlphaProperty was present
if (alphaFlags != -1) NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
if (result.first)
{ {
// The 237 alpha flags are by far the most common. Check alphaFlags = (1<<9) | (6<<10); /* alpha_rejection enabled, greater_equal */
// NiAlphaProperty in nif/property.h if you need to decode alphaTest = result.second;
// other values. 237 basically means normal transparencly. }
if (alphaFlags == 237)
{ if((alphaFlags&1))
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName); {
if (result.first) std::string blend_mode;
{ blend_mode += getBlendFactor((alphaFlags>>1)&0xf);
instance->setProperty("alpha_rejection", blend_mode += " ";
sh::makeProperty<sh::StringValue>(new sh::StringValue("greater_equal " + boost::lexical_cast<std::string>(result.second)))); blend_mode += getBlendFactor((alphaFlags>>5)&0xf);
} instance->setProperty("scene_blend", sh::makeProperty(new sh::StringValue(blend_mode)));
else
{
// Enable transparency
instance->setProperty("scene_blend", sh::makeProperty<sh::StringValue>(new sh::StringValue("alpha_blend")));
instance->setProperty("depth_write", sh::makeProperty<sh::StringValue>(new sh::StringValue("off")));
}
}
else
warn("Unhandled alpha setting for texture " + texName);
} }
else else
instance->getMaterial ()->setShadowCasterMaterial ("openmw_shadowcaster_noalpha"); instance->getMaterial()->setShadowCasterMaterial("openmw_shadowcaster_noalpha");
// As of yet UNTESTED code from Chris: if((alphaFlags>>9)&1)
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
pass->setDepthCheckEnabled(true);
// Add transparency if NiAlphaProperty was present
if (alphaFlags != -1)
{ {
std::cout << "Alpha flags set!" << endl; std::string reject;
if ((alphaFlags&1)) reject += getTestMode((alphaFlags>>10)&0x7);
{ reject += " ";
pass->setDepthWriteEnabled(false); reject += Ogre::StringConverter::toString(alphaTest);
pass->setSceneBlending(getBlendFactor((alphaFlags>>1)&0xf), instance->setProperty("alpha_rejection", sh::makeProperty(new sh::StringValue(reject)));
getBlendFactor((alphaFlags>>5)&0xf));
}
else
pass->setDepthWriteEnabled(true);
if ((alphaFlags>>9)&1)
pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7),
alphaTest);
pass->setTransparentSortingEnabled(!((alphaFlags>>13)&1));
} }
*/
instance->setProperty("transparent_sorting", sh::makeProperty(new sh::StringValue(((alphaFlags>>13)&1) ?
"off" : "on")));
sh::Factory::getInstance()._ensureMaterial(matname, "Default");
return matname; return matname;
} }
@ -855,9 +842,12 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
// Set the bounding box first // Set the bounding box first
BoundsFinder bounds; BoundsFinder bounds;
bounds.add(&srcVerts[0][0], srcVerts.size()); bounds.add(&srcVerts[0][0], srcVerts.size());
// No idea why this offset is needed. It works fine without it if the if(!bounds.isValid())
// vertices weren't transformed first, but otherwise it fails later on {
// when the object is being inserted into the scene. float v[3] = { 0.0f, 0.0f, 0.0f };
bounds.add(&v[0], 1);
}
mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX()-0.5f, bounds.minY()-0.5f, bounds.minZ()-0.5f, mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX()-0.5f, bounds.minY()-0.5f, bounds.minZ()-0.5f,
bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f)); bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f));
mesh->_setBoundingSphereRadius(bounds.getRadius()); mesh->_setBoundingSphereRadius(bounds.getRadius());
@ -1031,6 +1021,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
@ -1150,10 +1144,7 @@ MeshInfoList Loader::load(const std::string &name, const std::string &group)
bool hasSkel = Ogre::SkeletonManager::getSingleton().resourceExists(name); bool hasSkel = Ogre::SkeletonManager::getSingleton().resourceExists(name);
if(!hasSkel) if(!hasSkel)
{ hasSkel = !NIFSkeletonLoader::createSkeleton(name, group, node).isNull();
NIFSkeletonLoader skelldr;
hasSkel = skelldr.createSkeleton(name, group, node);
}
NIFMeshLoader meshldr(name, group); NIFMeshLoader meshldr(name, group);
if(hasSkel) if(hasSkel)
@ -1216,14 +1207,20 @@ EntityList Loader::createEntities(Ogre::Entity *parent, const std::string &bonen
if(meshes.size() == 0) if(meshes.size() == 0)
return entitylist; return entitylist;
bool isskinned = false;
Ogre::SceneManager *sceneMgr = parentNode->getCreator(); Ogre::SceneManager *sceneMgr = parentNode->getCreator();
std::string filter = "@shape=tri "+bonename; std::string filter = "@shape=tri "+bonename;
Misc::StringUtils::toLower(filter); Misc::StringUtils::toLower(filter);
for(size_t i = 0;i < meshes.size();i++) for(size_t i = 0;i < meshes.size();i++)
{ {
Ogre::Entity *ent = sceneMgr->createEntity(meshes[i].mMeshName); Ogre::Entity *ent = sceneMgr->createEntity(meshes[i].mMeshName);
if(!entitylist.mSkelBase && ent->hasSkeleton()) if(!entitylist.mSkelBase)
entitylist.mSkelBase = ent; {
if(ent->hasSkeleton())
entitylist.mSkelBase = ent;
}
else if(!isskinned && ent->hasSkeleton())
isskinned = true;
entitylist.mEntities.push_back(ent); entitylist.mEntities.push_back(ent);
} }
@ -1231,7 +1228,7 @@ EntityList Loader::createEntities(Ogre::Entity *parent, const std::string &bonen
if(bonename.find("Left") != std::string::npos) if(bonename.find("Left") != std::string::npos)
scale.x *= -1.0f; scale.x *= -1.0f;
if(entitylist.mSkelBase) if(isskinned)
{ {
for(size_t i = 0;i < entitylist.mEntities.size();i++) for(size_t i = 0;i < entitylist.mEntities.size();i++)
{ {
@ -1263,30 +1260,35 @@ EntityList Loader::createEntities(Ogre::Entity *parent, const std::string &bonen
} }
bool Loader::createSkeleton(const std::string &name, const std::string &group) Ogre::SkeletonPtr Loader::getSkeleton(std::string name, const std::string &group)
{ {
Nif::NIFFile::ptr pnif = Nif::NIFFile::create(name); Ogre::SkeletonPtr skel;
Nif::NIFFile &nif = *pnif.get();
if(nif.numRecords() < 1) Misc::StringUtils::toLower(name);
skel = Ogre::SkeletonManager::getSingleton().getByName(name);
if(!skel.isNull())
return skel;
Nif::NIFFile::ptr nif = Nif::NIFFile::create(name);
if(nif->numRecords() < 1)
{ {
nif.warn("Found no NIF records in "+name+"."); nif->warn("Found no NIF records in "+name+".");
return false; return skel;
} }
// The first record is assumed to be the root node // The first record is assumed to be the root node
Nif::Record const *r = nif.getRecord(0); const Nif::Record *r = nif->getRecord(0);
assert(r != NULL); assert(r != NULL);
Nif::Node const *node = dynamic_cast<Nif::Node const *>(r); const Nif::Node *node = dynamic_cast<const Nif::Node*>(r);
if(node == NULL) if(node == NULL)
{ {
nif.warn("First record in "+name+" was not a node, but a "+ nif->warn("First record in "+name+" was not a node, but a "+
r->recName+"."); r->recName+".");
return false; return skel;
} }
NIFSkeletonLoader skelldr; return NIFSkeletonLoader::createSkeleton(name, group, node);
return skelldr.createSkeleton(name, group, node);
} }

View file

@ -74,7 +74,7 @@ public:
std::string name, std::string name,
const std::string &group="General"); const std::string &group="General");
static bool createSkeleton(const std::string &name, const std::string &group="General"); static Ogre::SkeletonPtr getSkeleton(std::string name, const std::string &group="General");
}; };
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,7 +9,6 @@ set(MYGUI_FILES
core.skin core.skin
core.xml core.xml
EBGaramond-Regular.ttf EBGaramond-Regular.ttf
mwgui.png
Obliviontt.zip Obliviontt.zip
openmw_alchemy_window.layout openmw_alchemy_window.layout
openmw_book.layout openmw_book.layout

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View file

@ -4,6 +4,9 @@
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 249 249" name="_Main"> <Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 249 249" name="_Main">
<!-- Edit box --> <!-- Edit box -->
<Widget type="Widget" skin="MW_Box" position="14 14 220 192" align="Stretch" name = "Client"/>
<Widget type="EditBox" skin="MW_TextBoxEdit" position="14 14 220 192" name="TextEdit" align="ALIGN_LEFT ALIGN_TOP STRETCH"> <Widget type="EditBox" skin="MW_TextBoxEdit" position="14 14 220 192" name="TextEdit" align="ALIGN_LEFT ALIGN_TOP STRETCH">
<Property key="MultiLine" value="1" /> <Property key="MultiLine" value="1" />
<Property key="VisibleVScroll" value="1" /> <Property key="VisibleVScroll" value="1" />

View file

@ -8,33 +8,52 @@
<Property key="Caption" value="Appearance"/> <Property key="Caption" value="Appearance"/>
<Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/> <Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/>
</Widget> </Widget>
<Widget type="Widget" skin="MW_Box" position="8 39 241 230"> <Widget type="Widget" skin="MW_Box" position="8 39 241 220">
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Stretch" name="PreviewImage"/> <Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Stretch" name="PreviewImage"/>
</Widget> </Widget>
<!-- Sliders --> <!-- Sliders -->
<!-- Rotation of head --> <!-- Rotation of head -->
<Widget type="ScrollBar" skin="MW_HScroll" position="8 276 241 14" name="HeadRotate"/> <Widget type="ScrollBar" skin="MW_HScroll" position="8 270 241 14" name="HeadRotate"/>
<!-- Gender choice --> <!-- Gender choice -->
<Widget type="Button" skin="MW_ScrollLeft" position="8 298 14 14" name="PrevGenderButton"/>
<Widget type="TextBox" skin="HeaderText" position="14 298 227 14" name="GenderChoiceT"> <Widget type="Widget" skin="MW_Box" position="8 298 15 14">
<Widget type="Button" skin="MW_ArrowLeft" position="3 2 10 10" align="ALIGN_LEFT ALIGN_VSTRETCH" name="PrevGenderButton"/>
</Widget>
<Widget type="TextBox" skin="HeaderText" position="14 298 227 14" name="GenderChoiceT" />
<Widget type="Widget" skin="MW_Box" position="234 298 15 14">
<Widget type="Button" skin="MW_ArrowRight" position="1 2 10 10" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="NextGenderButton"/>
</Widget> </Widget>
<Widget type="Button" skin="MW_ScrollRight" position="235 298 14 14" name="NextGenderButton"/>
<!-- Face choice --> <!-- Face choice -->
<Widget type="Button" skin="MW_ScrollLeft" position="8 320 14 14" name="PrevFaceButton"/>
<Widget type="TextBox" skin="HeaderText" position="14 320 227 14" name="FaceChoiceT"> <Widget type="Widget" skin="MW_Box" position="8 320 15 14">
<Widget type="Button" skin="MW_ArrowLeft" position="3 2 10 10" align="ALIGN_LEFT ALIGN_VSTRETCH" name="PrevFaceButton"/>
</Widget>
<Widget type="TextBox" skin="HeaderText" position="14 320 227 14" name="FaceChoiceT" />
<Widget type="Widget" skin="MW_Box" position="234 320 15 14">
<Widget type="Button" skin="MW_ArrowRight" position="1 2 10 10" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="NextFaceButton"/>
</Widget> </Widget>
<Widget type="Button" skin="MW_ScrollRight" position="235 320 14 14" name="NextFaceButton"/>
<!-- Hair choice --> <!-- Hair choice -->
<Widget type="Button" skin="MW_ScrollLeft" position="8 342 14 14" name="PrevHairButton"/>
<Widget type="TextBox" skin="HeaderText" position="14 342 227 14" name="HairChoiceT"> <Widget type="Widget" skin="MW_Box" position="8 342 15 14">
<Widget type="Button" skin="MW_ArrowLeft" position="3 2 10 10" align="ALIGN_LEFT ALIGN_VSTRETCH" name="PrevHairButton"/>
</Widget>
<Widget type="TextBox" skin="HeaderText" position="14 342 227 14" name="HairChoiceT" />
<Widget type="Widget" skin="MW_Box" position="234 342 15 14">
<Widget type="Button" skin="MW_ArrowRight" position="1 2 10 10" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="NextHairButton"/>
</Widget> </Widget>
<Widget type="Button" skin="MW_ScrollRight" position="235 342 14 14" name="NextHairButton"/>
<!-- Race --> <!-- Race -->
<Widget type="TextBox" skin="HeaderText" position="261 16 132 18" name="RaceT" align="ALIGN_LEFT ALIGN_TOP"> <Widget type="TextBox" skin="HeaderText" position="261 16 132 18" name="RaceT" align="ALIGN_LEFT ALIGN_TOP">
<Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/> <Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/>
</Widget> </Widget>
@ -42,11 +61,11 @@
</Widget> </Widget>
<!-- Spell powers --> <!-- Spell powers -->
<Widget type="TextBox" skin="HeaderText" position="261 200 132 18" name="SpellPowerT" align="ALIGN_LEFT ALIGN_TOP"> <Widget type="TextBox" skin="HeaderText" position="261 210 132 18" name="SpellPowerT" align="ALIGN_LEFT ALIGN_TOP">
<Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/> <Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/>
</Widget> </Widget>
<!-- Spell power sub-widgets will be placed here, no skin to make it invisible --> <!-- Spell power sub-widgets will be placed here, no skin to make it invisible -->
<Widget type="Widget" skin="" position="261 220 250 140" name="SpellPowerList" /> <Widget type="Widget" skin="" position="261 230 250 140" name="SpellPowerList" />
<!-- Skill bonus --> <!-- Skill bonus -->
<Widget type="TextBox" skin="HeaderText" position="403 39 159 18" name="SkillsT" align="ALIGN_LEFT ALIGN_TOP"> <Widget type="TextBox" skin="HeaderText" position="403 39 159 18" name="SkillsT" align="ALIGN_LEFT ALIGN_TOP">

View file

@ -3,13 +3,15 @@
<MyGUI type="Layout"> <MyGUI type="Layout">
<Widget type="Window" skin="MW_Window" layer="Windows" position="0 0 588 433" name="_Main"> <Widget type="Window" skin="MW_Window" layer="Windows" position="0 0 588 433" name="_Main">
<Widget type="Widget" skin="MW_Box" position="8 8 415 381" align="Stretch" name = "Client"/>
<!-- The Dialogue history --> <!-- The Dialogue history -->
<Widget type="DialogueHistory" skin="MW_TextBoxEdit" position="8 8 415 381" name="History" align="ALIGN_LEFT ALIGN_TOP ALIGN_STRETCH"> <Widget type="DialogueHistory" skin="MW_TextBoxEdit" position="13 13 405 371" name="History" align="ALIGN_LEFT ALIGN_TOP ALIGN_STRETCH">
<Property key="Static" value="true"/> <Property key="Static" value="true"/>
<Property key="WordWrap" value="true"/> <Property key="WordWrap" value="true"/>
<Property key="MultiLine" value="1" /> <Property key="MultiLine" value="1" />
<Property key="VisibleVScroll" value="1" /> <Property key="VisibleVScroll" value="1" />
<!-- invisible box for receiving mouse events --> <!-- box for receiving mouse events -->
<Widget type="Widget" skin="" position="0 0 400 375" name="EventBox" align="ALIGN_LEFT ALIGN_TOP ALIGN_STRETCH"/> <Widget type="Widget" skin="" position="0 0 400 375" name="EventBox" align="ALIGN_LEFT ALIGN_TOP ALIGN_STRETCH"/>
</Widget> </Widget>

View file

@ -1,55 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin"> <MyGUI type="Skin">
<!-- Text edit widget --> <!-- Text edit widget -->
<Skin name = "MW_TextEditClient" size = "10 10"> <Skin name = "MW_TextEditClient" size = "10 10">
<BasisSkin type="EditText" offset = "0 0 10 10" align = "Stretch"/> <BasisSkin type="EditText" offset = "0 0 10 10" align = "Stretch"/>
</Skin> </Skin>
<Skin name = "MW_TextBoxEditClient" size = "10 10"> <Skin name = "MW_TextBoxEditClient" size = "10 10">
<BasisSkin type="EditText" offset = "0 0 10 10" align = "Stretch"/> <BasisSkin type="EditText" offset = "0 0 10 10" align = "Stretch"/>
</Skin> </Skin>
<Skin name="MW_TextEdit" size="512 20" texture="mwgui.png"> <Skin name="MW_TextEdit" size="512 20">
<Property key="FontName" value = "Default"/>
<Property key="TextAlign" value = "ALIGN_LEFT ALIGN_VCENTER" />
<Property key="TextColour" value = "0.75 0.6 0.35" />
<BasisSkin type="SubSkin" offset = "0 0 512 2" align = "ALIGN_TOP ALIGN_HSTRETCH"> <!-- Input -->
<State name="normal" offset = "2 2 512 2"/>
</BasisSkin> <Property key="FontName" value = "Default"/>
<BasisSkin type="SubSkin" offset = "0 2 2 16" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "2 4 2 16"/> <Property key="TextAlign" value = "ALIGN_LEFT ALIGN_VCENTER" />
</BasisSkin>
<BasisSkin type="SubSkin" offset = "510 2 2 16" align = "ALIGN_RIGHT ALIGN_VSTRETCH"> <Property key="TextColour" value = "0.75 0.6 0.35" />
<State name="normal" offset = "512 4 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 512 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "2 20 512 2"/>
</BasisSkin>
<Child type="TextBox" skin="MW_TextEditClient" offset = "2 2 508 18" align = "Stretch" name = "Client"/> <Child type="TextBox" skin="MW_TextEditClient" offset = "2 2 508 18" align = "Stretch" name = "Client"/>
<!-- Borders -->
<Child type="Widget" skin="MW_Box" offset="0 0 512 20" align="ALIGN_STRETCH" name="Client"/>
</Skin> </Skin>
<Skin name="MW_TextBoxEdit" size="512 20" texture="mwgui.png"> <Skin name="MW_TextBoxEdit" size="512 20">
<Property key="FontName" value = "Default"/> <Property key="FontName" value = "Default"/>
<Property key="TextAlign" value = "ALIGN_LEFT ALIGN_TOP" /> <Property key="TextAlign" value = "ALIGN_LEFT ALIGN_TOP" />
<Property key="TextColour" value = "0.75 0.6 0.35" /> <Property key="TextColour" value = "0.75 0.6 0.35" />
<BasisSkin type="SubSkin" offset = "0 0 512 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "2 2 512 2"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 2 2 16" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "2 4 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "510 2 2 16" align = "ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset = "512 4 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 512 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "2 20 512 2"/>
</BasisSkin>
<Child type="TextBox" skin="MW_TextBoxEditClient" offset = "2 2 490 18" align = "Stretch" name = "Client"/> <Child type="TextBox" skin="MW_TextBoxEditClient" offset = "2 2 490 18" align = "Stretch" name = "Client"/>
<Child type="ScrollBar" skin="MW_VScroll" offset = "494 3 14 14" align = "Right VStretch" name = "VScroll"/> <Child type="ScrollBar" skin="MW_VScroll" offset = "494 3 14 14" align = "Right VStretch" name = "VScroll"/>
</Skin> </Skin>
</MyGUI> </MyGUI>

View file

@ -31,7 +31,7 @@
<Property key="TextAlign" value="Center"/> <Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/> <Property key="Caption" value="0"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="MagnitudeMinSlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="122 20 210 13" name="MagnitudeMinSlider">
<Property key="Range" value="100"/> <Property key="Range" value="100"/>
</Widget> </Widget>
@ -39,7 +39,7 @@
<Property key="TextAlign" value="Center"/> <Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/> <Property key="Caption" value="0"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 52 210 13" name="MagnitudeMaxSlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="122 52 210 13" name="MagnitudeMaxSlider">
<Property key="Range" value="100"/> <Property key="Range" value="100"/>
</Widget> </Widget>
</Widget> </Widget>
@ -56,7 +56,7 @@
<Property key="TextAlign" value="Center"/> <Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/> <Property key="Caption" value="0"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="DurationSlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="122 20 210 13" name="DurationSlider">
<Property key="Range" value="1440"/> <Property key="Range" value="1440"/>
</Widget> </Widget>
</Widget> </Widget>
@ -72,7 +72,7 @@
<Property key="TextAlign" value="Center"/> <Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/> <Property key="Caption" value="0"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="122 20 210 13" name="AreaSlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="122 20 210 13" name="AreaSlider">
<Property key="Range" value="51"/> <Property key="Range" value="51"/>
</Widget> </Widget>
</Widget> </Widget>

View file

@ -1,80 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin"> <MyGUI type="Skin">
<!-- The 'box' frame that surrounds various HUD items and other elements --> <!-- The 'box' frame that surrounds various HUD items and other elements -->
<Skin name="HUD_Box" size="40 40" texture="mwgui.png">
<BasisSkin type="TileRect" offset="0 0 39 2" align="ALIGN_TOP ALIGN_HSTRETCH"> <Skin name="HUD_Box" size="40 40">
<State name="normal" offset="4 2 38 2">
<Property key="TileSize" value="40 2"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<BasisSkin type="TileRect" offset="0 1 2 37" align="ALIGN_LEFT ALIGN_VSTRETCH"> <!-- Borders -->
<State name="normal" offset="2 26 2 36">
<Property key="TileSize" value="2 40"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<BasisSkin type="TileRect" offset="38 0 2 40" align="ALIGN_RIGHT ALIGN_VSTRETCH"> <Child type="Widget" skin="MW_Box" offset="0 0 40 40" align="ALIGN_LEFT Stretch" name="Client"/>
<State name="normal" offset="16 26 2 38">
<Property key="TileSize" value="2 40"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<BasisSkin type="TileRect" offset="0 38 39 2" align="ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset="4 20 40 2">
<Property key="TileSize" value="40 2"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<!-- The interior of the box --> <!-- The interior of the box -->
<Child type="Widget" skin="BlackBG" offset="2 2 36 36" align="ALIGN_STRETCH" name="Client"/> <Child type="Widget" skin="BlackBG" offset="2 2 36 36" align="ALIGN_STRETCH" name="Client"/>
</Skin> </Skin>
<Skin name="HUD_Box_NoTransp" size="40 40" texture="mwgui.png"> <Skin name="HUD_Box_NoTransp" size="40 40">
<BasisSkin type="TileRect" offset="0 0 39 2" align="ALIGN_TOP ALIGN_HSTRETCH"> <!-- Borders -->
<State name="normal" offset="4 2 38 2">
<Property key="TileSize" value="40 2"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<BasisSkin type="TileRect" offset="0 1 2 37" align="ALIGN_LEFT ALIGN_VSTRETCH"> <Child type="Widget" skin="MW_Box" offset="0 0 40 40" align="ALIGN_LEFT Stretch" name="Client"/>
<State name="normal" offset="2 26 2 36">
<Property key="TileSize" value="2 40"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<BasisSkin type="TileRect" offset="38 0 2 40" align="ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset="16 26 2 38">
<Property key="TileSize" value="2 40"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<BasisSkin type="TileRect" offset="0 38 39 2" align="ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset="4 20 40 2">
<Property key="TileSize" value="40 2"/>
<Property key="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</BasisSkin>
<!-- The interior of the box --> <!-- The interior of the box -->
<Child type="Widget" skin="DialogBG" offset="2 2 36 36" align="ALIGN_STRETCH" name="Client"/> <Child type="Widget" skin="DialogBG" offset="2 2 36 36" align="ALIGN_STRETCH" name="Client"/>
</Skin> </Skin>
</MyGUI> </MyGUI>

View file

@ -1,228 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin"> <MyGUI type="Skin">
<!-- scroll tracker -->
<Skin name = "MW_ScrollTrack" size = "16 20" texture="mwgui.png"> <!-- Horizontal Scrollbar -->
<BasisSkin type="SubSkin" offset = "0 0 16 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "38 24 16 2"/> <Skin name="MW_HScroll" size="90 14">
</BasisSkin> <Property key="TrackRangeMargins" value="14 14" />
<BasisSkin type="TileRect" offset="0 2 16 16" align="ALIGN_STRETCH"> <Property key="MinTrackSize" value="14" />
<State name="normal" offset="38 26 16 16"> <Property key="VerticalAlignment" value="false"/>
<Property key="MoveToClick" value="true"/>
<!-- Tracker must be last to be on top and receive mouse events -->
<Child type="Button" skin="MW_Box" offset="18 0 54 14" align="ALIGN_STRETCH" name="Background"/>
<!-- Arrows -->
<Child type="Widget" skin="MW_Box" offset="0 0 15 14" align="ALIGN_LEFT ALIGN_VSTRETCH"/>
<Child type="Button" skin="MW_ArrowLeft" offset="3 2 10 10" align="ALIGN_LEFT ALIGN_VSTRETCH" name="Start"/>
<Child type="Widget" skin="MW_Box" offset="75 0 15 14" align="ALIGN_RIGHT ALIGN_VSTRETCH"/>
<Child type="Button" skin="MW_ArrowRight" offset="76 2 10 10" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="End"/>
<!-- These are only provided to get mouse input, they should have no skin and be transparent -->
<Child type="Button" skin="MW_ScrollEmptyPart" offset="14 0 24 14" align="ALIGN_TOP ALIGN_HSTRETCH" name="FirstPart"/>
<Child type="Button" skin="MW_ScrollEmptyPart" offset="52 0 24 14" align="ALIGN_TOP ALIGN_HSTRETCH" name="SecondPart"/>
<Child type="Button" skin="MW_ScrollTrackH" offset="38 2 30 9" align="ALIGN_LEFT ALIGN_VSTRETCH" name="Track"/>
</Skin>
<Skin name="MW_ScrollTrackH" size="16 16" texture="textures\tx_menubook_bookmark.dds">
<BasisSkin type="TileRect" offset="6 0 3 16" align="Stretch">
<State name="normal" offset="70 22 16 16">
<Property key="TileSize" value="16 16"/> <Property key="TileSize" value="16 16"/>
<Property key="TileH" value="true"/> <Property key="TileH" value="true"/>
<Property key="TileV" value="true"/> <Property key="TileV" value="true"/>
</State> </State>
</BasisSkin> </BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 16 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "38 42 16 2"/>
</BasisSkin>
</Skin> </Skin>
<Skin name = "MW_ScrollTrackH" size = "12 20" texture="mwgui.png">
<BasisSkin type="SubSkin" offset = "0 0 12 2" align = "ALIGN_TOP ALIGN_HSTRETCH"> <!-- Vertical Scrollbar -->
<State name="normal" offset = "38 24 12 2"/>
</BasisSkin> <Skin name="MW_VScroll" size="14 90">
<BasisSkin type="TileRect" offset="0 2 12 16" align="ALIGN_STRETCH"> <Property key="TrackRangeMargins" value="14 14" />
<State name="normal" offset="40 26 12 16"> <Property key="MinTrackSize" value="14" />
<Property key="TileSize" value="12 16"/> <Property key="MoveToClick" value="true"/>
<!-- Background widget trick that must go first to be placed behind Track and FirstPart/SecondPart widgets, provides the bar texture -->
<Child type="Button" skin="MW_Box" offset="0 18 14 55" align="ALIGN_STRETCH" name="Background"/>
<!-- Arrows -->
<Child type="Widget" skin="MW_Box" offset="0 0 14 15" align="ALIGN_TOP ALIGN_HSTRETCH"/>
<Child type="Button" skin="MW_ArrowUp" offset="2 3 10 10" align="ALIGN_TOP ALIGN_HSTRETCH" name="Start"/>
<Child type="Widget" skin="MW_Box" offset="0 76 14 15" align="ALIGN_BOTTOM ALIGN_HSTRETCH"/>
<Child type="Button" skin="MW_ArrowDown" offset="2 77 10 10" align="ALIGN_BOTTOM ALIGN_HSTRETCH" name="End"/>
<!-- These are only provided to get mouse input, they should have no skin and be transparent -->
<Child type="Button" skin="MW_ScrollEmptyPart" offset="0 14 24 14" align="ALIGN_LEFT ALIGN_VSTRETCH" name="FirstPart"/>
<Child type="Button" skin="MW_ScrollEmptyPart" offset="0 52 24 14" align="ALIGN_LEFT ALIGN_VSTRETCH" name="SecondPart"/>
<!-- Tracker must be last to be on top and receive mouse events -->
<Child type="Button" skin="MW_ScrollTrackV" offset="2 40 9 30" align="ALIGN_TOP ALIGN_HSTRETCH" name="Track"/>
</Skin>
<Skin name="MW_ScrollTrackV" size="16 16" texture="textures\tx_menubook_bookmark.dds">
<BasisSkin type="TileRect" offset="0 7 16 3" align="Stretch">
<State name="normal" offset="68 19 16 16">
<Property key="TileSize" value="16 16"/>
<Property key="TileH" value="true"/> <Property key="TileH" value="true"/>
<Property key="TileV" value="true"/> <Property key="TileV" value="true"/>
</State> </State>
</BasisSkin> </BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 12 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "38 42 12 2"/>
</BasisSkin>
</Skin> </Skin>
<Skin name = "MW_ScrollUp" size = "16 20" texture="mwgui.png"> <!-- Empty space in scrollbar -->
<!-- border -->
<BasisSkin type="SubSkin" offset = "0 0 16 2" align = "ALIGN_TOP ALIGN_HSTRETCH"> <Skin name="MW_ScrollEmptyPart" size="16 16" >
<State name="normal" offset = "20 24 16 2"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 2 2 16" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "20 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "14 2 2 16" align = "ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset = "34 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 16 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "20 42 16 2"/>
</BasisSkin>
<!-- arrow -->
<BasisSkin type="SubSkin" offset = "2 2 12 16" align = "ALIGN_STRETCH">
<State name="normal" offset = "56 24 8 8"/>
</BasisSkin>
</Skin> </Skin>
<Skin name = "MW_ScrollDown" size = "16 20" texture="mwgui.png"> <!-- Header text -->
<!-- border -->
<BasisSkin type="SubSkin" offset = "0 0 16 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "20 24 16 2"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 2 2 16" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "20 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "14 2 2 16" align = "ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset = "34 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 16 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "20 42 16 2"/>
</BasisSkin>
<!-- arrow -->
<BasisSkin type="SubSkin" offset = "2 2 12 16" align = "ALIGN_STRETCH">
<State name="normal" offset = "56 44 8 8"/>
</BasisSkin>
</Skin>
<Skin name = "MW_ScrollLeft" size = "16 20" texture="mwgui.png"> <Skin name="HeaderText" size="16 16">
<!-- border --> <Property key="FontName" value="Default"/>
<BasisSkin type="SubSkin" offset = "0 0 16 2" align = "ALIGN_TOP ALIGN_HSTRETCH"> <Property key="TextAlign" value="ALIGN_CENTER" />
<State name="normal" offset = "20 24 16 2"/> <Property key="TextColour" value="0.82 0.74 0.58" />
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 2 2 16" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "20 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "14 2 2 16" align = "ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset = "34 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 16 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "20 42 16 2"/>
</BasisSkin>
<!-- arrow -->
<BasisSkin type="SubSkin" offset = "2 2 12 16" align = "ALIGN_STRETCH">
<State name="normal" offset = "56 54 8 8"/>
</BasisSkin>
</Skin>
<Skin name = "MW_ScrollRight" size = "16 20" texture="mwgui.png"> <BasisSkin type="SimpleText" offset="0 0 16 16" align="ALIGN_STRETCH"/>
<!-- border -->
<BasisSkin type="SubSkin" offset = "0 0 16 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "20 24 16 2"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 2 2 16" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "20 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "14 2 2 16" align = "ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset = "34 26 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 16 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "20 42 16 2"/>
</BasisSkin>
<!-- arrow -->
<BasisSkin type="SubSkin" offset = "2 2 12 16" align = "ALIGN_STRETCH">
<State name="normal" offset = "56 34 8 8"/>
</BasisSkin>
</Skin>
<Skin name = "MW_HScrollBackground" size = "512 20" texture="mwgui.png">
<BasisSkin type="SubSkin" offset = "0 0 512 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "2 2 512 2"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 2 2 16" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "2 4 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "510 2 2 16" align = "ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset = "512 4 2 16"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 18 512 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "2 20 512 2"/>
</BasisSkin>
</Skin>
<Skin name = "MW_VScrollBackground" size = "16 512" texture="mwgui.png">
<BasisSkin type="SubSkin" offset = "0 0 16 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "2 24 16 2"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 2 2 512" align = "ALIGN_LEFT ALIGN_VSTRETCH">
<State name="normal" offset = "2 26 2 512"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "14 2 2 512" align = "ALIGN_RIGHT ALIGN_VSTRETCH">
<State name="normal" offset = "16 26 2 512"/>
</BasisSkin>
<BasisSkin type="SubSkin" offset = "0 512 16 2" align = "ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset = "2 538 16 2"/>
</BasisSkin>
</Skin>
<Skin name = "MW_ScrollEmptyPart" size = "16 16" >
</Skin>
<!-- Morrowind has a 1 pixel gap between the left arrow and the inner bar, this skin does not replicate that -->
<Skin name = "MW_HScroll" size = "90 14">
<Property key="TrackRangeMargins" value = "14 14" />
<Property key="MinTrackSize" value = "14" />
<Property key="VerticalAlignment" value="false"/>
<Property key="MoveToClick" value="true"/>
<!-- Background widget trick that must go first to be placed behind Track and FirstPart/SecondPart widgets, provides the bar texture -->
<Child type="Button" skin="MW_HScrollBackground" offset = "14 0 62 14" align = "ALIGN_STRETCH" name = "Background"/>
<Child type="Button" skin="MW_ScrollLeft" offset = "0 0 14 14" align = "ALIGN_LEFT ALIGN_VSTRETCH" name = "Start"/>
<Child type="Button" skin="MW_ScrollRight" offset = "76 0 14 14" align = "ALIGN_RIGHT ALIGN_VSTRETCH" name = "End"/>
<!-- These are only provided to get mouse input, they should have no skin and be transparent -->
<Child type="Button" skin="MW_ScrollEmptyPart" offset = "14 0 24 14" align = "ALIGN_TOP ALIGN_HSTRETCH" name = "FirstPart"/>
<Child type="Button" skin="MW_ScrollEmptyPart" offset = "52 0 24 14" align = "ALIGN_TOP ALIGN_HSTRETCH" name = "SecondPart"/>
<!-- Tracker must be last to be on top and receive mouse events -->
<Child type="Button" skin="MW_ScrollTrackH" offset = "38 0 14 14" align = "ALIGN_LEFT ALIGN_VSTRETCH" name = "Track"/>
</Skin>
<!-- Morrowind has a 1 pixel gap between the left arrow and the inner bar, this skin does not replicate that -->
<Skin name = "MW_HSlider" size = "90 14">
<Property key="TrackRangeMargins" value = "14 14" />
<Property key="MinTrackSize" value = "14" />
<Property key="VerticalAlignment" value="false"/>
<Property key="MoveToClick" value="true"/>
<!-- Background widget trick that must go first to be placed behind Track and FirstPart/SecondPart widgets, provides the bar texture -->
<Child type="Button" skin="MW_HScrollBackground" offset = "14 0 62 14" align = "ALIGN_STRETCH" name = "Background"/>
<Child type="Button" skin="MW_ScrollLeft" offset = "0 0 14 14" align = "ALIGN_LEFT ALIGN_VSTRETCH" name = "Start"/>
<Child type="Button" skin="MW_ScrollRight" offset = "76 0 14 14" align = "ALIGN_RIGHT ALIGN_VSTRETCH" name = "End"/>
<!-- These are only provided to get mouse input, they should have no skin and be transparent -->
<Child type="Button" skin="MW_ScrollEmptyPart" offset = "14 0 24 14" align = "ALIGN_TOP ALIGN_HSTRETCH" name = "FirstPart"/>
<Child type="Button" skin="MW_ScrollEmptyPart" offset = "52 0 24 14" align = "ALIGN_TOP ALIGN_HSTRETCH" name = "SecondPart"/>
<!-- Tracker must be last to be on top and receive mouse events -->
<Child type="Button" skin="MW_ScrollTrackH" offset = "38 0 14 14" align = "ALIGN_LEFT ALIGN_VSTRETCH" name = "Track"/>
</Skin>
<!-- Morrowind has a 1 pixel gap between the top arrow and the inner bar, this skin does not replicate that -->
<Skin name = "MW_VScroll" size = "14 90">
<Property key="TrackRangeMargins" value = "14 14" />
<Property key="MinTrackSize" value = "14" />
<Property key="MoveToClick" value="true"/>
<!-- Background widget trick that must go first to be placed behind Track and FirstPart/SecondPart widgets, provides the bar texture -->
<Child type="Button" skin="MW_VScrollBackground" offset = "0 14 14 62" align = "ALIGN_STRETCH" name = "Background"/>
<Child type="Button" skin="MW_ScrollUp" offset = "0 0 14 14" align = "ALIGN_TOP ALIGN_HSTRETCH" name = "Start"/>
<Child type="Button" skin="MW_ScrollDown" offset = "0 76 14 14" align = "ALIGN_BOTTOM ALIGN_HSTRETCH" name = "End"/>
<!-- These are only provided to get mouse input, they should have no skin and be transparent -->
<Child type="Button" skin="MW_ScrollEmptyPart" offset = "0 14 24 14" align = "ALIGN_LEFT ALIGN_VSTRETCH" name = "FirstPart"/>
<Child type="Button" skin="MW_ScrollEmptyPart" offset = "0 52 24 14" align = "ALIGN_LEFT ALIGN_VSTRETCH" name = "SecondPart"/>
<!-- Tracker must be last to be on top and receive mouse events -->
<Child type="Button" skin="MW_ScrollTrack" offset = "0 38 14 14" align = "ALIGN_TOP ALIGN_HSTRETCH" name = "Track"/>
</Skin>
<Skin name = "HeaderText" size = "16 16">
<Property key="FontName" value = "Default"/>
<Property key="TextAlign" value = "ALIGN_CENTER" />
<Property key="TextColour" value = "0.82 0.74 0.58" />
<BasisSkin type="SimpleText" offset = "0 0 16 16" align = "ALIGN_STRETCH"/>
</Skin> </Skin>
<!-- list and multilist skins --> <!-- list and multilist skins -->
<Skin name = "MW_ListLine" size = "5 5" texture="mwgui.png">
<Property key="FontName" value = "Default" />
<Property key="TextAlign" value = "ALIGN_LEFT ALIGN_VCENTER" />
<BasisSkin type="SimpleText" offset = "2 0 1 5" align = "ALIGN_STRETCH"> <Skin name="MW_ListLine" size="5 5">
<Property key="FontName" value="Default" />
<Property key="TextAlign" value="ALIGN_LEFT ALIGN_VCENTER" />
<BasisSkin type="SimpleText" offset="2 0 1 5" align="ALIGN_STRETCH">
<State name="disabled" colour="0.70 0.57 0.33" shift="0"/> <State name="disabled" colour="0.70 0.57 0.33" shift="0"/>
<State name="normal" colour="0.70 0.57 0.33" shift="0"/> <State name="normal" colour="0.70 0.57 0.33" shift="0"/>
<State name="highlighted" colour="0.85 0.76 0.60" shift="0"/> <State name="highlighted" colour="0.85 0.76 0.60" shift="0"/>
@ -234,81 +113,85 @@
</BasisSkin> </BasisSkin>
</Skin> </Skin>
<Skin name = "MW_List" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP" texture="mwgui.png"> <Skin name="MW_List" size="516 516" align="ALIGN_LEFT ALIGN_TOP">
<Property key="NeedKey" value = "true" /> <Property key="NeedKey" value="true" />
<Property key="SkinLine" value = "MW_ListLine" /> <Property key="SkinLine" value="MW_ListLine" />
<Property key="HeightLine" value = "20" /> <Property key="HeightLine" value="20" />
<Child type="ScrollBar" skin="MW_VScroll" offset = "498 3 14 509" align = "ALIGN_RIGHT ALIGN_VSTRETCH" name = "VScroll"> <Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="ALIGN_STRETCH"/>
</Child>
<Child type="Widget" skin="" offset = "3 3 493 509" align = "ALIGN_STRETCH" name = "Client"> <Child type="ScrollBar" skin="MW_VScroll" offset="498 3 14 509" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="VScroll"/>
</Child>
<Child type="Widget" skin="IB_T" offset="2 0 512 2" align="ALIGN_TOP ALIGN_HSTRETCH"/> <Child type="Widget" skin="" offset="3 3 493 509" align="ALIGN_STRETCH" name="Client"/>
<Child type="Widget" skin="IB_B" offset="2 514 512 2" align="ALIGN_BOTTOM ALIGN_HSTRETCH"/>
<Child type="Widget" skin="IB_L" offset="0 2 2 512" align="ALIGN_LEFT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_R" offset="514 2 2 512" align="ALIGN_RIGHT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_TL" offset="0 0 2 2" align="ALIGN_TOP ALIGN_LEFT"/>
<Child type="Widget" skin="IB_TR" offset="514 0 2 2" align="ALIGN_TOP ALIGN_RIGHT"/>
<Child type="Widget" skin="IB_BL" offset="0 514 2 2" align="ALIGN_BOTTOM ALIGN_LEFT"/>
<Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="ALIGN_BOTTOM ALIGN_RIGHT"/>
</Skin>
<Skin name = "MW_SimpleList" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP" texture="mwgui.png">
<Child type="Widget" skin="" offset = "3 3 510 510" align = "ALIGN_STRETCH" name = "Client">
</Child>
<Child type="Widget" skin="IB_T" offset="2 0 512 2" align="ALIGN_TOP ALIGN_HSTRETCH"/>
<Child type="Widget" skin="IB_B" offset="2 514 512 2" align="ALIGN_BOTTOM ALIGN_HSTRETCH"/>
<Child type="Widget" skin="IB_L" offset="0 2 2 512" align="ALIGN_LEFT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_R" offset="514 2 2 512" align="ALIGN_RIGHT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_TL" offset="0 0 2 2" align="ALIGN_TOP ALIGN_LEFT"/>
<Child type="Widget" skin="IB_TR" offset="514 0 2 2" align="ALIGN_TOP ALIGN_RIGHT"/>
<Child type="Widget" skin="IB_BL" offset="0 514 2 2" align="ALIGN_BOTTOM ALIGN_LEFT"/>
<Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="ALIGN_BOTTOM ALIGN_RIGHT"/>
</Skin>
<Skin name = "MW_MultiSubList" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP">
<Property key="NeedKey" value = "true" />
<Property key="SkinLine" value = "MW_ListLine" />
<Property key="HeightLine" value = "20" />
<Child type="ScrollBar" skin="VScroll" offset = "498 3 14 509" align = "ALIGN_RIGHT ALIGN_VSTRETCH" name = "VScroll">
</Child>
<Child type="Widget" skin="Default" offset = "3 3 493 509" align = "ALIGN_STRETCH" name = "Client">
</Child>
<BasisSkin type="MainSkin" offset = "0 0 0 0" align = "ALIGN_LEFT ALIGN_TOP"/>
</Skin> </Skin>
<Skin name = "MW_MultiList" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP"> <Skin name="MW_SimpleList" size="516 516" align="ALIGN_LEFT ALIGN_TOP">
<Property key="NeedKey" value = "true" />
<Property key="SkinButton" value = "ButtonSmall" />
<Property key="_SkinButtonEmpty" value = "EditBox" />
<Property key="HeightButton" value = "20" />
<Property key="SkinList" value = "MW_MultiSubList" /> <Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="ALIGN_STRETCH"/>
<Child type="Widget" skin="" offset = "3 3 516 516" align = "ALIGN_STRETCH" name = "Client"> <Child type="Widget" skin="" offset="3 3 510 510" align="Top Left ALIGN_STRETCH" name="Client"/>
</Child>
<Child type="Widget" skin="IB_T" offset="2 0 512 2" align="ALIGN_TOP ALIGN_HSTRETCH"/>
<Child type="Widget" skin="IB_B" offset="2 514 512 2" align="ALIGN_BOTTOM ALIGN_HSTRETCH"/>
<Child type="Widget" skin="IB_L" offset="0 2 2 512" align="ALIGN_LEFT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_R" offset="514 2 2 512" align="ALIGN_RIGHT ALIGN_VSTRETCH"/>
<Child type="Widget" skin="IB_TL" offset="0 0 2 2" align="ALIGN_TOP ALIGN_LEFT"/>
<Child type="Widget" skin="IB_TR" offset="514 0 2 2" align="ALIGN_TOP ALIGN_RIGHT"/>
<Child type="Widget" skin="IB_BL" offset="0 514 2 2" align="ALIGN_BOTTOM ALIGN_LEFT"/>
<Child type="Widget" skin="IB_BR" offset="514 514 2 2" align="ALIGN_BOTTOM ALIGN_RIGHT"/>
</Skin> </Skin>
<!-- textures/menu_thin_border_top.dds --> <Skin name="MW_MultiSubList" size="516 516" align="ALIGN_LEFT ALIGN_TOP">
<Skin name = "MW_HLine" size = "512 18" texture="mwgui.png"> <Property key="NeedKey" value="true" />
<BasisSkin type="SubSkin" offset = "0 8 512 2" align = "ALIGN_TOP ALIGN_HSTRETCH"> <Property key="SkinLine" value="MW_ListLine" />
<State name="normal" offset = "20 106 512 2"/> <Property key="HeightLine" value="20" />
<Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="ALIGN_STRETCH"/>
<Child type="ScrollBar" skin="MW_VScroll" offset="498 3 14 509" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="VScroll"/>
<Child type="Widget" skin="Default" offset="3 3 493 509" align="ALIGN_STRETCH" name="Client"/>
</Skin>
<Skin name="MW_MultiList" size="516 516" align="ALIGN_LEFT ALIGN_TOP">
<Property key="NeedKey" value="true" />
<Property key="SkinButton" value="ButtonSmall" />
<Property key="_SkinButtonEmpty" value="EditBox" />
<Property key="HeightButton" value="20" />
<Property key="SkinList" value="MW_MultiSubList" />
<Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="ALIGN_STRETCH"/>
<Child type="Widget" skin="" offset="3 3 516 516" align="ALIGN_STRETCH" name="Client"/>
</Skin>
<!-- Horizontal line -->
<Skin name="MW_HLine" size="512 10" texture="textures\menu_thin_border_top.dds">
<BasisSkin type="SubSkin" offset="0 0 512 2" align="ALIGN_BOTTOM ALIGN_HSTRETCH">
<State name="normal" offset="0 0 512 2"/>
</BasisSkin> </BasisSkin>
</Skin> </Skin>
<!-- Arrows -->
<Skin name="MW_ArrowLeft" size="20 20" texture="textures\menu_scroll_left.dds">
<BasisSkin type="SubSkin" offset="0 0 19 20" align="Stretch">
<State name="normal" offset="0 0 19 20"/>
</BasisSkin>
</Skin>
<Skin name="MW_ArrowRight" size="20 20" texture="textures\menu_scroll_right.dds">
<BasisSkin type="SubSkin" offset="1 0 19 20" align="Stretch">
<State name="normal" offset="1 0 19 20"/>
</BasisSkin>
</Skin>
<Skin name="MW_ArrowUp" size="20 20" texture="textures\menu_scroll_up.dds">
<BasisSkin type="SubSkin" offset="0 0 20 19" align="Stretch">
<State name="normal" offset="0 0 20 19"/>
</BasisSkin>
</Skin>
<Skin name="MW_ArrowDown" size="20 20" texture="textures\menu_scroll_down.dds">
<BasisSkin type="SubSkin" offset="0 1 20 20" align="Stretch">
<State name="normal" offset="0 1 20 20"/>
</BasisSkin>
</Skin>
</MyGUI> </MyGUI>

View file

@ -8,7 +8,8 @@
<Widget type="Widget" skin="HUD_Box" position="0 200 300 60" align="Bottom HCenter"> <Widget type="Widget" skin="HUD_Box" position="0 200 300 60" align="Bottom HCenter">
<Widget type="AutoSizedTextBox" skin="SandText" position="20 12 260 24" name="LoadingText"> <Widget type="TextBox" skin="SandText" position="20 12 260 20" name="LoadingText">
<Property key="TextAlign" value="Center"/>
</Widget> </Widget>
<Widget type="ProgressBar" skin="MW_Progress_Loading" position="20 36 260 8" name="ProgressBar"> <Widget type="ProgressBar" skin="MW_Progress_Loading" position="20 36 260 8" name="ProgressBar">

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin"> <MyGUI type="Skin">
<Skin name="MW_MapView" size="516 516" texture="mwgui.png"> <Skin name="MW_MapView" size="516 516">
<Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/> <Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/>
<!-- invisible scroll bars, needed for setting the view offset --> <!-- invisible scroll bars, needed for setting the view offset -->

View file

@ -5,26 +5,31 @@
<Property key="Point" value="7 0"/> <Property key="Point" value="7 0"/>
<Property key="Size" value="32 32"/> <Property key="Size" value="32 32"/>
<Property key="Resource" value="ArrowPointerImage"/> <Property key="Resource" value="ArrowPointerImage"/>
<Property key="Rotation" value="0"/>
</Resource> </Resource>
<Resource type="ResourceImageSetPointer" name="hresize"> <Resource type="ResourceImageSetPointer" name="hresize">
<Property key="Point" value="16 14"/> <Property key="Point" value="16 14"/>
<Property key="Size" value="32 32"/> <Property key="Size" value="32 32"/>
<Property key="Resource" value="HResizePointerImage"/> <Property key="Resource" value="HResizePointerImage"/>
<Property key="Rotation" value="0"/>
</Resource> </Resource>
<Resource type="ResourceImageSetPointer" name="vresize"> <Resource type="ResourceImageSetPointer" name="vresize">
<Property key="Point" value="17 16"/> <Property key="Point" value="17 16"/>
<Property key="Size" value="32 32"/> <Property key="Size" value="32 32"/>
<Property key="Resource" value="VResizePointerImage"/> <Property key="Resource" value="HResizePointerImage"/>
<Property key="Rotation" value="90"/>
</Resource> </Resource>
<Resource type="ResourceImageSetPointer" name="dresize"> <Resource type="ResourceImageSetPointer" name="dresize">
<Property key="Point" value="17 15"/> <Property key="Point" value="17 15"/>
<Property key="Size" value="32 32"/> <Property key="Size" value="32 32"/>
<Property key="Resource" value="DResizePointerImage"/> <Property key="Resource" value="HResizePointerImage"/>
<Property key="Rotation" value="45"/>
</Resource> </Resource>
<Resource type="ResourceImageSetPointer" name="dresize2"> <Resource type="ResourceImageSetPointer" name="dresize2">
<Property key="Point" value="15 15"/> <Property key="Point" value="15 15"/>
<Property key="Size" value="32 32"/> <Property key="Size" value="32 32"/>
<Property key="Resource" value="DResize2PointerImage"/> <Property key="Resource" value="HResizePointerImage"/>
<Property key="Rotation" value="-45"/>
</Resource> </Resource>
<Resource type="ResourceImageSetPointer" name="drop_ground"> <Resource type="ResourceImageSetPointer" name="drop_ground">
<Property key="Point" value="0 24"/> <Property key="Point" value="0 24"/>

View file

@ -17,27 +17,6 @@
</Index> </Index>
</Group> </Group>
</Resource> </Resource>
<Resource type="ResourceImageSet" name="VResizePointerImage">
<Group name="Pointer" texture="mwpointer_vresize.png" size="32 32">
<Index name="Pointer" >
<Frame point="0 0"/>
</Index>
</Group>
</Resource>
<Resource type="ResourceImageSet" name="DResizePointerImage">
<Group name="Pointer" texture="mwpointer_dresize1.png" size="32 32">
<Index name="Pointer" >
<Frame point="o o"/>
</Index>
</Group>
</Resource>
<Resource type="ResourceImageSet" name="DResize2PointerImage">
<Group name="Pointer" texture="mwpointer_dresize2.png" size="32 32">
<Index name="Pointer" >
<Frame point="0 0"/>
</Index>
</Group>
</Resource>
<Resource type="ResourceImageSet" name="DropGroundPointerImage"> <Resource type="ResourceImageSet" name="DropGroundPointerImage">
<Group name="Pointer" texture="textures\cursor_drop_ground.dds" size="32 32"> <Group name="Pointer" texture="textures\cursor_drop_ground.dds" size="32 32">
<Index name="Pointer" > <Index name="Pointer" >

View file

@ -2,12 +2,12 @@
<MyGUI type="Skin"> <MyGUI type="Skin">
<Skin name="MW_ScrollView" size="516 516" texture="mwgui.png"> <Skin name="MW_ScrollView" size="516 516">
<Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/> <Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/>
<Child type="ScrollBar" skin="MW_VScroll" offset="498 3 14 509" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="VScroll"/> <Child type="ScrollBar" skin="MW_VScroll" offset="498 3 14 509" align="ALIGN_RIGHT ALIGN_TOP ALIGN_VSTRETCH" name="VScroll"/>
</Skin> </Skin>
<Skin name="MW_ScrollViewH" size="516 516" texture="mwgui.png"> <Skin name="MW_ScrollViewH" size="516 516">
<Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/> <Child type="Widget" skin="" offset="0 0 516 516" align="Stretch" name="Client"/>
<Child type="ScrollBar" skin="MW_HScroll" offset="3 498 509 14" align="ALIGN_LEFT ALIGN_BOTTOM ALIGN_HSTRETCH" name="HScroll"/> <Child type="ScrollBar" skin="MW_HScroll" offset="3 498 509 14" align="ALIGN_LEFT ALIGN_BOTTOM ALIGN_HSTRETCH" name="HScroll"/>
</Skin> </Skin>

View file

@ -15,7 +15,7 @@
<Widget type="TextBox" skin="NormalText" position="4 4 352 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 4 352 18" align="Left Top">
<Property key="Caption" value="#{sTransparency_Menu}"/> <Property key="Caption" value="#{sTransparency_Menu}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 28 352 18" align="Left Top" name="MenuTransparencySlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 28 352 18" align="Left Top" name="MenuTransparencySlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 52 352 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="4 52 352 18" align="Left Top">
@ -30,7 +30,7 @@
<Widget type="TextBox" skin="NormalText" position="4 78 352 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 78 352 18" align="Left Top">
<Property key="Caption" value="#{sMenu_Help_Delay}"/> <Property key="Caption" value="#{sMenu_Help_Delay}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 102 352 18" align="Left Top" name="ToolTipDelaySlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 102 352 18" align="Left Top" name="ToolTipDelaySlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 126 352 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="4 126 352 18" align="Left Top">
@ -64,35 +64,35 @@
<Widget type="TextBox" skin="NormalText" position="4 4 352 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 4 352 18" align="Left Top">
<Property key="Caption" value="#{sMaster}"/> <Property key="Caption" value="#{sMaster}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 28 352 18" align="Left Top" name="MasterVolume"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 28 352 18" align="Left Top" name="MasterVolume">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="NormalText" position="4 54 352 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 54 352 18" align="Left Top">
<Property key="Caption" value="#{sVoice}"/> <Property key="Caption" value="#{sVoice}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 78 352 18" align="Left Top" name="VoiceVolume"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 78 352 18" align="Left Top" name="VoiceVolume">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="NormalText" position="4 104 352 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 104 352 18" align="Left Top">
<Property key="Caption" value="#{sEffects}"/> <Property key="Caption" value="#{sEffects}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 128 352 18" align="Left Top" name="EffectsVolume"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 128 352 18" align="Left Top" name="EffectsVolume">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="NormalText" position="4 154 352 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 154 352 18" align="Left Top">
<Property key="Caption" value="#{sFootsteps}"/> <Property key="Caption" value="#{sFootsteps}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 178 352 18" align="Left Top" name="FootstepsVolume"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 178 352 18" align="Left Top" name="FootstepsVolume">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="NormalText" position="4 204 352 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 204 352 18" align="Left Top">
<Property key="Caption" value="#{sMusic}"/> <Property key="Caption" value="#{sMusic}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 228 352 18" align="Left Top" name="MusicVolume"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 228 352 18" align="Left Top" name="MusicVolume">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
</Widget> </Widget>
@ -117,7 +117,7 @@
<Widget type="TextBox" skin="NormalText" position="4 228 160 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 228 160 18" align="Left Top">
<Property key="Caption" value="UI cursor sensitivity"/> <Property key="Caption" value="UI cursor sensitivity"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 252 160 18" align="Left Top" name="UISensitivitySlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 252 160 18" align="Left Top" name="UISensitivitySlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 276 160 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="4 276 160 18" align="Left Top">
@ -133,7 +133,7 @@
<Widget type="TextBox" skin="NormalText" position="180 228 160 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="180 228 160 18" align="Left Top">
<Property key="Caption" value="Camera sensitivity"/> <Property key="Caption" value="Camera sensitivity"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="180 252 160 18" align="Left Top" name="CameraSensitivitySlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="180 252 160 18" align="Left Top" name="CameraSensitivitySlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="180 276 160 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="180 276 160 18" align="Left Top">
@ -192,7 +192,7 @@
<Widget type="TextBox" skin="NormalText" position="4 128 329 18" align="Left Top" name="GammaText"> <Widget type="TextBox" skin="NormalText" position="4 128 329 18" align="Left Top" name="GammaText">
<Property key="Caption" value="Gamma"/> <Property key="Caption" value="Gamma"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 152 329 18" align="Left Top" name="GammaSlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 152 329 18" align="Left Top" name="GammaSlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 176 329 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="4 176 329 18" align="Left Top">
@ -208,7 +208,7 @@
<Widget type="TextBox" skin="NormalText" position="4 198 329 18" align="Left Top" name="FovText"> <Widget type="TextBox" skin="NormalText" position="4 198 329 18" align="Left Top" name="FovText">
<Property key="Caption" value="Field of View"/> <Property key="Caption" value="Field of View"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 222 329 18" align="Left Top" name="FOVSlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 222 329 18" align="Left Top" name="FOVSlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 246 329 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="4 246 329 18" align="Left Top">
@ -233,7 +233,7 @@
<Widget type="TextBox" skin="SandText" position="0 0 300 24" align="Left Top" name="AnisotropyLabel"> <Widget type="TextBox" skin="SandText" position="0 0 300 24" align="Left Top" name="AnisotropyLabel">
<Property key="Caption" value="Anisotropy"/> <Property key="Caption" value="Anisotropy"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="0 28 150 18" align="Left Top" name="AnisotropySlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="0 28 150 18" align="Left Top" name="AnisotropySlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
</Widget> </Widget>
@ -241,7 +241,7 @@
<Widget type="TextBox" skin="NormalText" position="4 130 322 18" align="Left Top"> <Widget type="TextBox" skin="NormalText" position="4 130 322 18" align="Left Top">
<Property key="Caption" value="#{sRender_Distance}"/> <Property key="Caption" value="#{sRender_Distance}"/>
</Widget> </Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 154 322 18" align="Left Top" name="ViewDistanceSlider"> <Widget type="ScrollBar" skin="MW_HScroll" position="4 154 322 18" align="Left Top" name="ViewDistanceSlider">
<Property key="Range" value="1000000"/> <Property key="Range" value="1000000"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="4 178 332 18" align="Left Top"> <Widget type="TextBox" skin="SandText" position="4 178 332 18" align="Left Top">

View file

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

View file

@ -53,7 +53,7 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool
// Create GUI // Create GUI
mGui = new Gui(); mGui = new Gui();
mGui->initialise("core.xml"); mGui->initialise("");
} }
void MyGUIManager::shutdown() void MyGUIManager::shutdown()

View file

@ -1,88 +0,0 @@
#include "imagerotate.hpp"
#include <OgreRoot.h>
#include <OgreSceneManager.h>
#include <OgreImage.h>
#include <OgreTexture.h>
#include <OgreRenderTarget.h>
#include <OgreCamera.h>
#include <OgreTextureUnitState.h>
#include <OgreHardwarePixelBuffer.h>
using namespace Ogre;
using namespace OEngine::Render;
void ImageRotate::rotate(const std::string& sourceImage, const std::string& destImage, const float angle)
{
Root* root = Ogre::Root::getSingletonPtr();
std::string destImageRot = std::string(destImage) + std::string("_rot");
SceneManager* sceneMgr = root->createSceneManager(ST_GENERIC);
Camera* camera = sceneMgr->createCamera("ImageRotateCamera");
MaterialPtr material = MaterialManager::getSingleton().create("ImageRotateMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
TextureUnitState* tus = material->getTechnique(0)->getPass(0)->createTextureUnitState(sourceImage);
Degree deg(angle);
tus->setTextureRotate(Radian(deg.valueRadians()));
tus->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
tus->setTextureBorderColour(ColourValue(0, 0, 0, 0));
Rectangle2D* rect = new Rectangle2D(true);
rect->setCorners(-1.0, 1.0, 1.0, -1.0);
rect->setMaterial("ImageRotateMaterial");
// Render the background before everything else
rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
// Use infinite AAB to always stay visible
AxisAlignedBox aabInf;
aabInf.setInfinite();
rect->setBoundingBox(aabInf);
// Attach background to the scene
SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(rect);
// retrieve image width and height
TexturePtr sourceTexture = TextureManager::getSingleton().getByName(sourceImage);
unsigned int width = sourceTexture->getWidth();
unsigned int height = sourceTexture->getHeight();
TexturePtr destTextureRot = TextureManager::getSingleton().createManual(
destImageRot,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
width, height,
0,
PF_FLOAT16_RGBA,
TU_RENDERTARGET);
RenderTarget* rtt = destTextureRot->getBuffer()->getRenderTarget();
rtt->setAutoUpdated(false);
Viewport* vp = rtt->addViewport(camera);
vp->setOverlaysEnabled(false);
vp->setShadowsEnabled(false);
vp->setBackgroundColour(ColourValue(0,0,0,0));
rtt->update();
//copy the rotated image to a static texture
TexturePtr destTexture = TextureManager::getSingleton().createManual(
destImage,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
TEX_TYPE_2D,
width, height,
0,
PF_FLOAT16_RGBA,
Ogre::TU_STATIC);
destTexture->getBuffer()->blit(destTextureRot->getBuffer());
// remove all the junk we've created
TextureManager::getSingleton().remove(destImageRot);
MaterialManager::getSingleton().remove("ImageRotateMaterial");
root->destroySceneManager(sceneMgr);
delete rect;
}

View file

@ -1,27 +0,0 @@
#ifndef OENGINE_OGRE_IMAGEROTATE_HPP
#define OENGINE_OGRE_IMAGEROTATE_HPP
#include <string>
namespace OEngine
{
namespace Render
{
/// Rotate an image by certain degrees and save as file, uses the GPU
/// Make sure Ogre Root is initialised before calling
class ImageRotate
{
public:
/**
* @param source image (file name - has to exist in an resource group)
* @param name of the destination texture to save to (in memory)
* @param angle in degrees to turn
*/
static void rotate(const std::string& sourceImage, const std::string& destImage, const float angle);
};
}
}
#endif

View file

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