mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw.git into Factions2
Conflicts: apps/openmw/mwscript/docs/vmformat.txt apps/openmw/mwworld/player.cpp apps/openmw/mwworld/player.hpp
This commit is contained in:
commit
0553227ee1
126 changed files with 4586 additions and 1938 deletions
|
@ -24,10 +24,12 @@ set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VE
|
||||||
|
|
||||||
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
|
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
|
||||||
|
|
||||||
|
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
|
||||||
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
|
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
|
||||||
|
|
||||||
# Sound source selection
|
# Sound source selection
|
||||||
option(USE_FFMPEG "use ffmpeg for sound" OFF)
|
option(USE_FFMPEG "use ffmpeg for sound" OFF)
|
||||||
|
option(USE_AUDIERE "use audiere for sound" OFF)
|
||||||
option(USE_MPG123 "use mpg123 + libsndfile for sound" ON)
|
option(USE_MPG123 "use mpg123 + libsndfile for sound" ON)
|
||||||
|
|
||||||
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
|
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
|
||||||
|
@ -133,6 +135,13 @@ if (USE_FFMPEG)
|
||||||
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_FFMPEG)
|
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_FFMPEG)
|
||||||
endif (USE_FFMPEG)
|
endif (USE_FFMPEG)
|
||||||
|
|
||||||
|
if (USE_AUDIERE)
|
||||||
|
find_package(Audiere REQUIRED)
|
||||||
|
set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${AUDIERE_INCLUDE_DIR})
|
||||||
|
set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${AUDIERE_LIBRARY})
|
||||||
|
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_AUDIERE)
|
||||||
|
endif (USE_AUDIERE)
|
||||||
|
|
||||||
if (USE_MPG123)
|
if (USE_MPG123)
|
||||||
find_package(MPG123 REQUIRED)
|
find_package(MPG123 REQUIRED)
|
||||||
find_package(SNDFILE REQUIRED)
|
find_package(SNDFILE REQUIRED)
|
||||||
|
@ -215,6 +224,9 @@ endif (APPLE)
|
||||||
|
|
||||||
# Other files
|
# Other files
|
||||||
|
|
||||||
|
configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
|
||||||
|
"${OpenMW_BINARY_DIR}/settings-default.cfg")
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
||||||
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
||||||
|
@ -241,8 +253,14 @@ if (APPLE)
|
||||||
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY)
|
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY)
|
||||||
|
|
||||||
# prepare plugins
|
# prepare plugins
|
||||||
if (${CMAKE_BUILD_TYPE} MATCHES "Release" OR
|
if (${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||||
${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo")
|
set(OPENMW_RELEASE_BUILD 1)
|
||||||
|
endif()
|
||||||
|
if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo")
|
||||||
|
set(OPENMW_RELEASE_BUILD 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${OPENMW_RELEASE_BUILD})
|
||||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
|
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
|
||||||
else()
|
else()
|
||||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})
|
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})
|
||||||
|
@ -289,6 +307,7 @@ if(DPKG_PROGRAM)
|
||||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
|
|
||||||
#Install global configuration files
|
#Install global configuration files
|
||||||
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
|
|
||||||
|
@ -327,7 +346,10 @@ if(WIN32)
|
||||||
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*")
|
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*")
|
||||||
INSTALL(FILES ${files} DESTINATION ".")
|
INSTALL(FILES ${files} DESTINATION ".")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
|
||||||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/readme.txt" DESTINATION ".")
|
INSTALL(FILES
|
||||||
|
"${OpenMW_SOURCE_DIR}/readme.txt"
|
||||||
|
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||||
|
DESTINATION ".")
|
||||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
|
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
|
||||||
|
|
||||||
SET(CPACK_GENERATOR "NSIS")
|
SET(CPACK_GENERATOR "NSIS")
|
||||||
|
@ -337,8 +359,12 @@ if(WIN32)
|
||||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
|
SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
|
||||||
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
|
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
|
||||||
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher")
|
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;omwlauncher;OpenMW Launcher")
|
||||||
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'")
|
SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'")
|
||||||
|
SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
|
||||||
|
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
|
||||||
|
Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\"
|
||||||
|
")
|
||||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
|
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
|
||||||
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
|
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
|
||||||
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||||
|
|
|
@ -12,12 +12,22 @@ MwIniImporter::MwIniImporter() {
|
||||||
const char *map[][2] =
|
const char *map[][2] =
|
||||||
{
|
{
|
||||||
{ "fps", "General:Show FPS" },
|
{ "fps", "General:Show FPS" },
|
||||||
|
{ "nosound", "General:Disable Audio" },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
const char *fallback[] = {
|
||||||
|
"Weather:Sunrise Time",
|
||||||
|
"Weather:Sunset Time",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
for(int i=0; map[i][0]; i++) {
|
for(int i=0; map[i][0]; i++) {
|
||||||
mMergeMap.insert(std::make_pair<std::string, std::string>(map[i][0], map[i][1]));
|
mMergeMap.insert(std::make_pair<std::string, std::string>(map[i][0], map[i][1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i=0; fallback[i]; i++) {
|
||||||
|
mMergeFallback.push_back(fallback[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::setVerbose(bool verbose) {
|
void MwIniImporter::setVerbose(bool verbose) {
|
||||||
|
@ -116,16 +126,38 @@ void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) {
|
||||||
multistrmap::iterator iniIt;
|
multistrmap::iterator iniIt;
|
||||||
for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); it++) {
|
for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); it++) {
|
||||||
if((iniIt = ini.find(it->second)) != ini.end()) {
|
if((iniIt = ini.find(it->second)) != ini.end()) {
|
||||||
|
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) {
|
||||||
cfg.erase(it->first);
|
cfg.erase(it->first);
|
||||||
if(!this->specialMerge(it->first, it->second, cfg, ini)) {
|
insertMultistrmap(cfg, it->first, *vc);
|
||||||
cfg.insert(std::make_pair<std::string, std::vector<std::string> >(it->first, iniIt->second));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MwIniImporter::specialMerge(std::string cfgKey, std::string iniKey, multistrmap &cfg, multistrmap &ini) {
|
void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
|
||||||
return false;
|
cfg.erase("fallback");
|
||||||
|
|
||||||
|
multistrmap::iterator cfgIt;
|
||||||
|
multistrmap::iterator iniIt;
|
||||||
|
for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); it++) {
|
||||||
|
if((iniIt = ini.find(*it)) != ini.end()) {
|
||||||
|
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) {
|
||||||
|
std::string value(*it);
|
||||||
|
std::replace( value.begin(), value.end(), ' ', '_' );
|
||||||
|
std::replace( value.begin(), value.end(), ':', '_' );
|
||||||
|
value.append(",").append(vc->substr(0,vc->length()-1));
|
||||||
|
insertMultistrmap(cfg, "fallback", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) {
|
||||||
|
multistrmap::iterator it = cfg.find(key);
|
||||||
|
if(it == cfg.end()) {
|
||||||
|
cfg.insert(std::make_pair<std::string, std::vector<std::string> >(key, std::vector<std::string>() ));
|
||||||
|
}
|
||||||
|
cfg[key].push_back(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
||||||
|
|
|
@ -18,14 +18,16 @@ class MwIniImporter {
|
||||||
multistrmap loadIniFile(std::string filename);
|
multistrmap loadIniFile(std::string filename);
|
||||||
multistrmap loadCfgFile(std::string filename);
|
multistrmap loadCfgFile(std::string filename);
|
||||||
void merge(multistrmap &cfg, multistrmap &ini);
|
void merge(multistrmap &cfg, multistrmap &ini);
|
||||||
|
void mergeFallback(multistrmap &cfg, multistrmap &ini);
|
||||||
void importGameFiles(multistrmap &cfg, multistrmap &ini);
|
void importGameFiles(multistrmap &cfg, multistrmap &ini);
|
||||||
void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg);
|
void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool specialMerge(std::string cfgKey, std::string iniKey, multistrmap &cfg, multistrmap &ini);
|
void insertMultistrmap(multistrmap &cfg, std::string key, std::string value);
|
||||||
std::string numberToString(int n);
|
std::string numberToString(int n);
|
||||||
bool mVerbose;
|
bool mVerbose;
|
||||||
strmap mMergeMap;
|
strmap mMergeMap;
|
||||||
|
std::vector<std::string> mMergeFallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ namespace bpo = boost::program_options;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
bpo::options_description desc("Syntax: mwiniimporter <options>\nAllowed options");
|
bpo::options_description desc("Syntax: mwiniimporter <options> inifile configfile\nAllowed options");
|
||||||
|
bpo::positional_options_description p_desc;
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce help message")
|
("help,h", "produce help message")
|
||||||
("verbose,v", "verbose output")
|
("verbose,v", "verbose output")
|
||||||
|
@ -18,29 +19,23 @@ int main(int argc, char *argv[]) {
|
||||||
("output,o", bpo::value<std::string>()->default_value(""), "openmw.cfg file")
|
("output,o", bpo::value<std::string>()->default_value(""), "openmw.cfg file")
|
||||||
("game-files,g", "import esm and esp files")
|
("game-files,g", "import esm and esp files")
|
||||||
;
|
;
|
||||||
|
p_desc.add("ini", 1).add("cfg", 1);
|
||||||
|
|
||||||
bpo::variables_map vm;
|
bpo::variables_map vm;
|
||||||
try {
|
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv)
|
||||||
bpo::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
|
.options(desc)
|
||||||
|
.positional(p_desc)
|
||||||
|
.run();
|
||||||
|
|
||||||
// parse help before calling notify because we dont want it to throw an error if help is set
|
bpo::store(parsed, vm);
|
||||||
if(vm.count("help")) {
|
|
||||||
|
if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) {
|
||||||
std::cout << desc;
|
std::cout << desc;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bpo::notify(vm);
|
bpo::notify(vm);
|
||||||
|
|
||||||
}
|
|
||||||
catch(std::exception& e) {
|
|
||||||
std::cerr << "Error:" << e.what() << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
catch(...) {
|
|
||||||
std::cerr << "Error" << std::endl;
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string iniFile = vm["ini"].as<std::string>();
|
std::string iniFile = vm["ini"].as<std::string>();
|
||||||
std::string cfgFile = vm["cfg"].as<std::string>();
|
std::string cfgFile = vm["cfg"].as<std::string>();
|
||||||
|
|
||||||
|
@ -61,18 +56,19 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
MwIniImporter importer;
|
MwIniImporter importer;
|
||||||
importer.setVerbose(vm.count("verbose"));
|
importer.setVerbose(vm.count("verbose"));
|
||||||
boost::iostreams::stream<boost::iostreams::file_sink> file(outputFile);
|
|
||||||
|
|
||||||
MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile);
|
MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile);
|
||||||
MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile);
|
MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile);
|
||||||
|
|
||||||
importer.merge(cfg, ini);
|
importer.merge(cfg, ini);
|
||||||
|
importer.mergeFallback(cfg, ini);
|
||||||
|
|
||||||
if(vm.count("game-files")) {
|
if(vm.count("game-files")) {
|
||||||
importer.importGameFiles(cfg, ini);
|
importer.importGameFiles(cfg, ini);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "write to: " << outputFile << std::endl;
|
std::cout << "write to: " << outputFile << std::endl;
|
||||||
|
boost::iostreams::stream<boost::iostreams::file_sink> file(outputFile);
|
||||||
importer.writeToFile(file, cfg);
|
importer.writeToFile(file, cfg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -25,6 +25,7 @@ add_openmw_dir (mwinput
|
||||||
add_openmw_dir (mwgui
|
add_openmw_dir (mwgui
|
||||||
layouts text_input widgets race class birth review window_manager console dialogue
|
layouts text_input widgets race class birth review window_manager console dialogue
|
||||||
dialogue_history window_base stats_window messagebox journalwindow charactercreation
|
dialogue_history window_base stats_window messagebox journalwindow charactercreation
|
||||||
|
map_window window_pinnable_base
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwdialogue
|
add_openmw_dir (mwdialogue
|
||||||
|
@ -39,7 +40,7 @@ add_openmw_dir (mwscript
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwsound
|
add_openmw_dir (mwsound
|
||||||
soundmanager openal_output mpgsnd_decoder ffmpeg_decoder
|
soundmanager openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwworld
|
add_openmw_dir (mwworld
|
||||||
|
@ -54,7 +55,7 @@ add_openmw_dir (mwclass
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwmechanics
|
add_openmw_dir (mwmechanics
|
||||||
mechanicsmanager stat creaturestats magiceffects movement
|
mechanicsmanager stat creaturestats magiceffects movement actors drawstate
|
||||||
)
|
)
|
||||||
|
|
||||||
# Main executable
|
# Main executable
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <components/esm/esm_reader.hpp>
|
#include <components/esm/esm_reader.hpp>
|
||||||
#include <components/files/fixedpath.hpp>
|
#include <components/files/fixedpath.hpp>
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||||
#include <components/nifogre/ogre_nif_loader.hpp>
|
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||||
|
@ -81,6 +82,11 @@ void OMW::Engine::updateFocusReport (float duration)
|
||||||
std::string handle = mEnvironment.mWorld->getFacedHandle();
|
std::string handle = mEnvironment.mWorld->getFacedHandle();
|
||||||
|
|
||||||
if (!handle.empty())
|
if (!handle.empty())
|
||||||
|
{
|
||||||
|
// the faced handle is not updated immediately, so on a cell change it might
|
||||||
|
// point to an object that doesn't exist anymore
|
||||||
|
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
|
||||||
|
try
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
||||||
|
|
||||||
|
@ -89,6 +95,9 @@ void OMW::Engine::updateFocusReport (float duration)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (std::runtime_error& e)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
if (name!=mFocusName)
|
if (name!=mFocusName)
|
||||||
{
|
{
|
||||||
|
@ -115,6 +124,9 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
{
|
{
|
||||||
mEnvironment.mFrameDuration = evt.timeSinceLastFrame;
|
mEnvironment.mFrameDuration = evt.timeSinceLastFrame;
|
||||||
|
|
||||||
|
// update input
|
||||||
|
mEnvironment.mInputManager->update();
|
||||||
|
|
||||||
// sound
|
// sound
|
||||||
if (mUseSound)
|
if (mUseSound)
|
||||||
mEnvironment.mSoundManager->update (evt.timeSinceLastFrame);
|
mEnvironment.mSoundManager->update (evt.timeSinceLastFrame);
|
||||||
|
@ -148,7 +160,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
|
|
||||||
// update actors
|
// update actors
|
||||||
std::vector<std::pair<std::string, Ogre::Vector3> > movement;
|
std::vector<std::pair<std::string, Ogre::Vector3> > movement;
|
||||||
mEnvironment.mMechanicsManager->update (movement);
|
mEnvironment.mMechanicsManager->update (movement, mEnvironment.mFrameDuration,
|
||||||
|
mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game);
|
||||||
|
|
||||||
if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game)
|
if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game)
|
||||||
mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration);
|
mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration);
|
||||||
|
@ -313,6 +326,29 @@ void OMW::Engine::go()
|
||||||
{
|
{
|
||||||
boost::filesystem::create_directories(configPath);
|
boost::filesystem::create_directories(configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the settings manager and load default settings file
|
||||||
|
Settings::Manager settings;
|
||||||
|
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg";
|
||||||
|
const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg";
|
||||||
|
|
||||||
|
// prefer local
|
||||||
|
if (boost::filesystem::exists(localdefault))
|
||||||
|
settings.loadDefault(localdefault);
|
||||||
|
else if (boost::filesystem::exists(globaldefault))
|
||||||
|
settings.loadDefault(globaldefault);
|
||||||
|
|
||||||
|
// load user settings if they exist, otherwise just load the default settings as user settings
|
||||||
|
const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg";
|
||||||
|
if (boost::filesystem::exists(settingspath))
|
||||||
|
settings.loadUser(settingspath);
|
||||||
|
else if (boost::filesystem::exists(localdefault))
|
||||||
|
settings.loadUser(localdefault);
|
||||||
|
else if (boost::filesystem::exists(globaldefault))
|
||||||
|
settings.loadUser(globaldefault);
|
||||||
|
|
||||||
|
mFpsLevel = settings.getInt("fps", "HUD");
|
||||||
|
|
||||||
mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()),
|
mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()),
|
||||||
mCfgMgr.getOgreConfigPath().string(),
|
mCfgMgr.getOgreConfigPath().string(),
|
||||||
mCfgMgr.getLogPath().string(),
|
mCfgMgr.getLogPath().string(),
|
||||||
|
@ -325,6 +361,7 @@ void OMW::Engine::go()
|
||||||
|
|
||||||
addResourcesDirectory(mResDir / "mygui");
|
addResourcesDirectory(mResDir / "mygui");
|
||||||
addResourcesDirectory(mResDir / "water");
|
addResourcesDirectory(mResDir / "water");
|
||||||
|
addResourcesDirectory(mResDir / "gbuffer");
|
||||||
|
|
||||||
// Create the window
|
// Create the window
|
||||||
mOgre->createWindow("OpenMW");
|
mOgre->createWindow("OpenMW");
|
||||||
|
@ -333,7 +370,7 @@ void OMW::Engine::go()
|
||||||
|
|
||||||
// Create the world
|
// Create the world
|
||||||
mEnvironment.mWorld = new MWWorld::World (*mOgre, mFileCollections, mMaster,
|
mEnvironment.mWorld = new MWWorld::World (*mOgre, mFileCollections, mMaster,
|
||||||
mResDir, mNewGame, mEnvironment, mEncoding);
|
mResDir, mNewGame, mEnvironment, mEncoding, mFallbackMap);
|
||||||
|
|
||||||
// Create window manager - this manages all the MW-specific GUI windows
|
// Create window manager - this manages all the MW-specific GUI windows
|
||||||
MWScript::registerExtensions (mExtensions);
|
MWScript::registerExtensions (mExtensions);
|
||||||
|
@ -407,6 +444,9 @@ void OMW::Engine::go()
|
||||||
// Start the main rendering loop
|
// Start the main rendering loop
|
||||||
mOgre->start();
|
mOgre->start();
|
||||||
|
|
||||||
|
// Save user settings
|
||||||
|
settings.saveUser(settingspath);
|
||||||
|
|
||||||
std::cout << "Quitting peacefully.\n";
|
std::cout << "Quitting peacefully.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,10 +460,21 @@ void OMW::Engine::activate()
|
||||||
if (handle.empty())
|
if (handle.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
// the faced handle is not updated immediately, so on a cell change it might
|
||||||
|
// point to an object that doesn't exist anymore
|
||||||
|
// therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case
|
||||||
|
MWWorld::Ptr ptr;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ptr = mEnvironment.mWorld->getPtrViaHandle (handle);
|
||||||
|
|
||||||
if (ptr.isEmpty())
|
if (ptr.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
catch (std::runtime_error&)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
MWScript::InterpreterContext interpreterContext (mEnvironment,
|
||||||
&ptr.getRefData().getLocals(), ptr);
|
&ptr.getRefData().getLocals(), ptr);
|
||||||
|
@ -489,3 +540,8 @@ void OMW::Engine::setEncoding(const std::string& encoding)
|
||||||
{
|
{
|
||||||
mEncoding = encoding;
|
mEncoding = encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OMW::Engine::setFallbackValues(std::map<std::string,std::string> fallbackMap)
|
||||||
|
{
|
||||||
|
mFallbackMap = fallbackMap;
|
||||||
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ namespace OMW
|
||||||
bool mReportFocus;
|
bool mReportFocus;
|
||||||
float mFocusTDiff;
|
float mFocusTDiff;
|
||||||
std::string mFocusName;
|
std::string mFocusName;
|
||||||
|
std::map<std::string,std::string> mFallbackMap;
|
||||||
|
|
||||||
MWWorld::Environment mEnvironment;
|
MWWorld::Environment mEnvironment;
|
||||||
Compiler::Extensions mExtensions;
|
Compiler::Extensions mExtensions;
|
||||||
|
@ -163,6 +164,8 @@ namespace OMW
|
||||||
|
|
||||||
void setAnimationVerbose(bool animverbose);
|
void setAnimationVerbose(bool animverbose);
|
||||||
|
|
||||||
|
void setFallbackValues(std::map<std::string,std::string> map);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Files::ConfigurationManager& mCfgMgr;
|
Files::ConfigurationManager& mCfgMgr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,6 +54,41 @@ inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
struct FallbackMap {
|
||||||
|
std::map<std::string,std::string> mMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
void validate(boost::any &v, std::vector<std::string> const &tokens, FallbackMap*, int)
|
||||||
|
{
|
||||||
|
if(v.empty())
|
||||||
|
{
|
||||||
|
v = boost::any(FallbackMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
FallbackMap *map = boost::any_cast<FallbackMap>(&v);
|
||||||
|
|
||||||
|
std::map<std::string,std::string>::iterator mapIt;
|
||||||
|
for(std::vector<std::string>::const_iterator it=tokens.begin(); it != tokens.end(); it++)
|
||||||
|
{
|
||||||
|
int sep = it->find(",");
|
||||||
|
if(sep < 1 || sep == (int)it->length()-1)
|
||||||
|
#if (BOOST_VERSION < 104200)
|
||||||
|
throw boost::program_options::validation_error("invalid value");
|
||||||
|
#else
|
||||||
|
throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string key(it->substr(0,sep));
|
||||||
|
std::string value(it->substr(sep+1));
|
||||||
|
|
||||||
|
if((mapIt = map->mMap.find(key)) == map->mMap.end())
|
||||||
|
{
|
||||||
|
map->mMap.insert(std::make_pair<std::string,std::string>(key,value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Parses application command line and calls \ref Cfg::ConfigurationManager
|
* \brief Parses application command line and calls \ref Cfg::ConfigurationManager
|
||||||
* to parse configuration files.
|
* to parse configuration files.
|
||||||
|
@ -92,39 +127,40 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
("plugin", bpo::value<StringsVector>()->default_value(StringsVector(), "")
|
("plugin", bpo::value<StringsVector>()->default_value(StringsVector(), "")
|
||||||
->multitoken(), "plugin file(s)")
|
->multitoken(), "plugin file(s)")
|
||||||
|
|
||||||
("fps", boost::program_options::value<int>()->implicit_value(1)
|
("anim-verbose", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(0), "fps counter detail (0 = off, 1 = fps counter, 2 = full detail)")
|
|
||||||
|
|
||||||
("anim-verbose", boost::program_options::value<bool>()->implicit_value(true)
|
|
||||||
->default_value(false), "output animation indices files")
|
->default_value(false), "output animation indices files")
|
||||||
|
|
||||||
("debug", boost::program_options::value<bool>()->implicit_value(true)
|
("debug", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "debug mode")
|
->default_value(false), "debug mode")
|
||||||
|
|
||||||
("nosound", boost::program_options::value<bool>()->implicit_value(true)
|
("nosound", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "disable all sounds")
|
->default_value(false), "disable all sounds")
|
||||||
|
|
||||||
("script-verbose", boost::program_options::value<bool>()->implicit_value(true)
|
("script-verbose", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "verbose script output")
|
->default_value(false), "verbose script output")
|
||||||
|
|
||||||
("new-game", boost::program_options::value<bool>()->implicit_value(true)
|
("new-game", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "activate char gen/new game mechanics")
|
->default_value(false), "activate char gen/new game mechanics")
|
||||||
|
|
||||||
("script-all", boost::program_options::value<bool>()->implicit_value(true)
|
("script-all", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "compile all scripts (excluding dialogue scripts) at startup")
|
->default_value(false), "compile all scripts (excluding dialogue scripts) at startup")
|
||||||
|
|
||||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)
|
("fs-strict", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "strict file system handling (no case folding)")
|
->default_value(false), "strict file system handling (no case folding)")
|
||||||
|
|
||||||
( "encoding", boost::program_options::value<std::string>()->
|
( "encoding", bpo::value<std::string>()->
|
||||||
default_value("win1252"),
|
default_value("win1252"),
|
||||||
"Character encoding used in OpenMW game messages:\n"
|
"Character encoding used in OpenMW game messages:\n"
|
||||||
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
|
"\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n"
|
||||||
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
||||||
"\n\twin1252 - Western European (Latin) alphabet, used by default")
|
"\n\twin1252 - Western European (Latin) alphabet, used by default")
|
||||||
|
|
||||||
("report-focus", boost::program_options::value<bool>()->implicit_value(true)
|
("report-focus", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "write name of focussed object to cout")
|
->default_value(false), "write name of focussed object to cout")
|
||||||
|
|
||||||
|
("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")
|
||||||
|
->multitoken()->composing(), "fallback values")
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
|
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
|
||||||
|
@ -225,13 +261,13 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||||
engine.setNewGame(variables["new-game"].as<bool>());
|
engine.setNewGame(variables["new-game"].as<bool>());
|
||||||
|
|
||||||
// other settings
|
// other settings
|
||||||
engine.showFPS(variables["fps"].as<int>());
|
|
||||||
engine.setDebugMode(variables["debug"].as<bool>());
|
engine.setDebugMode(variables["debug"].as<bool>());
|
||||||
engine.setSoundUsage(!variables["nosound"].as<bool>());
|
engine.setSoundUsage(!variables["nosound"].as<bool>());
|
||||||
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
||||||
engine.setCompileAll(variables["script-all"].as<bool>());
|
engine.setCompileAll(variables["script-all"].as<bool>());
|
||||||
engine.setReportFocus(variables["report-focus"].as<bool>());
|
engine.setReportFocus(variables["report-focus"].as<bool>());
|
||||||
engine.setAnimationVerbose(variables["anim-verbose"].as<bool>());
|
engine.setAnimationVerbose(variables["anim-verbose"].as<bool>());
|
||||||
|
engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,14 @@ namespace MWClass
|
||||||
return ref->base->script;
|
return ref->base->script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Apparatus::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Apparatus>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Apparatus::registerSelf()
|
void Apparatus::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Apparatus);
|
boost::shared_ptr<Class> instance (new Apparatus);
|
||||||
|
|
|
@ -25,6 +25,9 @@ namespace MWClass
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
|
@ -160,6 +160,14 @@ namespace MWClass
|
||||||
return ESM::Skill::HeavyArmor;
|
return ESM::Skill::HeavyArmor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Armor::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Armor, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Armor>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Armor::registerSelf()
|
void Armor::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Armor);
|
boost::shared_ptr<Class> instance (new Armor);
|
||||||
|
|
|
@ -40,6 +40,9 @@ namespace MWClass
|
||||||
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
||||||
/// no such skill.
|
/// no such skill.
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -72,6 +72,14 @@ namespace MWClass
|
||||||
return ref->base->script;
|
return ref->base->script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Book::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Book, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Book>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Book::registerSelf()
|
void Book::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Book);
|
boost::shared_ptr<Class> instance (new Book);
|
||||||
|
|
|
@ -25,6 +25,9 @@ namespace MWClass
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -123,6 +123,14 @@ namespace MWClass
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Clothing::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Clothing, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Clothing>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Clothing::registerSelf()
|
void Clothing::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Clothing);
|
boost::shared_ptr<Class> instance (new Clothing);
|
||||||
|
|
|
@ -34,6 +34,9 @@ namespace MWClass
|
||||||
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
||||||
/// no such skill.
|
/// no such skill.
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -68,6 +68,14 @@ namespace MWClass
|
||||||
return ref->base->script;
|
return ref->base->script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Ingredient::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Ingredient, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Ingredient>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Ingredient::registerSelf()
|
void Ingredient::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Ingredient);
|
boost::shared_ptr<Class> instance (new Ingredient);
|
||||||
|
|
|
@ -25,6 +25,9 @@ namespace MWClass
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -110,6 +110,14 @@ namespace MWClass
|
||||||
return std::make_pair (slots, false);
|
return std::make_pair (slots, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Light::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Light>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Light::registerSelf()
|
void Light::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Light);
|
boost::shared_ptr<Class> instance (new Light);
|
||||||
|
|
|
@ -34,6 +34,9 @@ namespace MWClass
|
||||||
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
||||||
/// stay stacked when equipped?
|
/// stay stacked when equipped?
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -81,6 +81,14 @@ namespace MWClass
|
||||||
return std::make_pair (slots, false);
|
return std::make_pair (slots, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Lockpick::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Tool, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Tool>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Lockpick::registerSelf()
|
void Lockpick::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Lockpick);
|
boost::shared_ptr<Class> instance (new Lockpick);
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace MWClass
|
||||||
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
||||||
/// stay stacked when equipped?
|
/// stay stacked when equipped?
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -70,6 +70,14 @@ namespace MWClass
|
||||||
return ref->base->script;
|
return ref->base->script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Miscellaneous, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Miscellaneous>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Miscellaneous::registerSelf()
|
void Miscellaneous::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Miscellaneous);
|
boost::shared_ptr<Class> instance (new Miscellaneous);
|
||||||
|
|
|
@ -25,6 +25,9 @@ namespace MWClass
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -70,6 +70,14 @@ namespace MWClass
|
||||||
return ref->base->script;
|
return ref->base->script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Potion::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Potion, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Potion>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Potion::registerSelf()
|
void Potion::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Potion);
|
boost::shared_ptr<Class> instance (new Potion);
|
||||||
|
|
|
@ -25,6 +25,9 @@ namespace MWClass
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -80,6 +80,14 @@ namespace MWClass
|
||||||
return std::make_pair (slots, false);
|
return std::make_pair (slots, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Probe::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Probe, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Probe>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Probe::registerSelf()
|
void Probe::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Probe);
|
boost::shared_ptr<Class> instance (new Probe);
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace MWClass
|
||||||
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
///< \return first: Return IDs of the slot this object can be equipped in; second: can object
|
||||||
/// stay stacked when equipped?
|
/// stay stacked when equipped?
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -70,6 +70,14 @@ namespace MWClass
|
||||||
return ref->base->script;
|
return ref->base->script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Repair::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Repair, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Repair>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Repair::registerSelf()
|
void Repair::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Repair);
|
boost::shared_ptr<Class> instance (new Repair);
|
||||||
|
|
|
@ -25,6 +25,9 @@ namespace MWClass
|
||||||
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return name of the script attached to ptr
|
///< Return name of the script attached to ptr
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -139,6 +139,14 @@ namespace MWClass
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Weapon::getValue (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
ESMS::LiveCellRef<ESM::Weapon, MWWorld::RefData> *ref =
|
||||||
|
ptr.get<ESM::Weapon>();
|
||||||
|
|
||||||
|
return ref->base->data.value;
|
||||||
|
}
|
||||||
|
|
||||||
void Weapon::registerSelf()
|
void Weapon::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Weapon);
|
boost::shared_ptr<Class> instance (new Weapon);
|
||||||
|
|
|
@ -40,6 +40,9 @@ namespace MWClass
|
||||||
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
/// Return the index of the skill this item corresponds to when equiopped or -1, if there is
|
||||||
/// no such skill.
|
/// no such skill.
|
||||||
|
|
||||||
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const;
|
||||||
|
|
|
@ -547,6 +547,13 @@ namespace MWDialogue
|
||||||
mChoice = -1;
|
mChoice = -1;
|
||||||
mIsInChoice = false;
|
mIsInChoice = false;
|
||||||
mCompilerContext.setExtensions (&extensions);
|
mCompilerContext.setExtensions (&extensions);
|
||||||
|
mDialogueMap.clear();
|
||||||
|
actorKnownTopics.clear();
|
||||||
|
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
|
||||||
|
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
|
||||||
|
{
|
||||||
|
mDialogueMap[it->first] = it->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::addTopic(std::string topic)
|
void DialogueManager::addTopic(std::string topic)
|
||||||
|
@ -582,13 +589,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
mActor = actor;
|
mActor = actor;
|
||||||
|
|
||||||
mDialogueMap.clear();
|
|
||||||
actorKnownTopics.clear();
|
actorKnownTopics.clear();
|
||||||
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
|
|
||||||
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
|
|
||||||
{
|
|
||||||
mDialogueMap[it->first] = it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
//initialise the GUI
|
//initialise the GUI
|
||||||
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue);
|
mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue);
|
||||||
|
@ -601,6 +602,7 @@ namespace MWDialogue
|
||||||
//greeting
|
//greeting
|
||||||
bool greetingFound = false;
|
bool greetingFound = false;
|
||||||
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
|
//ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
|
||||||
|
ESMS::RecListT<ESM::Dialogue>::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list;
|
||||||
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
|
for(ESMS::RecListT<ESM::Dialogue>::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++)
|
||||||
{
|
{
|
||||||
ESM::Dialogue ndialogue = it->second;
|
ESM::Dialogue ndialogue = it->second;
|
||||||
|
|
|
@ -31,6 +31,11 @@ HUD::HUD(int width, int height, int fpsLevel)
|
||||||
, fpscounter(NULL)
|
, fpscounter(NULL)
|
||||||
, trianglecounter(NULL)
|
, trianglecounter(NULL)
|
||||||
, batchcounter(NULL)
|
, batchcounter(NULL)
|
||||||
|
, hmsBaseLeft(0)
|
||||||
|
, weapBoxBaseLeft(0)
|
||||||
|
, spellBoxBaseLeft(0)
|
||||||
|
, effectBoxBaseRight(0)
|
||||||
|
, minimapBoxBaseRight(0)
|
||||||
{
|
{
|
||||||
setCoord(0,0, width, height);
|
setCoord(0,0, width, height);
|
||||||
|
|
||||||
|
@ -38,16 +43,25 @@ HUD::HUD(int width, int height, int fpsLevel)
|
||||||
getWidget(health, "Health");
|
getWidget(health, "Health");
|
||||||
getWidget(magicka, "Magicka");
|
getWidget(magicka, "Magicka");
|
||||||
getWidget(stamina, "Stamina");
|
getWidget(stamina, "Stamina");
|
||||||
|
hmsBaseLeft = health->getLeft();
|
||||||
|
|
||||||
// Item and spell images and status bars
|
// Item and spell images and status bars
|
||||||
|
getWidget(weapBox, "WeapBox");
|
||||||
getWidget(weapImage, "WeapImage");
|
getWidget(weapImage, "WeapImage");
|
||||||
getWidget(weapStatus, "WeapStatus");
|
getWidget(weapStatus, "WeapStatus");
|
||||||
|
weapBoxBaseLeft = weapBox->getLeft();
|
||||||
|
|
||||||
|
getWidget(spellBox, "SpellBox");
|
||||||
getWidget(spellImage, "SpellImage");
|
getWidget(spellImage, "SpellImage");
|
||||||
getWidget(spellStatus, "SpellStatus");
|
getWidget(spellStatus, "SpellStatus");
|
||||||
|
spellBoxBaseLeft = spellBox->getLeft();
|
||||||
|
|
||||||
getWidget(effectBox, "EffectBox");
|
getWidget(effectBox, "EffectBox");
|
||||||
getWidget(effect1, "Effect1");
|
getWidget(effect1, "Effect1");
|
||||||
|
effectBoxBaseRight = effectBox->getRight();
|
||||||
|
|
||||||
|
getWidget(minimapBox, "MiniMapBox");
|
||||||
|
minimapBoxBaseRight = minimapBox->getRight();
|
||||||
getWidget(minimap, "MiniMap");
|
getWidget(minimap, "MiniMap");
|
||||||
getWidget(compass, "Compass");
|
getWidget(compass, "Compass");
|
||||||
|
|
||||||
|
@ -163,15 +177,21 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<int>& v
|
||||||
|
|
||||||
void HUD::setPlayerDir(const float x, const float y)
|
void HUD::setPlayerDir(const float x, const float y)
|
||||||
{
|
{
|
||||||
|
if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return;
|
||||||
|
|
||||||
MyGUI::ISubWidget* main = compass->getSubWidgetMain();
|
MyGUI::ISubWidget* main = compass->getSubWidgetMain();
|
||||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||||
float angle = std::atan2(x,y);
|
float angle = std::atan2(x,y);
|
||||||
rotatingSubskin->setAngle(angle);
|
rotatingSubskin->setAngle(angle);
|
||||||
|
mLastPositionX = x;
|
||||||
|
mLastPositionY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HUD::setPlayerPos(const float x, const float y)
|
void HUD::setPlayerPos(const float x, const float y)
|
||||||
{
|
{
|
||||||
|
if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return;
|
||||||
|
|
||||||
MyGUI::IntSize size = minimap->getCanvasSize();
|
MyGUI::IntSize size = minimap->getCanvasSize();
|
||||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||||
MyGUI::IntCoord viewsize = minimap->getCoord();
|
MyGUI::IntCoord viewsize = minimap->getCoord();
|
||||||
|
@ -179,109 +199,54 @@ void HUD::setPlayerPos(const float x, const float y)
|
||||||
|
|
||||||
minimap->setViewOffset(pos);
|
minimap->setViewOffset(pos);
|
||||||
compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
||||||
|
|
||||||
|
mLastDirectionX = x;
|
||||||
|
mLastDirectionY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapWindow::MapWindow()
|
void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible)
|
||||||
: Layout("openmw_map_window_layout.xml")
|
|
||||||
, mGlobal(false)
|
|
||||||
, mVisible(false)
|
|
||||||
{
|
{
|
||||||
setCoord(500,0,320,300);
|
int weapDx = 0, spellDx = 0;
|
||||||
setText("WorldButton", "World");
|
if (!hmsVisible)
|
||||||
setImage("Compass", "textures\\compass.dds");
|
spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft;
|
||||||
|
|
||||||
// Obviously you should override this later on
|
if (!weapVisible)
|
||||||
setCellName("No Cell Loaded");
|
spellDx -= spellBoxBaseLeft - weapBoxBaseLeft;
|
||||||
|
|
||||||
getWidget(mLocalMap, "LocalMap");
|
health->setVisible(hmsVisible);
|
||||||
getWidget(mGlobalMap, "GlobalMap");
|
stamina->setVisible(hmsVisible);
|
||||||
getWidget(mPlayerArrow, "Compass");
|
magicka->setVisible(hmsVisible);
|
||||||
|
weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop());
|
||||||
getWidget(mButton, "WorldButton");
|
weapBox->setVisible(weapVisible);
|
||||||
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop());
|
||||||
|
spellBox->setVisible(spellVisible);
|
||||||
MyGUI::Button* eventbox;
|
|
||||||
getWidget(eventbox, "EventBox");
|
|
||||||
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
|
||||||
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
|
||||||
|
|
||||||
LocalMapBase::init(mLocalMap, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWindow::setVisible(bool b)
|
void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible)
|
||||||
{
|
{
|
||||||
mMainWidget->setVisible(b);
|
// effect box can have variable width -> variable left coordinate
|
||||||
if (b)
|
int effectsDx = 0;
|
||||||
mVisible = true;
|
if (!minimapBoxVisible)
|
||||||
else
|
effectsDx = minimapBoxBaseRight - effectBoxBaseRight;
|
||||||
mVisible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::setCellName(const std::string& cellName)
|
minimapBox->setVisible(minimapBoxVisible);
|
||||||
{
|
effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop());
|
||||||
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
|
effectBox->setVisible(effectBoxVisible);
|
||||||
adjustWindowCaption();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::setPlayerPos(const float x, const float y)
|
|
||||||
{
|
|
||||||
if (mGlobal || mVisible) return;
|
|
||||||
MyGUI::IntSize size = mLocalMap->getCanvasSize();
|
|
||||||
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
|
||||||
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
|
|
||||||
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
|
||||||
mLocalMap->setViewOffset(pos);
|
|
||||||
|
|
||||||
mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::setPlayerDir(const float x, const float y)
|
|
||||||
{
|
|
||||||
if (!mVisible) return;
|
|
||||||
MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain();
|
|
||||||
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
|
||||||
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
|
||||||
float angle = std::atan2(x,y);
|
|
||||||
rotatingSubskin->setAngle(angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
|
||||||
{
|
|
||||||
if (_id!=MyGUI::MouseButton::Left) return;
|
|
||||||
if (!mGlobal)
|
|
||||||
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
|
||||||
{
|
|
||||||
if (_id!=MyGUI::MouseButton::Left) return;
|
|
||||||
|
|
||||||
if (!mGlobal)
|
|
||||||
{
|
|
||||||
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
|
|
||||||
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
|
|
||||||
|
|
||||||
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
|
||||||
{
|
|
||||||
mGlobal = !mGlobal;
|
|
||||||
mGlobalMap->setVisible(mGlobal);
|
|
||||||
mLocalMap->setVisible(!mGlobal);
|
|
||||||
|
|
||||||
mButton->setCaption( mGlobal ? "Local" : "World" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalMapBase::LocalMapBase()
|
LocalMapBase::LocalMapBase()
|
||||||
: mCurX(0)
|
: mCurX(0)
|
||||||
, mCurY(0)
|
, mCurY(0)
|
||||||
, mInterior(false)
|
, mInterior(false)
|
||||||
|
, mFogOfWar(true)
|
||||||
, mLocalMap(NULL)
|
, mLocalMap(NULL)
|
||||||
, mPrefix()
|
, mPrefix()
|
||||||
, mChanged(true)
|
, mChanged(true)
|
||||||
, mLayout(NULL)
|
, mLayout(NULL)
|
||||||
|
, mLastPositionX(0.0f)
|
||||||
|
, mLastPositionY(0.0f)
|
||||||
|
, mLastDirectionX(0.0f)
|
||||||
|
, mLastDirectionY(0.0f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,6 +262,32 @@ void LocalMapBase::setCellPrefix(const std::string& prefix)
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::toggleFogOfWar()
|
||||||
|
{
|
||||||
|
mFogOfWar = !mFogOfWar;
|
||||||
|
applyFogOfWar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalMapBase::applyFogOfWar()
|
||||||
|
{
|
||||||
|
for (int mx=0; mx<3; ++mx)
|
||||||
|
{
|
||||||
|
for (int my=0; my<3; ++my)
|
||||||
|
{
|
||||||
|
std::string name = "Map_" + boost::lexical_cast<std::string>(mx) + "_"
|
||||||
|
+ 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)));
|
||||||
|
MyGUI::ImageBox* fog;
|
||||||
|
mLayout->getWidget(fog, name+"_fog");
|
||||||
|
fog->setImageTexture(mFogOfWar ?
|
||||||
|
((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog"
|
||||||
|
: "black.png" )
|
||||||
|
: "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
||||||
{
|
{
|
||||||
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell
|
||||||
|
@ -312,23 +303,17 @@ void LocalMapBase::setActiveCell(const int x, const int y, bool interior)
|
||||||
|
|
||||||
MyGUI::ImageBox* box;
|
MyGUI::ImageBox* box;
|
||||||
mLayout->getWidget(box, name);
|
mLayout->getWidget(box, name);
|
||||||
MyGUI::ImageBox* fog;
|
|
||||||
mLayout->getWidget(fog, name+"_fog");
|
|
||||||
|
|
||||||
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
if (MyGUI::RenderManager::getInstance().getTexture(image) != 0)
|
||||||
box->setImageTexture(image);
|
box->setImageTexture(image);
|
||||||
else
|
else
|
||||||
box->setImageTexture("black.png");
|
box->setImageTexture("black.png");
|
||||||
|
|
||||||
if (MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0)
|
|
||||||
fog->setImageTexture(image+"_fog");
|
|
||||||
else
|
|
||||||
fog->setImageTexture("black.png");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mInterior = interior;
|
mInterior = interior;
|
||||||
mCurX = x;
|
mCurX = x;
|
||||||
mCurY = y;
|
mCurY = y;
|
||||||
mChanged = false;
|
mChanged = false;
|
||||||
|
applyFogOfWar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,14 +40,24 @@ namespace MWGui
|
||||||
void setCellPrefix(const std::string& prefix);
|
void setCellPrefix(const std::string& prefix);
|
||||||
void setActiveCell(const int x, const int y, bool interior=false);
|
void setActiveCell(const int x, const int y, bool interior=false);
|
||||||
|
|
||||||
|
void toggleFogOfWar();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int mCurX, mCurY;
|
int mCurX, mCurY;
|
||||||
bool mInterior;
|
bool mInterior;
|
||||||
MyGUI::ScrollView* mLocalMap;
|
MyGUI::ScrollView* mLocalMap;
|
||||||
std::string mPrefix;
|
std::string mPrefix;
|
||||||
bool mChanged;
|
bool mChanged;
|
||||||
|
bool mFogOfWar;
|
||||||
|
|
||||||
|
void applyFogOfWar();
|
||||||
|
|
||||||
OEngine::GUI::Layout* mLayout;
|
OEngine::GUI::Layout* mLayout;
|
||||||
|
|
||||||
|
float mLastPositionX;
|
||||||
|
float mLastPositionY;
|
||||||
|
float mLastDirectionX;
|
||||||
|
float mLastDirectionY;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
class HUD : public OEngine::GUI::Layout, public LocalMapBase
|
||||||
|
@ -66,11 +76,14 @@ namespace MWGui
|
||||||
void setBatchCount(size_t count);
|
void setBatchCount(size_t count);
|
||||||
void setPlayerDir(const float x, const float y);
|
void setPlayerDir(const float x, const float y);
|
||||||
void setPlayerPos(const float x, const float y);
|
void setPlayerPos(const float x, const float y);
|
||||||
|
void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible);
|
||||||
|
void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible);
|
||||||
|
|
||||||
MyGUI::ProgressPtr health, magicka, stamina;
|
MyGUI::ProgressPtr health, magicka, stamina;
|
||||||
|
MyGUI::Widget *weapBox, *spellBox;
|
||||||
MyGUI::ImageBox *weapImage, *spellImage;
|
MyGUI::ImageBox *weapImage, *spellImage;
|
||||||
MyGUI::ProgressPtr weapStatus, spellStatus;
|
MyGUI::ProgressPtr weapStatus, spellStatus;
|
||||||
MyGUI::WidgetPtr effectBox;
|
MyGUI::Widget *effectBox, *minimapBox;
|
||||||
MyGUI::ImageBox* effect1;
|
MyGUI::ImageBox* effect1;
|
||||||
MyGUI::ScrollView* minimap;
|
MyGUI::ScrollView* minimap;
|
||||||
MyGUI::ImageBox* compass;
|
MyGUI::ImageBox* compass;
|
||||||
|
@ -80,30 +93,12 @@ namespace MWGui
|
||||||
MyGUI::TextBox* fpscounter;
|
MyGUI::TextBox* fpscounter;
|
||||||
MyGUI::TextBox* trianglecounter;
|
MyGUI::TextBox* trianglecounter;
|
||||||
MyGUI::TextBox* batchcounter;
|
MyGUI::TextBox* batchcounter;
|
||||||
};
|
|
||||||
|
|
||||||
class MapWindow : public OEngine::GUI::Layout, public LocalMapBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MapWindow();
|
|
||||||
virtual ~MapWindow(){}
|
|
||||||
|
|
||||||
void setVisible(bool b);
|
|
||||||
void setPlayerPos(const float x, const float y);
|
|
||||||
void setPlayerDir(const float x, const float y);
|
|
||||||
void setCellName(const std::string& cellName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
// bottom left elements
|
||||||
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft;
|
||||||
void onWorldButtonClicked(MyGUI::Widget* _sender);
|
// bottom right elements
|
||||||
|
int minimapBoxBaseRight, effectBoxBaseRight;
|
||||||
MyGUI::ScrollView* mGlobalMap;
|
|
||||||
MyGUI::ImageBox* mPlayerArrow;
|
|
||||||
MyGUI::Button* mButton;
|
|
||||||
MyGUI::IntPoint mLastDragPos;
|
|
||||||
bool mVisible;
|
|
||||||
bool mGlobal;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MainMenu : public OEngine::GUI::Layout
|
class MainMenu : public OEngine::GUI::Layout
|
||||||
|
|
106
apps/openmw/mwgui/map_window.cpp
Normal file
106
apps/openmw/mwgui/map_window.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#include "map_window.hpp"
|
||||||
|
#include "window_manager.hpp"
|
||||||
|
/*
|
||||||
|
#include "../mwmechanics/mechanicsmanager.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
*/
|
||||||
|
using namespace MWGui;
|
||||||
|
|
||||||
|
MapWindow::MapWindow(WindowManager& parWindowManager) :
|
||||||
|
MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager),
|
||||||
|
mGlobal(false)
|
||||||
|
{
|
||||||
|
setCoord(500,0,320,300);
|
||||||
|
setText("WorldButton", "World");
|
||||||
|
setImage("Compass", "textures\\compass.dds");
|
||||||
|
|
||||||
|
// Obviously you should override this later on
|
||||||
|
setCellName("No Cell Loaded");
|
||||||
|
|
||||||
|
getWidget(mLocalMap, "LocalMap");
|
||||||
|
getWidget(mGlobalMap, "GlobalMap");
|
||||||
|
getWidget(mPlayerArrow, "Compass");
|
||||||
|
|
||||||
|
getWidget(mButton, "WorldButton");
|
||||||
|
mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked);
|
||||||
|
|
||||||
|
MyGUI::Button* eventbox;
|
||||||
|
getWidget(eventbox, "EventBox");
|
||||||
|
eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag);
|
||||||
|
eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart);
|
||||||
|
|
||||||
|
LocalMapBase::init(mLocalMap, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::setCellName(const std::string& cellName)
|
||||||
|
{
|
||||||
|
static_cast<MyGUI::Window*>(mMainWidget)->setCaption(cellName);
|
||||||
|
adjustWindowCaption();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::setPlayerPos(const float x, const float y)
|
||||||
|
{
|
||||||
|
if (mGlobal || !mVisible || (x == mLastPositionX && y == mLastPositionY)) return;
|
||||||
|
MyGUI::IntSize size = mLocalMap->getCanvasSize();
|
||||||
|
MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height);
|
||||||
|
MyGUI::IntCoord viewsize = mLocalMap->getCoord();
|
||||||
|
MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top);
|
||||||
|
mLocalMap->setViewOffset(pos);
|
||||||
|
|
||||||
|
mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16));
|
||||||
|
mLastPositionX = x;
|
||||||
|
mLastPositionY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::setPlayerDir(const float x, const float y)
|
||||||
|
{
|
||||||
|
if (!mVisible || (x == mLastDirectionX && y == mLastDirectionY)) return;
|
||||||
|
MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain();
|
||||||
|
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
|
||||||
|
rotatingSubskin->setCenter(MyGUI::IntPoint(16,16));
|
||||||
|
float angle = std::atan2(x,y);
|
||||||
|
rotatingSubskin->setAngle(angle);
|
||||||
|
|
||||||
|
mLastDirectionX = x;
|
||||||
|
mLastDirectionY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||||
|
{
|
||||||
|
if (_id!=MyGUI::MouseButton::Left) return;
|
||||||
|
if (!mGlobal)
|
||||||
|
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
|
||||||
|
{
|
||||||
|
if (_id!=MyGUI::MouseButton::Left) return;
|
||||||
|
|
||||||
|
if (!mGlobal)
|
||||||
|
{
|
||||||
|
MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos;
|
||||||
|
mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff );
|
||||||
|
|
||||||
|
mLastDragPos = MyGUI::IntPoint(_left, _top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
mGlobal = !mGlobal;
|
||||||
|
mGlobalMap->setVisible(mGlobal);
|
||||||
|
mLocalMap->setVisible(!mGlobal);
|
||||||
|
|
||||||
|
mButton->setCaption( mGlobal ? "Local" : "World" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWindow::onPinToggled()
|
||||||
|
{
|
||||||
|
mWindowManager.setMinimapVisibility(!mPinned);
|
||||||
|
}
|
34
apps/openmw/mwgui/map_window.hpp
Normal file
34
apps/openmw/mwgui/map_window.hpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef MWGUI_MAPWINDOW_H
|
||||||
|
#define MWGUI_MAPWINDOW_H
|
||||||
|
|
||||||
|
#include "layouts.hpp"
|
||||||
|
#include "window_pinnable_base.hpp"
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MapWindow(WindowManager& parWindowManager);
|
||||||
|
virtual ~MapWindow(){}
|
||||||
|
|
||||||
|
void setPlayerPos(const float x, const float y);
|
||||||
|
void setPlayerDir(const float x, const float y);
|
||||||
|
void setCellName(const std::string& cellName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
||||||
|
void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
|
||||||
|
void onWorldButtonClicked(MyGUI::Widget* _sender);
|
||||||
|
|
||||||
|
MyGUI::ScrollView* mGlobalMap;
|
||||||
|
MyGUI::ImageBox* mPlayerArrow;
|
||||||
|
MyGUI::Button* mButton;
|
||||||
|
MyGUI::IntPoint mLastDragPos;
|
||||||
|
bool mGlobal;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void onPinToggled();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -12,7 +12,7 @@ using namespace MWGui;
|
||||||
const int StatsWindow::lineHeight = 18;
|
const int StatsWindow::lineHeight = 18;
|
||||||
|
|
||||||
StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
StatsWindow::StatsWindow (WindowManager& parWindowManager)
|
||||||
: WindowBase("openmw_stats_window_layout.xml", parWindowManager)
|
: WindowPinnableBase("openmw_stats_window_layout.xml", parWindowManager)
|
||||||
, skillAreaWidget(NULL)
|
, skillAreaWidget(NULL)
|
||||||
, skillClientWidget(NULL)
|
, skillClientWidget(NULL)
|
||||||
, skillScrollerWidget(NULL)
|
, skillScrollerWidget(NULL)
|
||||||
|
@ -381,3 +381,8 @@ void StatsWindow::updateScroller()
|
||||||
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
|
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
|
||||||
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
|
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatsWindow::onPinToggled()
|
||||||
|
{
|
||||||
|
mWindowManager.setHMSVisibility(!mPinned);
|
||||||
|
}
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "../mwmechanics/stat.hpp"
|
#include "../mwmechanics/stat.hpp"
|
||||||
#include "window_base.hpp"
|
#include "window_pinnable_base.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class WindowManager;
|
class WindowManager;
|
||||||
|
|
||||||
class StatsWindow : public WindowBase
|
class StatsWindow : public WindowPinnableBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::pair<std::string, int> Faction;
|
typedef std::pair<std::string, int> Faction;
|
||||||
|
@ -74,6 +74,9 @@ namespace MWGui
|
||||||
std::string birthSignId;
|
std::string birthSignId;
|
||||||
int reputation, bounty;
|
int reputation, bounty;
|
||||||
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
|
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void onPinToggled();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "review.hpp"
|
#include "review.hpp"
|
||||||
#include "dialogue.hpp"
|
#include "dialogue.hpp"
|
||||||
#include "dialogue_history.hpp"
|
#include "dialogue_history.hpp"
|
||||||
|
#include "map_window.hpp"
|
||||||
#include "stats_window.hpp"
|
#include "stats_window.hpp"
|
||||||
#include "messagebox.hpp"
|
#include "messagebox.hpp"
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ WindowManager::WindowManager(MWWorld::Environment& environment,
|
||||||
|
|
||||||
hud = new HUD(w,h, showFPSLevel);
|
hud = new HUD(w,h, showFPSLevel);
|
||||||
menu = new MainMenu(w,h);
|
menu = new MainMenu(w,h);
|
||||||
map = new MapWindow();
|
map = new MapWindow(*this);
|
||||||
stats = new StatsWindow(*this);
|
stats = new StatsWindow(*this);
|
||||||
console = new Console(w,h, environment, extensions);
|
console = new Console(w,h, environment, extensions);
|
||||||
mJournal = new JournalWindow(*this);
|
mJournal = new JournalWindow(*this);
|
||||||
|
@ -455,3 +456,19 @@ void WindowManager::setPlayerDir(const float x, const float y)
|
||||||
map->setPlayerDir(x,y);
|
map->setPlayerDir(x,y);
|
||||||
hud->setPlayerDir(x,y);
|
hud->setPlayerDir(x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::setHMSVisibility(bool visible)
|
||||||
|
{
|
||||||
|
hud->setBottomLeftVisibility(visible, hud->weapBox->getVisible(), hud->spellBox->getVisible());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::setMinimapVisibility(bool visible)
|
||||||
|
{
|
||||||
|
hud->setBottomRightVisibility(hud->effectBox->getVisible(), visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::toggleFogOfWar()
|
||||||
|
{
|
||||||
|
map->toggleFogOfWar();
|
||||||
|
hud->toggleFogOfWar();
|
||||||
|
}
|
||||||
|
|
|
@ -157,9 +157,16 @@ namespace MWGui
|
||||||
void setPlayerPos(const float x, const float y); ///< set player position in map space
|
void setPlayerPos(const float x, const float y); ///< set player position in map space
|
||||||
void setPlayerDir(const float x, const float y); ///< set player view direction in map space
|
void setPlayerDir(const float x, const float y); ///< set player view direction in map space
|
||||||
|
|
||||||
|
void toggleFogOfWar();
|
||||||
|
|
||||||
void setInteriorMapTexture(const int x, const int y);
|
void setInteriorMapTexture(const int x, const int y);
|
||||||
///< set the index of the map texture that should be used (for interiors)
|
///< set the index of the map texture that should be used (for interiors)
|
||||||
|
|
||||||
|
// sets the visibility of the hud health/magicka/stamina bars
|
||||||
|
void setHMSVisibility(bool visible);
|
||||||
|
// sets the visibility of the hud minimap
|
||||||
|
void setMinimapVisibility(bool visible);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
|
void removeDialog(T*& dialog); ///< Casts to OEngine::GUI::Layout and calls removeDialog, then resets pointer to nullptr.
|
||||||
void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
|
void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
|
||||||
|
|
33
apps/openmw/mwgui/window_pinnable_base.cpp
Normal file
33
apps/openmw/mwgui/window_pinnable_base.cpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#include "window_pinnable_base.hpp"
|
||||||
|
#include "window_manager.hpp"
|
||||||
|
|
||||||
|
using namespace MWGui;
|
||||||
|
|
||||||
|
WindowPinnableBase::WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager)
|
||||||
|
: WindowBase(parLayout, parWindowManager), mPinned(false), mVisible(false)
|
||||||
|
{
|
||||||
|
MyGUI::WindowPtr t = static_cast<MyGUI::WindowPtr>(mMainWidget);
|
||||||
|
t->eventWindowButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onWindowButtonPressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowPinnableBase::setVisible(bool b)
|
||||||
|
{
|
||||||
|
// Pinned windows can not be hidden
|
||||||
|
if (mPinned && !b)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WindowBase::setVisible(b);
|
||||||
|
mVisible = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowPinnableBase::onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName)
|
||||||
|
{
|
||||||
|
if ("PinToggle" == eventName)
|
||||||
|
{
|
||||||
|
mPinned = !mPinned;
|
||||||
|
onPinToggled();
|
||||||
|
}
|
||||||
|
|
||||||
|
eventDone(this);
|
||||||
|
}
|
||||||
|
|
28
apps/openmw/mwgui/window_pinnable_base.hpp
Normal file
28
apps/openmw/mwgui/window_pinnable_base.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef MWGUI_WINDOW_PINNABLE_BASE_H
|
||||||
|
#define MWGUI_WINDOW_PINNABLE_BASE_H
|
||||||
|
|
||||||
|
#include "window_base.hpp"
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
class WindowManager;
|
||||||
|
|
||||||
|
class WindowPinnableBase: public WindowBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WindowPinnableBase(const std::string& parLayout, WindowManager& parWindowManager);
|
||||||
|
void setVisible(bool b);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onWindowButtonPressed(MyGUI::Window* sender, const std::string& eventName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void onPinToggled() = 0;
|
||||||
|
|
||||||
|
bool mPinned;
|
||||||
|
bool mVisible;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -65,12 +65,14 @@ namespace MWInput
|
||||||
A_QuickLoad,
|
A_QuickLoad,
|
||||||
A_QuickMenu,
|
A_QuickMenu,
|
||||||
A_GameMenu,
|
A_GameMenu,
|
||||||
|
A_ToggleWeapon,
|
||||||
|
A_ToggleSpell,
|
||||||
|
|
||||||
A_LAST // Marker for the last item
|
A_LAST // Marker for the last item
|
||||||
};
|
};
|
||||||
|
|
||||||
// Class that handles all input and key bindings for OpenMW
|
// Class that handles all input and key bindings for OpenMW
|
||||||
class InputImpl : public Ogre::FrameListener
|
class InputImpl
|
||||||
{
|
{
|
||||||
OEngine::Input::DispatcherPtr disp;
|
OEngine::Input::DispatcherPtr disp;
|
||||||
OEngine::Render::OgreRenderer &ogre;
|
OEngine::Render::OgreRenderer &ogre;
|
||||||
|
@ -86,6 +88,38 @@ namespace MWInput
|
||||||
|
|
||||||
/* InputImpl Methods */
|
/* InputImpl Methods */
|
||||||
|
|
||||||
|
void toggleSpell()
|
||||||
|
{
|
||||||
|
DrawState state = player.getDrawState();
|
||||||
|
if(state == DrawState_Weapon || state == DrawState_Nothing)
|
||||||
|
{
|
||||||
|
player.setDrawState(DrawState_Spell);
|
||||||
|
std::cout << "Player has now readied his hands for spellcasting!\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.setDrawState(DrawState_Nothing);
|
||||||
|
std::cout << "Player does not have any kind of attack ready now.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggleWeapon()
|
||||||
|
{
|
||||||
|
DrawState state = player.getDrawState();
|
||||||
|
if(state == DrawState_Spell || state == DrawState_Nothing)
|
||||||
|
{
|
||||||
|
player.setDrawState(DrawState_Weapon);
|
||||||
|
std::cout << "Player is now drawing his weapon.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.setDrawState(DrawState_Nothing);
|
||||||
|
std::cout << "Player does not have any kind of attack ready now.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void screenshot()
|
void screenshot()
|
||||||
{
|
{
|
||||||
mEngine.screenshot();
|
mEngine.screenshot();
|
||||||
|
@ -197,11 +231,12 @@ namespace MWInput
|
||||||
"Auto Move");
|
"Auto Move");
|
||||||
disp->funcs.bind(A_ToggleWalk, boost::bind(&InputImpl::toggleWalking, this),
|
disp->funcs.bind(A_ToggleWalk, boost::bind(&InputImpl::toggleWalking, this),
|
||||||
"Toggle Walk/Run");
|
"Toggle Walk/Run");
|
||||||
|
disp->funcs.bind(A_ToggleWeapon,boost::bind(&InputImpl::toggleWeapon,this),
|
||||||
|
"Draw Weapon");
|
||||||
|
disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this),
|
||||||
|
"Ready hands");
|
||||||
// Add the exit listener
|
// Add the exit listener
|
||||||
ogre.getRoot()->addFrameListener(&exit);
|
ogre.getRoot()->addFrameListener(&exit);
|
||||||
// Add ourselves as a frame listener to catch movement keys
|
|
||||||
ogre.getRoot()->addFrameListener(this);
|
|
||||||
|
|
||||||
// Set up the mouse handler and tell it about the player camera
|
// Set up the mouse handler and tell it about the player camera
|
||||||
mouse = MouseLookEventPtr(new MouseLookEvent(player.getRenderer()->getCamera()));
|
mouse = MouseLookEventPtr(new MouseLookEvent(player.getRenderer()->getCamera()));
|
||||||
|
@ -244,6 +279,8 @@ namespace MWInput
|
||||||
disp->bind(A_AutoMove, KC_Z);
|
disp->bind(A_AutoMove, KC_Z);
|
||||||
disp->bind(A_ToggleSneak, KC_X);
|
disp->bind(A_ToggleSneak, KC_X);
|
||||||
disp->bind(A_ToggleWalk, KC_C);
|
disp->bind(A_ToggleWalk, KC_C);
|
||||||
|
disp->bind(A_ToggleWeapon,KC_F);
|
||||||
|
disp->bind(A_ToggleSpell,KC_R);
|
||||||
|
|
||||||
// Key bindings for polled keys
|
// Key bindings for polled keys
|
||||||
// NOTE: These keys are constantly being polled. Only add keys that must be checked each frame.
|
// NOTE: These keys are constantly being polled. Only add keys that must be checked each frame.
|
||||||
|
@ -262,7 +299,7 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: Used to check for movement keys
|
//NOTE: Used to check for movement keys
|
||||||
bool frameRenderingQueued (const Ogre::FrameEvent &evt)
|
void update ()
|
||||||
{
|
{
|
||||||
// Tell OIS to handle all input events
|
// Tell OIS to handle all input events
|
||||||
input.capture();
|
input.capture();
|
||||||
|
@ -276,7 +313,7 @@ namespace MWInput
|
||||||
windows.update();
|
windows.update();
|
||||||
|
|
||||||
// Disable movement in Gui mode
|
// Disable movement in Gui mode
|
||||||
if (windows.isGuiMode()) return true;
|
if (windows.isGuiMode()) return;
|
||||||
|
|
||||||
// Configure player movement according to keyboard input. Actual movement will
|
// Configure player movement according to keyboard input. Actual movement will
|
||||||
// be done in the physics system.
|
// be done in the physics system.
|
||||||
|
@ -305,8 +342,6 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player.setForwardBackward (0);
|
player.setForwardBackward (0);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch between gui modes. Besides controlling the Gui windows
|
// Switch between gui modes. Besides controlling the Gui windows
|
||||||
|
@ -358,4 +393,9 @@ namespace MWInput
|
||||||
{
|
{
|
||||||
impl->setGuiMode(mode);
|
impl->setGuiMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MWInputManager::update()
|
||||||
|
{
|
||||||
|
impl->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ namespace MWInput
|
||||||
OMW::Engine& engine);
|
OMW::Engine& engine);
|
||||||
~MWInputManager();
|
~MWInputManager();
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
void setGuiMode(MWGui::GuiMode mode);
|
void setGuiMode(MWGui::GuiMode mode);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
77
apps/openmw/mwmechanics/actors.cpp
Normal file
77
apps/openmw/mwmechanics/actors.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
|
||||||
|
#include "actors.hpp"
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
#include <components/esm/loadnpc.hpp>
|
||||||
|
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
void Actors::updateActor (const MWWorld::Ptr& ptr, float duration)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
|
||||||
|
{
|
||||||
|
if (!paused && ptr.getRefData().getHandle()!="player")
|
||||||
|
MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip (
|
||||||
|
MWWorld::Class::get (ptr).getNpcStats (ptr), mEnvironment);
|
||||||
|
}
|
||||||
|
|
||||||
|
Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment), mDuration (0) {}
|
||||||
|
|
||||||
|
void Actors::addActor (const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
mActors.insert (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
mActors.erase (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||||
|
{
|
||||||
|
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
||||||
|
|
||||||
|
while (iter!=mActors.end())
|
||||||
|
if (iter->getCell()==cellStore)
|
||||||
|
{
|
||||||
|
mActors.erase (iter++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actors::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
|
||||||
|
bool paused)
|
||||||
|
{
|
||||||
|
mDuration += duration;
|
||||||
|
|
||||||
|
if (mDuration>=0.25)
|
||||||
|
{
|
||||||
|
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter)
|
||||||
|
{
|
||||||
|
updateActor (*iter, mDuration);
|
||||||
|
|
||||||
|
if (iter->getTypeName()==typeid (ESM::NPC).name())
|
||||||
|
updateNpc (*iter, mDuration, paused);
|
||||||
|
}
|
||||||
|
|
||||||
|
mDuration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
|
||||||
|
|
||||||
|
if (vector!=Ogre::Vector3::ZERO)
|
||||||
|
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
apps/openmw/mwmechanics/actors.hpp
Normal file
51
apps/openmw/mwmechanics/actors.hpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef GAME_MWMECHANICS_ACTORS_H
|
||||||
|
#define GAME_MWMECHANICS_ACTORS_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Vector3;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class Environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
class Actors
|
||||||
|
{
|
||||||
|
MWWorld::Environment& mEnvironment;
|
||||||
|
std::set<MWWorld::Ptr> mActors;
|
||||||
|
float mDuration;
|
||||||
|
|
||||||
|
void updateActor (const MWWorld::Ptr& ptr, float duration);
|
||||||
|
|
||||||
|
void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Actors (MWWorld::Environment& environment);
|
||||||
|
|
||||||
|
void addActor (const MWWorld::Ptr& ptr);
|
||||||
|
///< Register an actor for stats management
|
||||||
|
|
||||||
|
void removeActor (const MWWorld::Ptr& ptr);
|
||||||
|
///< Deregister an actor for stats management
|
||||||
|
|
||||||
|
void dropActors (const MWWorld::Ptr::CellStore *cellStore);
|
||||||
|
///< Deregister all actors in the given cell.
|
||||||
|
|
||||||
|
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
|
||||||
|
float duration, bool paused);
|
||||||
|
///< Update actor stats and store desired velocity vectors in \a movement
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
11
apps/openmw/mwmechanics/drawstate.hpp
Normal file
11
apps/openmw/mwmechanics/drawstate.hpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef GAME_MWMECHANICS_DRAWSTATE_H
|
||||||
|
#define GAME_MWMECHANICS_DRAWSTATE_H
|
||||||
|
|
||||||
|
enum DrawState
|
||||||
|
{
|
||||||
|
DrawState_Weapon = 0,
|
||||||
|
DrawState_Spell = 1,
|
||||||
|
DrawState_Nothing = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -222,14 +222,14 @@ namespace MWMechanics
|
||||||
|
|
||||||
MechanicsManager::MechanicsManager (MWWorld::Environment& environment)
|
MechanicsManager::MechanicsManager (MWWorld::Environment& environment)
|
||||||
: mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false),
|
: mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false),
|
||||||
mRaceSelected (false)
|
mRaceSelected (false), mActors (environment)
|
||||||
{
|
{
|
||||||
buildPlayer();
|
buildPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::addActor (const MWWorld::Ptr& ptr)
|
void MechanicsManager::addActor (const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
mActors.insert (ptr);
|
mActors.addActor (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
void MechanicsManager::removeActor (const MWWorld::Ptr& ptr)
|
||||||
|
@ -237,7 +237,7 @@ namespace MWMechanics
|
||||||
if (ptr==mWatched)
|
if (ptr==mWatched)
|
||||||
mWatched = MWWorld::Ptr();
|
mWatched = MWWorld::Ptr();
|
||||||
|
|
||||||
mActors.erase (ptr);
|
mActors.removeActor (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore)
|
||||||
|
@ -245,16 +245,7 @@ namespace MWMechanics
|
||||||
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
|
if (!mWatched.isEmpty() && mWatched.getCell()==cellStore)
|
||||||
mWatched = MWWorld::Ptr();
|
mWatched = MWWorld::Ptr();
|
||||||
|
|
||||||
std::set<MWWorld::Ptr>::iterator iter = mActors.begin();
|
mActors.dropActors (cellStore);
|
||||||
|
|
||||||
while (iter!=mActors.end())
|
|
||||||
if (iter->getCell()==cellStore)
|
|
||||||
{
|
|
||||||
//std::cout << "Erasing an actor";
|
|
||||||
mActors.erase (iter++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++iter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::watchActor (const MWWorld::Ptr& ptr)
|
void MechanicsManager::watchActor (const MWWorld::Ptr& ptr)
|
||||||
|
@ -262,7 +253,8 @@ namespace MWMechanics
|
||||||
mWatched = ptr;
|
mWatched = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement)
|
void MechanicsManager::update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement,
|
||||||
|
float duration, bool paused)
|
||||||
{
|
{
|
||||||
if (!mWatched.isEmpty())
|
if (!mWatched.isEmpty())
|
||||||
{
|
{
|
||||||
|
@ -345,14 +337,7 @@ namespace MWMechanics
|
||||||
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
|
mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end();
|
mActors.update (movement, duration, paused);
|
||||||
++iter)
|
|
||||||
{
|
|
||||||
Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter);
|
|
||||||
|
|
||||||
if (vector!=Ogre::Vector3::ZERO)
|
|
||||||
movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::setPlayerName (const std::string& name)
|
void MechanicsManager::setPlayerName (const std::string& name)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H
|
#ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H
|
||||||
#define GAME_MWMECHANICS_MECHANICSMANAGER_H
|
#define GAME_MWMECHANICS_MECHANICSMANAGER_H
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -9,6 +8,7 @@
|
||||||
|
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
|
#include "actors.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -25,13 +25,13 @@ namespace MWMechanics
|
||||||
class MechanicsManager
|
class MechanicsManager
|
||||||
{
|
{
|
||||||
MWWorld::Environment& mEnvironment;
|
MWWorld::Environment& mEnvironment;
|
||||||
std::set<MWWorld::Ptr> mActors;
|
|
||||||
MWWorld::Ptr mWatched;
|
MWWorld::Ptr mWatched;
|
||||||
CreatureStats mWatchedCreature;
|
CreatureStats mWatchedCreature;
|
||||||
NpcStats mWatchedNpc;
|
NpcStats mWatchedNpc;
|
||||||
bool mUpdatePlayer;
|
bool mUpdatePlayer;
|
||||||
bool mClassSelected;
|
bool mClassSelected;
|
||||||
bool mRaceSelected;
|
bool mRaceSelected;
|
||||||
|
Actors mActors;
|
||||||
|
|
||||||
void buildPlayer();
|
void buildPlayer();
|
||||||
///< build player according to stored class/race/birthsign information. Will
|
///< build player according to stored class/race/birthsign information. Will
|
||||||
|
@ -60,8 +60,12 @@ namespace MWMechanics
|
||||||
///< On each update look for changes in a previously registered actor and update the
|
///< On each update look for changes in a previously registered actor and update the
|
||||||
/// GUI accordingly.
|
/// GUI accordingly.
|
||||||
|
|
||||||
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement);
|
void update (std::vector<std::pair<std::string, Ogre::Vector3> >& movement, float duration,
|
||||||
|
bool paused);
|
||||||
///< Update actor stats and store desired velocity vectors in \a movement
|
///< Update actor stats and store desired velocity vectors in \a movement
|
||||||
|
///
|
||||||
|
/// \param paused In game type does not currently advance (this usually means some GUI
|
||||||
|
/// component is up).
|
||||||
|
|
||||||
void setPlayerName (const std::string& name);
|
void setPlayerName (const std::string& name);
|
||||||
///< Set player name.
|
///< Set player name.
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "stat.hpp"
|
#include "stat.hpp"
|
||||||
|
#include "drawstate.hpp"
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
/// \brief Additional stats for NPCs
|
/// \brief Additional stats for NPCs
|
||||||
///
|
///
|
||||||
/// For non-NPC-specific stats, see the CreatureStats struct.
|
/// For non-NPC-specific stats, see the CreatureStats struct.
|
||||||
|
|
||||||
struct NpcStats
|
struct NpcStats
|
||||||
{
|
{
|
||||||
// NPCs other than the player can only have one faction. But for the sake of consistency
|
// NPCs other than the player can only have one faction. But for the sake of consistency
|
||||||
|
@ -24,9 +24,10 @@ namespace MWMechanics
|
||||||
bool mRun;
|
bool mRun;
|
||||||
bool mSneak;
|
bool mSneak;
|
||||||
bool mCombat;
|
bool mCombat;
|
||||||
|
DrawState mDrawState;
|
||||||
|
|
||||||
NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false),
|
NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false),
|
||||||
mCombat (false) {}
|
mCombat (false) , mDrawState(DrawState_Nothing) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "creatureanimation.hpp"
|
#include "creatureanimation.hpp"
|
||||||
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
#include "../mwworld/world.hpp"
|
#include "../mwworld/world.hpp"
|
||||||
|
|
||||||
|
@ -20,6 +21,28 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme
|
||||||
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
|
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
|
||||||
NifOgre::NIFLoader::load(meshNumbered);
|
NifOgre::NIFLoader::load(meshNumbered);
|
||||||
base = mRend.getScene()->createEntity(meshNumbered);
|
base = mRend.getScene()->createEntity(meshNumbered);
|
||||||
|
base->setVisibilityFlags(RV_Actors);
|
||||||
|
|
||||||
|
bool transparent = false;
|
||||||
|
for (unsigned int i=0; i<base->getNumSubEntities(); ++i)
|
||||||
|
{
|
||||||
|
Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial();
|
||||||
|
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
||||||
|
while (techIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::Technique* tech = techIt.getNext();
|
||||||
|
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
|
||||||
|
while (passIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::Pass* pass = passIt.getNext();
|
||||||
|
|
||||||
|
if (pass->getDepthWriteEnabled() == false)
|
||||||
|
transparent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
|
||||||
|
|
||||||
std::string meshZero = mesh + "0000>|";
|
std::string meshZero = mesh + "0000>|";
|
||||||
|
|
||||||
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){
|
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){
|
||||||
|
|
|
@ -2,24 +2,160 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "OgreRoot.h"
|
#include <OgreNode.h>
|
||||||
#include "OgreRenderWindow.h"
|
#include <OgreSceneManager.h>
|
||||||
#include "OgreSceneManager.h"
|
#include <OgreMaterial.h>
|
||||||
#include "OgreViewport.h"
|
#include <OgreMaterialManager.h>
|
||||||
#include "OgreCamera.h"
|
|
||||||
#include "OgreTextureManager.h"
|
|
||||||
|
|
||||||
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
|
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
|
||||||
|
#include "../mwworld/environment.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include <components/esm/loadstat.hpp>
|
#include <components/esm/loadstat.hpp>
|
||||||
|
#include <components/esm/loadpgrd.hpp>
|
||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
using namespace MWRender;
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
|
||||||
Debugging::Debugging(OEngine::Physic::PhysicEngine* engine){
|
namespace MWRender
|
||||||
eng = engine;
|
{
|
||||||
|
|
||||||
|
static const std::string PATHGRID_POINT_MATERIAL = "pathgridPointMaterial";
|
||||||
|
static const std::string PATHGRID_LINE_MATERIAL = "pathgridLineMaterial";
|
||||||
|
static const std::string DEBUGGING_GROUP = "debugging";
|
||||||
|
static const int POINT_MESH_BASE = 35;
|
||||||
|
|
||||||
|
void Debugging::createGridMaterials()
|
||||||
|
{
|
||||||
|
if (mGridMatsCreated) return;
|
||||||
|
|
||||||
|
if (MaterialManager::getSingleton().getByName(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP).isNull())
|
||||||
|
{
|
||||||
|
MaterialPtr lineMatPtr = MaterialManager::getSingleton().create(PATHGRID_LINE_MATERIAL, DEBUGGING_GROUP);
|
||||||
|
lineMatPtr->setReceiveShadows(false);
|
||||||
|
lineMatPtr->getTechnique(0)->setLightingEnabled(true);
|
||||||
|
lineMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,1,0,0);
|
||||||
|
lineMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,1,0);
|
||||||
|
lineMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MaterialManager::getSingleton().getByName(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP).isNull())
|
||||||
|
{
|
||||||
|
MaterialPtr pointMatPtr = MaterialManager::getSingleton().create(PATHGRID_POINT_MATERIAL, DEBUGGING_GROUP);
|
||||||
|
pointMatPtr->setReceiveShadows(false);
|
||||||
|
pointMatPtr->getTechnique(0)->setLightingEnabled(true);
|
||||||
|
pointMatPtr->getTechnique(0)->getPass(0)->setDiffuse(1,0,0,0);
|
||||||
|
pointMatPtr->getTechnique(0)->getPass(0)->setAmbient(1,0,0);
|
||||||
|
pointMatPtr->getTechnique(0)->getPass(0)->setSelfIllumination(1,0,0);
|
||||||
|
}
|
||||||
|
mGridMatsCreated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugging::destroyGridMaterials()
|
||||||
|
{
|
||||||
|
if (mGridMatsCreated)
|
||||||
|
{
|
||||||
|
MaterialManager::getSingleton().remove(PATHGRID_POINT_MATERIAL);
|
||||||
|
MaterialManager::getSingleton().remove(PATHGRID_LINE_MATERIAL);
|
||||||
|
mGridMatsCreated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ManualObject *Debugging::createPathgridLines(const ESM::Pathgrid *pathgrid)
|
||||||
|
{
|
||||||
|
ManualObject *result = mSceneMgr->createManualObject();
|
||||||
|
|
||||||
|
result->begin(PATHGRID_LINE_MATERIAL, RenderOperation::OT_LINE_LIST);
|
||||||
|
for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->edges.begin();
|
||||||
|
it != pathgrid->edges.end();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
const ESM::Pathgrid::Edge &edge = *it;
|
||||||
|
const ESM::Pathgrid::Point &p1 = pathgrid->points[edge.v0], &p2 = pathgrid->points[edge.v1];
|
||||||
|
Vector3 direction = (Vector3(p2.x, p2.y, p2.z) - Vector3(p1.x, p1.y, p1.z));
|
||||||
|
Vector3 lineDisplacement = direction.crossProduct(Vector3::UNIT_Z).normalisedCopy();
|
||||||
|
lineDisplacement = lineDisplacement * POINT_MESH_BASE +
|
||||||
|
Vector3(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape
|
||||||
|
result->position(Vector3(p1.x, p1.y, p1.z) + lineDisplacement);
|
||||||
|
result->position(Vector3(p2.x, p2.y, p2.z) + lineDisplacement);
|
||||||
|
}
|
||||||
|
result->end();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ManualObject *Debugging::createPathgridPoints(const ESM::Pathgrid *pathgrid)
|
||||||
|
{
|
||||||
|
ManualObject *result = mSceneMgr->createManualObject();
|
||||||
|
const float height = POINT_MESH_BASE * sqrtf(2);
|
||||||
|
|
||||||
|
result->begin(PATHGRID_POINT_MATERIAL, RenderOperation::OT_TRIANGLE_STRIP);
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
uint32 startIndex = 0;
|
||||||
|
for(ESM::Pathgrid::PointList::const_iterator it = pathgrid->points.begin();
|
||||||
|
it != pathgrid->points.end();
|
||||||
|
it++, startIndex += 6)
|
||||||
|
{
|
||||||
|
Vector3 pointPos(it->x, it->y, it->z);
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
{
|
||||||
|
// degenerate triangle from previous octahedron
|
||||||
|
result->index(startIndex - 4); // 2nd point of previous octahedron
|
||||||
|
result->index(startIndex); // start point of current octahedron
|
||||||
|
}
|
||||||
|
|
||||||
|
result->position(pointPos + Vector3(0, 0, height)); // 0
|
||||||
|
result->position(pointPos + Vector3(-POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 1
|
||||||
|
result->position(pointPos + Vector3(POINT_MESH_BASE, -POINT_MESH_BASE, 0)); // 2
|
||||||
|
result->position(pointPos + Vector3(POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 3
|
||||||
|
result->position(pointPos + Vector3(-POINT_MESH_BASE, POINT_MESH_BASE, 0)); // 4
|
||||||
|
result->position(pointPos + Vector3(0, 0, -height)); // 5
|
||||||
|
|
||||||
|
result->index(startIndex + 0);
|
||||||
|
result->index(startIndex + 1);
|
||||||
|
result->index(startIndex + 2);
|
||||||
|
result->index(startIndex + 5);
|
||||||
|
result->index(startIndex + 3);
|
||||||
|
result->index(startIndex + 4);
|
||||||
|
// degenerates
|
||||||
|
result->index(startIndex + 4);
|
||||||
|
result->index(startIndex + 5);
|
||||||
|
result->index(startIndex + 5);
|
||||||
|
// end degenerates
|
||||||
|
result->index(startIndex + 1);
|
||||||
|
result->index(startIndex + 4);
|
||||||
|
result->index(startIndex + 0);
|
||||||
|
result->index(startIndex + 3);
|
||||||
|
result->index(startIndex + 2);
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->end();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debugging::Debugging(SceneNode *mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine) :
|
||||||
|
mMwRoot(mwRoot), mEnvironment(env), mEngine(engine),
|
||||||
|
mSceneMgr(mwRoot->getCreator()),
|
||||||
|
mPathgridEnabled(false),
|
||||||
|
mInteriorPathgridNode(NULL), mPathGridRoot(NULL),
|
||||||
|
mGridMatsCreated(false)
|
||||||
|
{
|
||||||
|
ResourceGroupManager::getSingleton().createResourceGroup(DEBUGGING_GROUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debugging::~Debugging()
|
||||||
|
{
|
||||||
|
if (mPathgridEnabled)
|
||||||
|
{
|
||||||
|
togglePathgrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceGroupManager::getSingleton().destroyResourceGroup(DEBUGGING_GROUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,8 +163,122 @@ bool Debugging::toggleRenderMode (int mode){
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case MWWorld::World::Render_CollisionDebug:
|
case MWWorld::World::Render_CollisionDebug:
|
||||||
return eng->toggleDebugRendering();
|
|
||||||
|
return mEngine->toggleDebugRendering();
|
||||||
|
|
||||||
|
case MWWorld::World::Render_Pathgrid:
|
||||||
|
togglePathgrid();
|
||||||
|
return mPathgridEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Debugging::cellAdded(MWWorld::Ptr::CellStore *store)
|
||||||
|
{
|
||||||
|
mActiveCells.push_back(store);
|
||||||
|
if (mPathgridEnabled)
|
||||||
|
enableCellPathgrid(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugging::cellRemoved(MWWorld::Ptr::CellStore *store)
|
||||||
|
{
|
||||||
|
mActiveCells.erase(std::remove(mActiveCells.begin(), mActiveCells.end(), store), mActiveCells.end());
|
||||||
|
if (mPathgridEnabled)
|
||||||
|
disableCellPathgrid(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugging::togglePathgrid()
|
||||||
|
{
|
||||||
|
mPathgridEnabled = !mPathgridEnabled;
|
||||||
|
if (mPathgridEnabled)
|
||||||
|
{
|
||||||
|
createGridMaterials();
|
||||||
|
|
||||||
|
// add path grid meshes to already loaded cells
|
||||||
|
mPathGridRoot = mMwRoot->createChildSceneNode();
|
||||||
|
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++)
|
||||||
|
{
|
||||||
|
enableCellPathgrid(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remove path grid meshes from already loaded cells
|
||||||
|
for(CellList::iterator it = mActiveCells.begin(); it != mActiveCells.end(); it++)
|
||||||
|
{
|
||||||
|
disableCellPathgrid(*it);
|
||||||
|
}
|
||||||
|
mPathGridRoot->removeAndDestroyAllChildren();
|
||||||
|
mSceneMgr->destroySceneNode(mPathGridRoot);
|
||||||
|
mPathGridRoot = NULL;
|
||||||
|
destroyGridMaterials();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugging::enableCellPathgrid(MWWorld::Ptr::CellStore *store)
|
||||||
|
{
|
||||||
|
ESM::Pathgrid *pathgrid = mEnvironment.mWorld->getStore().pathgrids.search(*store->cell);
|
||||||
|
if (!pathgrid) return;
|
||||||
|
|
||||||
|
Vector3 cellPathGridPos(0, 0, 0);
|
||||||
|
if (store->cell->isExterior())
|
||||||
|
{
|
||||||
|
cellPathGridPos.x = store->cell->data.gridX * ESM::Land::REAL_SIZE;
|
||||||
|
cellPathGridPos.y = store->cell->data.gridY * ESM::Land::REAL_SIZE;
|
||||||
|
}
|
||||||
|
SceneNode *cellPathGrid = mPathGridRoot->createChildSceneNode(cellPathGridPos);
|
||||||
|
cellPathGrid->attachObject(createPathgridLines(pathgrid));
|
||||||
|
cellPathGrid->attachObject(createPathgridPoints(pathgrid));
|
||||||
|
|
||||||
|
if (store->cell->isExterior())
|
||||||
|
{
|
||||||
|
mExteriorPathgridNodes[std::make_pair(store->cell->data.gridX, store->cell->data.gridY)] = cellPathGrid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(mInteriorPathgridNode == NULL);
|
||||||
|
mInteriorPathgridNode = cellPathGrid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugging::disableCellPathgrid(MWWorld::Ptr::CellStore *store)
|
||||||
|
{
|
||||||
|
if (store->cell->isExterior())
|
||||||
|
{
|
||||||
|
ExteriorPathgridNodes::iterator it =
|
||||||
|
mExteriorPathgridNodes.find(std::make_pair(store->cell->data.gridX, store->cell->data.gridY));
|
||||||
|
if (it != mExteriorPathgridNodes.end())
|
||||||
|
{
|
||||||
|
destroyCellPathgridNode(it->second);
|
||||||
|
mExteriorPathgridNodes.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mInteriorPathgridNode)
|
||||||
|
{
|
||||||
|
destroyCellPathgridNode(mInteriorPathgridNode);
|
||||||
|
mInteriorPathgridNode = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugging::destroyCellPathgridNode(SceneNode *node)
|
||||||
|
{
|
||||||
|
mPathGridRoot->removeChild(node);
|
||||||
|
destroyAttachedObjects(node);
|
||||||
|
mSceneMgr->destroySceneNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugging::destroyAttachedObjects(SceneNode *node)
|
||||||
|
{
|
||||||
|
SceneNode::ObjectIterator objIt = node->getAttachedObjectIterator();
|
||||||
|
while (objIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
MovableObject *mesh = static_cast<MovableObject *>(objIt.getNext());
|
||||||
|
mSceneMgr->destroyMovableObject(mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <openengine/ogre/renderer.hpp>
|
#include <openengine/ogre/renderer.hpp>
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -22,19 +23,57 @@ namespace Ogre
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
class World;
|
class World;
|
||||||
|
class Environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class Player;
|
class Player;
|
||||||
|
|
||||||
class Debugging{
|
class Debugging
|
||||||
OEngine::Physic::PhysicEngine* eng;
|
{
|
||||||
|
OEngine::Physic::PhysicEngine* mEngine;
|
||||||
|
Ogre::SceneManager *mSceneMgr;
|
||||||
|
MWWorld::Environment& mEnvironment;
|
||||||
|
|
||||||
|
// Path grid stuff
|
||||||
|
bool mPathgridEnabled;
|
||||||
|
|
||||||
|
void togglePathgrid();
|
||||||
|
|
||||||
|
typedef std::vector<MWWorld::Ptr::CellStore *> CellList;
|
||||||
|
CellList mActiveCells;
|
||||||
|
|
||||||
|
Ogre::SceneNode *mMwRoot;
|
||||||
|
|
||||||
|
Ogre::SceneNode *mPathGridRoot;
|
||||||
|
|
||||||
|
typedef std::map<std::pair<int,int>, Ogre::SceneNode *> ExteriorPathgridNodes;
|
||||||
|
ExteriorPathgridNodes mExteriorPathgridNodes;
|
||||||
|
Ogre::SceneNode *mInteriorPathgridNode;
|
||||||
|
|
||||||
|
void enableCellPathgrid(MWWorld::Ptr::CellStore *store);
|
||||||
|
void disableCellPathgrid(MWWorld::Ptr::CellStore *store);
|
||||||
|
|
||||||
|
// utility
|
||||||
|
void destroyCellPathgridNode(Ogre::SceneNode *node);
|
||||||
|
void destroyAttachedObjects(Ogre::SceneNode *node);
|
||||||
|
|
||||||
|
// materials
|
||||||
|
bool mGridMatsCreated;
|
||||||
|
void createGridMaterials();
|
||||||
|
void destroyGridMaterials();
|
||||||
|
|
||||||
|
// path grid meshes
|
||||||
|
Ogre::ManualObject *createPathgridLines(const ESM::Pathgrid *pathgrid);
|
||||||
|
Ogre::ManualObject *createPathgridPoints(const ESM::Pathgrid *pathgrid);
|
||||||
public:
|
public:
|
||||||
Debugging(OEngine::Physic::PhysicEngine* engine);
|
Debugging(Ogre::SceneNode* mwRoot, MWWorld::Environment &env, OEngine::Physic::PhysicEngine *engine);
|
||||||
|
~Debugging();
|
||||||
bool toggleRenderMode (int mode);
|
bool toggleRenderMode (int mode);
|
||||||
|
|
||||||
|
void cellAdded(MWWorld::Ptr::CellStore* store);
|
||||||
|
void cellRemoved(MWWorld::Ptr::CellStore* store);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
#include "renderingmanager.hpp"
|
#include "renderingmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/environment.hpp"
|
#include "../mwworld/environment.hpp"
|
||||||
|
#include "../mwworld/world.hpp"
|
||||||
#include "../mwgui/window_manager.hpp"
|
#include "../mwgui/window_manager.hpp"
|
||||||
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
#include <OgreOverlayManager.h>
|
#include <OgreOverlayManager.h>
|
||||||
#include <OgreMaterialManager.h>
|
#include <OgreMaterialManager.h>
|
||||||
|
@ -10,16 +12,24 @@
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
|
||||||
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env)
|
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering, MWWorld::Environment* env) :
|
||||||
|
mInterior(false), mCellX(0), mCellY(0)
|
||||||
{
|
{
|
||||||
mRendering = rend;
|
mRendering = rend;
|
||||||
|
mRenderingManager = rendering;
|
||||||
mEnvironment = env;
|
mEnvironment = env;
|
||||||
|
|
||||||
|
mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
|
||||||
|
mCameraRotNode = mCameraPosNode->createChildSceneNode();
|
||||||
|
mCameraNode = mCameraRotNode->createChildSceneNode();
|
||||||
|
|
||||||
mCellCamera = mRendering->getScene()->createCamera("CellCamera");
|
mCellCamera = mRendering->getScene()->createCamera("CellCamera");
|
||||||
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
|
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
|
||||||
// look down -y
|
// look down -y
|
||||||
const float sqrt0pt5 = 0.707106781;
|
const float sqrt0pt5 = 0.707106781;
|
||||||
mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
|
mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
|
||||||
|
|
||||||
|
mCameraNode->attachObject(mCellCamera);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalMap::~LocalMap()
|
LocalMap::~LocalMap()
|
||||||
|
@ -27,6 +37,12 @@ LocalMap::~LocalMap()
|
||||||
deleteBuffers();
|
deleteBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Ogre::Vector2 LocalMap::rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle)
|
||||||
|
{
|
||||||
|
return Vector2( Math::Cos(angle) * (p.x - c.x) - Math::Sin(angle) * (p.y - c.y) + c.x,
|
||||||
|
Math::Sin(angle) * (p.x - c.x) + Math::Cos(angle) * (p.y - c.y) + c.y);
|
||||||
|
}
|
||||||
|
|
||||||
void LocalMap::deleteBuffers()
|
void LocalMap::deleteBuffers()
|
||||||
{
|
{
|
||||||
mBuffers.clear();
|
mBuffers.clear();
|
||||||
|
@ -65,9 +81,6 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
|
||||||
{
|
{
|
||||||
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
||||||
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
|
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
|
||||||
/// \todo why is this workaround needed?
|
|
||||||
min *= 1.3;
|
|
||||||
max *= 1.3;
|
|
||||||
Vector2 length = max-min;
|
Vector2 length = max-min;
|
||||||
|
|
||||||
// divide into segments
|
// divide into segments
|
||||||
|
@ -90,11 +103,15 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
|
||||||
{
|
{
|
||||||
mInterior = false;
|
mInterior = false;
|
||||||
|
|
||||||
|
mCameraRotNode->setOrientation(Quaternion::IDENTITY);
|
||||||
|
|
||||||
std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY);
|
std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY);
|
||||||
|
|
||||||
int x = cell->cell->data.gridX;
|
int x = cell->cell->data.gridX;
|
||||||
int y = cell->cell->data.gridY;
|
int y = cell->cell->data.gridY;
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,16 +121,40 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
|
||||||
mInterior = true;
|
mInterior = true;
|
||||||
mBounds = bounds;
|
mBounds = bounds;
|
||||||
|
|
||||||
Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y);
|
Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y);
|
||||||
Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z);
|
|
||||||
Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z);
|
|
||||||
|
|
||||||
/// \todo why is this workaround needed?
|
const Vector2& north = mEnvironment->mWorld->getNorthVector(cell);
|
||||||
min *= 1.3;
|
Radian angle(std::atan2(-north.x, -north.y));
|
||||||
max *= 1.3;
|
mAngle = angle.valueRadians();
|
||||||
|
mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0));
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
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));
|
||||||
|
|
||||||
|
Vector2 center(mBounds.getCenter().x, mBounds.getCenter().z);
|
||||||
|
|
||||||
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
||||||
|
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
|
||||||
|
|
||||||
Vector2 length = max-min;
|
Vector2 length = max-min;
|
||||||
Vector2 center(bounds.getCenter().x, bounds.getCenter().z);
|
|
||||||
|
mCameraPosNode->setPosition(Vector3(center.x, 0, center.y));
|
||||||
|
|
||||||
// divide into segments
|
// divide into segments
|
||||||
const int segsX = std::ceil( length.x / sSize );
|
const int segsX = std::ceil( length.x / sSize );
|
||||||
|
@ -128,7 +169,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
|
||||||
Vector2 start = min + Vector2(sSize*x,sSize*y);
|
Vector2 start = min + Vector2(sSize*x,sSize*y);
|
||||||
Vector2 newcenter = start + 4096;
|
Vector2 newcenter = start + 4096;
|
||||||
|
|
||||||
render(newcenter.x, newcenter.y, z.y, z.x, sSize, sSize,
|
render(newcenter.x - center.x, newcenter.y - center.y, z.y, z.x, sSize, sSize,
|
||||||
cell->cell->name + "_" + coordStr(x,y));
|
cell->cell->name + "_" + coordStr(x,y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,8 +188,9 @@ void LocalMap::render(const float x, const float y,
|
||||||
|
|
||||||
// make everything visible
|
// make everything visible
|
||||||
mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
|
mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
|
||||||
|
mRenderingManager->disableLights();
|
||||||
|
|
||||||
mCellCamera->setPosition(Vector3(x, zhigh+100000, y));
|
mCameraNode->setPosition(Vector3(x, zhigh+100000, y));
|
||||||
//mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
|
//mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
|
||||||
mCellCamera->setFarClipDistance(0); // infinite
|
mCellCamera->setFarClipDistance(0); // infinite
|
||||||
|
|
||||||
|
@ -182,7 +224,8 @@ void LocalMap::render(const float x, const float y,
|
||||||
vp->setOverlaysEnabled(false);
|
vp->setOverlaysEnabled(false);
|
||||||
vp->setShadowsEnabled(false);
|
vp->setShadowsEnabled(false);
|
||||||
vp->setBackgroundColour(ColourValue(0, 0, 0));
|
vp->setBackgroundColour(ColourValue(0, 0, 0));
|
||||||
//vp->setVisibilityMask( ... );
|
vp->setVisibilityMask(RV_Map);
|
||||||
|
vp->setMaterialScheme("Map");
|
||||||
|
|
||||||
rtt->update();
|
rtt->update();
|
||||||
|
|
||||||
|
@ -216,12 +259,13 @@ void LocalMap::render(const float x, const float y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mRenderingManager->enableLights();
|
||||||
|
|
||||||
// re-enable fog
|
// re-enable fog
|
||||||
mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd);
|
mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction)
|
void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation)
|
||||||
{
|
{
|
||||||
if (sFogOfWarSkip != 0)
|
if (sFogOfWarSkip != 0)
|
||||||
{
|
{
|
||||||
|
@ -232,7 +276,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
|
||||||
|
|
||||||
// retrieve the x,y grid coordinates the player is in
|
// retrieve the x,y grid coordinates the player is in
|
||||||
int x,y;
|
int x,y;
|
||||||
Vector2 pos(position.x, position.z);
|
Vector3 _pos(position.x, 0, position.z);
|
||||||
|
Vector2 pos(_pos.x, _pos.z);
|
||||||
|
|
||||||
|
if (mInterior)
|
||||||
|
{
|
||||||
|
pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis();
|
||||||
|
|
||||||
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
||||||
|
|
||||||
if (!mInterior)
|
if (!mInterior)
|
||||||
{
|
{
|
||||||
x = std::ceil(pos.x / sSize)-1;
|
x = std::ceil(pos.x / sSize)-1;
|
||||||
|
@ -242,9 +298,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
|
||||||
min *= 1.3;
|
|
||||||
|
|
||||||
x = std::ceil((pos.x - min.x)/sSize)-1;
|
x = std::ceil((pos.x - min.x)/sSize)-1;
|
||||||
y = std::ceil((pos.y - min.y)/sSize)-1;
|
y = std::ceil((pos.y - min.y)/sSize)-1;
|
||||||
|
|
||||||
|
@ -259,20 +312,17 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
|
||||||
u = std::abs((pos.x - (sSize*x))/sSize);
|
u = std::abs((pos.x - (sSize*x))/sSize);
|
||||||
v = 1-std::abs((pos.y + (sSize*y))/sSize);
|
v = 1-std::abs((pos.y + (sSize*y))/sSize);
|
||||||
texName = "Cell_"+coordStr(x,y);
|
texName = "Cell_"+coordStr(x,y);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
|
||||||
min *= 1.3;
|
|
||||||
|
|
||||||
u = (pos.x - min.x - sSize*x)/sSize;
|
u = (pos.x - min.x - sSize*x)/sSize;
|
||||||
v = (pos.y - min.y - sSize*y)/sSize;
|
v = (pos.y - min.y - sSize*y)/sSize;
|
||||||
|
|
||||||
texName = mInteriorName + "_" + coordStr(x,y);
|
texName = mInteriorName + "_" + coordStr(x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
mEnvironment->mWindowManager->setPlayerPos(u, v);
|
mEnvironment->mWindowManager->setPlayerPos(u, v);
|
||||||
mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z);
|
mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z);
|
||||||
|
|
||||||
// explore radius (squared)
|
// explore radius (squared)
|
||||||
const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution;
|
const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution;
|
||||||
|
|
|
@ -12,13 +12,15 @@ namespace MWWorld
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
class RenderingManager;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \brief Local map rendering
|
/// \brief Local map rendering
|
||||||
///
|
///
|
||||||
class LocalMap
|
class LocalMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LocalMap(OEngine::Render::OgreRenderer*, MWWorld::Environment* env);
|
LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering, MWWorld::Environment* env);
|
||||||
~LocalMap();
|
~LocalMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,9 +46,9 @@ namespace MWRender
|
||||||
* @remarks This is used to draw a "fog of war" effect
|
* @remarks This is used to draw a "fog of war" effect
|
||||||
* to hide areas on the map the player has not discovered yet.
|
* to hide areas on the map the player has not discovered yet.
|
||||||
* @param position (OGRE coordinates)
|
* @param position (OGRE coordinates)
|
||||||
* @param view direction (OGRE coordinates)
|
* @param camera orientation (OGRE coordinates)
|
||||||
*/
|
*/
|
||||||
void updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction);
|
void updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the fog of war for the current cell to disk.
|
* Save the fog of war for the current cell to disk.
|
||||||
|
@ -58,6 +60,7 @@ namespace MWRender
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEngine::Render::OgreRenderer* mRendering;
|
OEngine::Render::OgreRenderer* mRendering;
|
||||||
|
MWRender::RenderingManager* mRenderingManager;
|
||||||
MWWorld::Environment* mEnvironment;
|
MWWorld::Environment* mEnvironment;
|
||||||
|
|
||||||
// 1024*1024 pixels for a cell
|
// 1024*1024 pixels for a cell
|
||||||
|
@ -73,6 +76,12 @@ namespace MWRender
|
||||||
static const int sSize = 8192;
|
static const int sSize = 8192;
|
||||||
|
|
||||||
Ogre::Camera* mCellCamera;
|
Ogre::Camera* mCellCamera;
|
||||||
|
Ogre::SceneNode* mCameraNode;
|
||||||
|
Ogre::SceneNode* mCameraPosNode;
|
||||||
|
Ogre::SceneNode* mCameraRotNode;
|
||||||
|
|
||||||
|
float mAngle;
|
||||||
|
const Ogre::Vector2 rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle);
|
||||||
|
|
||||||
void render(const float x, const float y,
|
void render(const float x, const float y,
|
||||||
const float zlow, const float zhigh,
|
const float zlow, const float zhigh,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "npcanimation.hpp"
|
#include "npcanimation.hpp"
|
||||||
#include "../mwworld/world.hpp"
|
#include "../mwworld/world.hpp"
|
||||||
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
@ -65,6 +66,27 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
|
||||||
NifOgre::NIFLoader::load(smodel);
|
NifOgre::NIFLoader::load(smodel);
|
||||||
|
|
||||||
base = mRend.getScene()->createEntity(smodel);
|
base = mRend.getScene()->createEntity(smodel);
|
||||||
|
base->setVisibilityFlags(RV_Actors);
|
||||||
|
bool transparent = false;
|
||||||
|
for (unsigned int i=0; i<base->getNumSubEntities(); ++i)
|
||||||
|
{
|
||||||
|
Ogre::MaterialPtr mat = base->getSubEntity(i)->getMaterial();
|
||||||
|
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
||||||
|
while (techIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::Technique* tech = techIt.getNext();
|
||||||
|
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
|
||||||
|
while (passIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::Pass* pass = passIt.getNext();
|
||||||
|
|
||||||
|
if (pass->getDepthWriteEnabled() == false)
|
||||||
|
transparent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
|
||||||
|
|
||||||
base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones
|
base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones
|
||||||
//stay in the same place when we skipanim, or open a gui window
|
//stay in the same place when we skipanim, or open a gui window
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <OgreSceneNode.h>
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
#include <components/nifogre/ogre_nif_loader.hpp>
|
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
|
|
||||||
|
@ -88,18 +90,16 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
||||||
NifOgre::NIFLoader::load(mesh);
|
NifOgre::NIFLoader::load(mesh);
|
||||||
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
|
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
|
||||||
|
|
||||||
/*
|
|
||||||
Ogre::Vector3 extents = ent->getBoundingBox().getSize();
|
Ogre::Vector3 extents = ent->getBoundingBox().getSize();
|
||||||
extents *= insert->getScale();
|
extents *= insert->getScale();
|
||||||
// float size = std::max(std::max(extents.x, extents.y), extents.z);
|
float size = std::max(std::max(extents.x, extents.y), extents.z);
|
||||||
|
|
||||||
bool small = (size < 250); /// \todo config value
|
bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Objects");
|
||||||
|
|
||||||
// do not fade out doors. that will cause holes and look stupid
|
// do not fade out doors. that will cause holes and look stupid
|
||||||
if (ptr.getTypeName().find("Door") != std::string::npos)
|
if (ptr.getTypeName().find("Door") != std::string::npos)
|
||||||
small = false;
|
small = false;
|
||||||
*/
|
|
||||||
const bool small = false;
|
|
||||||
|
|
||||||
if (mBounds.find(ptr.getCell()) == mBounds.end())
|
if (mBounds.find(ptr.getCell()) == mBounds.end())
|
||||||
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
|
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
|
||||||
|
@ -113,17 +113,49 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
||||||
bounds.scale(insert->getScale());
|
bounds.scale(insert->getScale());
|
||||||
mBounds[ptr.getCell()].merge(bounds);
|
mBounds[ptr.getCell()].merge(bounds);
|
||||||
|
|
||||||
if(!mIsStatic)
|
bool transparent = false;
|
||||||
|
for (unsigned int i=0; i<ent->getNumSubEntities(); ++i)
|
||||||
|
{
|
||||||
|
Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial();
|
||||||
|
Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
||||||
|
while (techIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::Technique* tech = techIt.getNext();
|
||||||
|
Ogre::Technique::PassIterator passIt = tech->getPassIterator();
|
||||||
|
while (passIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::Pass* pass = passIt.getNext();
|
||||||
|
|
||||||
|
if (pass->getDepthWriteEnabled() == false)
|
||||||
|
transparent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects"))
|
||||||
{
|
{
|
||||||
insert->attachObject(ent);
|
insert->attachObject(ent);
|
||||||
|
|
||||||
ent->setRenderingDistance(small ? 2500 : 0); /// \todo config value
|
ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0);
|
||||||
|
ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc);
|
||||||
|
ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Ogre::StaticGeometry* sg = 0;
|
Ogre::StaticGeometry* sg = 0;
|
||||||
|
|
||||||
if (small)
|
/* if (transparent)
|
||||||
|
{
|
||||||
|
if( mStaticGeometryAlpha.find(ptr.getCell()) == mStaticGeometryAlpha.end())
|
||||||
|
{
|
||||||
|
uniqueID = uniqueID +1;
|
||||||
|
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
|
||||||
|
mStaticGeometryAlpha[ptr.getCell()] = sg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sg = mStaticGeometryAlpha[ptr.getCell()];
|
||||||
|
}
|
||||||
|
else*/ if (small)
|
||||||
{
|
{
|
||||||
if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end())
|
if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end())
|
||||||
{
|
{
|
||||||
|
@ -131,7 +163,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
||||||
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
|
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
|
||||||
mStaticGeometrySmall[ptr.getCell()] = sg;
|
mStaticGeometrySmall[ptr.getCell()] = sg;
|
||||||
|
|
||||||
sg->setRenderingDistance(2500); /// \todo config value
|
sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sg = mStaticGeometrySmall[ptr.getCell()];
|
sg = mStaticGeometrySmall[ptr.getCell()];
|
||||||
|
@ -159,6 +191,10 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
||||||
|
|
||||||
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
|
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
|
||||||
|
|
||||||
|
sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics);
|
||||||
|
|
||||||
|
sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
|
||||||
|
|
||||||
mRenderer.getScene()->destroyEntity(ent);
|
mRenderer.getScene()->destroyEntity(ent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +205,7 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
|
||||||
assert(insert);
|
assert(insert);
|
||||||
Ogre::Light *light = mRenderer.getScene()->createLight();
|
Ogre::Light *light = mRenderer.getScene()->createLight();
|
||||||
light->setDiffuseColour (r, g, b);
|
light->setDiffuseColour (r, g, b);
|
||||||
|
mLights.push_back(light->getName());
|
||||||
|
|
||||||
float cval=0.0f, lval=0.0f, qval=0.0f;
|
float cval=0.0f, lval=0.0f, qval=0.0f;
|
||||||
|
|
||||||
|
@ -251,6 +288,13 @@ void Objects::removeCell(MWWorld::Ptr::CellStore* store)
|
||||||
mRenderer.getScene()->destroyStaticGeometry (sg);
|
mRenderer.getScene()->destroyStaticGeometry (sg);
|
||||||
sg = 0;
|
sg = 0;
|
||||||
}
|
}
|
||||||
|
/*if(mStaticGeometryAlpha.find(store) != mStaticGeometryAlpha.end())
|
||||||
|
{
|
||||||
|
Ogre::StaticGeometry* sg = mStaticGeometryAlpha[store];
|
||||||
|
mStaticGeometryAlpha.erase(store);
|
||||||
|
mRenderer.getScene()->destroyStaticGeometry (sg);
|
||||||
|
sg = 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
if(mBounds.find(store) != mBounds.end())
|
if(mBounds.find(store) != mBounds.end())
|
||||||
mBounds.erase(store);
|
mBounds.erase(store);
|
||||||
|
@ -268,9 +312,45 @@ void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell)
|
||||||
Ogre::StaticGeometry* sg = mStaticGeometrySmall[&cell];
|
Ogre::StaticGeometry* sg = mStaticGeometrySmall[&cell];
|
||||||
sg->build();
|
sg->build();
|
||||||
}
|
}
|
||||||
|
/*if(mStaticGeometryAlpha.find(&cell) != mStaticGeometryAlpha.end())
|
||||||
|
{
|
||||||
|
Ogre::StaticGeometry* sg = mStaticGeometryAlpha[&cell];
|
||||||
|
sg->build();
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell)
|
Ogre::AxisAlignedBox Objects::getDimensions(MWWorld::Ptr::CellStore* cell)
|
||||||
{
|
{
|
||||||
return mBounds[cell];
|
return mBounds[cell];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Objects::enableLights()
|
||||||
|
{
|
||||||
|
std::vector<std::string>::iterator it = mLights.begin();
|
||||||
|
while (it != mLights.end())
|
||||||
|
{
|
||||||
|
if (mMwRoot->getCreator()->hasLight(*it))
|
||||||
|
{
|
||||||
|
mMwRoot->getCreator()->getLight(*it)->setVisible(true);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
it = mLights.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Objects::disableLights()
|
||||||
|
{
|
||||||
|
std::vector<std::string>::iterator it = mLights.begin();
|
||||||
|
while (it != mLights.end())
|
||||||
|
{
|
||||||
|
if (mMwRoot->getCreator()->hasLight(*it))
|
||||||
|
{
|
||||||
|
mMwRoot->getCreator()->getLight(*it)->setVisible(false);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
it = mLights.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@ class Objects{
|
||||||
std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
|
std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
|
||||||
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry;
|
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry;
|
||||||
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
|
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometrySmall;
|
||||||
|
//std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometryAlpha;
|
||||||
std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds;
|
std::map<MWWorld::Ptr::CellStore *, Ogre::AxisAlignedBox> mBounds;
|
||||||
|
std::vector<std::string> mLights;
|
||||||
Ogre::SceneNode* mMwRoot;
|
Ogre::SceneNode* mMwRoot;
|
||||||
bool mIsStatic;
|
bool mIsStatic;
|
||||||
static int uniqueID;
|
static int uniqueID;
|
||||||
|
@ -44,6 +46,9 @@ public:
|
||||||
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);
|
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);
|
||||||
void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius);
|
void insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius);
|
||||||
|
|
||||||
|
void enableLights();
|
||||||
|
void disableLights();
|
||||||
|
|
||||||
Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*);
|
Ogre::AxisAlignedBox getDimensions(MWWorld::Ptr::CellStore*);
|
||||||
///< get a bounding box that encloses all objects in the specified cell
|
///< get a bounding box that encloses all objects in the specified cell
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#include "occlusionquery.hpp"
|
#include "occlusionquery.hpp"
|
||||||
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
#include <OgreRenderSystem.h>
|
#include <OgreRenderSystem.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
#include <OgreBillboardSet.h>
|
#include <OgreBillboardSet.h>
|
||||||
#include <OgreHardwareOcclusionQuery.h>
|
#include <OgreHardwareOcclusionQuery.h>
|
||||||
#include <OgreEntity.h>
|
#include <OgreEntity.h>
|
||||||
|
#include <OgreSubEntity.h>
|
||||||
|
#include <OgreMaterialManager.h>
|
||||||
|
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
@ -38,9 +41,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This means that everything up to RENDER_QUEUE_MAIN can occlude the objects that are tested
|
|
||||||
const int queue = RENDER_QUEUE_MAIN+1;
|
|
||||||
|
|
||||||
MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
|
MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
|
||||||
MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels");
|
MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels");
|
||||||
matQueryArea->setDepthWriteEnabled(false);
|
matQueryArea->setDepthWriteEnabled(false);
|
||||||
|
@ -63,14 +63,14 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
||||||
mBBQueryTotal->setDefaultDimensions(150, 150);
|
mBBQueryTotal->setDefaultDimensions(150, 150);
|
||||||
mBBQueryTotal->createBillboard(Vector3::ZERO);
|
mBBQueryTotal->createBillboard(Vector3::ZERO);
|
||||||
mBBQueryTotal->setMaterialName("QueryTotalPixels");
|
mBBQueryTotal->setMaterialName("QueryTotalPixels");
|
||||||
mBBQueryTotal->setRenderQueueGroup(queue+1);
|
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
|
||||||
mBBNodeReal->attachObject(mBBQueryTotal);
|
mBBNodeReal->attachObject(mBBQueryTotal);
|
||||||
|
|
||||||
mBBQueryVisible = mRendering->getScene()->createBillboardSet(1);
|
mBBQueryVisible = mRendering->getScene()->createBillboardSet(1);
|
||||||
mBBQueryVisible->setDefaultDimensions(150, 150);
|
mBBQueryVisible->setDefaultDimensions(150, 150);
|
||||||
mBBQueryVisible->createBillboard(Vector3::ZERO);
|
mBBQueryVisible->createBillboard(Vector3::ZERO);
|
||||||
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
|
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
|
||||||
mBBQueryVisible->setRenderQueueGroup(queue+1);
|
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
|
||||||
mBBNodeReal->attachObject(mBBQueryVisible);
|
mBBNodeReal->attachObject(mBBQueryVisible);
|
||||||
|
|
||||||
mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1);
|
mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1);
|
||||||
|
@ -78,13 +78,12 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
||||||
mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003);
|
mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003);
|
||||||
mBBQuerySingleObject->createBillboard(Vector3::ZERO);
|
mBBQuerySingleObject->createBillboard(Vector3::ZERO);
|
||||||
mBBQuerySingleObject->setMaterialName("QueryVisiblePixels");
|
mBBQuerySingleObject->setMaterialName("QueryVisiblePixels");
|
||||||
mBBQuerySingleObject->setRenderQueueGroup(queue);
|
mBBQuerySingleObject->setRenderQueueGroup(RQG_OcclusionQuery);
|
||||||
mObjectNode->attachObject(mBBQuerySingleObject);
|
mObjectNode->attachObject(mBBQuerySingleObject);
|
||||||
|
|
||||||
mRendering->getScene()->addRenderObjectListener(this);
|
mRendering->getScene()->addRenderObjectListener(this);
|
||||||
mRendering->getScene()->addRenderQueueListener(this);
|
mRendering->getScene()->addRenderQueueListener(this);
|
||||||
mDoQuery = true;
|
mDoQuery = true;
|
||||||
mDoQuery2 = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OcclusionQuery::~OcclusionQuery()
|
OcclusionQuery::~OcclusionQuery()
|
||||||
|
@ -152,7 +151,7 @@ void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocati
|
||||||
* this can happen for example if the object that is tested is outside of the view frustum
|
* this can happen for example if the object that is tested is outside of the view frustum
|
||||||
* to prevent this, check if the queries have been performed after everything has been rendered and if not, start them manually
|
* to prevent this, check if the queries have been performed after everything has been rendered and if not, start them manually
|
||||||
*/
|
*/
|
||||||
if (queueGroupId == RENDER_QUEUE_SKIES_LATE)
|
if (queueGroupId == RQG_SkiesLate)
|
||||||
{
|
{
|
||||||
if (mWasVisible == false && mDoQuery)
|
if (mWasVisible == false && mDoQuery)
|
||||||
{
|
{
|
||||||
|
@ -195,7 +194,6 @@ void OcclusionQuery::update(float duration)
|
||||||
// Stop occlusion queries until we get their information
|
// Stop occlusion queries until we get their information
|
||||||
// (may not happen on the same frame they are requested in)
|
// (may not happen on the same frame they are requested in)
|
||||||
mDoQuery = false;
|
mDoQuery = false;
|
||||||
mDoQuery2 = false;
|
|
||||||
|
|
||||||
if (!mSunTotalAreaQuery->isStillOutstanding()
|
if (!mSunTotalAreaQuery->isStillOutstanding()
|
||||||
&& !mSunVisibleAreaQuery->isStillOutstanding()
|
&& !mSunVisibleAreaQuery->isStillOutstanding()
|
||||||
|
@ -264,3 +262,40 @@ bool OcclusionQuery::getTestResult()
|
||||||
|
|
||||||
return mTestResult;
|
return mTestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OcclusionQuery::isPotentialOccluder(Ogre::SceneNode* node)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (unsigned int i=0; i < node->numAttachedObjects(); ++i)
|
||||||
|
{
|
||||||
|
MovableObject* ob = node->getAttachedObject(i);
|
||||||
|
std::string type = ob->getMovableType();
|
||||||
|
if (type == "Entity")
|
||||||
|
{
|
||||||
|
Entity* ent = static_cast<Entity*>(ob);
|
||||||
|
for (unsigned int j=0; j < ent->getNumSubEntities(); ++j)
|
||||||
|
{
|
||||||
|
// if any sub entity has a material with depth write off,
|
||||||
|
// consider the object as not an occluder
|
||||||
|
MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
|
||||||
|
|
||||||
|
Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
||||||
|
while (techIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Technique* tech = techIt.getNext();
|
||||||
|
Technique::PassIterator passIt = tech->getPassIterator();
|
||||||
|
while (passIt.hasMoreElements())
|
||||||
|
{
|
||||||
|
Pass* pass = passIt.getNext();
|
||||||
|
|
||||||
|
if (pass->getDepthWriteEnabled() == false)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,14 @@ namespace MWRender
|
||||||
*/
|
*/
|
||||||
bool occlusionTestPending();
|
bool occlusionTestPending();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the objects held by this scenenode
|
||||||
|
* can be considered as potential occluders
|
||||||
|
* (which might not be the case when transparency is involved)
|
||||||
|
* @param Scene node
|
||||||
|
*/
|
||||||
|
bool isPotentialOccluder(Ogre::SceneNode* node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the object tested in the last request was occluded
|
* @return true if the object tested in the last request was occluded
|
||||||
*/
|
*/
|
||||||
|
|
62
apps/openmw/mwrender/renderconst.hpp
Normal file
62
apps/openmw/mwrender/renderconst.hpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef GAME_RENDER_CONST_H
|
||||||
|
#define GAME_RENDER_CONST_H
|
||||||
|
|
||||||
|
#include <OgreRenderQueue.h>
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
|
||||||
|
// Render queue groups
|
||||||
|
enum RenderQueueGroups
|
||||||
|
{
|
||||||
|
// Sky early (atmosphere, clouds, moons)
|
||||||
|
RQG_SkiesEarly = Ogre::RENDER_QUEUE_SKIES_EARLY,
|
||||||
|
|
||||||
|
RQG_Main = Ogre::RENDER_QUEUE_MAIN,
|
||||||
|
|
||||||
|
RQG_Water = Ogre::RENDER_QUEUE_7+1,
|
||||||
|
|
||||||
|
RQG_Alpha = Ogre::RENDER_QUEUE_MAIN,
|
||||||
|
|
||||||
|
RQG_UnderWater = Ogre::RENDER_QUEUE_7+1,
|
||||||
|
|
||||||
|
RQG_OcclusionQuery = Ogre::RENDER_QUEUE_8,
|
||||||
|
|
||||||
|
// Sky late (sun & sun flare)
|
||||||
|
RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Visibility flags
|
||||||
|
enum VisibilityFlags
|
||||||
|
{
|
||||||
|
// Terrain
|
||||||
|
RV_Terrain = 1,
|
||||||
|
|
||||||
|
// Statics (e.g. trees, houses)
|
||||||
|
RV_Statics = 2,
|
||||||
|
|
||||||
|
// Small statics
|
||||||
|
RV_StaticsSmall = 4,
|
||||||
|
|
||||||
|
// Water
|
||||||
|
RV_Water = 8,
|
||||||
|
|
||||||
|
// Actors (player, npcs, creatures)
|
||||||
|
RV_Actors = 16,
|
||||||
|
|
||||||
|
// Misc objects (containers, dynamic objects)
|
||||||
|
RV_Misc = 32,
|
||||||
|
|
||||||
|
RV_Sky = 64,
|
||||||
|
|
||||||
|
// Sun glare (not visible in reflection)
|
||||||
|
RV_Glare = 128,
|
||||||
|
|
||||||
|
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water,
|
||||||
|
|
||||||
|
/// \todo markers (normally hidden)
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,6 +12,7 @@
|
||||||
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
|
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include <components/esm/loadstat.hpp>
|
#include <components/esm/loadstat.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
|
@ -20,22 +21,54 @@ using namespace Ogre;
|
||||||
namespace MWRender {
|
namespace MWRender {
|
||||||
|
|
||||||
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment)
|
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment)
|
||||||
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mDebugging(engine)
|
:mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0)
|
||||||
{
|
{
|
||||||
mRendering.createScene("PlayerCam", 55, 5);
|
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
|
||||||
mTerrainManager = new TerrainManager(mRendering.getScene(),
|
mTerrainManager = new TerrainManager(mRendering.getScene(),
|
||||||
environment);
|
environment);
|
||||||
|
|
||||||
|
mWater = 0;
|
||||||
|
|
||||||
//The fog type must be set before any terrain objects are created as if the
|
//The fog type must be set before any terrain objects are created as if the
|
||||||
//fog type is set to FOG_NONE then the initially created terrain won't have any fog
|
//fog type is set to FOG_NONE then the initially created terrain won't have any fog
|
||||||
configureFog(1, ColourValue(1,1,1));
|
configureFog(1, ColourValue(1,1,1));
|
||||||
|
|
||||||
// Set default mipmap level (NB some APIs ignore this)
|
// Set default mipmap level (NB some APIs ignore this)
|
||||||
TextureManager::getSingleton().setDefaultNumMipmaps(5);
|
TextureManager::getSingleton().setDefaultNumMipmaps(Settings::Manager::getInt("num mipmaps", "General"));
|
||||||
|
|
||||||
|
// Set default texture filtering options
|
||||||
|
TextureFilterOptions tfo;
|
||||||
|
std::string filter = Settings::Manager::getString("texture filtering", "General");
|
||||||
|
if (filter == "anisotropic") tfo = TFO_ANISOTROPIC;
|
||||||
|
else if (filter == "trilinear") tfo = TFO_TRILINEAR;
|
||||||
|
else if (filter == "bilinear") tfo = TFO_BILINEAR;
|
||||||
|
else if (filter == "none") tfo = TFO_NONE;
|
||||||
|
|
||||||
|
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
|
||||||
|
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
|
||||||
|
|
||||||
// Load resources
|
// Load resources
|
||||||
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
||||||
|
|
||||||
|
// disable unsupported effects
|
||||||
|
const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
|
||||||
|
if (caps->getNumMultiRenderTargets() < 2)
|
||||||
|
Settings::Manager::setBool("shader", "Water", false);
|
||||||
|
|
||||||
|
// note that the order is important here
|
||||||
|
if (useMRT())
|
||||||
|
{
|
||||||
|
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbuffer");
|
||||||
|
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
|
||||||
|
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "Underwater");
|
||||||
|
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbufferFinalizer");
|
||||||
|
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "UnderwaterNoMRT");
|
||||||
|
}
|
||||||
|
|
||||||
// Turn the entire scene (represented by the 'root' node) -90
|
// Turn the entire scene (represented by the 'root' node) -90
|
||||||
// degrees around the x axis. This makes Z go upwards, and Y go into
|
// 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
|
// the screen (when x is to the right.) This is the orientation that
|
||||||
|
@ -58,12 +91,11 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
|
|
||||||
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
|
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
|
||||||
|
|
||||||
mWater = 0;
|
|
||||||
|
|
||||||
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
|
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
|
||||||
mSun = 0;
|
mSun = 0;
|
||||||
|
|
||||||
mLocalMap = new MWRender::LocalMap(&mRendering, &environment);
|
mDebugging = new Debugging(mMwRoot, environment, engine);
|
||||||
|
mLocalMap = new MWRender::LocalMap(&mRendering, this, &environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingManager::~RenderingManager ()
|
RenderingManager::~RenderingManager ()
|
||||||
|
@ -71,6 +103,7 @@ RenderingManager::~RenderingManager ()
|
||||||
//TODO: destroy mSun?
|
//TODO: destroy mSun?
|
||||||
delete mPlayer;
|
delete mPlayer;
|
||||||
delete mSkyManager;
|
delete mSkyManager;
|
||||||
|
delete mDebugging;
|
||||||
delete mTerrainManager;
|
delete mTerrainManager;
|
||||||
delete mLocalMap;
|
delete mLocalMap;
|
||||||
delete mOcclusionQuery;
|
delete mOcclusionQuery;
|
||||||
|
@ -101,6 +134,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
|
||||||
{
|
{
|
||||||
mObjects.removeCell(store);
|
mObjects.removeCell(store);
|
||||||
mActors.removeCell(store);
|
mActors.removeCell(store);
|
||||||
|
mDebugging->cellRemoved(store);
|
||||||
if (store->cell->isExterior())
|
if (store->cell->isExterior())
|
||||||
mTerrainManager->cellRemoved(store);
|
mTerrainManager->cellRemoved(store);
|
||||||
}
|
}
|
||||||
|
@ -108,8 +142,7 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store)
|
||||||
void RenderingManager::removeWater ()
|
void RenderingManager::removeWater ()
|
||||||
{
|
{
|
||||||
if(mWater){
|
if(mWater){
|
||||||
delete mWater;
|
mWater->setActive(false);
|
||||||
mWater = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +155,10 @@ void RenderingManager::toggleWater()
|
||||||
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
|
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
|
||||||
{
|
{
|
||||||
mObjects.buildStaticGeometry (*store);
|
mObjects.buildStaticGeometry (*store);
|
||||||
|
mDebugging->cellAdded(store);
|
||||||
if (store->cell->isExterior())
|
if (store->cell->isExterior())
|
||||||
mTerrainManager->cellAdded(store);
|
mTerrainManager->cellAdded(store);
|
||||||
|
waterAdded(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::addObject (const MWWorld::Ptr& ptr){
|
void RenderingManager::addObject (const MWWorld::Ptr& ptr){
|
||||||
|
@ -173,18 +208,17 @@ void RenderingManager::update (float duration){
|
||||||
|
|
||||||
mRendering.update(duration);
|
mRendering.update(duration);
|
||||||
|
|
||||||
mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealDirection() );
|
mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() );
|
||||||
|
|
||||||
checkUnderwater();
|
checkUnderwater();
|
||||||
}
|
}
|
||||||
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
|
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
|
||||||
if(store->cell->data.flags & store->cell->HasWater){
|
if(store->cell->data.flags & store->cell->HasWater){
|
||||||
if(mWater == 0)
|
if(mWater == 0)
|
||||||
mWater = new MWRender::Water(mRendering.getCamera(), store->cell);
|
mWater = new MWRender::Water(mRendering.getCamera(), mSkyManager, store->cell);
|
||||||
else
|
else
|
||||||
mWater->changeCell(store->cell);
|
mWater->changeCell(store->cell);
|
||||||
//else
|
mWater->setActive(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
removeWater();
|
removeWater();
|
||||||
|
@ -242,17 +276,31 @@ void RenderingManager::skySetMoonColour (bool red){
|
||||||
|
|
||||||
bool RenderingManager::toggleRenderMode(int mode)
|
bool RenderingManager::toggleRenderMode(int mode)
|
||||||
{
|
{
|
||||||
if (mode == MWWorld::World::Render_CollisionDebug)
|
if (mode != MWWorld::World::Render_Wireframe)
|
||||||
return mDebugging.toggleRenderMode(mode);
|
return mDebugging->toggleRenderMode(mode);
|
||||||
else // if (mode == MWWorld::World::Render_Wireframe)
|
else // if (mode == MWWorld::World::Render_Wireframe)
|
||||||
{
|
{
|
||||||
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
|
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
|
||||||
{
|
{
|
||||||
|
// disable compositors
|
||||||
|
if (useMRT())
|
||||||
|
{
|
||||||
|
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", false);
|
||||||
|
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", false);
|
||||||
|
}
|
||||||
|
|
||||||
mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
|
mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// re-enable compositors
|
||||||
|
if (useMRT())
|
||||||
|
{
|
||||||
|
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
|
||||||
|
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
|
||||||
|
}
|
||||||
|
|
||||||
mRendering.getCamera()->setPolygonMode(PM_SOLID);
|
mRendering.getCamera()->setPolygonMode(PM_SOLID);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -269,19 +317,21 @@ void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
|
||||||
|
|
||||||
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
|
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
|
||||||
{
|
{
|
||||||
/// \todo make the viewing distance and fog start/end configurable
|
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
|
||||||
|
|
||||||
// right now we load 3x3 cells, so the maximum viewing distance we
|
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
|
||||||
// can allow (to prevent objects suddenly popping up) equals:
|
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
|
||||||
// 8192 * 0.69
|
|
||||||
// ^ cell size ^ minimum density value used (clear weather)
|
|
||||||
float low = 5652.48 / density / 2.f;
|
|
||||||
float high = 5652.48 / density;
|
|
||||||
|
|
||||||
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
|
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
|
||||||
|
|
||||||
mRendering.getCamera()->setFarClipDistance ( high );
|
mRendering.getCamera()->setFarClipDistance ( max / density );
|
||||||
mRendering.getViewport()->setBackgroundColour (colour);
|
mRendering.getViewport()->setBackgroundColour (colour);
|
||||||
|
|
||||||
|
CompositorInstance* inst = CompositorManager::getSingleton().getCompositorChain(mRendering.getViewport())->getCompositor("gbuffer");
|
||||||
|
if (inst != 0)
|
||||||
|
inst->getCompositor()->getTechnique(0)->getTargetPass(0)->getPass(0)->setClearColour(colour);
|
||||||
|
if (mWater)
|
||||||
|
mWater->setViewportBackground(colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -341,8 +391,10 @@ void RenderingManager::toggleLight()
|
||||||
|
|
||||||
setAmbientMode();
|
setAmbientMode();
|
||||||
}
|
}
|
||||||
void RenderingManager::checkUnderwater(){
|
void RenderingManager::checkUnderwater()
|
||||||
if(mWater){
|
{
|
||||||
|
if(mWater)
|
||||||
|
{
|
||||||
mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y );
|
mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,6 +413,7 @@ void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr)
|
||||||
void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
|
void RenderingManager::setSunColour(const Ogre::ColourValue& colour)
|
||||||
{
|
{
|
||||||
mSun->setDiffuseColour(colour);
|
mSun->setDiffuseColour(colour);
|
||||||
|
mSun->setSpecularColour(colour);
|
||||||
mTerrainManager->setDiffuse(colour);
|
mTerrainManager->setDiffuse(colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,4 +460,19 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell)
|
||||||
mLocalMap->saveFogOfWar(cell);
|
mLocalMap->saveFogOfWar(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingManager::disableLights()
|
||||||
|
{
|
||||||
|
mObjects.disableLights();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingManager::enableLights()
|
||||||
|
{
|
||||||
|
mObjects.enableLights();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool RenderingManager::useMRT()
|
||||||
|
{
|
||||||
|
return Settings::Manager::getBool("shader", "Water");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -31,11 +31,8 @@
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Camera;
|
|
||||||
class Viewport;
|
|
||||||
class SceneManager;
|
class SceneManager;
|
||||||
class SceneNode;
|
class SceneNode;
|
||||||
class RaySceneQuery;
|
|
||||||
class Quaternion;
|
class Quaternion;
|
||||||
class Vector3;
|
class Vector3;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +81,8 @@ class RenderingManager: private RenderingInterface {
|
||||||
|
|
||||||
void removeWater();
|
void removeWater();
|
||||||
|
|
||||||
|
static const bool useMRT();
|
||||||
|
|
||||||
void preCellChange (MWWorld::Ptr::CellStore* store);
|
void preCellChange (MWWorld::Ptr::CellStore* store);
|
||||||
///< this event is fired immediately before changing cell
|
///< this event is fired immediately before changing cell
|
||||||
|
|
||||||
|
@ -109,6 +108,9 @@ class RenderingManager: private RenderingInterface {
|
||||||
void sunEnable();
|
void sunEnable();
|
||||||
void sunDisable();
|
void sunDisable();
|
||||||
|
|
||||||
|
void disableLights();
|
||||||
|
void enableLights();
|
||||||
|
|
||||||
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
|
bool occlusionQuerySupported() { return mOcclusionQuery->supported(); };
|
||||||
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; };
|
OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; };
|
||||||
|
|
||||||
|
@ -174,7 +176,8 @@ class RenderingManager: private RenderingInterface {
|
||||||
OEngine::Physic::PhysicEngine* mPhysicsEngine;
|
OEngine::Physic::PhysicEngine* mPhysicsEngine;
|
||||||
|
|
||||||
MWRender::Player *mPlayer;
|
MWRender::Player *mPlayer;
|
||||||
MWRender::Debugging mDebugging;
|
|
||||||
|
MWRender::Debugging *mDebugging;
|
||||||
|
|
||||||
MWRender::LocalMap* mLocalMap;
|
MWRender::LocalMap* mLocalMap;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
|
|
||||||
#include "../mwworld/environment.hpp"
|
#include "../mwworld/environment.hpp"
|
||||||
#include "../mwworld/world.hpp"
|
#include "../mwworld/world.hpp"
|
||||||
#include "occlusionquery.hpp"
|
#include "renderconst.hpp"
|
||||||
|
#include "renderingmanager.hpp"
|
||||||
|
|
||||||
using namespace MWRender;
|
using namespace MWRender;
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
@ -60,6 +61,11 @@ Vector3 BillboardObject::getPosition() const
|
||||||
return Vector3(p.x, -p.z, p.y);
|
return Vector3(p.x, -p.z, p.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BillboardObject::setVisibilityFlags(int flags)
|
||||||
|
{
|
||||||
|
mBBSet->setVisibilityFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
void BillboardObject::setColour(const ColourValue& pColour)
|
void BillboardObject::setColour(const ColourValue& pColour)
|
||||||
{
|
{
|
||||||
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour);
|
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour);
|
||||||
|
@ -89,9 +95,9 @@ void BillboardObject::init(const String& textureName,
|
||||||
/// \todo These billboards are not 100% correct, might want to revisit them later
|
/// \todo These billboards are not 100% correct, might want to revisit them later
|
||||||
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
|
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
|
||||||
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
|
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
|
||||||
mBBSet->setRenderQueueGroup(RENDER_QUEUE_MAIN+2);
|
|
||||||
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
|
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
|
||||||
mBBSet->setCommonDirection( -position.normalisedCopy() );
|
mBBSet->setCommonDirection( -position.normalisedCopy() );
|
||||||
|
mBBSet->setVisibilityFlags(RV_Sky);
|
||||||
mNode = rootNode->createChildSceneNode();
|
mNode = rootNode->createChildSceneNode();
|
||||||
mNode->setPosition(finalPosition);
|
mNode->setPosition(finalPosition);
|
||||||
mNode->attachObject(mBBSet);
|
mNode->attachObject(mBBSet);
|
||||||
|
@ -109,6 +115,65 @@ void BillboardObject::init(const String& textureName,
|
||||||
p->createTextureUnitState(textureName);
|
p->createTextureUnitState(textureName);
|
||||||
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
|
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
|
||||||
|
|
||||||
|
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||||
|
HighLevelGpuProgramPtr vshader;
|
||||||
|
if (mgr.resourceExists("BBO_VP"))
|
||||||
|
vshader = mgr.getByName("BBO_VP");
|
||||||
|
else
|
||||||
|
vshader = mgr.createProgram("BBO_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM);
|
||||||
|
vshader->setParameter("profiles", "vs_2_x arbvp1");
|
||||||
|
vshader->setParameter("entry_point", "main_vp");
|
||||||
|
StringUtil::StrStreamType outStream;
|
||||||
|
outStream <<
|
||||||
|
"void main_vp( \n"
|
||||||
|
" float4 position : POSITION, \n"
|
||||||
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
|
" out float2 oUV : TEXCOORD0, \n"
|
||||||
|
" out float4 oPosition : POSITION, \n"
|
||||||
|
" uniform float4x4 worldViewProj \n"
|
||||||
|
") \n"
|
||||||
|
"{ \n"
|
||||||
|
" oUV = uv; \n"
|
||||||
|
" oPosition = mul( worldViewProj, position ); \n"
|
||||||
|
"}";
|
||||||
|
vshader->setSource(outStream.str());
|
||||||
|
vshader->load();
|
||||||
|
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||||
|
mMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
|
||||||
|
|
||||||
|
HighLevelGpuProgramPtr fshader;
|
||||||
|
if (mgr.resourceExists("BBO_FP"))
|
||||||
|
fshader = mgr.getByName("BBO_FP");
|
||||||
|
else
|
||||||
|
fshader = mgr.createProgram("BBO_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_FRAGMENT_PROGRAM);
|
||||||
|
|
||||||
|
fshader->setParameter("profiles", "ps_2_x arbfp1");
|
||||||
|
fshader->setParameter("entry_point", "main_fp");
|
||||||
|
StringUtil::StrStreamType outStream2;
|
||||||
|
outStream2 <<
|
||||||
|
"void main_fp( \n"
|
||||||
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
|
" out float4 oColor : COLOR, \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream2 <<
|
||||||
|
" out float4 oColor1 : COLOR1, \n";
|
||||||
|
outStream2 <<
|
||||||
|
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||||
|
" uniform float4 diffuse, \n"
|
||||||
|
" uniform float4 emissive \n"
|
||||||
|
") \n"
|
||||||
|
"{ \n"
|
||||||
|
" float4 tex = tex2D(texture, uv); \n"
|
||||||
|
" oColor = float4(emissive.xyz,1) * tex * float4(1,1,1,diffuse.a); \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream2 <<
|
||||||
|
" oColor1 = float4(1, 0, 0, 1); \n";
|
||||||
|
outStream2 <<
|
||||||
|
"}";
|
||||||
|
fshader->setSource(outStream2.str());
|
||||||
|
fshader->load();
|
||||||
|
fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
||||||
|
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||||
|
mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
|
||||||
|
|
||||||
bodyCount++;
|
bodyCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +222,10 @@ Moon::Moon( const String& textureName,
|
||||||
outStream2 <<
|
outStream2 <<
|
||||||
"void main_fp( \n"
|
"void main_fp( \n"
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
" out float4 oColor : COLOR, \n"
|
" out float4 oColor : COLOR, \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream2 <<
|
||||||
|
" out float4 oColor1 : COLOR1, \n";
|
||||||
|
outStream2 <<
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||||
" uniform float4 skyColour, \n"
|
" uniform float4 skyColour, \n"
|
||||||
" uniform float4 diffuse, \n"
|
" uniform float4 diffuse, \n"
|
||||||
|
@ -165,7 +233,10 @@ Moon::Moon( const String& textureName,
|
||||||
") \n"
|
") \n"
|
||||||
"{ \n"
|
"{ \n"
|
||||||
" float4 tex = tex2D(texture, uv); \n"
|
" float4 tex = tex2D(texture, uv); \n"
|
||||||
" oColor = float4(emissive.xyz,1) * tex; \n"
|
" oColor = float4(emissive.xyz,1) * tex; \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream2 <<
|
||||||
|
" oColor1 = float4(1, 0, 0, 1); \n";
|
||||||
|
outStream2 <<
|
||||||
// use a circle for the alpha (compute UV distance to center)
|
// use a circle for the alpha (compute UV distance to center)
|
||||||
// looks a bit bad because its not filtered on the edges,
|
// looks a bit bad because its not filtered on the edges,
|
||||||
// but it's cheaper than a seperate alpha texture.
|
// but it's cheaper than a seperate alpha texture.
|
||||||
|
@ -358,15 +429,17 @@ void SkyManager::create()
|
||||||
|
|
||||||
mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode);
|
mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode);
|
||||||
mSecunda->setType(Moon::Type_Secunda);
|
mSecunda->setType(Moon::Type_Secunda);
|
||||||
mSecunda->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+4);
|
mSecunda->setRenderQueue(RQG_SkiesEarly+4);
|
||||||
|
|
||||||
mMasser = new Moon("textures\\tx_masser_full.dds", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode);
|
mMasser = new Moon("textures\\tx_masser_full.dds", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode);
|
||||||
mMasser->setRenderQueue(RENDER_QUEUE_SKIES_EARLY+3);
|
mMasser->setRenderQueue(RQG_SkiesEarly+3);
|
||||||
mMasser->setType(Moon::Type_Masser);
|
mMasser->setType(Moon::Type_Masser);
|
||||||
|
|
||||||
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode);
|
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode);
|
||||||
|
mSun->setRenderQueue(RQG_SkiesEarly+4);
|
||||||
mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode);
|
mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode);
|
||||||
mSunGlare->setRenderQueue(RENDER_QUEUE_SKIES_LATE);
|
mSunGlare->setRenderQueue(RQG_SkiesLate);
|
||||||
|
mSunGlare->setVisibilityFlags(RV_Glare);
|
||||||
|
|
||||||
|
|
||||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||||
|
@ -375,7 +448,8 @@ void SkyManager::create()
|
||||||
/// \todo sky_night_02.nif (available in Bloodmoon)
|
/// \todo sky_night_02.nif (available in Bloodmoon)
|
||||||
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
|
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
|
||||||
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
|
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
|
||||||
night1_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+1);
|
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
|
||||||
|
night1_ent->setVisibilityFlags(RV_Sky);
|
||||||
|
|
||||||
mAtmosphereNight = mRootNode->createChildSceneNode();
|
mAtmosphereNight = mRootNode->createChildSceneNode();
|
||||||
mAtmosphereNight->attachObject(night1_ent);
|
mAtmosphereNight->attachObject(night1_ent);
|
||||||
|
@ -413,7 +487,10 @@ void SkyManager::create()
|
||||||
outStream5 <<
|
outStream5 <<
|
||||||
"void main_fp( \n"
|
"void main_fp( \n"
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
" out float4 oColor : COLOR, \n"
|
" out float4 oColor : COLOR, \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream5 <<
|
||||||
|
" out float4 oColor1 : COLOR1, \n";
|
||||||
|
outStream5 <<
|
||||||
" in float fade : TEXCOORD1, \n"
|
" in float fade : TEXCOORD1, \n"
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||||
" uniform float opacity, \n"
|
" uniform float opacity, \n"
|
||||||
|
@ -421,7 +498,10 @@ void SkyManager::create()
|
||||||
" uniform float4 emissive \n"
|
" uniform float4 emissive \n"
|
||||||
") \n"
|
") \n"
|
||||||
"{ \n"
|
"{ \n"
|
||||||
" oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n"
|
" oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream5 <<
|
||||||
|
" oColor1 = float4(1, 0, 0, 1); \n";
|
||||||
|
outStream5 <<
|
||||||
"}";
|
"}";
|
||||||
stars_fp->setSource(outStream5.str());
|
stars_fp->setSource(outStream5.str());
|
||||||
stars_fp->load();
|
stars_fp->load();
|
||||||
|
@ -448,7 +528,8 @@ void SkyManager::create()
|
||||||
|
|
||||||
ModVertexAlpha(atmosphere_ent, 0);
|
ModVertexAlpha(atmosphere_ent, 0);
|
||||||
|
|
||||||
atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY);
|
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
|
||||||
|
atmosphere_ent->setVisibilityFlags(RV_Sky);
|
||||||
mAtmosphereDay = mRootNode->createChildSceneNode();
|
mAtmosphereDay = mRootNode->createChildSceneNode();
|
||||||
mAtmosphereDay->attachObject(atmosphere_ent);
|
mAtmosphereDay->attachObject(atmosphere_ent);
|
||||||
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
|
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
|
||||||
|
@ -466,26 +547,52 @@ void SkyManager::create()
|
||||||
" float4 position : POSITION, \n"
|
" float4 position : POSITION, \n"
|
||||||
" in float4 color : COLOR, \n"
|
" in float4 color : COLOR, \n"
|
||||||
" out float4 oPosition : POSITION, \n"
|
" out float4 oPosition : POSITION, \n"
|
||||||
" out float4 oColor : COLOR, \n"
|
" out float4 oVertexColor : TEXCOORD0, \n"
|
||||||
" uniform float4 emissive, \n"
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
" uniform float4x4 worldViewProj \n"
|
||||||
") \n"
|
") \n"
|
||||||
"{ \n"
|
"{ \n"
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
" oPosition = mul( worldViewProj, position ); \n"
|
||||||
" oColor = color * emissive; \n"
|
" oVertexColor = color; \n"
|
||||||
"}";
|
"}";
|
||||||
vshader->setSource(outStream.str());
|
vshader->setSource(outStream.str());
|
||||||
vshader->load();
|
vshader->load();
|
||||||
|
|
||||||
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||||
vshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram("");
|
|
||||||
|
HighLevelGpuProgramPtr fshader = mgr.createProgram("Atmosphere_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||||
|
"cg", GPT_FRAGMENT_PROGRAM);
|
||||||
|
|
||||||
|
fshader->setParameter("profiles", "ps_2_x arbfp1");
|
||||||
|
fshader->setParameter("entry_point", "main_fp");
|
||||||
|
|
||||||
|
StringUtil::StrStreamType _outStream;
|
||||||
|
_outStream <<
|
||||||
|
"void main_fp( \n"
|
||||||
|
" in float4 iVertexColor : TEXCOORD0, \n"
|
||||||
|
" out float4 oColor : COLOR, \n";
|
||||||
|
if (RenderingManager::useMRT()) _outStream <<
|
||||||
|
" out float4 oColor1 : COLOR1, \n";
|
||||||
|
_outStream <<
|
||||||
|
" uniform float4 emissive \n"
|
||||||
|
") \n"
|
||||||
|
"{ \n"
|
||||||
|
" oColor = iVertexColor * emissive; \n";
|
||||||
|
if (RenderingManager::useMRT()) _outStream <<
|
||||||
|
" oColor1 = float4(1, 0, 0, 1); \n";
|
||||||
|
_outStream <<
|
||||||
|
"}";
|
||||||
|
fshader->setSource(_outStream.str());
|
||||||
|
fshader->load();
|
||||||
|
|
||||||
|
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||||
|
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
|
||||||
|
|
||||||
// Clouds
|
// Clouds
|
||||||
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
|
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
|
||||||
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
|
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
|
||||||
clouds_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+5);
|
clouds_ent->setVisibilityFlags(RV_Sky);
|
||||||
|
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
|
||||||
SceneNode* clouds_node = mRootNode->createChildSceneNode();
|
SceneNode* clouds_node = mRootNode->createChildSceneNode();
|
||||||
clouds_node->attachObject(clouds_ent);
|
clouds_node->attachObject(clouds_ent);
|
||||||
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
|
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
|
||||||
|
@ -525,8 +632,11 @@ void SkyManager::create()
|
||||||
outStream2 <<
|
outStream2 <<
|
||||||
"void main_fp( \n"
|
"void main_fp( \n"
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
" in float2 uv : TEXCOORD0, \n"
|
||||||
" out float4 oColor : COLOR, \n"
|
|
||||||
" in float4 color : TEXCOORD1, \n"
|
" in float4 color : TEXCOORD1, \n"
|
||||||
|
" out float4 oColor : COLOR, \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream2 <<
|
||||||
|
" out float4 oColor1 : COLOR1, \n";
|
||||||
|
outStream2 <<
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||||
" uniform sampler2D secondTexture : TEXUNIT1, \n"
|
" uniform sampler2D secondTexture : TEXUNIT1, \n"
|
||||||
" uniform float transitionFactor, \n"
|
" uniform float transitionFactor, \n"
|
||||||
|
@ -538,7 +648,10 @@ void SkyManager::create()
|
||||||
"{ \n"
|
"{ \n"
|
||||||
" uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction
|
" uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction
|
||||||
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
|
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
|
||||||
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n"
|
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n";
|
||||||
|
if (RenderingManager::useMRT()) outStream2 <<
|
||||||
|
" oColor1 = float4(1, 0, 0, 1); \n";
|
||||||
|
outStream2 <<
|
||||||
"}";
|
"}";
|
||||||
mCloudFragmentShader->setSource(outStream2.str());
|
mCloudFragmentShader->setSource(outStream2.str());
|
||||||
mCloudFragmentShader->load();
|
mCloudFragmentShader->load();
|
||||||
|
@ -734,7 +847,8 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
||||||
strength = 1.f;
|
strength = 1.f;
|
||||||
|
|
||||||
mSunGlare->setVisibility(weather.mGlareView * mGlareFade * strength);
|
mSunGlare->setVisibility(weather.mGlareView * mGlareFade * strength);
|
||||||
mSun->setVisibility(mGlareFade >= 0.5 ? weather.mGlareView * mGlareFade * strength : 0);
|
|
||||||
|
mSun->setVisibility(weather.mGlareView * strength);
|
||||||
|
|
||||||
mAtmosphereNight->setVisible(weather.mNight && mEnabled);
|
mAtmosphereNight->setVisible(weather.mNight && mEnabled);
|
||||||
}
|
}
|
||||||
|
@ -746,6 +860,7 @@ void SkyManager::setGlare(const float glare)
|
||||||
|
|
||||||
Vector3 SkyManager::getRealSunPos()
|
Vector3 SkyManager::getRealSunPos()
|
||||||
{
|
{
|
||||||
|
if (!mCreated) return Vector3(0,0,0);
|
||||||
return mSun->getNode()->_getDerivedPosition();
|
return mSun->getNode()->_getDerivedPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,3 +951,18 @@ Ogre::SceneNode* SkyManager::getSunNode()
|
||||||
if (!mCreated) return 0;
|
if (!mCreated) return 0;
|
||||||
return mSun->getNode();
|
return mSun->getNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkyManager::setSkyPosition(const Ogre::Vector3& position)
|
||||||
|
{
|
||||||
|
mRootNode->_setDerivedPosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::resetSkyPosition()
|
||||||
|
{
|
||||||
|
mRootNode->setPosition(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::scaleSky(float scale)
|
||||||
|
{
|
||||||
|
mRootNode->setScale(scale, scale, scale);
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace MWRender
|
||||||
void setPosition(const Ogre::Vector3& pPosition);
|
void setPosition(const Ogre::Vector3& pPosition);
|
||||||
void setVisible(const bool visible);
|
void setVisible(const bool visible);
|
||||||
void setRenderQueue(unsigned int id);
|
void setRenderQueue(unsigned int id);
|
||||||
|
void setVisibilityFlags(int flags);
|
||||||
void setSize(const float size);
|
void setSize(const float size);
|
||||||
Ogre::Vector3 getPosition() const;
|
Ogre::Vector3 getPosition() const;
|
||||||
|
|
||||||
|
@ -168,6 +169,10 @@ namespace MWRender
|
||||||
void setGlare(const float glare);
|
void setGlare(const float glare);
|
||||||
Ogre::Vector3 getRealSunPos();
|
Ogre::Vector3 getRealSunPos();
|
||||||
|
|
||||||
|
void setSkyPosition(const Ogre::Vector3& position);
|
||||||
|
void resetSkyPosition();
|
||||||
|
void scaleSky(float scale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mCreated;
|
bool mCreated;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "terrainmaterial.hpp"
|
#include "terrainmaterial.hpp"
|
||||||
#include "terrain.hpp"
|
#include "terrain.hpp"
|
||||||
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
@ -97,9 +98,12 @@ namespace MWRender
|
||||||
|
|
||||||
ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
|
ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
|
||||||
if ( land != NULL )
|
if ( land != NULL )
|
||||||
|
{
|
||||||
|
if (!land->dataLoaded)
|
||||||
{
|
{
|
||||||
land->loadData();
|
land->loadData();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//split the cell terrain into four segments
|
//split the cell terrain into four segments
|
||||||
const int numTextures = ESM::Land::LAND_TEXTURE_SIZE/2;
|
const int numTextures = ESM::Land::LAND_TEXTURE_SIZE/2;
|
||||||
|
@ -159,6 +163,8 @@ namespace MWRender
|
||||||
x * numTextures, y * numTextures,
|
x * numTextures, y * numTextures,
|
||||||
numTextures,
|
numTextures,
|
||||||
indexes);
|
indexes);
|
||||||
|
terrain->setVisibilityFlags(RV_Terrain);
|
||||||
|
terrain->setRenderQueueGroup(RQG_Main);
|
||||||
|
|
||||||
if ( land && land->landData->usingColours )
|
if ( land && land->landData->usingColours )
|
||||||
{
|
{
|
||||||
|
@ -419,8 +425,12 @@ namespace MWRender
|
||||||
|
|
||||||
ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
|
ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
|
||||||
if ( land != NULL )
|
if ( land != NULL )
|
||||||
|
{
|
||||||
|
if (!land->dataLoaded)
|
||||||
{
|
{
|
||||||
land->loadData();
|
land->loadData();
|
||||||
|
}
|
||||||
|
|
||||||
return land->landData
|
return land->landData
|
||||||
->textures[y * ESM::Land::LAND_TEXTURE_SIZE + x];
|
->textures[y * ESM::Land::LAND_TEXTURE_SIZE + x];
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@ THE SOFTWARE.
|
||||||
#include "OgreHardwarePixelBuffer.h"
|
#include "OgreHardwarePixelBuffer.h"
|
||||||
#include "OgreShadowCameraSetupPSSM.h"
|
#include "OgreShadowCameraSetupPSSM.h"
|
||||||
|
|
||||||
#define POINTLIGHTS
|
#include <components/settings/settings.hpp>
|
||||||
|
#include "renderingmanager.hpp"
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -222,19 +223,7 @@ namespace Ogre
|
||||||
}
|
}
|
||||||
int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const
|
int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const
|
||||||
{
|
{
|
||||||
#ifndef POINTLIGHTS
|
return Settings::Manager::getInt("num lights", "Terrain");
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
// number of supported lights depends on the number of available constant registers,
|
|
||||||
// which in turn depends on the shader profile used
|
|
||||||
if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0")
|
|
||||||
|| GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0")
|
|
||||||
|| GpuProgramManager::getSingleton().isSyntaxSupported("fp40")
|
|
||||||
)
|
|
||||||
return 32;
|
|
||||||
else
|
|
||||||
return 8;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
MaterialPtr TerrainMaterialGeneratorB::SM2Profile::generate(const Terrain* terrain)
|
MaterialPtr TerrainMaterialGeneratorB::SM2Profile::generate(const Terrain* terrain)
|
||||||
|
@ -565,10 +554,14 @@ namespace Ogre
|
||||||
{
|
{
|
||||||
params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
|
params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
|
||||||
params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
|
params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
|
||||||
|
if (prof->getNumberOfLightsSupported() > 1)
|
||||||
params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
|
params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
|
||||||
//params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i);
|
//params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MWRender::RenderingManager::useMRT())
|
||||||
|
params->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
|
||||||
|
|
||||||
params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
|
params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
|
||||||
params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
|
params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
|
||||||
|
|
||||||
|
@ -764,11 +757,6 @@ namespace Ogre
|
||||||
ret->unload();
|
ret->unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prof->isLayerNormalMappingEnabled() || prof->isLayerParallaxMappingEnabled())
|
|
||||||
ret->setParameter("profiles", "ps_3_0 ps_2_x fp40 arbfp1");
|
|
||||||
//else
|
|
||||||
//ret->setParameter("profiles", "ps_3_0 ps_2_0 fp30 arbfp1");
|
|
||||||
else // fp30 doesn't work (black terrain)
|
|
||||||
ret->setParameter("profiles", "ps_3_0 ps_2_x fp40 arbfp1");
|
ret->setParameter("profiles", "ps_3_0 ps_2_x fp40 arbfp1");
|
||||||
ret->setParameter("entry_point", "main_fp");
|
ret->setParameter("entry_point", "main_fp");
|
||||||
|
|
||||||
|
@ -928,7 +916,7 @@ namespace Ogre
|
||||||
|
|
||||||
|
|
||||||
outStream <<
|
outStream <<
|
||||||
"float4 main_fp(\n"
|
"void main_fp(\n"
|
||||||
"float4 position : TEXCOORD0,\n";
|
"float4 position : TEXCOORD0,\n";
|
||||||
|
|
||||||
uint texCoordSet = 1;
|
uint texCoordSet = 1;
|
||||||
|
@ -980,10 +968,9 @@ namespace Ogre
|
||||||
//"uniform float3 lightSpecularColour"<<i<<",\n"
|
//"uniform float3 lightSpecularColour"<<i<<",\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
#ifdef POINTLIGHTS
|
if (prof->getNumberOfLightsSupported() > 1)
|
||||||
outStream <<
|
outStream <<
|
||||||
"uniform float4 lightAttenuation"<<i<<",\n";
|
"uniform float4 lightAttenuation"<<i<<",\n";
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1046,8 +1033,15 @@ namespace Ogre
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MWRender::RenderingManager::useMRT()) outStream <<
|
||||||
|
" , out float4 oColor : COLOR \n"
|
||||||
|
" , out float4 oColor1 : COLOR1 \n"
|
||||||
|
" , uniform float far \n";
|
||||||
|
else outStream <<
|
||||||
|
" , out float4 oColor : COLOR \n";
|
||||||
|
|
||||||
outStream <<
|
outStream <<
|
||||||
") : COLOR\n"
|
")\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float4 outputCol;\n"
|
" float4 outputCol;\n"
|
||||||
" float shadow = 1.0;\n"
|
" float shadow = 1.0;\n"
|
||||||
|
@ -1130,10 +1124,9 @@ namespace Ogre
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef POINTLIGHTS
|
if (prof->getNumberOfLightsSupported() > 1)
|
||||||
outStream << "float d; \n"
|
outStream << "float d; \n"
|
||||||
"float attn; \n";
|
"float attn; \n";
|
||||||
#endif
|
|
||||||
|
|
||||||
outStream <<
|
outStream <<
|
||||||
" eyeDir = normalize(eyeDir); \n";
|
" eyeDir = normalize(eyeDir); \n";
|
||||||
|
@ -1144,13 +1137,12 @@ namespace Ogre
|
||||||
outStream << " float3 halfAngle"<<i<<" = normalize(lightDir"<<i<<" + eyeDir);\n"
|
outStream << " float3 halfAngle"<<i<<" = normalize(lightDir"<<i<<" + eyeDir);\n"
|
||||||
" float4 litRes"<<i<<" = lit(dot(normalize(lightDir"<<i<<"), normal), dot(halfAngle"<<i<<", normal), scaleBiasSpecular.z);\n";
|
" float4 litRes"<<i<<" = lit(dot(normalize(lightDir"<<i<<"), normal), dot(halfAngle"<<i<<", normal), scaleBiasSpecular.z);\n";
|
||||||
|
|
||||||
#ifdef POINTLIGHTS
|
if (prof->getNumberOfLightsSupported() > 1)
|
||||||
outStream <<
|
outStream <<
|
||||||
// pre-multiply light color with attenuation factor
|
// pre-multiply light color with attenuation factor
|
||||||
"d = length( lightDir"<<i<<" ); \n"
|
"d = length( lightDir"<<i<<" ); \n"
|
||||||
"attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
|
"attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
|
||||||
"lightDiffuseColour"<<i<<" *= attn; \n";
|
"lightDiffuseColour"<<i<<" *= attn; \n";
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1255,6 +1247,10 @@ namespace Ogre
|
||||||
" oPos = mul(viewProjMatrix, worldPos);\n"
|
" oPos = mul(viewProjMatrix, worldPos);\n"
|
||||||
" oUVMisc.xy = uv.xy;\n";
|
" oUVMisc.xy = uv.xy;\n";
|
||||||
|
|
||||||
|
outStream <<
|
||||||
|
" // pass cam depth\n"
|
||||||
|
" oUVMisc.z = oPos.z;\n";
|
||||||
|
|
||||||
bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
|
bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP;
|
||||||
if (fog)
|
if (fog)
|
||||||
{
|
{
|
||||||
|
@ -1351,7 +1347,12 @@ namespace Ogre
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final return
|
// Final return
|
||||||
outStream << " return outputCol;\n"
|
outStream << " oColor = outputCol;\n";
|
||||||
|
|
||||||
|
if (MWRender::RenderingManager::useMRT()) outStream <<
|
||||||
|
" oColor1 = float4(uvMisc.z / far, 0, 0, 1); \n";
|
||||||
|
|
||||||
|
outStream
|
||||||
<< "}\n";
|
<< "}\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1525,14 +1526,6 @@ namespace Ogre
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (prof->getReceiveDynamicShadowsPSSM())
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" // pass cam depth\n"
|
|
||||||
" oUVMisc.z = oPos.z;\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
void TerrainMaterialGeneratorB::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsParams(
|
void TerrainMaterialGeneratorB::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsParams(
|
||||||
|
|
|
@ -1,29 +1,43 @@
|
||||||
#include "water.hpp"
|
#include "water.hpp"
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
#include "sky.hpp"
|
||||||
|
#include "renderingmanager.hpp"
|
||||||
|
|
||||||
|
using namespace Ogre;
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
|
||||||
Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) :
|
Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) :
|
||||||
mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()),
|
mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()),
|
||||||
mIsUnderwater(false)
|
mIsUnderwater(false), mVisibilityFlags(0),
|
||||||
|
mReflectionTarget(0), mActive(1)
|
||||||
{
|
{
|
||||||
|
mSky = sky;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "Water", -1);
|
CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false);
|
||||||
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false);
|
|
||||||
} catch(...) {}
|
} catch(...) {}
|
||||||
|
|
||||||
mTop = cell->water;
|
mTop = cell->water;
|
||||||
|
|
||||||
mIsUnderwater = false;
|
mIsUnderwater = false;
|
||||||
|
|
||||||
mWaterPlane = Ogre::Plane(Ogre::Vector3::UNIT_Y, 0);
|
mWaterPlane = Plane(Vector3::UNIT_Y, 0);
|
||||||
|
|
||||||
Ogre::MeshManager::getSingleton().createPlane("water", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,5, Ogre::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_Z);
|
||||||
|
|
||||||
mWater = mSceneManager->createEntity("water");
|
mWater = mSceneManager->createEntity("water");
|
||||||
|
mWater->setVisibilityFlags(RV_Water);
|
||||||
|
mWater->setRenderQueueGroup(RQG_Water);
|
||||||
|
|
||||||
mWater->setMaterialName("Examples/Water0");
|
mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water")
|
||||||
|
+ RV_Statics * Settings::Manager::getBool("reflect statics", "Water")
|
||||||
|
+ RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water")
|
||||||
|
+ RV_Actors * Settings::Manager::getBool("reflect actors", "Water")
|
||||||
|
+ RV_Misc * Settings::Manager::getBool("reflect misc", "Water")
|
||||||
|
+ RV_Sky;
|
||||||
|
|
||||||
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
|
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
|
||||||
mWaterNode->setPosition(0, mTop, 0);
|
mWaterNode->setPosition(0, mTop, 0);
|
||||||
|
@ -33,18 +47,51 @@ Water::Water (Ogre::Camera *camera, const ESM::Cell* cell) :
|
||||||
mWaterNode->setPosition(getSceneNodeCoordinates(cell->data.gridX, cell->data.gridY));
|
mWaterNode->setPosition(getSceneNodeCoordinates(cell->data.gridX, cell->data.gridY));
|
||||||
}
|
}
|
||||||
mWaterNode->attachObject(mWater);
|
mWaterNode->attachObject(mWater);
|
||||||
|
|
||||||
|
// Create rendertarget for reflection
|
||||||
|
int rttsize = Settings::Manager::getInt("rtt size", "Water");
|
||||||
|
|
||||||
|
if (Settings::Manager::getBool("shader", "Water"))
|
||||||
|
{
|
||||||
|
TexturePtr tex = TextureManager::getSingleton().createManual("WaterReflection",
|
||||||
|
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_R8G8B8, TU_RENDERTARGET);
|
||||||
|
|
||||||
|
RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
|
||||||
|
Viewport* vp = rtt->addViewport(mCamera);
|
||||||
|
vp->setOverlaysEnabled(false);
|
||||||
|
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f));
|
||||||
|
vp->setShadowsEnabled(false);
|
||||||
|
vp->setVisibilityMask( mVisibilityFlags );
|
||||||
|
rtt->addListener(this);
|
||||||
|
rtt->setActive(true);
|
||||||
|
|
||||||
|
mReflectionTarget = rtt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT";
|
||||||
|
|
||||||
|
createMaterial();
|
||||||
|
mWater->setMaterial(mMaterial);
|
||||||
|
|
||||||
|
mUnderwaterEffect = Settings::Manager::getBool("underwater effect", "Water");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::setActive(bool active)
|
||||||
|
{
|
||||||
|
mActive = active;
|
||||||
|
if (mReflectionTarget) mReflectionTarget->setActive(active && !mIsUnderwater);
|
||||||
|
mWater->setVisible(active);
|
||||||
|
}
|
||||||
|
|
||||||
Water::~Water()
|
Water::~Water()
|
||||||
{
|
{
|
||||||
Ogre::MeshManager::getSingleton().remove("water");
|
MeshManager::getSingleton().remove("water");
|
||||||
|
|
||||||
mWaterNode->detachObject(mWater);
|
mWaterNode->detachObject(mWater);
|
||||||
mSceneManager->destroyEntity(mWater);
|
mSceneManager->destroyEntity(mWater);
|
||||||
mSceneManager->destroySceneNode(mWaterNode);
|
mSceneManager->destroySceneNode(mWaterNode);
|
||||||
|
|
||||||
Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport);
|
CompositorManager::getSingleton().removeCompositorChain(mViewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::changeCell(const ESM::Cell* cell)
|
void Water::changeCell(const ESM::Cell* cell)
|
||||||
|
@ -65,31 +112,122 @@ void Water::setHeight(const float height)
|
||||||
|
|
||||||
void Water::toggle()
|
void Water::toggle()
|
||||||
{
|
{
|
||||||
|
if (mActive)
|
||||||
mWater->setVisible(!mWater->getVisible());
|
mWater->setVisible(!mWater->getVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::checkUnderwater(float y)
|
void Water::checkUnderwater(float y)
|
||||||
{
|
{
|
||||||
if ((mIsUnderwater && y > mTop) || !mWater->isVisible())
|
if (!mActive) return;
|
||||||
|
if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID)
|
||||||
{
|
{
|
||||||
try {
|
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false);
|
||||||
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false);
|
|
||||||
} catch(...) {}
|
// tell the shader we are not underwater
|
||||||
|
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
|
||||||
|
if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false))
|
||||||
|
pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(0));
|
||||||
|
|
||||||
|
if (mReflectionTarget)
|
||||||
|
mReflectionTarget->setActive(mActive);
|
||||||
|
|
||||||
|
mWater->setRenderQueueGroup(RQG_Water);
|
||||||
|
|
||||||
mIsUnderwater = false;
|
mIsUnderwater = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mIsUnderwater && y < mTop && mWater->isVisible())
|
if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID)
|
||||||
{
|
{
|
||||||
try {
|
if (mUnderwaterEffect)
|
||||||
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", true);
|
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, true);
|
||||||
} catch(...) {}
|
|
||||||
|
// tell the shader we are underwater
|
||||||
|
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
|
||||||
|
if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false))
|
||||||
|
pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(1));
|
||||||
|
|
||||||
|
if (mReflectionTarget)
|
||||||
|
mReflectionTarget->setActive(false);
|
||||||
|
|
||||||
|
mWater->setRenderQueueGroup(RQG_UnderWater);
|
||||||
|
|
||||||
mIsUnderwater = true;
|
mIsUnderwater = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
|
Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY)
|
||||||
{
|
{
|
||||||
return Ogre::Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2));
|
return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
|
||||||
|
{
|
||||||
|
if (evt.source == mReflectionTarget)
|
||||||
|
{
|
||||||
|
mWater->setVisible(false);
|
||||||
|
|
||||||
|
// Some messy code to get the skybox to show up at all
|
||||||
|
// The problem here is that it gets clipped by the water plane
|
||||||
|
// Therefore scale it up a bit
|
||||||
|
Vector3 pos = mCamera->getRealPosition();
|
||||||
|
pos.y = mTop*2 - pos.y;
|
||||||
|
mSky->setSkyPosition(pos);
|
||||||
|
mSky->scaleSky(mCamera->getFarClipDistance() / 1000.f);
|
||||||
|
|
||||||
|
mCamera->enableCustomNearClipPlane(Plane(Vector3::UNIT_Y, mTop));
|
||||||
|
mCamera->enableReflection(Plane(Vector3::UNIT_Y, mTop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::postRenderTargetUpdate(const RenderTargetEvent& evt)
|
||||||
|
{
|
||||||
|
mWater->setVisible(true);
|
||||||
|
|
||||||
|
if (evt.source == mReflectionTarget)
|
||||||
|
{
|
||||||
|
mSky->resetSkyPosition();
|
||||||
|
mSky->scaleSky(1);
|
||||||
|
mCamera->disableReflection();
|
||||||
|
mCamera->disableCustomNearClipPlane();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::createMaterial()
|
||||||
|
{
|
||||||
|
mMaterial = MaterialManager::getSingleton().getByName("Water");
|
||||||
|
|
||||||
|
// these have to be set in code
|
||||||
|
std::string textureNames[32];
|
||||||
|
for (int i=0; i<32; ++i)
|
||||||
|
{
|
||||||
|
textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds";
|
||||||
|
}
|
||||||
|
mMaterial->getTechnique(1)->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2);
|
||||||
|
|
||||||
|
// use technique without shaders if reflection is disabled
|
||||||
|
if (mReflectionTarget == 0)
|
||||||
|
mMaterial->removeTechnique(0);
|
||||||
|
|
||||||
|
if (Settings::Manager::getBool("shader", "Water"))
|
||||||
|
{
|
||||||
|
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("gbuffer");
|
||||||
|
|
||||||
|
TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0);
|
||||||
|
TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap");
|
||||||
|
if (tus != 0)
|
||||||
|
tus->setTexture(colorTexture);
|
||||||
|
|
||||||
|
TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1);
|
||||||
|
tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("depthMap");
|
||||||
|
if (tus != 0)
|
||||||
|
tus->setTexture(depthTexture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::setViewportBackground(const ColourValue& bg)
|
||||||
|
{
|
||||||
|
if (mReflectionTarget)
|
||||||
|
mReflectionTarget->getViewport(0)->setBackgroundColour(bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -4,10 +4,14 @@
|
||||||
#include <Ogre.h>
|
#include <Ogre.h>
|
||||||
#include <components/esm/loadcell.hpp>
|
#include <components/esm/loadcell.hpp>
|
||||||
|
|
||||||
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
namespace MWRender {
|
namespace MWRender {
|
||||||
|
|
||||||
|
class SkyManager;
|
||||||
|
|
||||||
/// Water rendering
|
/// Water rendering
|
||||||
class Water : Ogre::RenderTargetListener, Ogre::Camera::Listener
|
class Water : public Ogre::RenderTargetListener
|
||||||
{
|
{
|
||||||
static const int CELL_SIZE = 8192;
|
static const int CELL_SIZE = 8192;
|
||||||
Ogre::Camera *mCamera;
|
Ogre::Camera *mCamera;
|
||||||
|
@ -19,16 +23,37 @@ namespace MWRender {
|
||||||
Ogre::Entity *mWater;
|
Ogre::Entity *mWater;
|
||||||
|
|
||||||
bool mIsUnderwater;
|
bool mIsUnderwater;
|
||||||
|
bool mActive;
|
||||||
int mTop;
|
int mTop;
|
||||||
|
|
||||||
Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY);
|
Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
|
||||||
|
void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt);
|
||||||
|
|
||||||
|
SkyManager* mSky;
|
||||||
|
|
||||||
|
std::string mCompositorName;
|
||||||
|
|
||||||
|
void createMaterial();
|
||||||
|
Ogre::MaterialPtr mMaterial;
|
||||||
|
|
||||||
|
Ogre::RenderTarget* mReflectionTarget;
|
||||||
|
|
||||||
|
bool mUnderwaterEffect;
|
||||||
|
int mVisibilityFlags;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Water (Ogre::Camera *camera, const ESM::Cell* cell);
|
Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell);
|
||||||
~Water();
|
~Water();
|
||||||
|
|
||||||
|
void setActive(bool active);
|
||||||
|
|
||||||
void toggle();
|
void toggle();
|
||||||
|
|
||||||
|
void setViewportBackground(const Ogre::ColourValue& bg);
|
||||||
|
|
||||||
void checkUnderwater(float y);
|
void checkUnderwater(float y);
|
||||||
void changeCell(const ESM::Cell* cell);
|
void changeCell(const ESM::Cell* cell);
|
||||||
void setHeight(const float height);
|
void setHeight(const float height);
|
||||||
|
|
|
@ -130,5 +130,7 @@ op 0x2000141: GetWaterLevel
|
||||||
op 0x2000142: SetWaterLevel
|
op 0x2000142: SetWaterLevel
|
||||||
op 0x2000143: ModWaterLevel
|
op 0x2000143: ModWaterLevel
|
||||||
op 0x2000144: ToggleWater, twa
|
op 0x2000144: ToggleWater, twa
|
||||||
op 0x2000145: ModDisposition
|
op 0x2000145: ToggleFogOfWar (tfow)
|
||||||
opcodes 0x2000146-0x3ffffff unused
|
op 0x2000146: TogglePathgrid
|
||||||
|
op 0x2000147: ModDisposition
|
||||||
|
opcodes 0x2000148-0x3ffffff unused
|
||||||
|
|
|
@ -67,6 +67,19 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpToggleFogOfWar : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
context.getEnvironment().mWindowManager->toggleFogOfWar();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const int opcodeEnableBirthMenu = 0x200000e;
|
const int opcodeEnableBirthMenu = 0x200000e;
|
||||||
const int opcodeEnableClassMenu = 0x200000f;
|
const int opcodeEnableClassMenu = 0x200000f;
|
||||||
const int opcodeEnableNameMenu = 0x2000010;
|
const int opcodeEnableNameMenu = 0x2000010;
|
||||||
|
@ -79,6 +92,7 @@ namespace MWScript
|
||||||
const int opcodeEnableRest = 0x2000017;
|
const int opcodeEnableRest = 0x2000017;
|
||||||
const int opcodeShowRestMenu = 0x2000018;
|
const int opcodeShowRestMenu = 0x2000018;
|
||||||
const int opcodeGetButtonPressed = 0x2000137;
|
const int opcodeGetButtonPressed = 0x2000137;
|
||||||
|
const int opcodeToggleFogOfWar = 0x2000145;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -100,6 +114,9 @@ namespace MWScript
|
||||||
extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu);
|
extensions.registerInstruction ("showrestmenu", "", opcodeShowRestMenu);
|
||||||
|
|
||||||
extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed);
|
extensions.registerFunction ("getbuttonpressed", 'l', "", opcodeGetButtonPressed);
|
||||||
|
|
||||||
|
extensions.registerInstruction ("togglefogofwar", "", opcodeToggleFogOfWar);
|
||||||
|
extensions.registerInstruction ("tfow", "", opcodeToggleFogOfWar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -135,6 +152,8 @@ namespace MWScript
|
||||||
new OpShowDialogue (MWGui::GM_Rest));
|
new OpShowDialogue (MWGui::GM_Rest));
|
||||||
|
|
||||||
interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed);
|
interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed);
|
||||||
|
|
||||||
|
interpreter.installSegment5 (opcodeToggleFogOfWar, new OpToggleFogOfWar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,22 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpTogglePathgrid : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
InterpreterContext& context =
|
||||||
|
static_cast<InterpreterContext&> (runtime.getContext());
|
||||||
|
|
||||||
|
bool enabled =
|
||||||
|
context.getWorld().toggleRenderMode (MWWorld::World::Render_Pathgrid);
|
||||||
|
|
||||||
|
context.report (enabled ?
|
||||||
|
"Path Grid rendering -> On" : "Path Grid Rendering -> Off");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class OpFadeIn : public Interpreter::Opcode0
|
class OpFadeIn : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -201,6 +217,7 @@ namespace MWScript
|
||||||
const int opcodeFadeOut = 0x200013d;
|
const int opcodeFadeOut = 0x200013d;
|
||||||
const int opcodeFadeTo = 0x200013e;
|
const int opcodeFadeTo = 0x200013e;
|
||||||
const int opcodeToggleWater = 0x2000144;
|
const int opcodeToggleWater = 0x2000144;
|
||||||
|
const int opcodeTogglePathgrid = 0x2000146;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -220,6 +237,8 @@ namespace MWScript
|
||||||
extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
|
extensions.registerInstruction ("fadeto", "ff", opcodeFadeTo);
|
||||||
extensions.registerInstruction ("togglewater", "", opcodeToggleWater);
|
extensions.registerInstruction ("togglewater", "", opcodeToggleWater);
|
||||||
extensions.registerInstruction ("twa", "", opcodeToggleWater);
|
extensions.registerInstruction ("twa", "", opcodeToggleWater);
|
||||||
|
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
|
||||||
|
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -236,6 +255,7 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn);
|
interpreter.installSegment5 (opcodeFadeIn, new OpFadeIn);
|
||||||
interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut);
|
interpreter.installSegment5 (opcodeFadeOut, new OpFadeOut);
|
||||||
interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo);
|
interpreter.installSegment5 (opcodeFadeTo, new OpFadeTo);
|
||||||
|
interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid);
|
||||||
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
|
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -427,7 +427,7 @@ namespace MWScript
|
||||||
const int opcodePCRaiseRank = 0x2000b;
|
const int opcodePCRaiseRank = 0x2000b;
|
||||||
const int opcodePCLowerRank = 0x2000c;
|
const int opcodePCLowerRank = 0x2000c;
|
||||||
const int opcodePCJoinFaction = 0x2000d;
|
const int opcodePCJoinFaction = 0x2000d;
|
||||||
const int opcodeModDisposition = 0x2000145;
|
const int opcodeModDisposition = 0x2000147;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
|
122
apps/openmw/mwsound/audiere_decoder.cpp
Normal file
122
apps/openmw/mwsound/audiere_decoder.cpp
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#ifdef OPENMW_USE_AUDIERE
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "audiere_decoder.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
static void fail(const std::string &msg)
|
||||||
|
{ throw std::runtime_error("Audiere exception: "+msg); }
|
||||||
|
|
||||||
|
namespace MWSound
|
||||||
|
{
|
||||||
|
|
||||||
|
class OgreFile : public audiere::File
|
||||||
|
{
|
||||||
|
Ogre::DataStreamPtr mStream;
|
||||||
|
|
||||||
|
ADR_METHOD(int) read(void* buffer, int size)
|
||||||
|
{
|
||||||
|
return mStream->read(buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ADR_METHOD(bool) seek(int position, SeekMode mode)
|
||||||
|
{
|
||||||
|
if(mode == CURRENT)
|
||||||
|
mStream->seek(mStream->tell()+position);
|
||||||
|
else if(mode == BEGIN)
|
||||||
|
mStream->seek(position);
|
||||||
|
else if(mode == END)
|
||||||
|
mStream->seek(mStream->size()+position);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADR_METHOD(int) tell()
|
||||||
|
{
|
||||||
|
return mStream->tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t refs;
|
||||||
|
virtual void ref() { ++refs; }
|
||||||
|
virtual void unref()
|
||||||
|
{
|
||||||
|
if(--refs == 0)
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
OgreFile(const Ogre::DataStreamPtr &stream)
|
||||||
|
: mStream(stream), refs(1)
|
||||||
|
{ }
|
||||||
|
virtual ~OgreFile() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void Audiere_Decoder::open(const std::string &fname)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
|
||||||
|
audiere::FilePtr file(new OgreFile(mResourceMgr.openResource(fname)));
|
||||||
|
mSoundSource = audiere::OpenSampleSource(file);
|
||||||
|
|
||||||
|
int channels, srate;
|
||||||
|
audiere::SampleFormat format;
|
||||||
|
|
||||||
|
mSoundSource->getFormat(channels, srate, format);
|
||||||
|
if(format == audiere::SF_S16)
|
||||||
|
mSampleType = SampleType_Int16;
|
||||||
|
else if(format == audiere::SF_U8)
|
||||||
|
mSampleType = SampleType_UInt8;
|
||||||
|
else
|
||||||
|
fail("Unsupported sample type");
|
||||||
|
|
||||||
|
if(channels == 1)
|
||||||
|
mChannelConfig = ChannelConfig_Mono;
|
||||||
|
else if(channels == 2)
|
||||||
|
mChannelConfig = ChannelConfig_Stereo;
|
||||||
|
else
|
||||||
|
fail("Unsupported channel count");
|
||||||
|
|
||||||
|
mSampleRate = srate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audiere_Decoder::close()
|
||||||
|
{
|
||||||
|
mSoundSource = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audiere_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
|
||||||
|
{
|
||||||
|
*samplerate = mSampleRate;
|
||||||
|
*chans = mChannelConfig;
|
||||||
|
*type = mSampleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Audiere_Decoder::read(char *buffer, size_t bytes)
|
||||||
|
{
|
||||||
|
int size = bytesToFrames(bytes, mChannelConfig, mSampleType);
|
||||||
|
size = mSoundSource->read(size, buffer);
|
||||||
|
return framesToBytes(size, mChannelConfig, mSampleType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Audiere_Decoder::rewind()
|
||||||
|
{
|
||||||
|
mSoundSource->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
Audiere_Decoder::Audiere_Decoder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Audiere_Decoder::~Audiere_Decoder()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
42
apps/openmw/mwsound/audiere_decoder.hpp
Normal file
42
apps/openmw/mwsound/audiere_decoder.hpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef GAME_SOUND_AUDIERE_DECODER_H
|
||||||
|
#define GAME_SOUND_AUDIERE_DECODER_H
|
||||||
|
|
||||||
|
#include <OgreDataStream.h>
|
||||||
|
|
||||||
|
#include "audiere.h"
|
||||||
|
|
||||||
|
#include "sound_decoder.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace MWSound
|
||||||
|
{
|
||||||
|
class Audiere_Decoder : public Sound_Decoder
|
||||||
|
{
|
||||||
|
audiere::SampleSourcePtr mSoundSource;
|
||||||
|
int mSampleRate;
|
||||||
|
SampleType mSampleType;
|
||||||
|
ChannelConfig mChannelConfig;
|
||||||
|
|
||||||
|
virtual void open(const std::string &fname);
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
|
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
|
||||||
|
|
||||||
|
virtual size_t read(char *buffer, size_t bytes);
|
||||||
|
virtual void rewind();
|
||||||
|
|
||||||
|
Audiere_Decoder& operator=(const Audiere_Decoder &rhs);
|
||||||
|
Audiere_Decoder(const Audiere_Decoder &rhs);
|
||||||
|
|
||||||
|
Audiere_Decoder();
|
||||||
|
public:
|
||||||
|
virtual ~Audiere_Decoder();
|
||||||
|
|
||||||
|
friend class SoundManager;
|
||||||
|
};
|
||||||
|
#ifndef DEFAULT_DECODER
|
||||||
|
#define DEFAULT_DECODER (::MWSound::Audiere_Decoder)
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -467,10 +467,15 @@ void OpenAL_Output::init(const std::string &devname)
|
||||||
else
|
else
|
||||||
fail("Failed to open \""+devname+"\"");
|
fail("Failed to open \""+devname+"\"");
|
||||||
}
|
}
|
||||||
if(alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT"))
|
|
||||||
std::cout << "Opened \""<<alcGetString(mDevice, ALC_ALL_DEVICES_SPECIFIER)<<"\"" << std::endl;
|
|
||||||
else
|
else
|
||||||
std::cout << "Opened \""<<alcGetString(mDevice, ALC_DEVICE_SPECIFIER)<<"\"" << std::endl;
|
{
|
||||||
|
const ALCchar *name = NULL;
|
||||||
|
if(alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT"))
|
||||||
|
name = alcGetString(mDevice, ALC_ALL_DEVICES_SPECIFIER);
|
||||||
|
if(alcGetError(mDevice) != AL_NO_ERROR || !name)
|
||||||
|
name = alcGetString(mDevice, ALC_DEVICE_SPECIFIER);
|
||||||
|
std::cout << "Opened \""<<name<<"\"" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
mContext = alcCreateContext(mDevice, NULL);
|
mContext = alcCreateContext(mDevice, NULL);
|
||||||
if(!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE)
|
if(!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE)
|
||||||
|
@ -508,6 +513,8 @@ void OpenAL_Output::init(const std::string &devname)
|
||||||
}
|
}
|
||||||
if(mFreeSources.empty())
|
if(mFreeSources.empty())
|
||||||
fail("Could not allocate any sources");
|
fail("Could not allocate any sources");
|
||||||
|
|
||||||
|
mInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenAL_Output::deinit()
|
void OpenAL_Output::deinit()
|
||||||
|
@ -535,6 +542,8 @@ void OpenAL_Output::deinit()
|
||||||
if(mDevice)
|
if(mDevice)
|
||||||
alcCloseDevice(mDevice);
|
alcCloseDevice(mDevice);
|
||||||
mDevice = 0;
|
mDevice = 0;
|
||||||
|
|
||||||
|
mInitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,15 +35,19 @@ namespace MWSound
|
||||||
Sound_Output(const Sound_Output &rhs);
|
Sound_Output(const Sound_Output &rhs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool mInitialized;
|
||||||
Ogre::Vector3 mPos;
|
Ogre::Vector3 mPos;
|
||||||
|
|
||||||
Sound_Output(SoundManager &mgr)
|
Sound_Output(SoundManager &mgr)
|
||||||
: mManager(mgr)
|
: mManager(mgr)
|
||||||
|
, mInitialized(false)
|
||||||
, mPos(0.0f, 0.0f, 0.0f)
|
, mPos(0.0f, 0.0f, 0.0f)
|
||||||
{ }
|
{ }
|
||||||
public:
|
public:
|
||||||
virtual ~Sound_Output() { }
|
virtual ~Sound_Output() { }
|
||||||
|
|
||||||
|
bool isInitialized() { return mInitialized; }
|
||||||
|
|
||||||
friend class OpenAL_Output;
|
friend class OpenAL_Output;
|
||||||
friend class SoundManager;
|
friend class SoundManager;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
#include <components/esm_store/store.hpp>
|
#include <components/esm_store/store.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwworld/environment.hpp"
|
#include "../mwworld/environment.hpp"
|
||||||
#include "../mwworld/world.hpp"
|
#include "../mwworld/world.hpp"
|
||||||
|
@ -18,8 +19,8 @@
|
||||||
|
|
||||||
#include "openal_output.hpp"
|
#include "openal_output.hpp"
|
||||||
#define SOUND_OUT "OpenAL"
|
#define SOUND_OUT "OpenAL"
|
||||||
/* Set up the sound manager to use FFMPEG or MPG123+libsndfile for input. The
|
/* Set up the sound manager to use FFMPEG, MPG123+libsndfile, or Audiere for
|
||||||
* OPENMW_USE_x macros are set in CMakeLists.txt.
|
* input. The OPENMW_USE_x macros are set in CMakeLists.txt.
|
||||||
*/
|
*/
|
||||||
#ifdef OPENMW_USE_FFMPEG
|
#ifdef OPENMW_USE_FFMPEG
|
||||||
#include "ffmpeg_decoder.hpp"
|
#include "ffmpeg_decoder.hpp"
|
||||||
|
@ -28,6 +29,13 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPENMW_USE_AUDIERE
|
||||||
|
#include "audiere_decoder.hpp"
|
||||||
|
#ifndef SOUND_IN
|
||||||
|
#define SOUND_IN "Audiere"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef OPENMW_USE_MPG123
|
#ifdef OPENMW_USE_MPG123
|
||||||
#include "mpgsnd_decoder.hpp"
|
#include "mpgsnd_decoder.hpp"
|
||||||
#ifndef SOUND_IN
|
#ifndef SOUND_IN
|
||||||
|
@ -42,11 +50,20 @@ namespace MWSound
|
||||||
: mResourceMgr(Ogre::ResourceGroupManager::getSingleton())
|
: mResourceMgr(Ogre::ResourceGroupManager::getSingleton())
|
||||||
, mEnvironment(environment)
|
, mEnvironment(environment)
|
||||||
, mOutput(new DEFAULT_OUTPUT(*this))
|
, mOutput(new DEFAULT_OUTPUT(*this))
|
||||||
|
, mMasterVolume(1.0f)
|
||||||
|
, mSFXVolume(1.0f)
|
||||||
|
, mMusicVolume(1.0f)
|
||||||
{
|
{
|
||||||
if(!useSound)
|
if(!useSound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mMasterVolume = Settings::Manager::getFloat("master volume", "Sound");
|
||||||
|
mMasterVolume = std::min(std::max(mMasterVolume, 0.0f), 1.0f);
|
||||||
|
mSFXVolume = Settings::Manager::getFloat("sfx volume", "Sound");
|
||||||
|
mSFXVolume = std::min(std::max(mSFXVolume, 0.0f), 1.0f);
|
||||||
|
mMusicVolume = Settings::Manager::getFloat("music volume", "Sound");
|
||||||
|
mMusicVolume = std::min(std::max(mMusicVolume, 0.0f), 1.0f);
|
||||||
|
|
||||||
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
||||||
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
||||||
|
|
||||||
|
@ -57,7 +74,19 @@ namespace MWSound
|
||||||
for(size_t i = 0;i < names.size();i++)
|
for(size_t i = 0;i < names.size();i++)
|
||||||
std::cout <<" "<<names[i]<< std::endl;
|
std::cout <<" "<<names[i]<< std::endl;
|
||||||
|
|
||||||
|
std::string devname = Settings::Manager::getString("device", "Sound");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mOutput->init(devname);
|
||||||
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
if(devname.empty())
|
||||||
|
throw;
|
||||||
|
std::cout <<"Failed to open device \""<<devname<<"\", trying default"<< std::endl;
|
||||||
mOutput->init();
|
mOutput->init();
|
||||||
|
Settings::Manager::setString("device", "Sound", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
|
@ -129,12 +158,15 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::streamMusicFull(const std::string& filename)
|
void SoundManager::streamMusicFull(const std::string& filename)
|
||||||
{
|
{
|
||||||
|
if(!mOutput->isInitialized())
|
||||||
|
return;
|
||||||
std::cout <<"Playing "<<filename<< std::endl;
|
std::cout <<"Playing "<<filename<< std::endl;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
float basevol = mMasterVolume * mMusicVolume;
|
||||||
stopMusic();
|
stopMusic();
|
||||||
mMusic = mOutput->streamSound(filename, 0.4f, 1.0f, Play_NoEnv);
|
mMusic = mOutput->streamSound(filename, basevol, 1.0f, Play_NoEnv);
|
||||||
mMusic->mBaseVolume = 0.4f;
|
mMusic->mBaseVolume = basevol;
|
||||||
mMusic->mFlags = Play_NoEnv;
|
mMusic->mFlags = Play_NoEnv;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
|
@ -173,10 +205,12 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::say(MWWorld::Ptr ptr, const std::string& filename)
|
void SoundManager::say(MWWorld::Ptr ptr, const std::string& filename)
|
||||||
{
|
{
|
||||||
|
if(!mOutput->isInitialized())
|
||||||
|
return;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// The range values are not tested
|
// The range values are not tested
|
||||||
float basevol = 1.0f; /* TODO: volume settings */
|
float basevol = mMasterVolume * mSFXVolume;
|
||||||
std::string filePath = "Sound/"+filename;
|
std::string filePath = "Sound/"+filename;
|
||||||
const ESM::Position &pos = ptr.getCellRef().pos;
|
const ESM::Position &pos = ptr.getCellRef().pos;
|
||||||
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
|
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
|
||||||
|
@ -203,9 +237,11 @@ namespace MWSound
|
||||||
SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode)
|
SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode)
|
||||||
{
|
{
|
||||||
SoundPtr sound;
|
SoundPtr sound;
|
||||||
|
if(!mOutput->isInitialized())
|
||||||
|
return sound;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
float basevol = 1.0f; /* TODO: volume settings */
|
float basevol = mMasterVolume * mSFXVolume;
|
||||||
float min, max;
|
float min, max;
|
||||||
std::string file = lookup(soundId, basevol, min, max);
|
std::string file = lookup(soundId, basevol, min, max);
|
||||||
|
|
||||||
|
@ -230,10 +266,12 @@ namespace MWSound
|
||||||
float volume, float pitch, int mode)
|
float volume, float pitch, int mode)
|
||||||
{
|
{
|
||||||
SoundPtr sound;
|
SoundPtr sound;
|
||||||
|
if(!mOutput->isInitialized())
|
||||||
|
return sound;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Look up the sound in the ESM data
|
// Look up the sound in the ESM data
|
||||||
float basevol = 1.0f; /* TODO: volume settings */
|
float basevol = mMasterVolume * mSFXVolume;
|
||||||
float min, max;
|
float min, max;
|
||||||
std::string file = lookup(soundId, basevol, min, max);
|
std::string file = lookup(soundId, basevol, min, max);
|
||||||
const ESM::Position &pos = ptr.getCellRef().pos;
|
const ESM::Position &pos = ptr.getCellRef().pos;
|
||||||
|
@ -407,7 +445,7 @@ namespace MWSound
|
||||||
if(!isMusicPlaying())
|
if(!isMusicPlaying())
|
||||||
startRandomTitle();
|
startRandomTitle();
|
||||||
|
|
||||||
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
|
const ESM::Cell *cell = mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell;
|
||||||
Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera();
|
Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera();
|
||||||
Ogre::Vector3 nPos, nDir, nUp;
|
Ogre::Vector3 nPos, nDir, nUp;
|
||||||
nPos = cam->getRealPosition();
|
nPos = cam->getRealPosition();
|
||||||
|
@ -415,7 +453,7 @@ namespace MWSound
|
||||||
nUp = cam->getRealUp();
|
nUp = cam->getRealUp();
|
||||||
|
|
||||||
Environment env = Env_Normal;
|
Environment env = Env_Normal;
|
||||||
if(nPos.y < current->cell->water)
|
if((cell->data.flags&cell->HasWater) && nPos.y < cell->water)
|
||||||
env = Env_Underwater;
|
env = Env_Underwater;
|
||||||
|
|
||||||
// The output handler is expecting vectors oriented like the game
|
// The output handler is expecting vectors oriented like the game
|
||||||
|
@ -443,6 +481,8 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::update(float duration)
|
void SoundManager::update(float duration)
|
||||||
{
|
{
|
||||||
|
if(!mOutput->isInitialized())
|
||||||
|
return;
|
||||||
updateSounds(duration);
|
updateSounds(duration);
|
||||||
updateRegionSound(duration);
|
updateRegionSound(duration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,10 @@ namespace MWSound
|
||||||
|
|
||||||
std::auto_ptr<Sound_Output> mOutput;
|
std::auto_ptr<Sound_Output> mOutput;
|
||||||
|
|
||||||
|
float mMasterVolume;
|
||||||
|
float mSFXVolume;
|
||||||
|
float mMusicVolume;
|
||||||
|
|
||||||
boost::shared_ptr<Sound> mMusic;
|
boost::shared_ptr<Sound> mMusic;
|
||||||
std::string mCurrentPlaylist;
|
std::string mCurrentPlaylist;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
void Class::insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const{
|
|
||||||
|
void Class::insertObject(const Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +139,11 @@ namespace MWWorld
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Class::getValue (const Ptr& ptr) const
|
||||||
|
{
|
||||||
|
throw std::logic_error ("value not supported by this class");
|
||||||
|
}
|
||||||
|
|
||||||
const Class& Class::get (const std::string& key)
|
const Class& Class::get (const std::string& key)
|
||||||
{
|
{
|
||||||
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);
|
std::map<std::string, boost::shared_ptr<Class> >::const_iterator iter = sClasses.find (key);
|
||||||
|
|
|
@ -155,6 +155,10 @@ namespace MWWorld
|
||||||
/// no such skill.
|
/// no such skill.
|
||||||
/// (default implementation: return -1)
|
/// (default implementation: return -1)
|
||||||
|
|
||||||
|
virtual int getValue (const Ptr& ptr) const;
|
||||||
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
/// (default implementation: throws an exception)
|
||||||
|
|
||||||
static const Class& get (const std::string& key);
|
static const Class& get (const std::string& key);
|
||||||
///< If there is no class for this \a key, an exception is thrown.
|
///< If there is no class for this \a key, an exception is thrown.
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,12 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
|
|
||||||
|
#include <iostream> /// \todo remove after rendering is implemented
|
||||||
|
|
||||||
void MWWorld::InventoryStore::copySlots (const InventoryStore& store)
|
void MWWorld::InventoryStore::copySlots (const InventoryStore& store)
|
||||||
{
|
{
|
||||||
// some const-trickery, required because of a flaw in the handling of MW-references and the
|
// some const-trickery, required because of a flaw in the handling of MW-references and the
|
||||||
|
@ -24,10 +28,15 @@ void MWWorld::InventoryStore::copySlots (const InventoryStore& store)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::InventoryStore::InventoryStore()
|
void MWWorld::InventoryStore::initSlots (TSlots& slots)
|
||||||
{
|
{
|
||||||
for (int i=0; i<Slots; ++i)
|
for (int i=0; i<Slots; ++i)
|
||||||
mSlots.push_back (end());
|
slots.push_back (end());
|
||||||
|
}
|
||||||
|
|
||||||
|
MWWorld::InventoryStore::InventoryStore()
|
||||||
|
{
|
||||||
|
initSlots (mSlots);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::InventoryStore::InventoryStore (const InventoryStore& store)
|
MWWorld::InventoryStore::InventoryStore (const InventoryStore& store)
|
||||||
|
@ -86,3 +95,87 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot)
|
||||||
|
|
||||||
return mSlots[slot];
|
return mSlots[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MWWorld::InventoryStore::autoEquip (const MWMechanics::NpcStats& stats,
|
||||||
|
const Environment& environment)
|
||||||
|
{
|
||||||
|
TSlots slots;
|
||||||
|
initSlots (slots);
|
||||||
|
|
||||||
|
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
||||||
|
{
|
||||||
|
Ptr test = *iter;
|
||||||
|
int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test, environment);
|
||||||
|
|
||||||
|
std::pair<std::vector<int>, bool> itemsSlots =
|
||||||
|
MWWorld::Class::get (*iter).getEquipmentSlots (*iter);
|
||||||
|
|
||||||
|
for (std::vector<int>::const_iterator iter2 (itemsSlots.first.begin());
|
||||||
|
iter2!=itemsSlots.first.end(); ++iter2)
|
||||||
|
{
|
||||||
|
bool use = false;
|
||||||
|
|
||||||
|
if (slots.at (*iter2)==end())
|
||||||
|
use = true; // slot was empty before -> skill all further checks
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ptr old = *slots.at (*iter2);
|
||||||
|
|
||||||
|
if (!use)
|
||||||
|
{
|
||||||
|
// check skill
|
||||||
|
int oldSkill =
|
||||||
|
MWWorld::Class::get (old).getEquipmentSkill (old, environment);
|
||||||
|
|
||||||
|
if (testSkill!=-1 || oldSkill!=-1 || testSkill!=oldSkill)
|
||||||
|
{
|
||||||
|
if (stats.mSkill[oldSkill].getModified()>stats.mSkill[testSkill].getModified())
|
||||||
|
continue; // rejected, because old item better matched the NPC's skills.
|
||||||
|
|
||||||
|
if (stats.mSkill[oldSkill].getModified()<stats.mSkill[testSkill].getModified())
|
||||||
|
use = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!use)
|
||||||
|
{
|
||||||
|
// check value
|
||||||
|
if (MWWorld::Class::get (old).getValue (old)>=
|
||||||
|
MWWorld::Class::get (test).getValue (test))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
use = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \todo unstack, if reqquired (itemsSlots.second)
|
||||||
|
|
||||||
|
slots[*iter2] = iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
for (std::size_t i=0; i<slots.size(); ++i)
|
||||||
|
if (slots[i]!=mSlots[i])
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
mSlots.swap (slots);
|
||||||
|
flagAsModified();
|
||||||
|
|
||||||
|
/// \todo remove the following line after rendering is implemented
|
||||||
|
for (std::size_t i=0; i<mSlots.size(); ++i)
|
||||||
|
if (mSlots[i]!=end())
|
||||||
|
{
|
||||||
|
std::cout<<"NPC is equipping " << MWWorld::Class::get (*mSlots[i]).getName (*mSlots[i])
|
||||||
|
<< " in slot " << i << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,15 @@
|
||||||
|
|
||||||
#include "containerstore.hpp"
|
#include "containerstore.hpp"
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
struct NpcStats;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
class Environment;
|
||||||
|
|
||||||
///< \brief Variant of the ContainerStore for NPCs
|
///< \brief Variant of the ContainerStore for NPCs
|
||||||
class InventoryStore : public ContainerStore
|
class InventoryStore : public ContainerStore
|
||||||
{
|
{
|
||||||
|
@ -36,10 +43,14 @@ namespace MWWorld
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
mutable std::vector<ContainerStoreIterator> mSlots;
|
typedef std::vector<ContainerStoreIterator> TSlots;
|
||||||
|
|
||||||
|
mutable TSlots mSlots;
|
||||||
|
|
||||||
void copySlots (const InventoryStore& store);
|
void copySlots (const InventoryStore& store);
|
||||||
|
|
||||||
|
void initSlots (TSlots& slots);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InventoryStore();
|
InventoryStore();
|
||||||
|
@ -52,6 +63,9 @@ namespace MWWorld
|
||||||
///< \note \a iteartor can be an end-iterator
|
///< \note \a iteartor can be an end-iterator
|
||||||
|
|
||||||
ContainerStoreIterator getSlot (int slot);
|
ContainerStoreIterator getSlot (int slot);
|
||||||
|
|
||||||
|
void autoEquip (const MWMechanics::NpcStats& stats, const Environment& environment);
|
||||||
|
///< Auto equip items according to stats and item value.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../mwrender/player.hpp"
|
#include "../mwrender/player.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/movement.hpp"
|
#include "../mwmechanics/movement.hpp"
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
#include "world.hpp"
|
#include "world.hpp"
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
|
@ -48,6 +49,12 @@ namespace MWWorld
|
||||||
mClass = new_class;
|
mClass = new_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setDrawState(const DrawState& value)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState = value;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::setAutoMove (bool enable)
|
void Player::setAutoMove (bool enable)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = getPlayer();
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
@ -90,81 +97,9 @@ namespace MWWorld
|
||||||
MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running);
|
MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running);
|
||||||
}
|
}
|
||||||
|
|
||||||
Player::Faction Player::getFaction(std::string factionID)
|
DrawState Player::getDrawState()
|
||||||
{
|
{
|
||||||
for(std::list<Player::Faction>::iterator it = mFactions.begin(); it != mFactions.end();it++)
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
{
|
return MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState;
|
||||||
if(it->name == factionID) return *it;
|
|
||||||
}
|
|
||||||
//faction was not found->dummy faction
|
|
||||||
Player::Faction fact;
|
|
||||||
fact.id = "not found";
|
|
||||||
fact.name = "not found";
|
|
||||||
fact.rank = -10;
|
|
||||||
fact.expelled = false;
|
|
||||||
return fact;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::addFaction(std::string factionID)
|
|
||||||
{
|
|
||||||
if(getFaction(factionID).name == "not found")
|
|
||||||
{
|
|
||||||
Player::Faction fact;
|
|
||||||
const ESM::Faction* eFact = mWorld.getStore().factions.find(factionID);
|
|
||||||
fact.expelled = false;
|
|
||||||
fact.rank = 0;
|
|
||||||
fact.name = eFact->name;
|
|
||||||
fact.id = eFact->id;
|
|
||||||
mFactions.push_back(fact);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Player::getRank(std::string factionID)
|
|
||||||
{
|
|
||||||
Player::Faction fact = getFaction(factionID);
|
|
||||||
return fact.rank;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::setRank(std::string factionID,int rank)
|
|
||||||
{
|
|
||||||
Player::Faction fact = getFaction(factionID);
|
|
||||||
fact.rank = rank;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::raiseRank(std::string factionID)
|
|
||||||
{
|
|
||||||
if(getFaction(factionID).name == "not found")
|
|
||||||
{
|
|
||||||
addFaction(factionID);
|
|
||||||
setRank(factionID,1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setRank(factionID,getRank(factionID) + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::lowerRank(std::string factionID)
|
|
||||||
{
|
|
||||||
if(getFaction(factionID).name == "not found")
|
|
||||||
{
|
|
||||||
std::cout << "cannot lower the rank of the player: faction no found. Faction: "<< factionID << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setRank(factionID,getRank(factionID) - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Player::isExpelled(std::string factionID)
|
|
||||||
{
|
|
||||||
Player::Faction fact = getFaction(factionID);
|
|
||||||
return fact.expelled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::setExpelled(std::string factionID,bool expelled)
|
|
||||||
{
|
|
||||||
Player::Faction fact = getFaction(factionID);
|
|
||||||
fact.expelled = expelled;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
#include "OgreCamera.h"
|
#include "OgreCamera.h"
|
||||||
|
|
||||||
#include <components/esm_store/cell_store.hpp>
|
#include <components/esm_store/cell_store.hpp>
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include "../mwworld/refdata.hpp"
|
#include "../mwworld/refdata.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/drawstate.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class Player;
|
class Player;
|
||||||
|
@ -21,13 +22,6 @@ namespace MWWorld
|
||||||
/// \brief NPC object representing the player and additional player data
|
/// \brief NPC object representing the player and additional player data
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
struct Faction
|
|
||||||
{
|
|
||||||
std::string id,name;
|
|
||||||
int rank;
|
|
||||||
bool expelled;
|
|
||||||
};
|
|
||||||
|
|
||||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> mPlayer;
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> mPlayer;
|
||||||
MWWorld::Ptr::CellStore *mCellStore;
|
MWWorld::Ptr::CellStore *mCellStore;
|
||||||
MWRender::Player *mRenderer;
|
MWRender::Player *mRenderer;
|
||||||
|
@ -37,12 +31,8 @@ namespace MWWorld
|
||||||
std::string mRace;
|
std::string mRace;
|
||||||
std::string mBirthsign;
|
std::string mBirthsign;
|
||||||
ESM::Class *mClass;
|
ESM::Class *mClass;
|
||||||
std::list<Faction> mFactions;
|
|
||||||
bool mAutoMove;
|
bool mAutoMove;
|
||||||
int mForwardBackward;
|
int mForwardBackward;
|
||||||
|
|
||||||
Faction getFaction(std::string faction);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Player(MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world);
|
Player(MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world);
|
||||||
|
@ -87,6 +77,8 @@ namespace MWWorld
|
||||||
|
|
||||||
void setClass (const ESM::Class& class_);
|
void setClass (const ESM::Class& class_);
|
||||||
|
|
||||||
|
void setDrawState(const DrawState& state);
|
||||||
|
|
||||||
std::string getName() const
|
std::string getName() const
|
||||||
{
|
{
|
||||||
return mName;
|
return mName;
|
||||||
|
@ -117,22 +109,10 @@ namespace MWWorld
|
||||||
return mAutoMove;
|
return mAutoMove;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawState getDrawState();
|
||||||
|
|
||||||
void setAutoMove (bool enable);
|
void setAutoMove (bool enable);
|
||||||
|
|
||||||
void addFaction(std::string factionID);
|
|
||||||
|
|
||||||
int getRank(std::string factionID);
|
|
||||||
|
|
||||||
void setRank(std::string factionID,int rank);
|
|
||||||
|
|
||||||
void raiseRank(std::string factionID);
|
|
||||||
|
|
||||||
void lowerRank(std::string factionID);
|
|
||||||
|
|
||||||
bool isExpelled(std::string factionID);
|
|
||||||
|
|
||||||
void setExpelled(std::string factionID,bool expelled);
|
|
||||||
|
|
||||||
void setLeftRight (int value);
|
void setLeftRight (int value);
|
||||||
|
|
||||||
void setForwardBackward (int value);
|
void setForwardBackward (int value);
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace MWWorld
|
||||||
return mPtr.empty();
|
return mPtr.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::type_info& getType()
|
const std::type_info& getType() const
|
||||||
{
|
{
|
||||||
assert (!mPtr.empty());
|
assert (!mPtr.empty());
|
||||||
return mPtr.type();
|
return mPtr.type();
|
||||||
|
|
|
@ -204,7 +204,6 @@ namespace MWWorld
|
||||||
mWorld->adjustSky();
|
mWorld->adjustSky();
|
||||||
|
|
||||||
mCellChanged = true;
|
mCellChanged = true;
|
||||||
mRendering.waterAdded(mCurrentCell);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//We need the ogre renderer and a scene node.
|
//We need the ogre renderer and a scene node.
|
||||||
|
@ -257,8 +256,6 @@ namespace MWWorld
|
||||||
mWorld->adjustSky();
|
mWorld->adjustSky();
|
||||||
|
|
||||||
mCellChanged = true;
|
mCellChanged = true;
|
||||||
|
|
||||||
mRendering.waterAdded(cell);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changeToExteriorCell (const ESM::Position& position)
|
void Scene::changeToExteriorCell (const ESM::Position& position)
|
||||||
|
|
|
@ -34,7 +34,7 @@ const float WeatherGlobals::mThunderFrequency = .4;
|
||||||
const float WeatherGlobals::mThunderThreshold = 0.6;
|
const float WeatherGlobals::mThunderThreshold = 0.6;
|
||||||
const float WeatherGlobals::mThunderSoundDelay = 0.25;
|
const float WeatherGlobals::mThunderSoundDelay = 0.25;
|
||||||
|
|
||||||
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) :
|
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::Environment* env) :
|
||||||
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
|
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
|
||||||
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
|
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0)
|
||||||
{
|
{
|
||||||
|
@ -335,13 +335,15 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environmen
|
||||||
void WeatherManager::setWeather(const String& weather, bool instant)
|
void WeatherManager::setWeather(const String& weather, bool instant)
|
||||||
{
|
{
|
||||||
if (weather == mCurrentWeather && mNextWeather == "")
|
if (weather == mCurrentWeather && mNextWeather == "")
|
||||||
|
{
|
||||||
|
mFirstUpdate = false;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (instant || mFirstUpdate)
|
if (instant || mFirstUpdate)
|
||||||
{
|
{
|
||||||
mNextWeather = "";
|
mNextWeather = "";
|
||||||
mCurrentWeather = weather;
|
mCurrentWeather = weather;
|
||||||
mFirstUpdate = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -355,6 +357,7 @@ void WeatherManager::setWeather(const String& weather, bool instant)
|
||||||
mNextWeather = weather;
|
mNextWeather = weather;
|
||||||
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600;
|
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600;
|
||||||
}
|
}
|
||||||
|
mFirstUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
WeatherResult WeatherManager::getResult(const String& weather)
|
WeatherResult WeatherManager::getResult(const String& weather)
|
||||||
|
@ -472,6 +475,7 @@ WeatherResult WeatherManager::transition(float factor)
|
||||||
result.mCloudSpeed = current.mCloudSpeed;
|
result.mCloudSpeed = current.mCloudSpeed;
|
||||||
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
|
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
|
||||||
result.mGlareView = lerp(current.mGlareView, other.mGlareView);
|
result.mGlareView = lerp(current.mGlareView, other.mGlareView);
|
||||||
|
result.mNightFade = lerp(current.mNightFade, other.mNightFade);
|
||||||
|
|
||||||
result.mNight = current.mNight;
|
result.mNight = current.mNight;
|
||||||
|
|
||||||
|
@ -520,23 +524,23 @@ void WeatherManager::update(float duration)
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
float random = ((rand()%100)/100.f) * total;
|
float random = ((rand()%100)/100.f) * total;
|
||||||
|
|
||||||
//if (random > snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
//if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
// weather = "blizzard";
|
// weather = "blizzard";
|
||||||
//else if (random > blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
//else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
// weather = "snow";
|
// weather = "snow";
|
||||||
/*else*/ if (random > ash+thunder+rain+overcast+foggy+cloudy+clear)
|
/*else*/ if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
weather = "blight";
|
weather = "blight";
|
||||||
else if (random > thunder+rain+overcast+foggy+cloudy+clear)
|
else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
|
||||||
weather = "ashstorm";
|
weather = "ashstorm";
|
||||||
else if (random > rain+overcast+foggy+cloudy+clear)
|
else if (random >= rain+overcast+foggy+cloudy+clear)
|
||||||
weather = "thunderstorm";
|
weather = "thunderstorm";
|
||||||
else if (random > overcast+foggy+cloudy+clear)
|
else if (random >= overcast+foggy+cloudy+clear)
|
||||||
weather = "rain";
|
weather = "rain";
|
||||||
else if (random > foggy+cloudy+clear)
|
else if (random >= foggy+cloudy+clear)
|
||||||
weather = "overcast";
|
weather = "overcast";
|
||||||
else if (random > cloudy+clear)
|
else if (random >= cloudy+clear)
|
||||||
weather = "foggy";
|
weather = "foggy";
|
||||||
else if (random > clear)
|
else if (random >= clear)
|
||||||
weather = "cloudy";
|
weather = "cloudy";
|
||||||
else
|
else
|
||||||
weather = "clear";
|
weather = "clear";
|
||||||
|
@ -584,8 +588,8 @@ void WeatherManager::update(float duration)
|
||||||
int facing = (mHour > 13.f) ? 1 : -1;
|
int facing = (mHour > 13.f) ? 1 : -1;
|
||||||
|
|
||||||
Vector3 final(
|
Vector3 final(
|
||||||
(1-height)*facing,
|
-(1-height)*facing,
|
||||||
(1-height)*facing,
|
-(1-height)*facing,
|
||||||
height);
|
height);
|
||||||
mRendering->setSunDirection(final);
|
mRendering->setSunDirection(final);
|
||||||
|
|
||||||
|
|
|
@ -152,10 +152,30 @@ namespace MWWorld
|
||||||
mRendering->skyDisable();
|
mRendering->skyDisable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::setFallbackValues(std::map<std::string,std::string> fallbackMap)
|
||||||
|
{
|
||||||
|
mFallback = fallbackMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string World::getFallback(std::string key)
|
||||||
|
{
|
||||||
|
return getFallback(key, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string World::getFallback(std::string key, std::string def)
|
||||||
|
{
|
||||||
|
std::map<std::string,std::string>::iterator it;
|
||||||
|
if((it = mFallback.find(key)) == mFallback.end())
|
||||||
|
{
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
World::World (OEngine::Render::OgreRenderer& renderer,
|
World::World (OEngine::Render::OgreRenderer& renderer,
|
||||||
const Files::Collections& fileCollections,
|
const Files::Collections& fileCollections,
|
||||||
const std::string& master, const boost::filesystem::path& resDir,
|
const std::string& master, const boost::filesystem::path& resDir,
|
||||||
bool newGame, Environment& environment, const std::string& encoding)
|
bool newGame, Environment& environment, const std::string& encoding, std::map<std::string,std::string> fallbackMap)
|
||||||
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
|
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
|
||||||
mSky (true), mEnvironment (environment), mNextDynamicRecord (0), mCells (mStore, mEsm, *this),
|
mSky (true), mEnvironment (environment), mNextDynamicRecord (0), mCells (mStore, mEsm, *this),
|
||||||
mNumFacing(0)
|
mNumFacing(0)
|
||||||
|
@ -191,6 +211,8 @@ namespace MWWorld
|
||||||
|
|
||||||
mWorldScene = new Scene(environment, this, *mRendering, mPhysics);
|
mWorldScene = new Scene(environment, this, *mRendering, mPhysics);
|
||||||
|
|
||||||
|
setFallbackValues(fallbackMap);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -750,15 +772,16 @@ namespace MWWorld
|
||||||
// figure out which object we want to test against
|
// figure out which object we want to test against
|
||||||
std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects();
|
std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects();
|
||||||
|
|
||||||
// ignore the player
|
// ignore the player and other things we're not interested in
|
||||||
for (std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
||||||
it != results.end(); ++it)
|
while (it != results.end())
|
||||||
{
|
{
|
||||||
if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle() )
|
if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() )
|
||||||
{
|
{
|
||||||
results.erase(it);
|
it = results.erase(it);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.size() == 0)
|
if (results.size() == 0)
|
||||||
|
@ -774,6 +797,10 @@ namespace MWWorld
|
||||||
btVector3 p = mPhysics->getRayPoint(results.front().first);
|
btVector3 p = mPhysics->getRayPoint(results.front().first);
|
||||||
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||||
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
|
Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode();
|
||||||
|
|
||||||
|
//std::cout << "Num facing 1 : " << mFaced1Name << std::endl;
|
||||||
|
//std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl;
|
||||||
|
|
||||||
query->occlusionTest(pos, node);
|
query->occlusionTest(pos, node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -786,8 +813,33 @@ namespace MWWorld
|
||||||
|
|
||||||
btVector3 p = mPhysics->getRayPoint(results[1].first);
|
btVector3 p = mPhysics->getRayPoint(results[1].first);
|
||||||
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
Ogre::Vector3 pos(p.x(), p.z(), -p.y());
|
||||||
Ogre::SceneNode* node = mFaced2.getRefData().getBaseNode();
|
Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode();
|
||||||
query->occlusionTest(pos, node);
|
Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode();
|
||||||
|
|
||||||
|
// no need to test if the first node is not occluder
|
||||||
|
if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos))
|
||||||
|
{
|
||||||
|
mFacedHandle = mFaced1Name;
|
||||||
|
//std::cout << "node1 Not an occluder" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to test if the second object is static (thus cannot be activated)
|
||||||
|
if (mFaced2.getTypeName().find("Static") != std::string::npos)
|
||||||
|
{
|
||||||
|
mFacedHandle = mFaced1Name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// work around door problems
|
||||||
|
if (mFaced1.getTypeName().find("Static") != std::string::npos
|
||||||
|
&& mFaced2.getTypeName().find("Door") != std::string::npos)
|
||||||
|
{
|
||||||
|
mFacedHandle = mFaced2Name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
query->occlusionTest(pos, node2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -834,6 +886,18 @@ namespace MWWorld
|
||||||
return mRendering->getFader();
|
return mRendering->getFader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::Vector2 World::getNorthVector(Ptr::CellStore* cell)
|
||||||
|
{
|
||||||
|
ESMS::CellRefList<ESM::Static, MWWorld::RefData> statics = cell->statics;
|
||||||
|
ESMS::LiveCellRef<ESM::Static, MWWorld::RefData>* ref = statics.find("northmarker");
|
||||||
|
if (!ref)
|
||||||
|
return Vector2(0, 1);
|
||||||
|
Ogre::SceneNode* node = ref->mData.getBaseNode();
|
||||||
|
Vector3 dir = node->_getDerivedOrientation().yAxis();
|
||||||
|
Vector2 d = Vector2(dir.x, dir.z);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
void World::setWaterHeight(const float height)
|
void World::setWaterHeight(const float height)
|
||||||
{
|
{
|
||||||
mRendering->setWaterHeight(height);
|
mRendering->setWaterHeight(height);
|
||||||
|
|
|
@ -63,7 +63,8 @@ namespace MWWorld
|
||||||
enum RenderMode
|
enum RenderMode
|
||||||
{
|
{
|
||||||
Render_CollisionDebug,
|
Render_CollisionDebug,
|
||||||
Render_Wireframe
|
Render_Wireframe,
|
||||||
|
Render_Pathgrid
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -99,6 +100,7 @@ namespace MWWorld
|
||||||
std::string mFaced1Name;
|
std::string mFaced1Name;
|
||||||
std::string mFaced2Name;
|
std::string mFaced2Name;
|
||||||
int mNumFacing;
|
int mNumFacing;
|
||||||
|
std::map<std::string,std::string> mFallback;
|
||||||
|
|
||||||
int getDaysPerMonth (int month) const;
|
int getDaysPerMonth (int month) const;
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ namespace MWWorld
|
||||||
World (OEngine::Render::OgreRenderer& renderer,
|
World (OEngine::Render::OgreRenderer& renderer,
|
||||||
const Files::Collections& fileCollections,
|
const Files::Collections& fileCollections,
|
||||||
const std::string& master, const boost::filesystem::path& resDir, bool newGame,
|
const std::string& master, const boost::filesystem::path& resDir, bool newGame,
|
||||||
Environment& environment, const std::string& encoding);
|
Environment& environment, const std::string& encoding, std::map<std::string,std::string> fallbackMap);
|
||||||
|
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
|
@ -124,6 +126,12 @@ namespace MWWorld
|
||||||
|
|
||||||
void adjustSky();
|
void adjustSky();
|
||||||
|
|
||||||
|
void setFallbackValues(std::map<std::string,std::string> fallbackMap);
|
||||||
|
|
||||||
|
std::string getFallback(std::string key);
|
||||||
|
|
||||||
|
std::string getFallback(std::string key, std::string def);
|
||||||
|
|
||||||
MWWorld::Player& getPlayer();
|
MWWorld::Player& getPlayer();
|
||||||
|
|
||||||
const ESMS::ESMStore& getStore() const;
|
const ESMS::ESMStore& getStore() const;
|
||||||
|
@ -138,6 +146,9 @@ namespace MWWorld
|
||||||
bool isCellExterior() const;
|
bool isCellExterior() const;
|
||||||
bool isCellQuasiExterior() const;
|
bool isCellQuasiExterior() const;
|
||||||
|
|
||||||
|
Ogre::Vector2 getNorthVector(Ptr::CellStore* cell);
|
||||||
|
///< get north vector (OGRE coordinates) for given interior cell
|
||||||
|
|
||||||
Globals::Data& getGlobalVariable (const std::string& name);
|
Globals::Data& getGlobalVariable (const std::string& name);
|
||||||
|
|
||||||
Globals::Data getGlobalVariable (const std::string& name) const;
|
Globals::Data getGlobalVariable (const std::string& name) const;
|
||||||
|
|
|
@ -82,6 +82,22 @@ findpkg_finish ( "MYGUI" )
|
||||||
ELSE (WIN32) #Unix
|
ELSE (WIN32) #Unix
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR)
|
||||||
FIND_PACKAGE(PkgConfig)
|
FIND_PACKAGE(PkgConfig)
|
||||||
|
IF(MYGUI_STATIC)
|
||||||
|
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 "")
|
||||||
|
SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform")
|
||||||
|
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_PLATFORM_LIBRARIES "MyGUI.OgrePlatform")
|
||||||
|
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(MYGUI_STATIC)
|
||||||
PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI)
|
PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI)
|
||||||
IF (MYGUI_INCLUDE_DIRS)
|
IF (MYGUI_INCLUDE_DIRS)
|
||||||
SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS})
|
SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS})
|
||||||
|
@ -96,6 +112,7 @@ ELSE (WIN32) #Unix
|
||||||
STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}")
|
STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}")
|
||||||
STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}")
|
STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}")
|
||||||
ENDIF (MYGUI_INCLUDE_DIRS)
|
ENDIF (MYGUI_INCLUDE_DIRS)
|
||||||
|
ENDIF(MYGUI_STATIC)
|
||||||
ENDIF (WIN32)
|
ENDIF (WIN32)
|
||||||
|
|
||||||
#Do some preparation
|
#Do some preparation
|
||||||
|
|
|
@ -2,6 +2,10 @@ project (Components)
|
||||||
|
|
||||||
# source files
|
# source files
|
||||||
|
|
||||||
|
add_component_dir (settings
|
||||||
|
settings
|
||||||
|
)
|
||||||
|
|
||||||
add_component_dir (bsa
|
add_component_dir (bsa
|
||||||
bsa_archive bsa_file
|
bsa_archive bsa_file
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "errorhandler.hpp"
|
#include "errorhandler.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
|
#include "scanner.hpp"
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
@ -81,6 +82,8 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
if (!(mOptional && mEmpty))
|
if (!(mOptional && mEmpty))
|
||||||
reportSeriousError ("Unexpected numeric value", loc);
|
reportSeriousError ("Unexpected numeric value", loc);
|
||||||
|
else
|
||||||
|
scanner.putbackInt (value, loc);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -94,6 +97,8 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
if (!(mOptional && mEmpty))
|
if (!(mOptional && mEmpty))
|
||||||
reportSeriousError ("Unexpected floating point value", loc);
|
reportSeriousError ("Unexpected floating point value", loc);
|
||||||
|
else
|
||||||
|
scanner.putbackFloat (value, loc);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -108,6 +113,8 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
if (!(mOptional && mEmpty))
|
if (!(mOptional && mEmpty))
|
||||||
reportSeriousError ("Unexpected name", loc);
|
reportSeriousError ("Unexpected name", loc);
|
||||||
|
else
|
||||||
|
scanner.putbackName (name, loc);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -121,6 +128,8 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
if (!(mOptional && mEmpty))
|
if (!(mOptional && mEmpty))
|
||||||
reportSeriousError ("Unexpected keyword", loc);
|
reportSeriousError ("Unexpected keyword", loc);
|
||||||
|
else
|
||||||
|
scanner.putbackKeyword (keyword, loc);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +143,8 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
if (!(mOptional && mEmpty))
|
if (!(mOptional && mEmpty))
|
||||||
reportSeriousError ("Unexpected special token", loc);
|
reportSeriousError ("Unexpected special token", loc);
|
||||||
|
else
|
||||||
|
scanner.putbackSpecial (code, loc);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,6 @@ namespace Compiler
|
||||||
mState = CommaState;
|
mState = CommaState;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (code==Scanner::S_newline && mState==StartState)
|
|
||||||
{
|
|
||||||
scanner.putbackSpecial (code, loc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Parser::parseSpecial (code, loc, scanner);
|
return Parser::parseSpecial (code, loc, scanner);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,24 @@
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Land::Land()
|
||||||
|
: flags(0)
|
||||||
|
, X(0)
|
||||||
|
, Y(0)
|
||||||
|
, mEsm(NULL)
|
||||||
|
, hasData(false)
|
||||||
|
, dataLoaded(false)
|
||||||
|
, landData(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Land::~Land()
|
||||||
|
{
|
||||||
|
delete landData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Land::load(ESMReader &esm)
|
void Land::load(ESMReader &esm)
|
||||||
{
|
{
|
||||||
mEsm = &esm;
|
mEsm = &esm;
|
||||||
|
|
|
@ -11,6 +11,9 @@ namespace ESM
|
||||||
|
|
||||||
struct Land
|
struct Land
|
||||||
{
|
{
|
||||||
|
Land();
|
||||||
|
~Land();
|
||||||
|
|
||||||
int flags; // Only first four bits seem to be used, don't know what
|
int flags; // Only first four bits seem to be used, don't know what
|
||||||
// they mean.
|
// they mean.
|
||||||
int X, Y; // Map coordinates.
|
int X, Y; // Map coordinates.
|
||||||
|
@ -77,6 +80,11 @@ struct Land
|
||||||
* Frees memory allocated for land data
|
* Frees memory allocated for land data
|
||||||
*/
|
*/
|
||||||
void unloadData();
|
void unloadData();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Land(const Land& land);
|
||||||
|
Land& operator=(const Land& land);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -457,7 +457,7 @@ namespace ESMS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pathgrid *find(int cellX, int cellY, std::string cellName) const
|
Pathgrid *find(int cellX, int cellY, const std::string &cellName) const
|
||||||
{
|
{
|
||||||
Pathgrid *result = search(cellX, cellY, cellName);
|
Pathgrid *result = search(cellX, cellY, cellName);
|
||||||
if (!result)
|
if (!result)
|
||||||
|
@ -467,7 +467,7 @@ namespace ESMS
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pathgrid *search(int cellX, int cellY, std::string cellName) const
|
Pathgrid *search(int cellX, int cellY, const std::string &cellName) const
|
||||||
{
|
{
|
||||||
Pathgrid *result = NULL;
|
Pathgrid *result = NULL;
|
||||||
if (cellX == 0 && cellY == 0) // possibly interior
|
if (cellX == 0 && cellY == 0) // possibly interior
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "ogre_nif_loader.hpp"
|
#include "ogre_nif_loader.hpp"
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
typedef unsigned char ubyte;
|
typedef unsigned char ubyte;
|
||||||
|
|
||||||
|
@ -299,6 +300,10 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]);
|
material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]);
|
||||||
material->setShininess(glossiness);
|
material->setShininess(glossiness);
|
||||||
|
|
||||||
|
if (Settings::Manager::getBool("shaders", "Objects"))
|
||||||
|
{
|
||||||
|
bool mrt = Settings::Manager::getBool("shader", "Water");
|
||||||
|
|
||||||
// Create shader for the material
|
// Create shader for the material
|
||||||
// vertex
|
// vertex
|
||||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||||
|
@ -321,9 +326,8 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
" out float4 oPosition : POSITION, \n"
|
" out float4 oPosition : POSITION, \n"
|
||||||
" out float4 oPositionObjSpace : TEXCOORD1, \n"
|
" out float4 oPositionObjSpace : TEXCOORD1, \n"
|
||||||
" out float4 oNormal : TEXCOORD2, \n"
|
" out float4 oNormal : TEXCOORD2, \n"
|
||||||
" out float oFogValue : TEXCOORD3, \n"
|
" out float oDepth : TEXCOORD3, \n"
|
||||||
" out float4 oVertexColour : TEXCOORD4, \n"
|
" out float4 oVertexColour : TEXCOORD4, \n"
|
||||||
" uniform float4 fogParams, \n"
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
" uniform float4x4 worldViewProj \n"
|
||||||
") \n"
|
") \n"
|
||||||
"{ \n"
|
"{ \n"
|
||||||
|
@ -331,13 +335,12 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
" oUV = uv; \n"
|
" oUV = uv; \n"
|
||||||
" oNormal = normal; \n"
|
" oNormal = normal; \n"
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
" oPosition = mul( worldViewProj, position ); \n"
|
||||||
" oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n"
|
" oDepth = oPosition.z; \n"
|
||||||
" oPositionObjSpace = position; \n"
|
" oPositionObjSpace = position; \n"
|
||||||
"}";
|
"}";
|
||||||
vertex->setSource(outStream.str());
|
vertex->setSource(outStream.str());
|
||||||
vertex->load();
|
vertex->load();
|
||||||
vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||||
vertex->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vertex = mgr.getByName("main_vp");
|
vertex = mgr.getByName("main_vp");
|
||||||
|
@ -349,12 +352,7 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
// not work perfectly for objects batched together (they will all use the same
|
// not work perfectly for objects batched together (they will all use the same
|
||||||
// lights). to work around this, we are simply pushing the maximum number
|
// lights). to work around this, we are simply pushing the maximum number
|
||||||
// of lights here in order to minimize disappearing lights.
|
// of lights here in order to minimize disappearing lights.
|
||||||
float num_lights;
|
int num_lights = Settings::Manager::getInt("num lights", "Objects");
|
||||||
if (GpuProgramManager::getSingleton().isSyntaxSupported("fp40") ||
|
|
||||||
GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0"))
|
|
||||||
num_lights = 8 /* 32 */;
|
|
||||||
else
|
|
||||||
num_lights = 8;
|
|
||||||
|
|
||||||
// fragment
|
// fragment
|
||||||
HighLevelGpuProgramPtr fragment;
|
HighLevelGpuProgramPtr fragment;
|
||||||
|
@ -372,9 +370,14 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||||
" float4 positionObjSpace : TEXCOORD1, \n"
|
" float4 positionObjSpace : TEXCOORD1, \n"
|
||||||
" float4 normal : TEXCOORD2, \n"
|
" float4 normal : TEXCOORD2, \n"
|
||||||
" float fogValue : TEXCOORD3, \n"
|
" float iDepth : TEXCOORD3, \n"
|
||||||
" float4 vertexColour : TEXCOORD4, \n"
|
" float4 vertexColour : TEXCOORD4, \n"
|
||||||
" uniform float4 fogColour, \n";
|
" uniform float4 fogColour, \n"
|
||||||
|
" uniform float4 fogParams, \n";
|
||||||
|
|
||||||
|
if (mrt) outStream <<
|
||||||
|
" out float4 oColor1 : COLOR1, \n"
|
||||||
|
" uniform float far, \n";
|
||||||
|
|
||||||
for (int i=0; i<num_lights; ++i)
|
for (int i=0; i<num_lights; ++i)
|
||||||
{
|
{
|
||||||
|
@ -410,8 +413,14 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
|
|
||||||
outStream <<
|
outStream <<
|
||||||
" float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
|
" float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
|
||||||
|
" float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n"
|
||||||
" oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n"
|
" oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n"
|
||||||
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n"
|
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n";
|
||||||
|
|
||||||
|
if (mrt) outStream <<
|
||||||
|
" oColor1 = float4(iDepth / far, 0, 0, (oColor.a == 1)); \n"; // only write to MRT if alpha is 1
|
||||||
|
|
||||||
|
outStream <<
|
||||||
"}";
|
"}";
|
||||||
fragment->setSource(outStream.str());
|
fragment->setSource(outStream.str());
|
||||||
fragment->load();
|
fragment->load();
|
||||||
|
@ -427,11 +436,15 @@ void NIFLoader::createMaterial(const String &name,
|
||||||
fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
|
fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
|
||||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
|
fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
|
||||||
fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
|
fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
|
||||||
|
fragment->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
|
||||||
|
if (mrt)
|
||||||
|
fragment->getDefaultParameters()->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fragment = mgr.getByName("main_fp");
|
fragment = mgr.getByName("main_fp");
|
||||||
material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName());
|
material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Takes a name and adds a unique part to it. This is just used to
|
// Takes a name and adds a unique part to it. This is just used to
|
||||||
// make sure that all materials are given unique names.
|
// make sure that all materials are given unique names.
|
||||||
|
|
158
components/settings/settings.cpp
Normal file
158
components/settings/settings.cpp
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
#include "settings.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <OgreResourceGroupManager.h>
|
||||||
|
#include <OgreStringConverter.h>
|
||||||
|
|
||||||
|
using namespace Settings;
|
||||||
|
|
||||||
|
Ogre::ConfigFile Manager::mFile = Ogre::ConfigFile();
|
||||||
|
Ogre::ConfigFile Manager::mDefaultFile = Ogre::ConfigFile();
|
||||||
|
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
|
||||||
|
CategorySettingValueMap Manager::mNewSettings = CategorySettingValueMap();
|
||||||
|
|
||||||
|
void Manager::loadUser (const std::string& file)
|
||||||
|
{
|
||||||
|
mFile.load(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::loadDefault (const std::string& file)
|
||||||
|
{
|
||||||
|
mDefaultFile.load(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::saveUser(const std::string& file)
|
||||||
|
{
|
||||||
|
std::fstream fout(file.c_str(), std::ios::out);
|
||||||
|
|
||||||
|
Ogre::ConfigFile::SectionIterator seci = mFile.getSectionIterator();
|
||||||
|
|
||||||
|
while (seci.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::String sectionName = seci.peekNextKey();
|
||||||
|
|
||||||
|
if (sectionName.length() > 0)
|
||||||
|
fout << '\n' << '[' << seci.peekNextKey() << ']' << '\n';
|
||||||
|
|
||||||
|
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
|
||||||
|
Ogre::ConfigFile::SettingsMultiMap::iterator i;
|
||||||
|
for (i = settings->begin(); i != settings->end(); ++i)
|
||||||
|
{
|
||||||
|
fout << i->first.c_str() << " = " << i->second.c_str() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
CategorySettingValueMap::iterator it = mNewSettings.begin();
|
||||||
|
while (it != mNewSettings.end())
|
||||||
|
{
|
||||||
|
if (it->first.first == sectionName)
|
||||||
|
{
|
||||||
|
fout << it->first.second << " = " << it->second << '\n';
|
||||||
|
mNewSettings.erase(it++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string category = "";
|
||||||
|
for (CategorySettingValueMap::iterator it = mNewSettings.begin();
|
||||||
|
it != mNewSettings.end(); ++it)
|
||||||
|
{
|
||||||
|
if (category != it->first.first)
|
||||||
|
{
|
||||||
|
category = it->first.first;
|
||||||
|
fout << '\n' << '[' << category << ']' << '\n';
|
||||||
|
}
|
||||||
|
fout << it->first.second << " = " << it->second << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string Manager::getString (const std::string& setting, const std::string& category)
|
||||||
|
{
|
||||||
|
if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end())
|
||||||
|
return mNewSettings[std::make_pair(category, setting)];
|
||||||
|
|
||||||
|
std::string defaultval = mDefaultFile.getSetting(setting, category);
|
||||||
|
return mFile.getSetting(setting, category, defaultval);
|
||||||
|
}
|
||||||
|
|
||||||
|
const float Manager::getFloat (const std::string& setting, const std::string& category)
|
||||||
|
{
|
||||||
|
return Ogre::StringConverter::parseReal( getString(setting, category) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const int Manager::getInt (const std::string& setting, const std::string& category)
|
||||||
|
{
|
||||||
|
return Ogre::StringConverter::parseInt( getString(setting, category) );
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool Manager::getBool (const std::string& setting, const std::string& category)
|
||||||
|
{
|
||||||
|
return Ogre::StringConverter::parseBool( getString(setting, category) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::setString (const std::string& setting, const std::string& category, const std::string& value)
|
||||||
|
{
|
||||||
|
CategorySetting s = std::make_pair(category, setting);
|
||||||
|
|
||||||
|
bool found=false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Ogre::ConfigFile::SettingsIterator it = mFile.getSettingsIterator(category);
|
||||||
|
while (it.hasMoreElements())
|
||||||
|
{
|
||||||
|
Ogre::ConfigFile::SettingsMultiMap::iterator i = it.current();
|
||||||
|
|
||||||
|
if ((*i).first == setting)
|
||||||
|
{
|
||||||
|
if ((*i).second != value)
|
||||||
|
{
|
||||||
|
mChangedSettings.push_back(std::make_pair(category, setting));
|
||||||
|
(*i).second = value;
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Ogre::Exception&)
|
||||||
|
{}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
if (mNewSettings.find(s) != mNewSettings.end())
|
||||||
|
{
|
||||||
|
if (mNewSettings[s] != value)
|
||||||
|
{
|
||||||
|
mChangedSettings.push_back(std::make_pair(category, setting));
|
||||||
|
mNewSettings[s] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mNewSettings[s] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::setInt (const std::string& setting, const std::string& category, const int value)
|
||||||
|
{
|
||||||
|
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::setFloat (const std::string& setting, const std::string& category, const float value)
|
||||||
|
{
|
||||||
|
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::setBool (const std::string& setting, const std::string& category, const bool value)
|
||||||
|
{
|
||||||
|
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
const CategorySettingVector Manager::apply()
|
||||||
|
{
|
||||||
|
CategorySettingVector vec = mChangedSettings;
|
||||||
|
mChangedSettings.clear();
|
||||||
|
return vec;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue