diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index c0ac12d04..6cd39fd0e 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -428,11 +428,7 @@ printf "MyGUI 3.2.2... " mv MyGUI-3.2.2-win$BITS MyGUI fi - MYGUI_SDK="`real_pwd`/MyGUI" - - add_cmake_opts -DMYGUISDK="$MYGUI_SDK" \ - -DMYGUI_INCLUDE_DIRS="$MYGUI_SDK/include/MYGUI" \ - -DMYGUI_PREQUEST_FILE="$MYGUI_SDK/include/MYGUI/MyGUI_Prerequest.h" + export MYGUI_HOME="`real_pwd`/MyGUI" if [ $CONFIGURATION == "Debug" ]; then SUFFIX="_d" diff --git a/CMakeLists.txt b/CMakeLists.txt index 25d34709e..a5a934624 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,76 +227,74 @@ IF(BOOST_STATIC) endif() IF(BUILD_OPENMW OR BUILD_OPENCS) - find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle osgUtil osgFX) - - include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}) - - if(OSG_STATIC) - macro(use_static_osg_plugin_library PLUGIN_NAME) - set(PLUGIN_NAME_DBG ${PLUGIN_NAME}d ${PLUGIN_NAME}D ${PLUGIN_NAME}_d ${PLUGIN_NAME}_D ${PLUGIN_NAME}_debug ${PLUGIN_NAME}) - - # For now, users wishing to do a static build will need to pass the path to where the plugins reside - # More clever logic would need to deduce the path, probably installed under /lib/osgPlugins- - include(FindPkgMacros) - find_library(${PLUGIN_NAME}_LIBRARY_REL NAMES ${PLUGIN_NAME} HINTS ${OSG_PLUGIN_LIB_SEARCH_PATH}) - find_library(${PLUGIN_NAME}_LIBRARY_DBG NAMES ${PLUGIN_NAME_DBG} HINTS ${OSG_PLUGIN_LIB_SEARCH_PATH}) - make_library_set(${PLUGIN_NAME}_LIBRARY) - - if("${${PLUGIN_NAME}_LIBRARY}" STREQUAL "") - message(FATAL_ERROR "Unable to find static OpenSceneGraph plugin: ${PLUGIN_NAME}") - endif() - - set(OPENSCENEGRAPH_LIBRARIES ${OPENSCENEGRAPH_LIBRARIES} ${${PLUGIN_NAME}_LIBRARY}) - endmacro() - - add_definitions(-DOSG_LIBRARY_STATIC) - - set(PLUGIN_LIST - osgdb_png # depends on libpng, zlib - osgdb_tga - osgdb_dds - osgdb_jpeg # depends on libjpeg - ) - - foreach(PLUGIN ${PLUGIN_LIST}) - use_static_osg_plugin_library(${PLUGIN}) - endforeach() - - # OSG static plugins need to linked against their respective dependencies - set(PLUGIN_DEPS_LIST - PNG # needed by osgdb_png - ZLIB # needed by osgdb_png - JPEG # needed by osgdb_jpeg - ) - - macro(use_static_osg_plugin_dep DEPENDENCY) - find_package(${DEPENDENCY} REQUIRED) - - set(OPENSCENEGRAPH_LIBRARIES ${OPENSCENEGRAPH_LIBRARIES} ${${DEPENDENCY}_LIBRARIES}) - endmacro() - foreach(DEPENDENCY ${PLUGIN_DEPS_LIST}) - use_static_osg_plugin_dep(${DEPENDENCY}) - endforeach() - endif() - - if(QT_STATIC) - if(WIN32) - if(DESIRED_QT_VERSION MATCHES 4) - # QtCore needs WSAAsyncSelect from Ws2_32.lib - set(QT_QTCORE_LIBRARY ${QT_QTCORE_LIBRARY} Ws2_32.lib) - message("QT_QTCORE_LIBRARY: ${QT_QTCORE_LIBRARY}") - endif() - endif() - endif() - - find_package(MyGUI REQUIRED) - if (${MYGUI_VERSION} VERSION_LESS "3.2.1") - message(FATAL_ERROR "OpenMW requires MyGUI 3.2.1 or later, please install the latest version from http://mygui.info") - endif() - - find_package(SDL2 REQUIRED) - find_package(OpenAL REQUIRED) - find_package(Bullet 283 REQUIRED COMPONENTS BulletCollision LinearMath) + + find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle osgUtil osgFX) + + include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}) + + if(OSG_STATIC) + macro(use_static_osg_plugin_library PLUGIN_NAME) + set(PLUGIN_NAME_DBG ${PLUGIN_NAME}d ${PLUGIN_NAME}D ${PLUGIN_NAME}_d ${PLUGIN_NAME}_D ${PLUGIN_NAME}_debug ${PLUGIN_NAME}) + + # For now, users wishing to do a static build will need to pass the path to where the plugins reside + # More clever logic would need to deduce the path, probably installed under /lib/osgPlugins- + include(FindPkgMacros) + find_library(${PLUGIN_NAME}_LIBRARY_REL NAMES ${PLUGIN_NAME} HINTS ${OSG_PLUGIN_LIB_SEARCH_PATH}) + find_library(${PLUGIN_NAME}_LIBRARY_DBG NAMES ${PLUGIN_NAME_DBG} HINTS ${OSG_PLUGIN_LIB_SEARCH_PATH}) + make_library_set(${PLUGIN_NAME}_LIBRARY) + + if("${${PLUGIN_NAME}_LIBRARY}" STREQUAL "") + message(FATAL_ERROR "Unable to find static OpenSceneGraph plugin: ${PLUGIN_NAME}") + endif() + + set(OPENSCENEGRAPH_LIBRARIES ${OPENSCENEGRAPH_LIBRARIES} ${${PLUGIN_NAME}_LIBRARY}) + endmacro() + + add_definitions(-DOSG_LIBRARY_STATIC) + + set(PLUGIN_LIST + osgdb_png # depends on libpng, zlib + osgdb_tga + osgdb_dds + osgdb_jpeg # depends on libjpeg + ) + + foreach(PLUGIN ${PLUGIN_LIST}) + use_static_osg_plugin_library(${PLUGIN}) + endforeach() + + # OSG static plugins need to linked against their respective dependencies + set(PLUGIN_DEPS_LIST + PNG # needed by osgdb_png + ZLIB # needed by osgdb_png + JPEG # needed by osgdb_jpeg + ) + + macro(use_static_osg_plugin_dep DEPENDENCY) + find_package(${DEPENDENCY} REQUIRED) + + set(OPENSCENEGRAPH_LIBRARIES ${OPENSCENEGRAPH_LIBRARIES} ${${DEPENDENCY}_LIBRARIES}) + endmacro() + foreach(DEPENDENCY ${PLUGIN_DEPS_LIST}) + use_static_osg_plugin_dep(${DEPENDENCY}) + endforeach() + endif() + + if(QT_STATIC) + if(WIN32) + if(DESIRED_QT_VERSION MATCHES 4) + # QtCore needs WSAAsyncSelect from Ws2_32.lib + set(QT_QTCORE_LIBRARY ${QT_QTCORE_LIBRARY} Ws2_32.lib) + message("QT_QTCORE_LIBRARY: ${QT_QTCORE_LIBRARY}") + endif() + endif() + endif() + + find_package(MyGUI 3.2.1 REQUIRED) + find_package(SDL2 REQUIRED) + find_package(OpenAL REQUIRED) + find_package(Bullet 283 REQUIRED COMPONENTS BulletCollision LinearMath) + ENDIF(BUILD_OPENMW OR BUILD_OPENCS) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) @@ -305,12 +303,12 @@ include_directories("." SYSTEM ${SDL2_INCLUDE_DIR} ${Boost_INCLUDE_DIR} - ${MYGUI_INCLUDE_DIRS} + ${MyGUI_INCLUDE_DIRS} ${OPENAL_INCLUDE_DIR} ${Bullet_INCLUDE_DIRS} ) -link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${MYGUI_LIB_DIR}) +link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS}) if(MYGUI_STATIC) add_definitions(-DMYGUI_STATIC) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8a830f2cb..1f572c3f8 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -66,7 +66,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world - table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator + table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator globalcreator cellcreator pathgridcreator referenceablecreator startscriptcreator referencecreator scenesubview infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable dialoguespinbox recordbuttonbar tableeditidaction scripterrortable extendedcommandconfigurator diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 4eb9ea388..8b644edbe 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -370,8 +370,6 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event) selection.add (CSMWorld::CellCoordinates::fromId (cellId).first); paged->setCellSelection (selection); } - - noCell = false; } } else if (CSVRender::PagedWorldspaceWidget *paged = diff --git a/apps/opencs/view/render/orbitcameramode.cpp b/apps/opencs/view/render/orbitcameramode.cpp index c7d980454..ba25beaba 100644 --- a/apps/opencs/view/render/orbitcameramode.cpp +++ b/apps/opencs/view/render/orbitcameramode.cpp @@ -15,9 +15,9 @@ namespace CSVRender , mWorldspaceWidget(worldspaceWidget) , mCenterOnSelection(0) { - mCenterShortcut.reset(new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget)); + mCenterShortcut = new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget); mCenterShortcut->enable(false); - connect(mCenterShortcut.get(), SIGNAL(activated()), this, SLOT(centerSelection())); + connect(mCenterShortcut, SIGNAL(activated()), this, SLOT(centerSelection())); } OrbitCameraMode::~OrbitCameraMode() diff --git a/apps/opencs/view/render/orbitcameramode.hpp b/apps/opencs/view/render/orbitcameramode.hpp index 4f72de957..312cd1756 100644 --- a/apps/opencs/view/render/orbitcameramode.hpp +++ b/apps/opencs/view/render/orbitcameramode.hpp @@ -32,7 +32,7 @@ namespace CSVRender WorldspaceWidget* mWorldspaceWidget; QAction* mCenterOnSelection; - std::auto_ptr mCenterShortcut; + CSMPrefs::Shortcut* mCenterShortcut; private slots: diff --git a/apps/opencs/view/world/globalcreator.cpp b/apps/opencs/view/world/globalcreator.cpp new file mode 100644 index 000000000..c7b140e15 --- /dev/null +++ b/apps/opencs/view/world/globalcreator.cpp @@ -0,0 +1,26 @@ +#include "globalcreator.hpp" + +#include + +#include "../../model/world/data.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/columns.hpp" +#include "../../model/world/idtable.hpp" + +namespace CSVWorld +{ + void GlobalCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const + { + CSMWorld::IdTable* table = static_cast(getData().getTableModel(getCollectionId())); + + int index = table->findColumnIndex(CSMWorld::Columns::ColumnId_ValueType); + int type = (int)ESM::VT_Float; + + command.addValue(index, type); + } + + GlobalCreator::GlobalCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) + : GenericCreator (data, undoStack, id, true) + { + } +} diff --git a/apps/opencs/view/world/globalcreator.hpp b/apps/opencs/view/world/globalcreator.hpp new file mode 100644 index 000000000..8c6cc628c --- /dev/null +++ b/apps/opencs/view/world/globalcreator.hpp @@ -0,0 +1,22 @@ +#ifndef CSV_WORLD_GLOBALCREATOR_H +#define CSV_WORLD_GLOBALCREATOR_H + +#include "genericcreator.hpp" + +namespace CSVWorld +{ + class GlobalCreator : public GenericCreator + { + Q_OBJECT + + public: + + GlobalCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); + + protected: + + virtual void configureCreateCommand(CSMWorld::CreateCommand& command) const; + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 69c0c01cc..32661ed93 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -7,6 +7,7 @@ #include "scriptsubview.hpp" #include "regionmapsubview.hpp" #include "genericcreator.hpp" +#include "globalcreator.hpp" #include "cellcreator.hpp" #include "referenceablecreator.hpp" #include "referencecreator.hpp" @@ -32,7 +33,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) static const CSMWorld::UniversalId::Type sTableTypes[] = { - CSMWorld::UniversalId::Type_Globals, CSMWorld::UniversalId::Type_Classes, CSMWorld::UniversalId::Type_Factions, CSMWorld::UniversalId::Type_Races, @@ -78,6 +78,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Pathgrids, new CSVDoc::SubViewFactoryWithCreator >); + manager.add (CSMWorld::UniversalId::Type_Globals, + new CSVDoc::SubViewFactoryWithCreator >); + // Subviews for resources tables manager.add (CSMWorld::UniversalId::Type_Meshes, new CSVDoc::SubViewFactoryWithCreator); diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 87b9e114e..8f1fb74b8 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -134,7 +134,7 @@ target_link_libraries(openmw ${Boost_PROGRAM_OPTIONS_LIBRARY} ${OPENAL_LIBRARY} ${FFmpeg_LIBRARIES} - ${MYGUI_LIBRARIES} + ${MyGUI_LIBRARIES} ${SDL2_LIBRARY} "osg-ffmpeg-videoplayer" "oics" diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 8907a5f8d..3642a22ed 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -112,7 +112,7 @@ namespace MWClass std::string text; text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 2e4667016..867e14bd9 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -226,8 +226,10 @@ namespace MWClass typeText = "#{sLight}"; else if (armorType == ESM::Skill::MediumArmor) typeText = "#{sMedium}"; - else + else if (armorType == ESM::Skill::HeavyArmor) typeText = "#{sHeavy}"; + else // if (armorType == ESM::Skill::Unarmored) + typeText = ""; text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(getEffectiveArmorRating(ptr, MWMechanics::getPlayer())); @@ -236,7 +238,9 @@ namespace MWClass text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/" + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")"; + if (typeText != "") + text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight) + " (" + typeText + ")"; + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index a7d8ed8f4..f2c97d770 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -126,7 +126,7 @@ namespace MWClass std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 20ebab314..1d99ee8e2 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -175,7 +175,7 @@ namespace MWClass std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 09891652a..47e24f0d6 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -190,7 +190,7 @@ namespace MWClass } else { - boost::shared_ptr action(new MWWorld::FailedAction); + boost::shared_ptr action(new MWWorld::FailedAction(std::string(), ptr)); action->setSound(lockedSound); return action; } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index a54b64897..99d4a6011 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -25,6 +25,7 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" +#include "../mwrender/animation.hpp" #include "../mwmechanics/actorutil.hpp" @@ -112,6 +113,20 @@ namespace MWClass bool hasKey = false; std::string keyName; + // make door glow if player activates it with telekinesis + if (actor == MWBase::Environment::get().getWorld()->getPlayerPtr() && + MWBase::Environment::get().getWorld()->getDistanceToFacedObject() > + MWBase::Environment::get().getWorld()->getMaxActivationDistance()) + { + MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr); + + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + int index = ESM::MagicEffect::effectStringToId("sEffectTelekinesis"); + const ESM::MagicEffect *effect = store.get().find(index); + + animation->addSpellCastGlow(effect); // TODO: Telekinesis glow should only be as long as the door animation + } + // make key id lowercase std::string keyId = ptr.getCellRef().getKey(); Misc::StringUtils::lowerCaseInPlace(keyId); @@ -205,7 +220,7 @@ namespace MWClass else { // locked, and we can't open. - boost::shared_ptr action(new MWWorld::FailedAction); + boost::shared_ptr action(new MWWorld::FailedAction(std::string(), ptr)); action->setSound(lockedSound); return action; } diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 99a50a67a..a9a995f2f 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -125,7 +125,7 @@ namespace MWClass std::string text; - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index c7ebc184f..335c0453a 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -159,11 +159,9 @@ namespace MWClass if (Settings::Manager::getBool("show effect duration","Game")) text += "\n#{sDuration}: " + MWGui::ToolTips::toString(ptr.getClass().getRemainingUsageTime(ptr)); - if (ref->mBase->mData.mWeight != 0) - { - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); - text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - } + + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); + text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index d3889d2fc..a335415ac 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -126,7 +126,7 @@ namespace MWClass text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 2f41fca30..3e1d750ad 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -159,11 +159,9 @@ namespace MWClass std::string text; + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); if (!gold && !ref->mBase->mData.mIsKey) - { - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); - } if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index f4f26ed93..88f5c4228 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1203,6 +1203,7 @@ namespace MWClass switch(boots->getClass().getEquipmentSkill(*boots)) { + case ESM::Skill::Unarmored: case ESM::Skill::LightArmor: return (name == "left") ? "FootLightLeft" : "FootLightRight"; case ESM::Skill::MediumArmor: diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 79d33ba60..185aa66cb 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -126,7 +126,7 @@ namespace MWClass text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 271f52bde..cbdfade2b 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -129,7 +129,7 @@ namespace MWClass text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index f3f840921..470c7040d 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -318,7 +318,7 @@ namespace MWClass + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); } - text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight); + text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); info.enchant = ref->mBase->mEnchant; diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index e64eb510e..1434455b2 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -135,27 +135,6 @@ namespace MWGui MWMechanics::CreatureStats& creatureStats = player.getClass().getCreatureStats(player); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); - const ESM::NPC *playerData = player.get()->mBase; - - // set class image - const ESM::Class *cls = - world->getStore().get().find(playerData->mClass); - - if(world->getStore().get().isDynamic(cls->mId)) - { - // Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found. - MWWorld::SharedIterator it = world->getStore().get().begin(); - for(; it != world->getStore().get().end(); ++it) - { - if(it->mData.mIsPlayable && it->mData.mSpecialization == 2 && it->mData.mAttribute[0] == 4 && it->mData.mAttribute[1] == 3) - break; - } - if (it == world->getStore().get().end()) - it = world->getStore().get().begin(); - if (it != world->getStore().get().end()) - cls = &*it; - } - setClassImage(mClassImage, getLevelupClassImage(pcStats.getSkillIncreasesForSpecialization(0), pcStats.getSkillIncreasesForSpecialization(1), pcStats.getSkillIncreasesForSpecialization(2))); diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 7c52f09cb..d51af87d9 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -163,7 +163,6 @@ namespace MWGui , mInterior(false) , mLocalMap(NULL) , mCompass(NULL) - , mPrefix() , mChanged(true) , mFogOfWarToggled(true) , mFogOfWarEnabled(fogOfWarEnabled) @@ -174,6 +173,7 @@ namespace MWGui , mMarkerUpdateTimer(0.0f) , mLastDirectionX(0.0f) , mLastDirectionY(0.0f) + , mNeedDoorMarkersUpdate(false) { mCustomMarkers.eventMarkersChanged += MyGUI::newDelegate(this, &LocalMapBase::updateCustomMarkers); } @@ -368,12 +368,6 @@ namespace MWGui applyFogOfWar(); - - // clear all previous door markers - for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) - MyGUI::Gui::getInstance().destroyWidget(*it); - mDoorMarkerWidgets.clear(); - // Update the map textures TextureVector textures; for (int mx=0; mx doors; - if (interior) - { - MWWorld::CellStore* cell = world->getInterior (mPrefix); - world->getDoorMarkers(cell, doors); - } - else - { - for (int dX=-mCellDistance; dX<=mCellDistance; ++dX) - { - for (int dY=-mCellDistance; dY<=mCellDistance; ++dY) - { - MWWorld::CellStore* cell = world->getExterior (mCurX+dX, mCurY+dY); - world->getDoorMarkers(cell, doors); - } - } - } - - // Create a widget for each marker - int counter = 0; - for (std::vector::iterator it = doors.begin(); it != doors.end(); ++it) - { - MWBase::World::DoorMarker marker = *it; - - std::vector destNotes; - CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest); - for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; ++it) - destNotes.push_back(it->second.mNote); - - MarkerUserData data (mLocalMapRender); - data.notes = destNotes; - data.caption = marker.name; - MyGUI::IntPoint widgetPos = getMarkerPosition(marker.x, marker.y, data); - MyGUI::IntCoord widgetCoord(widgetPos.left - 4, - widgetPos.top - 4, - 8, 8); - ++counter; - MarkerWidget* markerWidget = mLocalMap->createWidget("MarkerButton", - widgetCoord, MyGUI::Align::Default); - markerWidget->setNormalColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}"))); - markerWidget->setHoverColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal_over}"))); - markerWidget->setDepth(Local_MarkerLayer); - markerWidget->setNeedMouseFocus(true); - // Used by tooltips to not show the tooltip if marker is hidden by fog of war - markerWidget->setUserString("ToolTipType", "MapMarker"); - - markerWidget->setUserData(data); - doorMarkerCreated(markerWidget); - - mDoorMarkerWidgets.push_back(markerWidget); - } + // Delay the door markers update until scripts have been given a chance to run. + // If we don't do this, door markers that should be disabled will still appear on the map. + mNeedDoorMarkersUpdate = true; updateMagicMarkers(); updateCustomMarkers(); @@ -565,6 +508,12 @@ namespace MWGui void LocalMapBase::onFrame(float dt) { + if (mNeedDoorMarkersUpdate) + { + updateDoorMarkers(); + mNeedDoorMarkersUpdate = false; + } + mMarkerUpdateTimer += dt; if (mMarkerUpdateTimer >= 0.25) @@ -574,6 +523,69 @@ namespace MWGui } } + void LocalMapBase::updateDoorMarkers() + { + // clear all previous door markers + for (std::vector::iterator it = mDoorMarkerWidgets.begin(); it != mDoorMarkerWidgets.end(); ++it) + MyGUI::Gui::getInstance().destroyWidget(*it); + mDoorMarkerWidgets.clear(); + + MWBase::World* world = MWBase::Environment::get().getWorld(); + + // Retrieve the door markers we want to show + std::vector doors; + if (mInterior) + { + MWWorld::CellStore* cell = world->getInterior (mPrefix); + world->getDoorMarkers(cell, doors); + } + else + { + for (int dX=-mCellDistance; dX<=mCellDistance; ++dX) + { + for (int dY=-mCellDistance; dY<=mCellDistance; ++dY) + { + MWWorld::CellStore* cell = world->getExterior (mCurX+dX, mCurY+dY); + world->getDoorMarkers(cell, doors); + } + } + } + + // Create a widget for each marker + int counter = 0; + for (std::vector::iterator it = doors.begin(); it != doors.end(); ++it) + { + MWBase::World::DoorMarker marker = *it; + + std::vector destNotes; + CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest); + for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; ++it) + destNotes.push_back(it->second.mNote); + + MarkerUserData data (mLocalMapRender); + data.notes = destNotes; + data.caption = marker.name; + MyGUI::IntPoint widgetPos = getMarkerPosition(marker.x, marker.y, data); + MyGUI::IntCoord widgetCoord(widgetPos.left - 4, + widgetPos.top - 4, + 8, 8); + ++counter; + MarkerWidget* markerWidget = mLocalMap->createWidget("MarkerButton", + widgetCoord, MyGUI::Align::Default); + markerWidget->setNormalColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}"))); + markerWidget->setHoverColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal_over}"))); + markerWidget->setDepth(Local_MarkerLayer); + markerWidget->setNeedMouseFocus(true); + // Used by tooltips to not show the tooltip if marker is hidden by fog of war + markerWidget->setUserString("ToolTipType", "MapMarker"); + + markerWidget->setUserData(data); + doorMarkerCreated(markerWidget); + + mDoorMarkerWidgets.push_back(markerWidget); + } + } + void LocalMapBase::updateMagicMarkers() { // clear all previous markers diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 773522903..977773179 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -155,6 +155,10 @@ namespace MWGui float mLastDirectionX; float mLastDirectionY; + + private: + void updateDoorMarkers(); + bool mNeedDoorMarkersUpdate; }; class EditNoteDialog : public MWGui::WindowModal diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 9e26cb0f9..4bcf273cd 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -586,6 +586,14 @@ namespace MWGui return stream.str(); } + std::string ToolTips::getWeightString(const float weight, const std::string& prefix) + { + if (weight == 0) + return ""; + else + return "\n" + prefix + ": " + toString(weight); + } + std::string ToolTips::getValueString(const int value, const std::string& prefix) { if (value == 0) diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 1fc736bff..de5b89b7f 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -62,6 +62,7 @@ namespace MWGui void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y); ///< set the screen-space position of the tooltip for focused object + static std::string getWeightString(const float weight, const std::string& prefix); static std::string getValueString(const int value, const std::string& prefix); ///< @return "prefix: value" or "" if value is 0 diff --git a/apps/openmw/mwgui/windowbase.cpp b/apps/openmw/mwgui/windowbase.cpp index c9d1b0617..99b74529e 100644 --- a/apps/openmw/mwgui/windowbase.cpp +++ b/apps/openmw/mwgui/windowbase.cpp @@ -79,12 +79,13 @@ void WindowModal::close() NoDrop::NoDrop(DragAndDrop *drag, MyGUI::Widget *widget) : mWidget(widget), mDrag(drag), mTransparent(false) { - if (!mWidget) - throw std::runtime_error("NoDrop needs a non-NULL widget!"); } void NoDrop::onFrame(float dt) { + if (!mWidget) + return; + MyGUI::IntPoint mousePos = MyGUI::InputManager::getInstance().getMousePosition(); if (mDrag->mIsOnDragAndDrop) @@ -113,5 +114,6 @@ void NoDrop::onFrame(float dt) void NoDrop::setAlpha(float alpha) { - mWidget->setAlpha(alpha); + if (mWidget) + mWidget->setAlpha(alpha); } diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index a6694c314..87fb3b9b7 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -812,9 +812,6 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->moveObject(actor, static_cast(dest.mX), static_cast(dest.mY), static_cast(dest.mZ)); actor.getClass().adjustPosition(actor, false); - - // may have changed cell - storage.mPopulateAvailableNodes = true; } int AiWander::OffsetToPreventOvercrowding() diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 07aba2f7d..e65195531 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -44,6 +44,7 @@ #include "creaturestats.hpp" #include "security.hpp" #include "actorutil.hpp" +#include "spellcasting.hpp" namespace { @@ -961,34 +962,6 @@ void CharacterController::updateIdleStormState(bool inwater) } } -void CharacterController::castSpell(const std::string &spellid) -{ - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; - - const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Spell *spell = store.get().find(spellid); - const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0); - - const ESM::MagicEffect *effect; - effect = store.get().find(effectentry.mEffectID); - - const ESM::Static* castStatic; - if (!effect->mCasting.empty()) - castStatic = store.get().find (effect->mCasting); - else - castStatic = store.get().find ("VFX_DefaultCast"); - - mAnimation->addEffect("meshes\\" + castStatic->mModel, effect->mIndex); - - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(!effect->mCastSound.empty()) - sndMgr->playSound3D(mPtr, effect->mCastSound, 1.0f, 1.0f); - else - sndMgr->playSound3D(mPtr, schools[effect->mData.mSchool]+" cast", 1.0f, 1.0f); -} - bool CharacterController::updateCreatureState() { const MWWorld::Class &cls = mPtr.getClass(); @@ -1020,7 +993,8 @@ bool CharacterController::updateCreatureState() const std::string spellid = stats.getSpells().getSelectedSpell(); if (!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr)) { - castSpell(spellid); + MWMechanics::CastSpell cast(mPtr, NULL); + cast.playSpellCastingEffects(spellid); if (!mAnimation->hasAnimation("spellcast")) MWBase::Environment::get().getWorld()->castSpell(mPtr); // No "release" text key to use, so cast immediately @@ -1248,7 +1222,8 @@ bool CharacterController::updateWeaponState() if(!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr)) { - castSpell(spellid); + MWMechanics::CastSpell cast(mPtr, NULL); + cast.playSpellCastingEffects(spellid); const ESM::Spell *spell = store.get().find(spellid); const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 190e171b3..d5dc5fe28 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -214,8 +214,6 @@ class CharacterController : public MWRender::Animation::TextKeyListener void updateHeadTracking(float duration); - void castSpell(const std::string& spellid); - void updateMagicEffects(); void playDeath(float startpoint, CharacterState death); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 5b09a9b02..38d1fd0b2 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -358,6 +358,14 @@ namespace MWMechanics bool castByPlayer = (!caster.isEmpty() && caster == getPlayer()); + ActiveSpells targetSpells; + if (target.getClass().isActor()) + targetSpells = target.getClass().getCreatureStats(target).getActiveSpells(); + + bool canCastAnEffect = false; // For bound equipment.If this remains false + // throughout the iteration of this spell's + // effects, we display a "can't re-cast" message + for (std::vector::const_iterator effectIt (effects.mList.begin()); effectIt!=effects.mList.end(); ++effectIt) { @@ -368,6 +376,16 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->getStore().get().find ( effectIt->mEffectID); + // Re-casting a bound equipment effect has no effect if the spell is still active + if (magicEffect->mData.mFlags & ESM::MagicEffect::NonRecastable && targetSpells.isSpellActive(mId)) + { + if (effectIt == (effects.mList.end() - 1) && !canCastAnEffect && castByPlayer) + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicCannotRecast}"); + continue; + } + else + canCastAnEffect = true; + if (!checkEffectTarget(effectIt->mEffectID, target, castByPlayer)) continue; @@ -576,6 +594,10 @@ namespace MWMechanics { if (effectId == ESM::MagicEffect::Lock) { + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::MagicEffect *magiceffect = store.get().find(effectId); + MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(target); + animation->addSpellCastGlow(magiceffect); if (target.getCellRef().getLockLevel() < magnitude) //If the door is not already locked to a higher value, lock it to spell magnitude { if (caster == getPlayer()) @@ -586,6 +608,10 @@ namespace MWMechanics } else if (effectId == ESM::MagicEffect::Open) { + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::MagicEffect *magiceffect = store.get().find(effectId); + MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(target); + animation->addSpellCastGlow(magiceffect); if (target.getCellRef().getLockLevel() <= magnitude) { if (target.getCellRef().getLockLevel() > 0) @@ -863,6 +889,10 @@ namespace MWMechanics if (mCaster == getPlayer() && spellIncreasesSkill(spell)) mCaster.getClass().skillUsageSucceeded(mCaster, spellSchoolToSkill(school), 0); + + // A non-actor doesn't play its spell cast effects from a character controller, so play them here + if (!mCaster.getClass().isActor()) + playSpellCastingEffects(mId); inflict(mCaster, mCaster, spell->mEffects, ESM::RT_Self); @@ -957,6 +987,42 @@ namespace MWMechanics return true; } + void CastSpell::playSpellCastingEffects(const std::string &spellid){ + + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Spell *spell = store.get().find(spellid); + const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0); + + const ESM::MagicEffect *effect; + effect = store.get().find(effectentry.mEffectID); + + MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(mCaster); + + if (mCaster.getClass().isActor()) // TODO: Non-actors (except for large statics?) should also create a spell cast vfx + { + const ESM::Static* castStatic; + if (!effect->mCasting.empty()) + castStatic = store.get().find (effect->mCasting); + else + castStatic = store.get().find ("VFX_DefaultCast"); + + animation->addEffect("meshes\\" + castStatic->mModel, effect->mIndex); + } + + if (!mCaster.getClass().isActor()) + animation->addSpellCastGlow(effect); + + static const std::string schools[] = { + "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" + }; + + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + if(!effect->mCastSound.empty()) + sndMgr->playSound3D(mCaster, effect->mCastSound, 1.0f, 1.0f); + else + sndMgr->playSound3D(mCaster, schools[effect->mData.mSchool]+" cast", 1.0f, 1.0f); + } + int getEffectiveEnchantmentCastCost(float castCost, const MWWorld::Ptr &actor) { /* diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index ae20a39d0..aba263b01 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -92,6 +92,8 @@ namespace MWMechanics /// @note Auto detects if spell, ingredient or potion bool cast (const std::string& id); + void playSpellCastingEffects(const std::string &spellid); + /// @note \a target can be any type of object, not just actors. /// @note \a caster can be any type of object, or even an empty object. void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster, diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 0412e1e41..e5614f3f8 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -86,48 +86,6 @@ namespace std::vector > mToRemove; }; - class GlowUpdater : public SceneUtil::StateSetUpdater - { - public: - GlowUpdater(int texUnit, osg::Vec4f color, const std::vector >& textures) - : mTexUnit(texUnit) - , mColor(color) - , mTextures(textures) - { - } - - virtual void setDefaults(osg::StateSet *stateset) - { - stateset->setTextureMode(mTexUnit, GL_TEXTURE_2D, osg::StateAttribute::ON); - - osg::TexGen* texGen = new osg::TexGen; - texGen->setMode(osg::TexGen::SPHERE_MAP); - - stateset->setTextureAttributeAndModes(mTexUnit, texGen, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - - osg::TexEnvCombine* texEnv = new osg::TexEnvCombine; - texEnv->setSource0_RGB(osg::TexEnvCombine::CONSTANT); - texEnv->setConstantColor(mColor); - texEnv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); - texEnv->setSource2_RGB(osg::TexEnvCombine::TEXTURE); - texEnv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); - - stateset->setTextureAttributeAndModes(mTexUnit, texEnv, osg::StateAttribute::ON); - } - - virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) - { - float time = nv->getFrameStamp()->getSimulationTime(); - int index = (int)(time*16) % mTextures.size(); - stateset->setTextureAttribute(mTexUnit, mTextures[index], osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - } - - private: - int mTexUnit; - osg::Vec4f mColor; - std::vector > mTextures; - }; - class NodeMapVisitor : public osg::NodeVisitor { public: @@ -289,6 +247,134 @@ namespace namespace MWRender { + class GlowUpdater : public SceneUtil::StateSetUpdater + { + public: + GlowUpdater(int texUnit, osg::Vec4f color, const std::vector >& textures, + osg::Node* node, float duration, Resource::ResourceSystem* resourcesystem) + : mTexUnit(texUnit) + , mColor(color) + , mOriginalColor(color) + , mTextures(textures) + , mNode(node) + , mDuration(duration) + , mOriginalDuration(duration) + , mStartingTime(0) + , mResourceSystem(resourcesystem) + , mColorChanged(false) + , mDone(false) + { + } + + virtual void setDefaults(osg::StateSet *stateset) + { + if (mDone) + removeTexture(stateset); + else + { + stateset->setTextureMode(mTexUnit, GL_TEXTURE_2D, osg::StateAttribute::ON); + osg::TexGen* texGen = new osg::TexGen; + texGen->setMode(osg::TexGen::SPHERE_MAP); + + stateset->setTextureAttributeAndModes(mTexUnit, texGen, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + + osg::TexEnvCombine* texEnv = new osg::TexEnvCombine; + texEnv->setSource0_RGB(osg::TexEnvCombine::CONSTANT); + texEnv->setConstantColor(mColor); + texEnv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texEnv->setSource2_RGB(osg::TexEnvCombine::TEXTURE); + texEnv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR); + + stateset->setTextureAttributeAndModes(mTexUnit, texEnv, osg::StateAttribute::ON); + stateset->addUniform(new osg::Uniform("envMapColor", mColor)); + } + } + + void removeTexture(osg::StateSet* stateset) + { + stateset->removeTextureAttribute(mTexUnit, osg::StateAttribute::TEXTURE); + stateset->removeTextureAttribute(mTexUnit, osg::StateAttribute::TEXGEN); + stateset->removeTextureAttribute(mTexUnit, osg::StateAttribute::TEXENV); + stateset->removeTextureMode(mTexUnit, GL_TEXTURE_2D); + stateset->removeUniform("envMapColor"); + + osg::StateSet::TextureAttributeList& list = stateset->getTextureAttributeList(); + while (list.size() && list.rbegin()->empty()) + list.pop_back(); + } + + virtual void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) + { + if (mColorChanged){ + this->reset(); + setDefaults(stateset); + mColorChanged = false; + } + if (mDone) + return; + + // Set the starting time to measure glow duration from if this is a temporary glow + if ((mDuration >= 0) && mStartingTime == 0) + mStartingTime = nv->getFrameStamp()->getSimulationTime(); + + float time = nv->getFrameStamp()->getSimulationTime(); + int index = (int)(time*16) % mTextures.size(); + stateset->setTextureAttribute(mTexUnit, mTextures[index], osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + + if ((mDuration >= 0) && (time - mStartingTime > mDuration)) // If this is a temporary glow and it has finished its duration + { + if (mOriginalDuration >= 0) // if this glowupdater was a temporary glow since its creation + { + removeTexture(stateset); + this->reset(); + mDone = true; + mResourceSystem->getSceneManager()->recreateShaders(mNode); + } + if (mOriginalDuration < 0) // if this glowupdater was originally a permanent glow + { + mDuration = mOriginalDuration; + mStartingTime = 0; + mColor = mOriginalColor; + this->reset(); + setDefaults(stateset); + } + } + } + + bool isPermanentGlowUpdater() + { + return (mDuration < 0); + } + + bool isDone() + { + return mDone; + } + + void setColor(osg::Vec4f color) + { + mColor = color; + mColorChanged = true; + } + + void setDuration(float duration) + { + mDuration = duration; + } + + private: + int mTexUnit; + osg::Vec4f mColor; + osg::Vec4f mOriginalColor; // for restoring the color of a permanent glow after a temporary glow on the object finishes + std::vector > mTextures; + osg::Node* mNode; + float mDuration; + float mOriginalDuration; // for recording that this is originally a permanent glow if it is changed to a temporary one + float mStartingTime; + Resource::ResourceSystem* mResourceSystem; + bool mColorChanged; + bool mDone; + }; struct Animation::AnimSource { @@ -1106,7 +1192,29 @@ namespace MWRender int mLowestUnusedTexUnit; }; - void Animation::addGlow(osg::ref_ptr node, osg::Vec4f glowColor) + void Animation::addSpellCastGlow(const ESM::MagicEffect *effect) + { + osg::Vec4f glowColor(1,1,1,1); + glowColor.x() = effect->mData.mRed / 255.f; + glowColor.y() = effect->mData.mGreen / 255.f; + glowColor.z() = effect->mData.mBlue / 255.f; + + if (!mGlowUpdater || (mGlowUpdater->isDone() || (mGlowUpdater->isPermanentGlowUpdater() == true))) + { + if (mGlowUpdater && mGlowUpdater->isDone()) + mObjectRoot->removeUpdateCallback(mGlowUpdater); + + if (mGlowUpdater && mGlowUpdater->isPermanentGlowUpdater()) + { + mGlowUpdater->setColor(glowColor); + mGlowUpdater->setDuration(1.5); // Glow length measured from original engine as about 1.5 seconds + } + else + addGlow(mObjectRoot, glowColor, 1.5); + } + } + + void Animation::addGlow(osg::ref_ptr node, osg::Vec4f glowColor, float glowDuration) { std::vector > textures; for (int i=0; i<32; ++i) @@ -1130,18 +1238,22 @@ namespace MWRender FindLowestUnusedTexUnitVisitor findLowestUnusedTexUnitVisitor; node->accept(findLowestUnusedTexUnitVisitor); int texUnit = findLowestUnusedTexUnitVisitor.mLowestUnusedTexUnit; - osg::ref_ptr glowupdater (new GlowUpdater(texUnit, glowColor, textures)); - node->addUpdateCallback(glowupdater); + osg::ref_ptr glowUpdater = new GlowUpdater(texUnit, glowColor, textures, node, glowDuration, mResourceSystem); + mGlowUpdater = glowUpdater; + node->addUpdateCallback(glowUpdater); + // set a texture now so that the ShaderVisitor can find it osg::ref_ptr writableStateSet = NULL; if (!node->getStateSet()) writableStateSet = node->getOrCreateStateSet(); else + { writableStateSet = osg::clone(node->getStateSet(), osg::CopyOp::SHALLOW_COPY); + node->setStateSet(writableStateSet); + } writableStateSet->setTextureAttributeAndModes(texUnit, textures.front(), osg::StateAttribute::ON); writableStateSet->addUniform(new osg::Uniform("envMapColor", glowColor)); - mResourceSystem->getSceneManager()->recreateShaders(node); } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index ad9d4ab4a..a837a26ae 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -8,6 +8,7 @@ namespace ESM { struct Light; + struct MagicEffect; } namespace Resource @@ -32,6 +33,7 @@ namespace MWRender class ResetAccumRootCallback; class RotateController; +class GlowUpdater; class EffectAnimationTime : public SceneUtil::ControllerSource { @@ -261,6 +263,7 @@ protected: float mHeadPitchRadians; osg::ref_ptr mGlowLight; + osg::ref_ptr mGlowUpdater; float mAlpha; @@ -317,7 +320,7 @@ protected: osg::Vec4f getEnchantmentColor(const MWWorld::ConstPtr& item) const; - void addGlow(osg::ref_ptr node, osg::Vec4f glowColor); + void addGlow(osg::ref_ptr node, osg::Vec4f glowColor, float glowDuration = -1); /// Set the render bin for this animation's object root. May be customized by subclasses. virtual void setRenderBin(); @@ -351,6 +354,8 @@ public: void removeEffect (int effectId); void getLoopingEffects (std::vector& out) const; + void addSpellCastGlow(const ESM::MagicEffect *effect); + virtual void updatePtr(const MWWorld::Ptr &ptr); bool hasAnimation(const std::string &anim) const; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ab76b86f1..8f73036e9 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -258,6 +258,8 @@ namespace MWRender RenderingManager::~RenderingManager() { + // let background loading thread finish before we delete anything else + mWorkQueue = NULL; } MWRender::Objects& RenderingManager::getObjects() diff --git a/apps/openmw/mwrender/util.cpp b/apps/openmw/mwrender/util.cpp index 876ec285f..cb1953c61 100644 --- a/apps/openmw/mwrender/util.cpp +++ b/apps/openmw/mwrender/util.cpp @@ -22,7 +22,7 @@ void overrideTexture(const std::string &texture, Resource::ResourceSystem *resou osg::ref_ptr stateset; if (node->getStateSet()) - stateset = static_cast(node->getStateSet()->clone(osg::CopyOp::SHALLOW_COPY)); + stateset = osg::clone(node->getStateSet(), osg::CopyOp::SHALLOW_COPY); else stateset = new osg::StateSet; diff --git a/apps/openmw/mwscript/animationextensions.cpp b/apps/openmw/mwscript/animationextensions.cpp index 44c4612ec..347bbca56 100644 --- a/apps/openmw/mwscript/animationextensions.cpp +++ b/apps/openmw/mwscript/animationextensions.cpp @@ -89,7 +89,7 @@ namespace MWScript throw std::runtime_error ("animation mode out of range"); } - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup (ptr, group, mode, loops, true); + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup (ptr, group, mode, loops + 1, true); } }; diff --git a/apps/openmw/mwworld/failedaction.cpp b/apps/openmw/mwworld/failedaction.cpp index 49ca9dae0..45df75a32 100644 --- a/apps/openmw/mwworld/failedaction.cpp +++ b/apps/openmw/mwworld/failedaction.cpp @@ -8,8 +8,8 @@ namespace MWWorld { - FailedAction::FailedAction(const std::string &msg) - : Action(false), mMessage(msg) + FailedAction::FailedAction(const std::string &msg, const Ptr& target) + : Action(false, target), mMessage(msg) { } void FailedAction::executeImp(const Ptr &actor) diff --git a/apps/openmw/mwworld/failedaction.hpp b/apps/openmw/mwworld/failedaction.hpp index f248ee3bd..bafbb6f2d 100644 --- a/apps/openmw/mwworld/failedaction.hpp +++ b/apps/openmw/mwworld/failedaction.hpp @@ -13,7 +13,7 @@ namespace MWWorld virtual void executeImp(const Ptr &actor); public: - FailedAction(const std::string &message = std::string()); + FailedAction(const std::string &message = std::string(), const Ptr& target = Ptr()); }; } diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 1cfba0daf..46991c440 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -96,8 +96,8 @@ T TimeOfDayInterpolator::getValue(const float gameHour, const TimeOfDaySettin -template class TimeOfDayInterpolator; -template class TimeOfDayInterpolator; +template class MWWorld::TimeOfDayInterpolator; +template class MWWorld::TimeOfDayInterpolator; Weather::Weather(const std::string& name, const Fallback::Map& fallback, diff --git a/cmake/FindFreetype.cmake b/cmake/FindFreetype.cmake index c154628da..3d28613ae 100644 --- a/cmake/FindFreetype.cmake +++ b/cmake/FindFreetype.cmake @@ -48,7 +48,6 @@ # ====================================== include(LibFindMacros) -include(PreprocessorUtils) set(_REGULAR_INSTALL_PATHS /usr/X11R6 @@ -78,21 +77,13 @@ find_path(Freetype_OLD_INCLUDE_DIR PATH_SUFFIXES freetype2 NO_DEFAULT_PATH ) - -# get version from freetype.h -find_file(Freetype_HEADER - NAMES freetype.h - PATH_SUFFIXES freetype - PATHS ${Freetype_OLD_INCLUDE_DIR} +libfind_version_n_header(Freetype + NAMES freetype/freetype.h freetype.h + PATHS Freetype_OLD_INCLUDE_DIR + DEFINES FREETYPE_MAJOR FREETYPE_MINOR FREETYPE_PATCH ) -if (Freetype_HEADER) - get_version_from_n_defines(Freetype_VERSION - ${Freetype_HEADER} - FREETYPE_MAJOR FREETYPE_MINOR FREETYPE_PATCH - ) -endif() -set(Freetype_PROCESS_INCLUDES Freetype_INCLUDE_DIR Freetype_OLD_INCLUDE_DIR) +set(Freetype_PROCESS_INCLUDES Freetype_OLD_INCLUDE_DIR) libfind_process(Freetype) if (Freetype_INCLUDE_DIRS) diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index 0b3ac730e..473f543ba 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -1,158 +1,53 @@ # - Find MyGUI includes and library # +# This module accepts the following env variables +# MYGUI_HOME - Can be set to MyGUI install path or Windows build path +# # This module defines -# MYGUI_INCLUDE_DIRS -# MYGUI_LIBRARIES, the libraries to link against to use MYGUI. -# MYGUI_LIB_DIR, the location of the libraries -# MYGUI_FOUND, If false, do not try to use MYGUI +# MyGUI_INCLUDE_DIRS +# MyGUI_LIBRARIES, the libraries to link against to use MyGUI. +# MyGUI_FOUND, If false, do not try to use MyGUI # # Copyright © 2007, Matt Williams # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. -CMAKE_POLICY(PUSH) -include(FindPkgMacros) -include(PreprocessorUtils) - -# IF (MYGUI_LIBRARIES AND MYGUI_INCLUDE_DIRS) - # SET(MYGUI_FIND_QUIETLY TRUE) -# ENDIF (MYGUI_LIBRARIES AND MYGUI_INCLUDE_DIRS) - -IF (WIN32) #Windows - - MESSAGE(STATUS "Looking for MyGUI") - - IF(MINGW) - - FIND_PATH ( MYGUI_INCLUDE_DIRS MyGUI.h PATH_SUFFIXES MYGUI) - FIND_LIBRARY ( MYGUI_LIBRARIES_REL NAMES - libMyGUIEngine${CMAKE_SHARED_LIBRARY_SUFFIX} - HINTS - ${MYGUI_LIB_DIR} - PATH_SUFFIXES "" release relwithdebinfo minsizerel ) - - FIND_LIBRARY ( MYGUI_LIBRARIES_DBG NAMES - libMyGUIEngine_d${CMAKE_SHARED_LIBRARY_SUFFIX} - HINTS - ${MYGUI_LIB_DIR} - PATH_SUFFIXES "" debug ) - - make_library_set ( MYGUI_LIBRARIES ) - - MESSAGE ("${MYGUI_LIBRARIES}") - ENDIF(MINGW) - - SET(MYGUISDK $ENV{MYGUI_HOME}) - IF (MYGUISDK) - findpkg_begin ( "MYGUI" ) - MESSAGE(STATUS "Using MyGUI in MyGUI SDK") - STRING(REGEX REPLACE "[\\]" "/" MYGUISDK "${MYGUISDK}" ) - - find_path ( MYGUI_INCLUDE_DIRS MyGUI.h "${MYGUISDK}/MyGUIEngine/include" NO_DEFAULT_PATH ) - - SET ( MYGUI_LIB_DIR ${MYGUISDK}/lib ${MYGUISDK}/*/lib ) - - if ( MYGUI_STATIC ) - set(LIB_SUFFIX "Static") - find_package(Freetype) - endif ( MYGUI_STATIC ) - - find_library ( MYGUI_LIBRARIES_REL NAMES MyGUIEngine${LIB_SUFFIX}.lib HINTS ${MYGUI_LIB_DIR} PATH_SUFFIXES "" release relwithdebinfo minsizerel ) - find_library ( MYGUI_LIBRARIES_DBG NAMES MyGUIEngine${LIB_SUFFIX}_d.lib HINTS ${MYGUI_LIB_DIR} PATH_SUFFIXES "" debug ) - - make_library_set ( MYGUI_LIBRARIES ) - - MESSAGE ("${MYGUI_LIBRARIES}") - - #findpkg_finish ( "MYGUI" ) - ENDIF (MYGUISDK) -ELSE (WIN32) #Unix - CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR) - FIND_PACKAGE(PkgConfig) - IF(MYGUI_STATIC) - # don't use pkgconfig on OS X, find freetype & append it's libs to resulting MYGUI_LIBRARIES - IF (NOT APPLE AND NOT ANDROID) - PKG_SEARCH_MODULE(MYGUI MYGUIStatic MyGUIStatic) - IF (MYGUI_INCLUDE_DIRS) - SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) - SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") - ELSE (MYGUI_INCLUDE_DIRS) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES myguistatic PATHS /usr/lib /usr/local/lib) - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (MYGUI_INCLUDE_DIRS) - ELSE (NOT APPLE AND NOT ANDROID) - SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${MYGUI_DEPENDENCIES_DIR}) - FIND_PACKAGE(Freetype REQUIRED) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES MyGUIEngineStatic PATHS /usr/lib /usr/local/lib ${OPENMW_DEPENDENCIES_DIR}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (NOT APPLE AND NOT ANDROID) - ELSE(MYGUI_STATIC) - PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI) - IF (MYGUI_INCLUDE_DIRS) - SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) - SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") - ELSE (MYGUI_INCLUDE_DIRS) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES MyGUIEngine PATHS /usr/local/lib /usr/lib) - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (MYGUI_INCLUDE_DIRS) - ENDIF(MYGUI_STATIC) -ENDIF (WIN32) - - -#Do some preparation -IF (NOT WIN32) # This does not work on Windows for paths with spaces in them - SEPARATE_ARGUMENTS(MYGUI_INCLUDE_DIRS) - SEPARATE_ARGUMENTS(MYGUI_LIBRARIES) -ENDIF (NOT WIN32) - -SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} ${Freetype_LIBRARIES}) - -SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS} CACHE PATH "") -SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") -SET(MYGUI_LIB_DIR ${MYGUI_LIB_DIR} CACHE PATH "") - -IF (NOT APPLE OR NOT MYGUI_STATIC) # we need explicit freetype libs only on OS X for static build, for other cases just make it TRUE - SET(Freetype_LIBRARIES TRUE) -ENDIF (NOT APPLE OR NOT MYGUI_STATIC) - -IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES AND Freetype_LIBRARIES) - SET(MYGUI_FOUND TRUE) -ENDIF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES AND Freetype_LIBRARIES) - -IF (MYGUI_FOUND) - MARK_AS_ADVANCED(MYGUI_LIB_DIR) - IF (NOT MYGUI_FIND_QUIETLY) - MESSAGE(STATUS " libraries : ${MYGUI_LIBRARIES} from ${MYGUI_LIB_DIR}") - MESSAGE(STATUS " includes : ${MYGUI_INCLUDE_DIRS}") - ENDIF (NOT MYGUI_FIND_QUIETLY) - - find_file(MYGUI_PREQUEST_FILE NAMES MyGUI_Prerequest.h PATHS ${MYGUI_INCLUDE_DIRS}) - file(READ ${MYGUI_PREQUEST_FILE} MYGUI_TEMP_VERSION_CONTENT) - get_preprocessor_entry(MYGUI_TEMP_VERSION_CONTENT MYGUI_VERSION_MAJOR MYGUI_VERSION_MAJOR) - get_preprocessor_entry(MYGUI_TEMP_VERSION_CONTENT MYGUI_VERSION_MINOR MYGUI_VERSION_MINOR) - get_preprocessor_entry(MYGUI_TEMP_VERSION_CONTENT MYGUI_VERSION_PATCH MYGUI_VERSION_PATCH) - set(MYGUI_VERSION "${MYGUI_VERSION_MAJOR}.${MYGUI_VERSION_MINOR}.${MYGUI_VERSION_PATCH}") - - IF (NOT MYGUI_FIND_QUIETLY) - MESSAGE(STATUS "MyGUI version: ${MYGUI_VERSION}") - ENDIF (NOT MYGUI_FIND_QUIETLY) -ENDIF (MYGUI_FOUND) - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(MyGUI DEFAULT_MSG - MYGUI_INCLUDE_DIRS - Freetype_LIBRARIES - MYGUI_LIBRARIES) -CMAKE_POLICY(POP) +include(LibFindMacros) + +if (MYGUI_STATIC) + set(MYGUI_STATIC_SUFFIX "Static") +else() + set(MYGUI_STATIC_SUFFIX "") +endif() + +libfind_pkg_detect(MyGUI_Debug MyGUI${MYGUI_STATIC_SUFFIX} MYGUI${MYGUI_STATIC_SUFFIX} + FIND_LIBRARY MyGUIEngine_d${MYGUI_STATIC_SUFFIX} + HINTS $ENV{MYGUI_HOME}/lib + PATH_SUFFIXES "" debug +) +set(MyGUI_Debug_FIND_QUIETLY TRUE) +libfind_process(MyGUI_Debug) + +libfind_pkg_detect(MyGUI MyGUI${MYGUI_STATIC_SUFFIX} MYGUI${MYGUI_STATIC_SUFFIX} + FIND_PATH MyGUI.h + HINTS $ENV{MYGUI_HOME}/include + PATH_SUFFIXES MYGUI MyGUI + FIND_LIBRARY MyGUIEngine${MYGUI_STATIC_SUFFIX} + HINTS $ENV{MYGUI_HOME}/lib + PATH_SUFFIXES "" release relwithdebinfo minsizerel +) +if (MYGUI_STATIC AND (APPLE OR ANDROID)) + # we need explicit Freetype libs only on OS X and ANDROID for static build + libfind_package(MyGUI Freetype) +endif() + +libfind_version_n_header(MyGUI + NAMES MyGUI_Prerequest.h + DEFINES MYGUI_VERSION_MAJOR MYGUI_VERSION_MINOR MYGUI_VERSION_PATCH +) +libfind_process(MyGUI) + +if (MyGUI_Debug_FOUND) + set(MyGUI_LIBRARIES optimized ${MyGUI_LIBRARIES} debug ${MyGUI_Debug_LIBRARIES}) +endif() diff --git a/cmake/FindTinyXML.cmake b/cmake/FindTinyXML.cmake index d79a21c4a..cfbacb881 100644 --- a/cmake/FindTinyXML.cmake +++ b/cmake/FindTinyXML.cmake @@ -7,7 +7,6 @@ # include(LibFindMacros) -include(PreprocessorUtils) libfind_pkg_detect(TinyXML tinyxml FIND_PATH tinyxml.h diff --git a/cmake/PreprocessorUtils.cmake b/cmake/PreprocessorUtils.cmake deleted file mode 100644 index 7fb135bd3..000000000 --- a/cmake/PreprocessorUtils.cmake +++ /dev/null @@ -1,85 +0,0 @@ -#------------------------------------------------------------------- -# This file is part of the CMake build system for OGRE -# (Object-oriented Graphics Rendering Engine) -# For the latest info, see http://www.ogre3d.org/ -# -# The contents of this file are placed in the public domain. Feel -# free to make use of it in any way you like. -#------------------------------------------------------------------- - -macro(get_preprocessor_entry CONTENTS KEYWORD VARIABLE) - string(REGEX MATCH - "# *define +${KEYWORD} +((\"([^\n]*)\")|([^ \n]*))" - PREPROC_TEMP_VAR - ${${CONTENTS}} - ) - if (CMAKE_MATCH_3) - set(${VARIABLE} ${CMAKE_MATCH_3}) - else () - set(${VARIABLE} ${CMAKE_MATCH_4}) - endif () -endmacro() - -macro(has_preprocessor_entry CONTENTS KEYWORD VARIABLE) - string(REGEX MATCH - "\n *# *define +(${KEYWORD})" - PREPROC_TEMP_VAR - ${${CONTENTS}} - ) - if (CMAKE_MATCH_1) - set(${VARIABLE} TRUE) - else () - set(${VARIABLE} FALSE) - endif () -endmacro() - -macro(replace_preprocessor_entry VARIABLE KEYWORD NEW_VALUE) - string(REGEX REPLACE - "(// *)?# *define +${KEYWORD} +[^ \n]*" - "#define ${KEYWORD} ${NEW_VALUE}" - ${VARIABLE}_TEMP - ${${VARIABLE}} - ) - set(${VARIABLE} ${${VARIABLE}_TEMP}) -endmacro() - -macro(set_preprocessor_entry VARIABLE KEYWORD ENABLE) - if (${ENABLE}) - set(TMP_REPLACE_STR "#define ${KEYWORD}") - else () - set(TMP_REPLACE_STR "// #define ${KEYWORD}") - endif () - string(REGEX REPLACE - "(// *)?# *define +${KEYWORD} *\n" - ${TMP_REPLACE_STR} - ${VARIABLE}_TEMP - ${${VARIABLE}} - ) - set(${VARIABLE} ${${VARIABLE}_TEMP}) -endmacro() - - -# get_version_from_n_defines(result_version_name header_path [list of defines...]) -# -# get_version_from_n_defines(MyPackage_VERSION /Header/Path/HeaderName.h -# MYPACKAGE_VERSION_MAJOR -# MYPACKAGE_VERSION_MINOR -# ) -# Function call will get the values of defines MYPACKAGE_VERSION_MAJOR & MYPACKAGE_VERSION_MINOR -# from header and set "${MYPACKAGE_VERSION_MAJOR}.${MYPACKAGE_VERSION_MINOR}" into MyPackage_VERSION -# - -function(get_version_from_n_defines OUT_VAR HEADER_PATH) - if (NOT EXISTS ${HEADER_PATH}) - message(FATAL_ERROR "Unable to find '${HEADER_PATH}'") - return() - endif () - file(READ ${HEADER_PATH} _CONTENT) - unset(_DEFINES_LIST) - foreach (_DEFINE_NAME ${ARGN}) - get_preprocessor_entry(_CONTENT ${_DEFINE_NAME} _DEFINE_VALUE) - list(APPEND _DEFINES_LIST ${_DEFINE_VALUE}) - endforeach() - string(REPLACE ";" "." _VERSION "${_DEFINES_LIST}") - set(${OUT_VAR} "${_VERSION}" PARENT_SCOPE) -endfunction() diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index a9feae10f..5923c2be4 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -222,7 +222,7 @@ target_link_libraries(components ${SDL2_LIBRARY} # For MyGUI platform ${GL_LIB} - ${MYGUI_LIBRARIES} + ${MyGUI_LIBRARIES} ) if (WIN32) diff --git a/components/files/escape.hpp b/components/files/escape.hpp index 3b016a12d..2017c2ed2 100644 --- a/components/files/escape.hpp +++ b/components/files/escape.hpp @@ -193,4 +193,4 @@ namespace Files std::istream & operator>> (std::istream & istream, EscapePath & escapePath); } /* namespace Files */ -#endif /* COMPONENTS_FILES_ESCAPE_HPP */ \ No newline at end of file +#endif /* COMPONENTS_FILES_ESCAPE_HPP */ diff --git a/components/nifosg/controller.cpp b/components/nifosg/controller.cpp index 5a3a7ac59..8d0c73bff 100644 --- a/components/nifosg/controller.cpp +++ b/components/nifosg/controller.cpp @@ -239,7 +239,7 @@ UVController::UVController(const UVController& copy, const osg::CopyOp& copyop) void UVController::setDefaults(osg::StateSet *stateset) { - osg::TexMat* texMat = new osg::TexMat; + osg::ref_ptr texMat (new osg::TexMat); for (std::set::const_iterator it = mTextureUnits.begin(); it != mTextureUnits.end(); ++it) stateset->setTextureAttributeAndModes(*it, texMat, osg::StateAttribute::ON); } diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 3e67fbb3c..309dac88b 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1110,7 +1110,7 @@ namespace NifOsg geometry->setDataVariance(osg::Object::STATIC); osg::ref_ptr frameswitch = new FrameSwitch; - osg::ref_ptr geom2 = static_cast(osg::clone(geometry.get(), osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES)); + osg::ref_ptr geom2 = osg::clone(geometry.get(), osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES); frameswitch->addChild(geometry); frameswitch->addChild(geom2); @@ -1224,8 +1224,7 @@ namespace NifOsg osg::ref_ptr frameswitch = new FrameSwitch; - SceneUtil::RigGeometry* rig2 = static_cast(osg::clone(rig.get(), osg::CopyOp::DEEP_COPY_NODES| - osg::CopyOp::DEEP_COPY_DRAWABLES)); + SceneUtil::RigGeometry* rig2 = osg::clone(rig.get(), osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES); frameswitch->addChild(rig); frameswitch->addChild(rig2); diff --git a/components/sceneutil/statesetupdater.cpp b/components/sceneutil/statesetupdater.cpp index 0e325082e..31d42d342 100644 --- a/components/sceneutil/statesetupdater.cpp +++ b/components/sceneutil/statesetupdater.cpp @@ -15,7 +15,7 @@ namespace SceneUtil for (int i=0; i<2; ++i) // Using SHALLOW_COPY for StateAttributes, if users want to modify it is their responsibility to set a non-shared one first // This can be done conveniently in user implementations of the setDefaults() method { - mStateSets[i] = static_cast(osg::clone(src, osg::CopyOp::SHALLOW_COPY)); + mStateSets[i] = osg::clone(src, osg::CopyOp::SHALLOW_COPY); setDefaults(mStateSets[i]); } } @@ -65,7 +65,7 @@ namespace SceneUtil : StateSetUpdater(copy, copyop) { for (unsigned int i=0; i(osg::clone(copy.mCtrls[i].get(), copyop))); + mCtrls.push_back(osg::clone(copy.mCtrls[i].get(), copyop)); } unsigned int CompositeStateSetUpdater::getNumControllers() diff --git a/extern/osgQt/GraphicsWindowQt b/extern/osgQt/GraphicsWindowQt index 3be1da051..1e34fc9db 100644 --- a/extern/osgQt/GraphicsWindowQt +++ b/extern/osgQt/GraphicsWindowQt @@ -37,16 +37,6 @@ namespace osgQt // forward declarations class GraphicsWindowQt; -/** The function sets the viewer that will be used after entering - * the Qt main loop (QCoreApplication::exec()). - * - * The function also initializes internal structures required for proper - * scene rendering. - * - * The method must be called from main thread. */ -void setViewer( osgViewer::ViewerBase *viewer ); - - class GLWidget : public QGLWidget { typedef QGLWidget inherited; diff --git a/extern/osgQt/GraphicsWindowQt.cpp b/extern/osgQt/GraphicsWindowQt.cpp index 17150bed4..9e5f6e55e 100644 --- a/extern/osgQt/GraphicsWindowQt.cpp +++ b/extern/osgQt/GraphicsWindowQt.cpp @@ -26,28 +26,6 @@ using namespace osgQt; -/// The object responsible for the scene re-rendering. -class HeartBeat : public QObject { -public: - int _timerId; - osg::Timer _lastFrameStartTime; - osg::observer_ptr< osgViewer::ViewerBase > _viewer; - - virtual ~HeartBeat(); - - void init( osgViewer::ViewerBase *viewer ); - void stopTimer(); - void timerEvent( QTimerEvent *event ); - - static HeartBeat* instance(); -private: - HeartBeat(); - - static QPointer heartBeat; -}; - -QPointer HeartBeat::heartBeat; - #if (QT_VERSION < QT_VERSION_CHECK(5, 2, 0)) #define GETDEVICEPIXELRATIO() 1.0 #else @@ -637,104 +615,3 @@ private: QtWindowingSystem& operator=( const QtWindowingSystem& ); }; - -void osgQt::setViewer( osgViewer::ViewerBase *viewer ) -{ - HeartBeat::instance()->init( viewer ); -} - - -/// Constructor. Must be called from main thread. -HeartBeat::HeartBeat() : _timerId( 0 ) -{ -} - - -/// Destructor. Must be called from main thread. -HeartBeat::~HeartBeat() -{ - stopTimer(); -} - -HeartBeat* HeartBeat::instance() -{ - if (!heartBeat) - { - heartBeat = new HeartBeat(); - } - return heartBeat; -} - -void HeartBeat::stopTimer() -{ - if ( _timerId != 0 ) - { - killTimer( _timerId ); - _timerId = 0; - } -} - - -/// Initializes the loop for viewer. Must be called from main thread. -void HeartBeat::init( osgViewer::ViewerBase *viewer ) -{ - if( _viewer == viewer ) - return; - - stopTimer(); - - _viewer = viewer; - - if( viewer ) - { - _timerId = startTimer( 0 ); - _lastFrameStartTime.setStartTick( 0 ); - } -} - - -void HeartBeat::timerEvent( QTimerEvent * /*event*/ ) -{ - osg::ref_ptr< osgViewer::ViewerBase > viewer; - if( !_viewer.lock( viewer ) ) - { - // viewer has been deleted -> stop timer - stopTimer(); - return; - } - - // limit the frame rate - if( viewer->getRunMaxFrameRate() > 0.0) - { - double dt = _lastFrameStartTime.time_s(); - double minFrameTime = 1.0 / viewer->getRunMaxFrameRate(); - if (dt < minFrameTime) - OpenThreads::Thread::microSleep(static_cast(1000000.0*(minFrameTime-dt))); - } - else - { - // avoid excessive CPU loading when no frame is required in ON_DEMAND mode - if( viewer->getRunFrameScheme() == osgViewer::ViewerBase::ON_DEMAND ) - { - double dt = _lastFrameStartTime.time_s(); - if (dt < 0.01) - OpenThreads::Thread::microSleep(static_cast(1000000.0*(0.01-dt))); - } - - // record start frame time - _lastFrameStartTime.setStartTick(); - - // make frame - if( viewer->getRunFrameScheme() == osgViewer::ViewerBase::ON_DEMAND ) - { - if( viewer->checkNeedToDoFrame() ) - { - viewer->frame(); - } - } - else - { - viewer->frame(); - } - } -} diff --git a/files/shaders/objects_fragment.glsl b/files/shaders/objects_fragment.glsl index b3a0150af..5a72b44b3 100644 --- a/files/shaders/objects_fragment.glsl +++ b/files/shaders/objects_fragment.glsl @@ -59,7 +59,9 @@ varying vec3 passNormal; void main() { +#if @diffuseMap vec2 adjustedDiffuseUV = diffuseMapUV; +#endif #if @normalMap vec4 normalTex = texture2D(normalMap, normalMapUV); diff --git a/plugins/mygui_resource_plugin/CMakeLists.txt b/plugins/mygui_resource_plugin/CMakeLists.txt index 72965c917..be834b17d 100644 --- a/plugins/mygui_resource_plugin/CMakeLists.txt +++ b/plugins/mygui_resource_plugin/CMakeLists.txt @@ -27,6 +27,5 @@ set_target_properties(${MYGUI_RESOURCE_PLUGIN_LIBRARY} PROPERTIES PREFIX "") target_link_libraries(${MYGUI_RESOURCE_PLUGIN_LIBRARY} ${OGRE_LIBRARIES} - ${MYGUI_LIBRARIES} components )