1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-04 00:15:37 +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
${LIBDIR}/openengine/ogre/renderer.cpp
${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
)
set(OENGINE_GUI
@ -297,7 +296,7 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
"${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
"${OpenMW_BINARY_DIR}/openmw.desktop")
endif()
@ -378,7 +377,7 @@ if(WIN32)
"${OpenMW_SOURCE_DIR}/readme.txt"
"${OpenMW_SOURCE_DIR}/GPL3.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_BINARY_DIR}/launcher.qss"
"${OpenMW_BINARY_DIR}/settings-default.cfg"
@ -389,7 +388,7 @@ if(WIN32)
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
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_VERSION ${OPENMW_VERSION})
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_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
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_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
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(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/esmtool" DESTINATION "${BINDIR}" )
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/mwiniimport" DESTINATION "${BINDIR}" )
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/opencs" DESTINATION "${BINDIR}" )
IF(BUILD_LAUNCHER)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/omwlauncher" DESTINATION "${BINDIR}" )
ENDIF(BUILD_LAUNCHER)
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(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(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)

View file

@ -26,11 +26,11 @@ add_openmw_dir (mwinput
add_openmw_dir (mwgui
text_input widgets race class birth review windowmanagerimp console dialogue
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
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor
)
add_openmw_dir (mwdialogue

View file

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

View file

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

View file

@ -2,6 +2,7 @@
#include "dialoguemanagerimp.hpp"
#include <cctype>
#include <cstdlib>
#include <algorithm>
#include <iterator>
@ -251,8 +252,12 @@ namespace MWDialogue
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);
if (dialogue.mType==ESM::Dialogue::Persuasion)

View file

@ -289,7 +289,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con
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:
{
@ -559,8 +559,21 @@ MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedTo
: 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;
// 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 (testDisposition (*iter))
return &*iter;
if (testDisposition (*iter)) {
infos.push_back(&*iter);
if (!searchAll)
break;
}
else
infoRefusal = true;
}
}
if (infoRefusal && fallbackToInfoRefusal)
if (infos.empty() && infoRefusal && fallbackToInfoRefusal)
{
// No response is valid because of low NPC disposition,
// 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();
iter!=infoRefusalDialogue.mInfo.end(); ++iter)
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter))
return &*iter;
if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter)) {
infos.push_back(&*iter);
if (!searchAll)
break;
}
}
return 0;
return infos;
}
bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const

View file

@ -1,6 +1,8 @@
#ifndef GAME_MWDIALOGUE_FILTER_H
#define GAME_MWDIALOGUE_FILTER_H
#include <vector>
#include "../mwworld/ptr.hpp"
namespace ESM
@ -51,7 +53,10 @@ namespace MWDialogue
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.
/// 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);
assert(progress <= 1 && progress >= 0);
mLoadingText->setCaption(stage + "... ");
mLoadingText->setCaption(stage);
mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000));
static float loadingScreenFps = 30.f;

View file

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

View file

@ -6,6 +6,8 @@
#include <OgreTextureManager.h>
#include <OgreSceneNode.h>
#include <MyGUI_Gui.h>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
@ -13,6 +15,8 @@
#include "../mwrender/globalmap.hpp"
#include "widgets.hpp"
using namespace MWGui;
LocalMapBase::LocalMapBase()
@ -88,7 +92,7 @@ void LocalMapBase::applyFogOfWar()
+ boost::lexical_cast<std::string>(my);
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(mCurX + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(mCurY + (mInterior ? (my-1) : -1*(my-1)));
+ boost::lexical_cast<std::string>(mCurY + (-1*(my-1)));
MyGUI::ImageBox* fog = mFogWidgets[my + 3*mx];
fog->setImageTexture(mFogOfWar ?
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
@ -96,6 +100,7 @@ void LocalMapBase::applyFogOfWar()
: "");
}
}
notifyMapChanged ();
}
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
std::string image = mPrefix+"_"+ boost::lexical_cast<std::string>(x + (mx-1)) + "_"
+ boost::lexical_cast<std::string>(y + (interior ? (my-1) : -1*(my-1)));
+ boost::lexical_cast<std::string>(y + (-1*(my-1)));
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
+ boost::lexical_cast<std::string>(my);
@ -173,7 +178,7 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
}
else
{
Ogre::Vector2 position (marker.x, -marker.y);
Ogre::Vector2 position (marker.x, marker.y);
MWBase::Environment::get().getWorld ()->getInteriorMapPosition (position, nX, nY, cellDx, cellDy);
widgetCoord = MyGUI::IntCoord(nX * 512 - 4 + (1+cellDx-x) * 512, nY * 512 - 4 + (1+cellDy-y) * 512, 8, 8);
@ -394,10 +399,10 @@ void MapWindow::globalMapUpdatePlayer ()
{
Ogre::Vector3 pos = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedPosition ();
Ogre::Quaternion orient = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer().getRefData ().getBaseNode ()->_getDerivedOrientation ();
Ogre::Vector2 dir (orient.yAxis ().x, -orient.yAxis().z);
Ogre::Vector2 dir (orient.yAxis ().x, orient.yAxis().y);
float worldX, worldY;
mGlobalMapRender->worldPosToImageSpace (pos.x, pos.z, worldX, worldY);
mGlobalMapRender->worldPosToImageSpace (pos.x, pos.y, worldX, worldY);
worldX *= mGlobalMapRender->getWidth();
worldY *= mGlobalMapRender->getHeight();
@ -425,3 +430,17 @@ void MapWindow::notifyPlayerUpdate ()
{
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);
virtual void notifyPlayerUpdate() {}
virtual void notifyMapChanged() {}
OEngine::GUI::Layout* mLayout;
@ -99,6 +100,8 @@ namespace MWGui
virtual void onPinToggled();
virtual void notifyPlayerUpdate();
virtual void notifyMapChanged();
};
}
#endif

View file

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

View file

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

View file

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

View file

@ -53,6 +53,7 @@
#include "trainingwindow.hpp"
#include "imagebutton.hpp"
#include "exposedwindow.hpp"
#include "cursor.hpp"
using namespace MWGui;
@ -130,6 +131,9 @@ WindowManager::WindowManager(
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ImageButton>("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);
// 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","");
mCursor = new Cursor();
// The HUD is always on
mHud->setVisible(true);
@ -236,6 +242,7 @@ WindowManager::~WindowManager()
delete mTrainingWindow;
delete mCountDialog;
delete mQuickKeysMenu;
delete mCursor;
cleanupGarbage();
@ -262,6 +269,8 @@ void WindowManager::update()
mHud->setFPS(mFPS);
mHud->setTriangleCount(mTriangleCount);
mHud->setBatchCount(mBatchCount);
mCursor->update();
}
void WindowManager::updateVisible()
@ -293,7 +302,7 @@ void WindowManager::updateVisible()
mHud->setVisible(true);
// Mouse is visible whenever we're not in game mode
MyGUI::PointerManager::getInstance().setVisible(isGuiMode());
mCursor->setVisible(isGuiMode());
bool gameMode = !isGuiMode();
@ -421,13 +430,19 @@ void WindowManager::updateVisible()
break;
case GM_LoadingWallpaper:
mHud->setVisible(false);
MyGUI::PointerManager::getInstance().setVisible(false);
mCursor->setVisible(false);
break;
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;
case GM_Video:
MyGUI::PointerManager::getInstance().setVisible(false);
mCursor->setVisible(false);
mHud->setVisible(false);
break;
default:
@ -749,7 +764,7 @@ void WindowManager::setSpellVisibility(bool visible)
void WindowManager::setMouseVisible(bool visible)
{
MyGUI::PointerManager::getInstance().setVisible(visible);
mCursor->setVisible(visible);
}
void WindowManager::setDragDrop(bool dragDrop)

View file

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

View file

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

View file

@ -31,20 +31,18 @@ ActivatorAnimation::ActivatorAnimation(const MWWorld::Ptr &ptr)
Ogre::Entity *ent = mEntityList.mEntities[i];
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::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements() && !transparent)
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements() && !transparent)
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
transparent = pass->isTransparent();
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -32,20 +32,18 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr)
ent->setVisibilityFlags(RV_Actors);
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::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements() && !transparent)
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements() && !transparent)
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
transparent = pass->isTransparent();
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -107,19 +107,18 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
base->setVisibilityFlags(mVisibilityFlags);
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::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements())
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
transparent = pass->isTransparent();
}
}
}
@ -322,8 +321,26 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int
std::vector<Ogre::Entity*> &parts = entities.mEntities;
for(size_t i = 0;i < parts.size();i++)
{
parts[i]->setVisibilityFlags(mVisibilityFlags);
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)
{

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_)
{
Ogre::SceneNode* root = mMwRoot;
Ogre::SceneNode* root = mRootNode;
Ogre::SceneNode* cellnode;
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;
NifOgre::EntityList entities = NifOgre::Loader::createEntities(insert, mesh);
for(size_t i = 0;i < entities.mEntities.size();i++)
{
const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox();
bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(),
insert->_getDerivedPosition() + tmp.getMaximum())
);
}
bounds.merge(entities.mEntities[i]->getWorldBoundingBox(true));
Ogre::Vector3 extents = bounds.getSize();
extents *= insert->getScale();
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);
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];
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::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
while (techIt.hasMoreElements())
while(!transparent && techIt.hasMoreElements())
{
Ogre::Technique* tech = techIt.getNext();
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
while (passIt.hasMoreElements())
while(!transparent && passIt.hasMoreElements())
{
Ogre::Pass* pass = passIt.getNext();
if (pass->getDepthWriteEnabled() == false)
transparent = true;
transparent = pass->isTransparent();
}
}
}
@ -390,9 +384,9 @@ void Objects::enableLights()
std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(it->name))
if (mRootNode->getCreator()->hasLight(it->name))
{
mMwRoot->getCreator()->getLight(it->name)->setVisible(true);
mRootNode->getCreator()->getLight(it->name)->setVisible(true);
++it;
}
else
@ -405,9 +399,9 @@ void Objects::disableLights()
std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(it->name))
if (mRootNode->getCreator()->hasLight(it->name))
{
mMwRoot->getCreator()->getLight(it->name)->setVisible(false);
mRootNode->getCreator()->getLight(it->name)->setVisible(false);
++it;
}
else
@ -460,9 +454,9 @@ void Objects::update(const float dt)
std::vector<LightInfo>::iterator it = mLights.begin();
while (it != mLights.end())
{
if (mMwRoot->getCreator()->hasLight(it->name))
if (mRootNode->getCreator()->hasLight(it->name))
{
Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name);
Ogre::Light* light = mRootNode->getCreator()->getLight(it->name);
float brightness;
float cycle_time;
@ -550,7 +544,7 @@ void Objects::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
MWWorld::CellStore *newCell = cur.getCell();
if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) {
node = mMwRoot->createChildSceneNode();
node = mRootNode->createChildSceneNode();
mCellSceneNodes[newCell] = node;
} else {
node = mCellSceneNodes[newCell];

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

@ -27,13 +27,10 @@ namespace
{
const MWWorld::Class& class_ =
MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.mList.begin(), &cell));
size_t numRefs = cellRefList.mList.size();
int current = 0;
for (typename T::List::iterator it = cellRefList.mList.begin();
it != cellRefList.mList.end(); it++)
{
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Loading cells", 1, current, numRefs);
++current;
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)
{
Nif::NIFFile::CacheLock cachelock;
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
mRendering.preCellChange(mCurrentCell);
// remove active
MWBase::Environment::get().getMechanicsManager()->remove(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
std::string loadingExteriorText;
loadingExteriorText = gmst.find ("sLoadingMessage3")->getString();
CellStoreCollection::iterator active = mActiveCells.begin();
// get the number of cells to unload
@ -216,8 +215,6 @@ namespace MWWorld
continue;
}
}
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload);
unloadCell (active++);
++current;
}
@ -266,7 +263,9 @@ namespace MWWorld
{
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);
++current;
}
@ -325,6 +324,13 @@ namespace MWWorld
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);
bool loadcell = (mCurrentCell == NULL);
if(!loadcell)
@ -360,8 +366,6 @@ namespace MWWorld
active = mActiveCells.begin();
while (active!=mActiveCells.end())
{
MWBase::Environment::get().getWindowManager ()->setLoadingProgress ("Unloading cells", 0, current, numUnload);
unloadCell (active++);
++current;
}
@ -369,7 +373,9 @@ namespace MWWorld
// Load cell.
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);
mCurrentCell = cell;

View file

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

View file

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

View file

@ -77,8 +77,7 @@ void ESMReader::open(Ogre::DataStreamPtr _esm, const std::string &name)
// Get the header
getHNT(mCtx.header, "HEDR", 300);
if (mCtx.header.version != VER_12 && mCtx.header.version != VER_13)
fail("Unsupported file format version");
// 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.
while (isNextSub("MAST"))
{

View file

@ -37,14 +37,14 @@ public:
*************************************************************************/
int getVer() const { return mCtx.header.version; }
float getFVer() { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; }
int getSpecial() { return mSpf; }
int getType() { return mCtx.header.type; }
const std::string getAuthor() { return mCtx.header.author.toString(); }
const std::string getDesc() { return mCtx.header.desc.toString(); }
float getFVer() const { if(mCtx.header.version == VER_12) return 1.2; else return 1.3; }
int getSpecial() const { return mSpf; }
int getType() const { return mCtx.header.type; }
const std::string getAuthor() const { return mCtx.header.author.toString(); }
const std::string getDesc() const { return mCtx.header.desc.toString(); }
const SaveData &getSaveData() const { return mSaveData; }
const MasterList &getMasters() { return mMasters; }
const NAME &retSubName() { return mCtx.subName; }
const MasterList &getMasters() const { return mMasters; }
const NAME &retSubName() const { return mCtx.subName; }
uint32_t getSubSize() const { return mCtx.leftSub; }
/*************************************************************************
@ -85,7 +85,7 @@ public:
int mIdx;
void setIndex(const int index) {mIdx = index; mCtx.index = index;}
const int getIndex() {return mIdx;}
void setGlobalReaderList(std::vector<ESMReader> *list) {mGlobalReaderList = list;}
std::vector<ESMReader> *getGlobalReaderList() {return mGlobalReaderList;}

View file

@ -7,12 +7,27 @@ namespace ESM
{
void Apparatus::load(ESMReader &esm)
{
mModel = esm.getHNString("MODL");
mName = esm.getHNString("FNAM");
esm.getHNT(mData, "AADT", 16);
mScript = esm.getHNOString("SCRI");
mIcon = esm.getHNString("ITEX");
// we will not treat duplicated subrecords as errors here
while (esm.hasMoreSubs())
{
esm.getSubName();
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)
{
esm.writeHNCString("MODL", mModel);

View file

@ -112,8 +112,8 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
// instead.
if (mData.mFlags & QuasiEx)
mRegion = esm.getHNOString("RGNN");
else
esm.getHNT(mAmbi, "AMBI", 16);
else if (esm.isNextSub("AMBI"))
esm.getHT(mAmbi);
}
else
{
@ -126,7 +126,7 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
if (esm.isNextSub("NAM0")) {
esm.getHT(mNAM0);
}
// preload moved references
while (esm.isNextSub("MVRF")) {
CellRef ref;
@ -135,7 +135,7 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
MWWorld::Store<ESM::Cell> &cStore = const_cast<MWWorld::Store<ESM::Cell>&>(store.get<ESM::Cell>());
ESM::Cell *cellAlt = const_cast<ESM::Cell*>(cStore.searchOrCreate(cMRef.mTarget[0], cMRef.mTarget[1]));
// Get regular moved reference data. Adapted from CellStore::loadRefs. Maybe we can optimize the following
// implementation when the oher implementation works as well.
getNextRef(esm, ref);
@ -143,7 +143,7 @@ void Cell::load(ESMReader &esm, MWWorld::ESMStore &store)
std::transform (ref.mRefID.begin(), ref.mRefID.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
// Add data required to make reference appear in the correct cell.
// We should not need to test for duplicates, as this part of the code is pre-cell merge.
mMovedRefs.push_back(cMRef);
@ -186,7 +186,7 @@ void Cell::save(ESMWriter &esm)
if (mMapColor != 0)
esm.writeHNT("NAM5", mMapColor);
}
if (mNAM0 != 0)
esm.writeHNT("NAM0", mNAM0);
}
@ -226,7 +226,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
esm.getHNT(ref.mRefnum, "FRMR");
ref.mRefID = esm.getHNString("NAME");
// Identify references belonging to a parent file and adapt the ID accordingly.
int local = (ref.mRefnum & 0xff000000) >> 24;
size_t global = esm.getIndex() + 1;
@ -249,7 +249,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
// missing
ref.mScale = 1.0;
esm.getHNOT(ref.mScale, "XSCL");
// TODO: support loading references from saves, there are tons of keys not recognized yet.
// The following is just an incomplete list.
if (esm.isNextSub("ACTN"))
@ -266,7 +266,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
esm.skipHSub();
else if (esm.isNextSub("CRED")) // ???
esm.skipHSub();
ref.mOwner = esm.getHNOString("ANAM");
ref.mGlob = esm.getHNOString("BNAM");
ref.mSoul = esm.getHNOString("XSOL");
@ -305,7 +305,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
esm.getHNOT(ref.mFltv, "FLTV");
esm.getHNOT(ref.mPos, "DATA", 24);
// Number of references in the cell? Maximum once in each cell,
// but not always at the beginning, and not always right. In other
// words, completely useless.
@ -318,7 +318,7 @@ bool Cell::getNextRef(ESMReader &esm, CellRef &ref)
esm.getHT(ref.mNam0);
//esm.getHNOT(NAM0, "NAM0");
}
if (esm.isNextSub("DELE")) {
esm.skipHSub();
ref.mDeleted = 2; // Deleted, will not respawn.
@ -333,7 +333,7 @@ bool Cell::getNextMVRF(ESMReader &esm, MovedCellRef &mref)
{
esm.getHT(mref.mRefnum);
esm.getHNOT(mref.mTarget, "CNDT");
// Identify references belonging to a parent file and adapt the ID accordingly.
int local = (mref.mRefnum & 0xff000000) >> 24;
size_t global = esm.getIndex() + 1;

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
#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"
#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
#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"
#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
#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
#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
#define COMPONENTS_FILES_WINDOWSPATH_HPP

View file

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

View file

@ -220,11 +220,10 @@ void NIFFile::parse()
for(size_t i = 0;i < recNum;i++)
{
std::string rec = getString();
//cout << i << ": " << rec.toString() << endl;
Record *r = NULL;
std::string rec = getString();
/* These are all the record types we know how to read.
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 == "NiWireframeProperty") { r = new NiWireframeProperty; r->recType = RC_NiWireframeProperty; }
else if(rec == "NiSpecularProperty") { r = new NiSpecularProperty; r->recType = RC_NiSpecularProperty; }
else if(rec == "NiStencilProperty") { r = new NiStencilProperty; r->recType = RC_NiStencilProperty; }
// Controllers
else if(rec == "NiVisController") { r = new NiVisController; r->recType = RC_NiVisController; }

View file

@ -158,6 +158,7 @@ public:
short getShort() { return read_le16(); }
unsigned short getUShort() { return read_le16(); }
int getInt() { return read_le32(); }
unsigned int getUInt() { return read_le32(); }
float getFloat() { return read_le32f(); }
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_MaterialProperty> NiMaterialProperty;
typedef StructPropT<S_VertexColorProperty> NiVertexColorProperty;
typedef StructPropT<S_StencilProperty> NiStencilProperty;
} // Namespace
#endif

View file

@ -48,6 +48,7 @@ enum RecordType
RC_NiDitherProperty,
RC_NiWireframeProperty,
RC_NiSpecularProperty,
RC_NiStencilProperty,
RC_NiVisController,
RC_NiGeomMorpherController,
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
* 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->recType == Nif::RC_NiTriShape)
return false;
return Ogre::SkeletonPtr();
if(node->controller.empty() && node->name != "AttachLight")
{
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(createSkeleton(name, group, children[i].getPtr()))
return true;
Ogre::SkeletonPtr skel = createSkeleton(name, group, children[i].getPtr());
if(!skel.isNull())
return skel;
}
}
return false;
return Ogre::SkeletonPtr();
}
}
}
Ogre::SkeletonManager &skelMgr = Ogre::SkeletonManager::getSingleton();
skelMgr.create(name, group, true, &sLoaders[name]);
return true;
return skelMgr.create(name, group, true, &sLoaders[name]);
}
};
NIFSkeletonLoader::LoaderMap NIFSkeletonLoader::sLoaders;
// Conversion of blend / test mode from NIF -> OGRE.
// Not in use yet, so let's comment it out.
/*
static SceneBlendFactor getBlendFactor(int mode)
// Conversion of blend / test mode from NIF
static const char *getBlendFactor(int mode)
{
switch(mode)
switch(mode)
{
case 0: return SBF_ONE;
case 1: return SBF_ZERO;
case 2: return SBF_SOURCE_COLOUR;
case 3: return SBF_ONE_MINUS_SOURCE_COLOUR;
case 4: return SBF_DEST_COLOUR;
case 5: return SBF_ONE_MINUS_DEST_COLOUR;
case 6: return SBF_SOURCE_ALPHA;
case 7: return SBF_ONE_MINUS_SOURCE_ALPHA;
case 8: return SBF_DEST_ALPHA;
case 9: return SBF_ONE_MINUS_DEST_ALPHA;
// [Comment from Chris Robinson:] Can't handle this mode? :/
// case 10: return SBF_SOURCE_ALPHA_SATURATE;
default:
return SBF_SOURCE_ALPHA;
case 0: return "one";
case 1: return "zero";
case 2: return "src_colour";
case 3: return "one_minus_src_colour";
case 4: return "dest_colour";
case 5: return "one_minus_dest_colour";
case 6: return "src_alpha";
case 7: return "one_minus_src_alpha";
case 8: return "dest_alpha";
case 9: return "one_minus_dest_alpha";
case 10: return "src_alpha_saturate";
}
std::cerr<< "Unexpected blend mode: "<<mode <<std::endl;
return "src_alpha";
}
// This is also unused
static CompareFunction getTestMode(int mode)
static const char *getTestMode(int mode)
{
switch(mode)
switch(mode)
{
case 0: return CMPF_ALWAYS_PASS;
case 1: return CMPF_LESS;
case 2: return CMPF_EQUAL;
case 3: return CMPF_LESS_EQUAL;
case 4: return CMPF_GREATER;
case 5: return CMPF_NOT_EQUAL;
case 6: return CMPF_GREATER_EQUAL;
case 7: return CMPF_ALWAYS_FAIL;
default:
return CMPF_ALWAYS_PASS;
case 0: return "always_pass";
case 1: return "less";
case 2: return "equal";
case 3: return "less_equal";
case 4: return "greater";
case 5: return "not_equal";
case 6: return "greater_equal";
case 7: return "always_fail";
}
std::cerr<< "Unexpected test mode: "<<mode <<std::endl;
return "less_equal";
}
*/
class NIFMaterialLoader {
@ -567,8 +562,8 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
Ogre::Vector3 emissive(0.0f);
float glossiness = 0.0f;
float alpha = 1.0f;
int alphaFlags = -1;
// ubyte alphaTest = 0;
int alphaFlags = 0;
int alphaTest = 0;
Ogre::String texName;
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);
else if (pr->recType == Nif::RC_NiAlphaProperty)
a = static_cast<const Nif::NiAlphaProperty*>(pr);
else if (pr->recType == Nif::RC_NiStencilProperty)
/* unused */;
else
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();
if (st->external)
{
/* Bethesda at some at some point converted all their BSA
/* Bethesda at some point converted all their BSA
* textures from tga to dds for increased load speed, but all
* texture file name references were kept as .tga.
*/
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('.');
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)
// verify, and revert if false (this call succeeds quickly, but fails slowly)
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.");
@ -629,7 +636,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
if (a)
{
alphaFlags = a->flags;
// alphaTest = a->data.threshold;
alphaTest = a->data.threshold;
}
// 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, vertexColour);
boost::hash_combine(h, alphaFlags);
boost::hash_combine(h, alphaTest);
std::map<size_t,std::string>::iterator itr = MaterialMap.find(h);
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)));
instance->setProperty ("specular", sh::makeProperty<sh::Vector4> (
new sh::Vector4(specular.x, specular.y, specular.z, glossiness)));
new sh::Vector4(specular.x, specular.y, specular.z, glossiness*255.0f)));
instance->setProperty ("emissive", sh::makeProperty<sh::Vector3> (
new sh::Vector3(emissive.x, emissive.y, emissive.z)));
@ -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)));
// 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
// NiAlphaProperty in nif/property.h if you need to decode
// other values. 237 basically means normal transparencly.
if (alphaFlags == 237)
{
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
if (result.first)
{
instance->setProperty("alpha_rejection",
sh::makeProperty<sh::StringValue>(new sh::StringValue("greater_equal " + boost::lexical_cast<std::string>(result.second))));
}
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);
alphaFlags = (1<<9) | (6<<10); /* alpha_rejection enabled, greater_equal */
alphaTest = result.second;
}
if((alphaFlags&1))
{
std::string blend_mode;
blend_mode += getBlendFactor((alphaFlags>>1)&0xf);
blend_mode += " ";
blend_mode += getBlendFactor((alphaFlags>>5)&0xf);
instance->setProperty("scene_blend", sh::makeProperty(new sh::StringValue(blend_mode)));
}
else
instance->getMaterial ()->setShadowCasterMaterial ("openmw_shadowcaster_noalpha");
instance->getMaterial()->setShadowCasterMaterial("openmw_shadowcaster_noalpha");
// As of yet UNTESTED code from Chris:
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
pass->setDepthCheckEnabled(true);
// Add transparency if NiAlphaProperty was present
if (alphaFlags != -1)
if((alphaFlags>>9)&1)
{
std::cout << "Alpha flags set!" << endl;
if ((alphaFlags&1))
{
pass->setDepthWriteEnabled(false);
pass->setSceneBlending(getBlendFactor((alphaFlags>>1)&0xf),
getBlendFactor((alphaFlags>>5)&0xf));
}
else
pass->setDepthWriteEnabled(true);
if ((alphaFlags>>9)&1)
pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7),
alphaTest);
pass->setTransparentSortingEnabled(!((alphaFlags>>13)&1));
std::string reject;
reject += getTestMode((alphaFlags>>10)&0x7);
reject += " ";
reject += Ogre::StringConverter::toString(alphaTest);
instance->setProperty("alpha_rejection", sh::makeProperty(new sh::StringValue(reject)));
}
*/
instance->setProperty("transparent_sorting", sh::makeProperty(new sh::StringValue(((alphaFlags>>13)&1) ?
"off" : "on")));
sh::Factory::getInstance()._ensureMaterial(matname, "Default");
return matname;
}
@ -855,9 +842,12 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
// Set the bounding box first
BoundsFinder bounds;
bounds.add(&srcVerts[0][0], srcVerts.size());
// No idea why this offset is needed. It works fine without it if the
// vertices weren't transformed first, but otherwise it fails later on
// when the object is being inserted into the scene.
if(!bounds.isValid())
{
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,
bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f));
mesh->_setBoundingSphereRadius(bounds.getRadius());
@ -1031,6 +1021,10 @@ public:
void createMeshes(const Nif::Node *node, MeshInfoList &meshes, int flags=0)
{
// Do not create meshes for the collision shape (includes all children)
if(node->recType == Nif::RC_RootCollisionNode)
return;
flags |= node->flags;
// Marker objects: just skip the entire node
@ -1150,10 +1144,7 @@ MeshInfoList Loader::load(const std::string &name, const std::string &group)
bool hasSkel = Ogre::SkeletonManager::getSingleton().resourceExists(name);
if(!hasSkel)
{
NIFSkeletonLoader skelldr;
hasSkel = skelldr.createSkeleton(name, group, node);
}
hasSkel = !NIFSkeletonLoader::createSkeleton(name, group, node).isNull();
NIFMeshLoader meshldr(name, group);
if(hasSkel)
@ -1216,14 +1207,20 @@ EntityList Loader::createEntities(Ogre::Entity *parent, const std::string &bonen
if(meshes.size() == 0)
return entitylist;
bool isskinned = false;
Ogre::SceneManager *sceneMgr = parentNode->getCreator();
std::string filter = "@shape=tri "+bonename;
Misc::StringUtils::toLower(filter);
for(size_t i = 0;i < meshes.size();i++)
{
Ogre::Entity *ent = sceneMgr->createEntity(meshes[i].mMeshName);
if(!entitylist.mSkelBase && ent->hasSkeleton())
entitylist.mSkelBase = ent;
if(!entitylist.mSkelBase)
{
if(ent->hasSkeleton())
entitylist.mSkelBase = ent;
}
else if(!isskinned && ent->hasSkeleton())
isskinned = true;
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)
scale.x *= -1.0f;
if(entitylist.mSkelBase)
if(isskinned)
{
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);
Nif::NIFFile &nif = *pnif.get();
if(nif.numRecords() < 1)
Ogre::SkeletonPtr skel;
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+".");
return false;
nif->warn("Found no NIF records in "+name+".");
return skel;
}
// 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);
Nif::Node const *node = dynamic_cast<Nif::Node const *>(r);
const Nif::Node *node = dynamic_cast<const Nif::Node*>(r);
if(node == NULL)
{
nif.warn("First record in "+name+" was not a node, but a "+
r->recName+".");
return false;
nif->warn("First record in "+name+" was not a node, but a "+
r->recName+".");
return skel;
}
NIFSkeletonLoader skelldr;
return skelldr.createSkeleton(name, group, node);
return NIFSkeletonLoader::createSkeleton(name, group, node);
}

View file

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

View file

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

View file

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

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

View file

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

View file

@ -9,7 +9,6 @@ set(MYGUI_FILES
core.skin
core.xml
EBGaramond-Regular.ttf
mwgui.png
Obliviontt.zip
openmw_alchemy_window.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">
<!-- 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">
<Property key="MultiLine" value="1" />
<Property key="VisibleVScroll" value="1" />

View file

@ -8,33 +8,52 @@
<Property key="Caption" value="Appearance"/>
<Property key="TextAlign" value="ALIGN_LEFT ALIGN_TOP"/>
</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>
<!-- Sliders -->
<!-- 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 -->
<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 type="Button" skin="MW_ScrollRight" position="235 298 14 14" name="NextGenderButton"/>
<!-- 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 type="Button" skin="MW_ScrollRight" position="235 320 14 14" name="NextFaceButton"/>
<!-- 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 type="Button" skin="MW_ScrollRight" position="235 342 14 14" name="NextHairButton"/>
<!-- Race -->
<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"/>
</Widget>
@ -42,11 +61,11 @@
</Widget>
<!-- 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"/>
</Widget>
<!-- 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 -->
<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">
<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 -->
<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="WordWrap" value="true"/>
<Property key="MultiLine" 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>

View file

@ -1,55 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin">
<!-- Text edit widget -->
<Skin name = "MW_TextEditClient" size = "10 10">
<BasisSkin type="EditText" offset = "0 0 10 10" align = "Stretch"/>
</Skin>
<Skin name = "MW_TextBoxEditClient" size = "10 10">
<BasisSkin type="EditText" offset = "0 0 10 10" align = "Stretch"/>
</Skin>
<Skin name="MW_TextEdit" size="512 20" texture="mwgui.png">
<Property key="FontName" value = "Default"/>
<Property key="TextAlign" value = "ALIGN_LEFT ALIGN_VCENTER" />
<Property key="TextColour" value = "0.75 0.6 0.35" />
<Skin name="MW_TextEdit" size="512 20">
<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>
<!-- Input -->
<Property key="FontName" value = "Default"/>
<Property key="TextAlign" value = "ALIGN_LEFT ALIGN_VCENTER" />
<Property key="TextColour" value = "0.75 0.6 0.35" />
<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 name="MW_TextBoxEdit" size="512 20" texture="mwgui.png">
<Skin name="MW_TextBoxEdit" size="512 20">
<Property key="FontName" value = "Default"/>
<Property key="TextAlign" value = "ALIGN_LEFT ALIGN_TOP" />
<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="ScrollBar" skin="MW_VScroll" offset = "494 3 14 14" align = "Right VStretch" name = "VScroll"/>
</Skin>
</MyGUI>

View file

@ -31,7 +31,7 @@
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</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"/>
</Widget>
@ -39,7 +39,7 @@
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</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"/>
</Widget>
</Widget>
@ -56,7 +56,7 @@
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</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"/>
</Widget>
</Widget>
@ -72,7 +72,7 @@
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="0"/>
</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"/>
</Widget>
</Widget>

View file

@ -1,80 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin">
<!-- 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">
<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>
<Skin name="HUD_Box" size="40 40">
<BasisSkin type="TileRect" offset="0 1 2 37" align="ALIGN_LEFT ALIGN_VSTRETCH">
<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>
<!-- Borders -->
<Child type="Widget" skin="MW_Box" offset="0 0 40 40" align="ALIGN_LEFT Stretch" name="Client"/>
<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 -->
<Child type="Widget" skin="BlackBG" offset="2 2 36 36" align="ALIGN_STRETCH" name="Client"/>
</Skin>
<Skin name="HUD_Box_NoTransp" size="40 40" texture="mwgui.png">
<BasisSkin type="TileRect" offset="0 0 39 2" align="ALIGN_TOP ALIGN_HSTRETCH">
<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>
<Skin name="HUD_Box_NoTransp" size="40 40">
<BasisSkin type="TileRect" offset="0 1 2 37" align="ALIGN_LEFT ALIGN_VSTRETCH">
<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>
<!-- Borders -->
<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>
<Child type="Widget" skin="MW_Box" offset="0 0 40 40" align="ALIGN_LEFT Stretch" name="Client"/>
<!-- The interior of the box -->
<Child type="Widget" skin="DialogBG" offset="2 2 36 36" align="ALIGN_STRETCH" name="Client"/>
</Skin>
</MyGUI>

View file

@ -1,228 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Skin">
<!-- scroll tracker -->
<Skin name = "MW_ScrollTrack" size = "16 20" texture="mwgui.png">
<BasisSkin type="SubSkin" offset = "0 0 16 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "38 24 16 2"/>
</BasisSkin>
<BasisSkin type="TileRect" offset="0 2 16 16" align="ALIGN_STRETCH">
<State name="normal" offset="38 26 16 16">
<!-- Horizontal Scrollbar -->
<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"/>
<!-- 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="TileH" value="true"/>
<Property key="TileV" value="true"/>
</State>
</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 name = "MW_ScrollTrackH" size = "12 20" texture="mwgui.png">
<BasisSkin type="SubSkin" offset = "0 0 12 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "38 24 12 2"/>
</BasisSkin>
<BasisSkin type="TileRect" offset="0 2 12 16" align="ALIGN_STRETCH">
<State name="normal" offset="40 26 12 16">
<Property key="TileSize" value="12 16"/>
<!-- Vertical Scrollbar -->
<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_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="TileV" value="true"/>
</State>
</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 name = "MW_ScrollUp" size = "16 20" texture="mwgui.png">
<!-- 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 24 8 8"/>
</BasisSkin>
<!-- Empty space in scrollbar -->
<Skin name="MW_ScrollEmptyPart" size="16 16" >
</Skin>
<Skin name = "MW_ScrollDown" size = "16 20" texture="mwgui.png">
<!-- 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>
<!-- Header text -->
<Skin name = "MW_ScrollLeft" size = "16 20" texture="mwgui.png">
<!-- 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 54 8 8"/>
</BasisSkin>
</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" />
<Skin name = "MW_ScrollRight" size = "16 20" texture="mwgui.png">
<!-- 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"/>
<BasisSkin type="SimpleText" offset="0 0 16 16" align="ALIGN_STRETCH"/>
</Skin>
<!-- 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="normal" colour="0.70 0.57 0.33" shift="0"/>
<State name="highlighted" colour="0.85 0.76 0.60" shift="0"/>
@ -234,81 +113,85 @@
</BasisSkin>
</Skin>
<Skin name = "MW_List" size = "516 516" align = "ALIGN_LEFT ALIGN_TOP" texture="mwgui.png">
<Property key="NeedKey" value = "true" />
<Property key="SkinLine" value = "MW_ListLine" />
<Property key="HeightLine" value = "20" />
<Skin name="MW_List" 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="MW_VScroll" offset = "498 3 14 509" align = "ALIGN_RIGHT ALIGN_VSTRETCH" name = "VScroll">
</Child>
<Child type="Widget" skin="MW_Box" offset="0 0 516 516" align="ALIGN_STRETCH"/>
<Child type="Widget" skin="" offset = "3 3 493 509" align = "ALIGN_STRETCH" name = "Client">
</Child>
<Child type="ScrollBar" skin="MW_VScroll" offset="498 3 14 509" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="VScroll"/>
<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_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"/>
<Child type="Widget" skin="" 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" />
<Skin name="MW_SimpleList" size="516 516" align="ALIGN_LEFT ALIGN_TOP">
<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>
<Child type="Widget" skin="" offset="3 3 510 510" align="Top Left ALIGN_STRETCH" name="Client"/>
<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>
<!-- textures/menu_thin_border_top.dds -->
<Skin name = "MW_HLine" size = "512 18" texture="mwgui.png">
<BasisSkin type="SubSkin" offset = "0 8 512 2" align = "ALIGN_TOP ALIGN_HSTRETCH">
<State name="normal" offset = "20 106 512 2"/>
<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="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>
</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>

View file

@ -8,7 +8,8 @@
<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 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"?>
<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"/>
<!-- invisible scroll bars, needed for setting the view offset -->

View file

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

View file

@ -17,27 +17,6 @@
</Index>
</Group>
</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">
<Group name="Pointer" texture="textures\cursor_drop_ground.dds" size="32 32">
<Index name="Pointer" >

View file

@ -2,12 +2,12 @@
<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="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 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="ScrollBar" skin="MW_HScroll" offset="3 498 509 14" align="ALIGN_LEFT ALIGN_BOTTOM ALIGN_HSTRETCH" name="HScroll"/>
</Skin>

View file

@ -15,7 +15,7 @@
<Widget type="TextBox" skin="NormalText" position="4 4 352 18" align="Left Top">
<Property key="Caption" value="#{sTransparency_Menu}"/>
</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"/>
</Widget>
<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">
<Property key="Caption" value="#{sMenu_Help_Delay}"/>
</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"/>
</Widget>
<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">
<Property key="Caption" value="#{sMaster}"/>
</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"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="4 54 352 18" align="Left Top">
<Property key="Caption" value="#{sVoice}"/>
</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"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="4 104 352 18" align="Left Top">
<Property key="Caption" value="#{sEffects}"/>
</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"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="4 154 352 18" align="Left Top">
<Property key="Caption" value="#{sFootsteps}"/>
</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"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="4 204 352 18" align="Left Top">
<Property key="Caption" value="#{sMusic}"/>
</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"/>
</Widget>
</Widget>
@ -117,7 +117,7 @@
<Widget type="TextBox" skin="NormalText" position="4 228 160 18" align="Left Top">
<Property key="Caption" value="UI cursor sensitivity"/>
</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"/>
</Widget>
<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">
<Property key="Caption" value="Camera sensitivity"/>
</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"/>
</Widget>
<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">
<Property key="Caption" value="Gamma"/>
</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"/>
</Widget>
<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">
<Property key="Caption" value="Field of View"/>
</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"/>
</Widget>
<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">
<Property key="Caption" value="Anisotropy"/>
</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"/>
</Widget>
</Widget>
@ -241,7 +241,7 @@
<Widget type="TextBox" skin="NormalText" position="4 130 322 18" align="Left Top">
<Property key="Caption" value="#{sRender_Distance}"/>
</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"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="4 178 332 18" align="Left Top">

View file

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

View file

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