mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 15:35:23 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
51a2d4ef5a
@ -1,6 +1,6 @@
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
# - osx
|
||||
language: cpp
|
||||
branches:
|
||||
only:
|
||||
|
@ -12,9 +12,10 @@ echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_
|
||||
echo "yes" | sudo apt-add-repository ppa:openmw/openmw
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qq libgtest-dev google-mock
|
||||
sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-wave-dev
|
||||
sudo apt-get install -qq libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev
|
||||
sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
|
||||
sudo apt-get install -qq libbullet-dev libogre-1.9-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
|
||||
sudo apt-get install -qq libbullet-dev libopenscenegraph-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev
|
||||
sudo apt-get install -qq cmake-data #workaround for broken osgqt cmake script in ubuntu 12.04
|
||||
if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi
|
||||
sudo mkdir /usr/src/gtest/build
|
||||
cd /usr/src/gtest/build
|
||||
|
331
CMakeLists.txt
331
CMakeLists.txt
@ -54,15 +54,13 @@ endif (ANDROID)
|
||||
configure_file ("${OpenMW_SOURCE_DIR}/docs/mainpage.hpp.cmake" "${OpenMW_BINARY_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(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
||||
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
||||
|
||||
set(CUSTOM_OGRE_PLUGIN_DIR "" CACHE PATH "Specify a custom directory for Ogre plugins (autodetected by default)")
|
||||
|
||||
option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE)
|
||||
|
||||
# Apps and tools
|
||||
option(BUILD_OPENMW "build OpenMW" ON)
|
||||
option(BUILD_BSATOOL "build BSA extractor" ON)
|
||||
option(BUILD_ESMTOOL "build ESM inspector" ON)
|
||||
option(BUILD_LAUNCHER "build Launcher" ON)
|
||||
@ -72,12 +70,16 @@ option(BUILD_OPENCS "build OpenMW Construction Set" ON)
|
||||
option(BUILD_WIZARD "build Installation Wizard" ON)
|
||||
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
|
||||
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest" OFF)
|
||||
option(BUILD_NIFTEST "build nif file tester" OFF)
|
||||
option(BUILD_MYGUI_PLUGIN "build MyGUI plugin for OpenMW resources, to use with MyGUI tools" ON)
|
||||
|
||||
# OS X deployment
|
||||
option(OPENMW_OSX_DEPLOYMENT OFF)
|
||||
|
||||
if (MSVC)
|
||||
option(OPENMW_MP_BUILD "Build OpenMW with /MP flag" OFF)
|
||||
option(OPENMW_LTO_BUILD "Build OpenMW with Link-Time Optimization (Needs ~2GB of RAM)" OFF)
|
||||
endif()
|
||||
|
||||
# Location of morrowind data files
|
||||
if (APPLE)
|
||||
set(MORROWIND_DATA_FILES "./data" CACHE PATH "location of Morrowind data files")
|
||||
@ -118,6 +120,8 @@ else()
|
||||
message(FATAL_ERROR "Install either libswresample (FFmpeg) or libavresample (Libav).")
|
||||
endif()
|
||||
endif()
|
||||
# Required for building the FFmpeg headers
|
||||
add_definitions(-D__STDC_CONSTANT_MACROS)
|
||||
|
||||
set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES})
|
||||
|
||||
@ -140,17 +144,14 @@ endif()
|
||||
if (WIN32)
|
||||
if(NOT MINGW)
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
set(PLATFORM_INCLUDE_DIR "platform")
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
endif(NOT MINGW)
|
||||
|
||||
# Suppress WinMain(), provided by SDL
|
||||
add_definitions(-DSDL_MAIN_HANDLED)
|
||||
else (WIN32)
|
||||
set(PLATFORM_INCLUDE_DIR "")
|
||||
endif (WIN32)
|
||||
if (MSVC10)
|
||||
set(PLATFORM_INCLUDE_DIR "")
|
||||
|
||||
# Get rid of useless crud from windows.h
|
||||
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
|
||||
endif()
|
||||
|
||||
# Dependencies
|
||||
@ -159,11 +160,12 @@ set(DESIRED_QT_VERSION 4 CACHE STRING "The QT version OpenMW should use (4 or 5)
|
||||
message(STATUS "Using Qt${DESIRED_QT_VERSION}")
|
||||
|
||||
if (DESIRED_QT_VERSION MATCHES 4)
|
||||
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork)
|
||||
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork QtOpenGL)
|
||||
else()
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(Qt5Core REQUIRED)
|
||||
find_package(Qt5Network REQUIRED)
|
||||
find_package(Qt5OpenGL REQUIRED)
|
||||
# Instruct CMake to run moc automatically when needed.
|
||||
#set(CMAKE_AUTOMOC ON)
|
||||
endif()
|
||||
@ -188,7 +190,7 @@ if (HAVE_UNORDERED_MAP)
|
||||
endif ()
|
||||
|
||||
|
||||
set(BOOST_COMPONENTS system filesystem program_options thread wave)
|
||||
set(BOOST_COMPONENTS system filesystem program_options thread)
|
||||
if(WIN32)
|
||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale)
|
||||
endif(WIN32)
|
||||
@ -197,10 +199,8 @@ IF(BOOST_STATIC)
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
endif()
|
||||
|
||||
find_package(OGRE REQUIRED)
|
||||
if (${OGRE_VERSION} VERSION_LESS "1.9")
|
||||
message(FATAL_ERROR "OpenMW requires Ogre 1.9 or later, please install the latest stable version from http://ogre3d.org")
|
||||
endif()
|
||||
find_package(OpenSceneGraph 3.2.0 REQUIRED osgDB osgViewer osgGA osgAnimation osgParticle osgQt osgUtil osgFX)
|
||||
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
|
||||
|
||||
find_package(MyGUI REQUIRED)
|
||||
if (${MYGUI_VERSION} VERSION_LESS "3.2.1")
|
||||
@ -212,87 +212,22 @@ find_package(SDL2 REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
find_package(Bullet REQUIRED)
|
||||
|
||||
set(OGRE_PLUGIN_INCLUDE_DIRS "")
|
||||
set(OGRE_STATIC_PLUGINS "")
|
||||
|
||||
macro(add_static_ogre_plugin PLUGIN)
|
||||
if(OGRE_${PLUGIN}_FOUND)
|
||||
# strip RenderSystem_ or Plugin_ prefix from plugin name
|
||||
string(REPLACE "RenderSystem_" "" PLUGIN_TEMP ${PLUGIN})
|
||||
string(REPLACE "Plugin_" "" PLUGIN_NAME ${PLUGIN_TEMP})
|
||||
add_definitions(-DENABLE_PLUGIN_${PLUGIN_NAME})
|
||||
|
||||
list(APPEND OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_${PLUGIN}_INCLUDE_DIRS})
|
||||
list(APPEND OGRE_STATIC_PLUGINS ${OGRE_${PLUGIN}_LIBRARIES})
|
||||
endif(OGRE_${PLUGIN}_FOUND)
|
||||
endmacro(add_static_ogre_plugin)
|
||||
|
||||
if(OGRE_STATIC)
|
||||
# set up OGRE_PLUGIN_INCLUDE_DIRS and OGRE_STATIC_PLUGINS
|
||||
add_static_ogre_plugin(Plugin_OctreeSceneManager)
|
||||
add_static_ogre_plugin(Plugin_ParticleFX)
|
||||
find_package(Cg)
|
||||
if(Cg_FOUND)
|
||||
add_static_ogre_plugin(Plugin_CgProgramManager)
|
||||
list(APPEND OGRE_STATIC_PLUGINS ${Cg_LIBRARIES})
|
||||
endif(Cg_FOUND)
|
||||
|
||||
if (ANDROID)
|
||||
add_static_ogre_plugin(RenderSystem_GLES2)
|
||||
else ()
|
||||
add_static_ogre_plugin(RenderSystem_GL)
|
||||
endif ()
|
||||
|
||||
if(WIN32)
|
||||
add_static_ogre_plugin(RenderSystem_Direct3D9)
|
||||
endif(WIN32)
|
||||
endif(OGRE_STATIC)
|
||||
|
||||
include_directories("." ${LIBS_DIR}
|
||||
include_directories("."
|
||||
SYSTEM
|
||||
${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS}
|
||||
${OGRE_INCLUDE_DIR}/Overlay ${OGRE_Overlay_INCLUDE_DIR}
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR}
|
||||
${PLATFORM_INCLUDE_DIR}
|
||||
${MYGUI_INCLUDE_DIRS}
|
||||
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
||||
${OPENAL_INCLUDE_DIR}
|
||||
${BULLET_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
|
||||
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${MYGUI_LIB_DIR})
|
||||
|
||||
if(MYGUI_STATIC)
|
||||
add_definitions(-DMYGUI_STATIC)
|
||||
endif (MYGUI_STATIC)
|
||||
|
||||
if (APPLE)
|
||||
# List used Ogre plugins
|
||||
SET(USED_OGRE_PLUGINS ${OGRE_RenderSystem_GL_LIBRARY_REL}
|
||||
${OGRE_Plugin_ParticleFX_LIBRARY_REL})
|
||||
|
||||
# Actually we must use OGRE_Plugin_CgProgramManager_FOUND but it's
|
||||
# not reliable and equals TRUE even if there's no Ogre Cg plugin
|
||||
if (Cg_FOUND)
|
||||
set(USED_OGRE_PLUGINS ${USED_OGRE_PLUGINS}
|
||||
${OGRE_Plugin_CgProgramManager_LIBRARY_REL})
|
||||
endif ()
|
||||
|
||||
if (${OGRE_PLUGIN_DIR_REL}})
|
||||
set(OGRE_PLUGINS_REL_FOUND TRUE)
|
||||
endif ()
|
||||
|
||||
if (${OGRE_PLUGIN_DIR_DBG})
|
||||
set(OGRE_PLUGINS_DBG_FOUND TRUE)
|
||||
endif ()
|
||||
|
||||
if (${OGRE_PLUGINS_REL_FOUND})
|
||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
|
||||
else ()
|
||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG})
|
||||
endif ()
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
|
||||
"${APP_BUNDLE_DIR}/Contents/Info.plist")
|
||||
|
||||
@ -303,30 +238,7 @@ endif (APPLE)
|
||||
# Set up DEBUG define
|
||||
set_directory_properties(PROPERTIES COMPILE_DEFINITIONS_DEBUG DEBUG=1)
|
||||
|
||||
# Set up Ogre plugin folder & debug suffix
|
||||
if (APPLE)
|
||||
# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt)
|
||||
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="")
|
||||
else ()
|
||||
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
|
||||
endif()
|
||||
|
||||
if (APPLE AND OPENMW_OSX_DEPLOYMENT)
|
||||
# make it empty so plugin loading code can check this and try to find plugins inside app bundle
|
||||
add_definitions(-DOGRE_PLUGIN_DIR="")
|
||||
else()
|
||||
if (CUSTOM_OGRE_PLUGIN_DIR STREQUAL "")
|
||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL})
|
||||
else()
|
||||
set(OGRE_PLUGIN_DIR ${CUSTOM_OGRE_PLUGIN_DIR})
|
||||
endif()
|
||||
|
||||
add_definitions(-DOGRE_PLUGIN_DIR="${OGRE_PLUGIN_DIR}")
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(files/)
|
||||
add_subdirectory(files/mygui)
|
||||
|
||||
# Specify build paths
|
||||
|
||||
@ -343,9 +255,6 @@ endif (APPLE)
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg")
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/transparency-overrides.cfg
|
||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg")
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
||||
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
||||
|
||||
@ -387,10 +296,14 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
endif(CMAKE_CXX_COMPILER_ID STREQUAL GNU AND "${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||
elseif (MSVC)
|
||||
# Enable link-time code generation globally for all linking
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
if (OPENMW_LTO_BUILD)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
endif()
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /FORCE:MULTIPLE")
|
||||
endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
|
||||
IF(NOT WIN32 AND NOT APPLE)
|
||||
@ -411,7 +324,9 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||
SET(SYSCONFDIR "${GLOBAL_CONFIG_PATH}/openmw" CACHE PATH "Set config dir")
|
||||
|
||||
# Install binaries
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
|
||||
IF(BUILD_OPENMW)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_OPENMW)
|
||||
IF(BUILD_LAUNCHER)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-launcher" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_LAUNCHER)
|
||||
@ -430,19 +345,15 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||
IF(BUILD_OPENCS)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-cs" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_OPENCS)
|
||||
IF(BUILD_NIFTEST)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/niftest" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_NIFTEST)
|
||||
IF(BUILD_WIZARD)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-wizard" DESTINATION "${BINDIR}" )
|
||||
ENDIF(BUILD_WIZARD)
|
||||
if(BUILD_MYGUI_PLUGIN)
|
||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Plugin_MyGUI_OpenMW_Resources.so" DESTINATION "${LIBDIR}" )
|
||||
ENDIF(BUILD_MYGUI_PLUGIN)
|
||||
#if(BUILD_MYGUI_PLUGIN)
|
||||
# INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Plugin_MyGUI_OpenMW_Resources.so" DESTINATION "${LIBDIR}" )
|
||||
#ENDIF(BUILD_MYGUI_PLUGIN)
|
||||
|
||||
# Install licenses
|
||||
INSTALL(FILES "docs/license/DejaVu Font License.txt" DESTINATION "${LICDIR}" )
|
||||
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
||||
|
||||
# Install icon and desktop file
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "${DATAROOTDIR}/applications" COMPONENT "openmw")
|
||||
@ -454,7 +365,6 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||
|
||||
# Install global configuration files
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "${SYSCONFDIR}" RENAME "openmw.cfg" COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
|
||||
|
||||
@ -477,7 +387,6 @@ if(WIN32)
|
||||
"${OpenMW_SOURCE_DIR}/Docs/license/GPL3.txt"
|
||||
"${OpenMW_SOURCE_DIR}/Docs/license/DejaVu Font License.txt"
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
||||
"${OpenMW_BINARY_DIR}/gamecontrollerdb.txt"
|
||||
"${OpenMW_BINARY_DIR}/Release/openmw.exe"
|
||||
DESTINATION ".")
|
||||
@ -503,6 +412,8 @@ if(WIN32)
|
||||
ENDIF(BUILD_MYGUI_PLUGIN)
|
||||
|
||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
|
||||
FILE(GLOB plugin_dir "${OpenMW_BINARY_DIR}/Release/osgPlugins-*")
|
||||
INSTALL(DIRECTORY ${plugin_dir} DESTINATION ".")
|
||||
|
||||
SET(CPACK_GENERATOR "NSIS")
|
||||
SET(CPACK_PACKAGE_NAME "OpenMW")
|
||||
@ -563,31 +474,22 @@ if(WIN32)
|
||||
include(CPack)
|
||||
endif(WIN32)
|
||||
|
||||
# Libs
|
||||
include_directories(libs)
|
||||
add_subdirectory(libs/openengine)
|
||||
|
||||
# Extern
|
||||
add_subdirectory (extern/shiny)
|
||||
add_subdirectory (extern/ogre-ffmpeg-videoplayer)
|
||||
add_subdirectory (extern/osg-ffmpeg-videoplayer)
|
||||
add_subdirectory (extern/oics)
|
||||
add_subdirectory (extern/sdl4ogre)
|
||||
|
||||
# Components
|
||||
add_subdirectory (components)
|
||||
|
||||
# Plugins
|
||||
if (BUILD_MYGUI_PLUGIN)
|
||||
add_subdirectory(plugins/mygui_resource_plugin)
|
||||
endif()
|
||||
|
||||
#Testing
|
||||
if (BUILD_NIFTEST)
|
||||
add_subdirectory(components/nif/tests/)
|
||||
endif(BUILD_NIFTEST)
|
||||
#if (BUILD_MYGUI_PLUGIN)
|
||||
# add_subdirectory(plugins/mygui_resource_plugin)
|
||||
#endif()
|
||||
|
||||
# Apps and tools
|
||||
add_subdirectory( apps/openmw )
|
||||
if (BUILD_OPENMW)
|
||||
add_subdirectory( apps/openmw )
|
||||
endif()
|
||||
|
||||
if (BUILD_BSATOOL)
|
||||
add_subdirectory( apps/bsatool )
|
||||
@ -624,9 +526,9 @@ endif()
|
||||
|
||||
if (WIN32)
|
||||
if (MSVC)
|
||||
if (MULTITHREADED_BUILD)
|
||||
if (OPENMW_MP_BUILD)
|
||||
set( MT_BUILD "/MP")
|
||||
endif (MULTITHREADED_BUILD)
|
||||
endif()
|
||||
|
||||
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
|
||||
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
|
||||
@ -634,20 +536,22 @@ if (WIN32)
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "$(ProjectDir)$(Configuration)" )
|
||||
endforeach( OUTPUTCONFIG )
|
||||
|
||||
if (USE_DEBUG_CONSOLE)
|
||||
if (USE_DEBUG_CONSOLE AND BUILD_OPENMW)
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
|
||||
else()
|
||||
elseif (BUILD_OPENMW)
|
||||
# Turn off debug console, debug output will be written to visual studio output instead
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:WINDOWS")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:WINDOWS")
|
||||
endif()
|
||||
|
||||
# Release builds use the debug console
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_RELEASE "_CONSOLE")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE")
|
||||
if (BUILD_OPENMW)
|
||||
# Release builds use the debug console
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:CONSOLE")
|
||||
set_target_properties(openmw PROPERTIES COMPILE_DEFINITIONS_RELEASE "_CONSOLE")
|
||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:CONSOLE")
|
||||
endif()
|
||||
|
||||
# Play a bit with the warning levels
|
||||
|
||||
@ -656,8 +560,8 @@ if (WIN32)
|
||||
set(WARNINGS_DISABLE
|
||||
# Warnings that aren't enabled normally and don't need to be enabled
|
||||
# They're unneeded and sometimes completely retarded warnings that /Wall enables
|
||||
# Not going to bother commenting them as they tend to warn on every standard library files
|
||||
4061 4263 4264 4266 4350 4371 4514 4548 4571 4610 4619 4623 4625 4626 4628 4640 4668 4710 4711 4820 4826 4917 4946
|
||||
# Not going to bother commenting them as they tend to warn on every standard library file
|
||||
4061 4263 4264 4266 4350 4371 4435 4514 4548 4571 4610 4619 4623 4625 4626 4628 4640 4668 4710 4711 4820 4826 4917 4946
|
||||
|
||||
# Warnings that are thrown on standard libraries and not OpenMW
|
||||
4347 # Non-template function with same name and parameter count as template function
|
||||
@ -669,12 +573,6 @@ if (WIN32)
|
||||
4987 # nonstandard extension used (triggered by setjmp.h)
|
||||
4996 # Function was declared deprecated
|
||||
|
||||
# cause by ogre extensivly
|
||||
4193 # #pragma warning(pop) : no matching '#pragma warning(push)'
|
||||
4251 # class 'XXXX' needs to have dll-interface to be used by clients of class 'YYYY'
|
||||
4275 # non dll-interface struct 'XXXX' used as base for dll-interface class 'YYYY'
|
||||
4315 # undocumented, 'this' pointer for member might not be aligned (OgreMemoryStlAllocator.h)
|
||||
|
||||
# caused by boost
|
||||
4191 # 'type cast' : unsafe conversion (1.56, thread_primitives.hpp, normally off)
|
||||
|
||||
@ -685,6 +583,7 @@ if (WIN32)
|
||||
4127 # Conditional expression is constant
|
||||
4242 # Storing value in a variable of a smaller type, possible loss of data
|
||||
4244 # Storing value of one type in variable of another (size_t in int, for example)
|
||||
4245 # Signed/unsigned mismatch
|
||||
4267 # Conversion from 'size_t' to 'int', possible loss of data
|
||||
4305 # Truncating value (double to float, for example)
|
||||
4309 # Variable overflow, trying to store 128 in a signed char for example
|
||||
@ -700,21 +599,42 @@ if (WIN32)
|
||||
set(WARNINGS "${WARNINGS} /wd${d}")
|
||||
endforeach(d)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNINGS} ${MT_BUILD}")
|
||||
|
||||
# boost::wave has a few issues with signed / unsigned conversions, so we suppress those here
|
||||
set(SHINY_WARNINGS "${WARNINGS} /wd4245")
|
||||
set_target_properties(shiny PROPERTIES COMPILE_FLAGS "${SHINY_WARNINGS} ${MT_BUILD}")
|
||||
|
||||
set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
# oics uses tinyxml, which has an initialized but unused variable
|
||||
set(OICS_WARNINGS "${WARNINGS} /wd4189")
|
||||
set_target_properties(oics PROPERTIES COMPILE_FLAGS "${OICS_WARNINGS} ${MT_BUILD}")
|
||||
set_target_properties(oics PROPERTIES COMPILE_FLAGS "${WARNINGS} /wd4189 ${MT_BUILD}")
|
||||
set_target_properties(osg-ffmpeg-videoplayer PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
|
||||
if (BUILD_BSATOOL)
|
||||
set_target_properties(bsatool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_ESMTOOL)
|
||||
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_ESSIMPORTER)
|
||||
set_target_properties(openmw-essimporter PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_LAUNCHER)
|
||||
set_target_properties(openmw-launcher PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_MWINIIMPORTER)
|
||||
set_target_properties(openmw-iniimporter PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_OPENCS)
|
||||
# QT triggers an informational warning that the object layout may differ when compiled with /vd2
|
||||
set(OPENCS_WARNINGS "${WARNINGS} ${MT_BUILD} /wd4435")
|
||||
set_target_properties(openmw-cs PROPERTIES COMPILE_FLAGS ${OPENCS_WARNINGS})
|
||||
endif (BUILD_OPENCS)
|
||||
set_target_properties(openmw-cs PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_OPENMW)
|
||||
set_target_properties(openmw PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
|
||||
if (BUILD_WIZARD)
|
||||
set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||
endif()
|
||||
endif(MSVC)
|
||||
|
||||
# TODO: At some point release builds should not use the console but rather write to a log file
|
||||
@ -731,7 +651,6 @@ if (APPLE)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
@ -745,90 +664,14 @@ if (APPLE)
|
||||
set(OPENCS_BUNDLE_NAME "OpenMW-CS.app")
|
||||
set(OPENCS_APP "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}")
|
||||
|
||||
set(ABSOLUTE_PLUGINS "")
|
||||
|
||||
foreach (PLUGIN ${USED_OGRE_PLUGINS})
|
||||
get_filename_component(PLUGIN_ABS ${PLUGIN} REALPATH)
|
||||
set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS})
|
||||
endforeach ()
|
||||
|
||||
install(CODE "
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
include(BundleUtilities)
|
||||
" COMPONENT Runtime)
|
||||
|
||||
# installs used plugins in bundle at given path (bundle_path must be relative to ${CMAKE_INSTALL_PREFIX})
|
||||
# and returns list of install paths for all installed plugins
|
||||
function (install_plugins_for_bundle bundle_path plugins_var)
|
||||
set(RELATIVE_PLUGIN_INSTALL_BASE "${bundle_path}/Contents/Frameworks")
|
||||
|
||||
set(PLUGINS "")
|
||||
set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${RELATIVE_PLUGIN_INSTALL_BASE}")
|
||||
|
||||
foreach (PLUGIN ${ABSOLUTE_PLUGINS})
|
||||
get_filename_component(PLUGIN_RELATIVE ${PLUGIN} NAME)
|
||||
get_filename_component(PLUGIN_RELATIVE_WE ${PLUGIN} NAME_WE)
|
||||
|
||||
set(PLUGIN_DYLIB_IN_BUNDLE "${PLUGIN_INSTALL_BASE}/${PLUGIN_RELATIVE}/${PLUGIN_RELATIVE_WE}")
|
||||
set(PLUGINS ${PLUGINS} "${PLUGIN_DYLIB_IN_BUNDLE}")
|
||||
|
||||
install(CODE "
|
||||
copy_resolved_framework_into_bundle(\"${PLUGIN}/${PLUGIN_RELATIVE_WE}\" \"${PLUGIN_DYLIB_IN_BUNDLE}\")
|
||||
" COMPONENT Runtime)
|
||||
endforeach ()
|
||||
|
||||
set(${plugins_var} ${PLUGINS} PARENT_SCOPE)
|
||||
endfunction (install_plugins_for_bundle)
|
||||
|
||||
install_plugins_for_bundle("${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}" PLUGINS)
|
||||
install_plugins_for_bundle("${INSTALL_SUBDIR}/${OPENCS_BUNDLE_NAME}" OPENCS_PLUGINS)
|
||||
|
||||
#For now, search unresolved dependencies only in default system paths, so if you put unresolveable (i.e. with @executable_path in id name) lib or framework somewhere else, it would fail
|
||||
set(DIRS "")
|
||||
|
||||
# Overriding item resolving during installation, it needed if
|
||||
# some library already has been "fixed up", i.e. its id name contains @executable_path,
|
||||
# but library is not embedded in bundle. For example, it's Ogre.framework from Ogre SDK.
|
||||
# Current implementation of GetPrerequsities/BundleUtilities doesn't handle that case.
|
||||
#
|
||||
# Current limitations:
|
||||
# 1. Handles only frameworks, not simple libs
|
||||
INSTALL(CODE "
|
||||
cmake_policy(SET CMP0009 OLD)
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES})
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
set(CMAKE_SYSTEM_FRAMEWORK_PATH ${CMAKE_SYSTEM_FRAMEWORK_PATH})
|
||||
|
||||
set(OPENMW_RESOLVED_ITEMS \"\")
|
||||
|
||||
function(gp_resolve_item_override context item exepath dirs resolved_item_var resolved_var)
|
||||
if(item MATCHES \"@executable_path\" AND NOT \${\${resolved_var}})
|
||||
if (item MATCHES \"Frameworks\") # if it is a framework
|
||||
# get last segment of path
|
||||
get_filename_component(fname \"\${item}\" NAME_WE)
|
||||
find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} \${CMAKE_SYSTEM_FRAMEWORK_PATH})
|
||||
if (ri)
|
||||
string(REGEX REPLACE \"^.*/Frameworks/.*\\\\.framework\" \"\" item_part \${item})
|
||||
set(ri \"\${ri}\${item_part}\")
|
||||
set(\${resolved_item_var} \${ri} PARENT_SCOPE)
|
||||
set(\${resolved_var} 1 PARENT_SCOPE)
|
||||
endif()
|
||||
else()
|
||||
# code path for standard (non-framework) libs (ogre & qt pugins)
|
||||
get_filename_component(fname \"\${item}\" NAME_WE)
|
||||
string(REGEX REPLACE \"^lib\" \"\" fname \${fname})
|
||||
find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} /usr/lib /usr/local/lib)
|
||||
if (ri)
|
||||
set(\${resolved_item_var} \${ri} PARENT_SCOPE)
|
||||
set(\${resolved_var} 1 PARENT_SCOPE)
|
||||
endif ()
|
||||
endif()
|
||||
endif()
|
||||
endfunction(gp_resolve_item_override)
|
||||
|
||||
fixup_bundle(\"${OPENMW_APP}\" \"${PLUGINS}\" \"${DIRS}\")
|
||||
fixup_bundle(\"${OPENCS_APP}\" \"${OPENCS_PLUGINS}\" \"${DIRS}\")
|
||||
" COMPONENT Runtime)
|
||||
include(CPack)
|
||||
endif (APPLE)
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
|
||||
@ -237,12 +238,14 @@ int extract(Bsa::BSAFile& bsa, Arguments& info)
|
||||
}
|
||||
|
||||
// Get a stream for the file to extract
|
||||
Ogre::DataStreamPtr data = bsa.getFile(archivePath.c_str());
|
||||
Files::IStreamPtr stream = bsa.getFile(archivePath.c_str());
|
||||
|
||||
bfs::ofstream out(target, std::ios::binary);
|
||||
|
||||
// Write the file to disk
|
||||
std::cout << "Extracting " << info.extractfile << " to " << target << std::endl;
|
||||
out.write(data->getAsString().c_str(), data->size());
|
||||
|
||||
out << stream->rdbuf();
|
||||
out.close();
|
||||
|
||||
return 0;
|
||||
@ -276,12 +279,12 @@ int extractAll(Bsa::BSAFile& bsa, Arguments& info)
|
||||
|
||||
// Get a stream for the file to extract
|
||||
// (inefficient because getFile iter on the list again)
|
||||
Ogre::DataStreamPtr data = bsa.getFile(archivePath);
|
||||
Files::IStreamPtr data = bsa.getFile(archivePath);
|
||||
bfs::ofstream out(target, std::ios::binary);
|
||||
|
||||
// Write the file to disk
|
||||
std::cout << "Extracting " << target << std::endl;
|
||||
out.write(data->getAsString().c_str(), data->size());
|
||||
out << data->rdbuf();
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
@ -284,7 +285,7 @@ void printRaw(ESM::ESMReader &esm)
|
||||
esm.getRecHeader();
|
||||
while(esm.hasMoreSubs())
|
||||
{
|
||||
uint64_t offs = esm.getOffset();
|
||||
size_t offs = esm.getFileOffset();
|
||||
esm.getSubName();
|
||||
esm.skipHSub();
|
||||
n = esm.retSubName();
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <OgreImage.h>
|
||||
#include <OgreColourValue.h>
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include <components/esm/creaturestate.hpp>
|
||||
#include <components/esm/containerstate.hpp>
|
||||
@ -15,12 +14,14 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
void convertImage(char* data, int size, int width, int height, Ogre::PixelFormat pf, const std::string& out)
|
||||
void convertImage(char* data, int size, int width, int height, GLenum pf, const std::string& out)
|
||||
{
|
||||
Ogre::Image screenshot;
|
||||
Ogre::DataStreamPtr stream (new Ogre::MemoryDataStream(data, size));
|
||||
screenshot.loadRawData(stream, width, height, 1, pf);
|
||||
screenshot.save(out);
|
||||
osg::ref_ptr<osg::Image> image (new osg::Image);
|
||||
image->allocateImage(width, height, 1, pf, GL_UNSIGNED_BYTE);
|
||||
memcpy(image->data(), data, size);
|
||||
image->flipVertical();
|
||||
|
||||
osgDB::writeImageFile(*image, out);
|
||||
}
|
||||
|
||||
|
||||
@ -71,17 +72,20 @@ namespace ESSImport
|
||||
data.resize(esm.getSubSize());
|
||||
esm.getExact(&data[0], data.size());
|
||||
|
||||
Ogre::DataStreamPtr stream (new Ogre::MemoryDataStream(&data[0], data.size()));
|
||||
mGlobalMapImage.loadRawData(stream, maph.size, maph.size, 1, Ogre::PF_BYTE_RGB);
|
||||
mGlobalMapImage = new osg::Image;
|
||||
mGlobalMapImage->allocateImage(maph.size, maph.size, 1, GL_RGB, GL_UNSIGNED_BYTE);
|
||||
memcpy(mGlobalMapImage->data(), &data[0], data.size());
|
||||
|
||||
// to match openmw size
|
||||
mGlobalMapImage.resize(maph.size*2, maph.size*2, Ogre::Image::FILTER_BILINEAR);
|
||||
// FIXME: filtering?
|
||||
mGlobalMapImage->scaleImage(maph.size*2, maph.size*2, 1, GL_UNSIGNED_BYTE);
|
||||
}
|
||||
|
||||
void ConvertFMAP::write(ESM::ESMWriter &esm)
|
||||
{
|
||||
int numcells = mGlobalMapImage.getWidth() / 18; // NB truncating, doesn't divide perfectly
|
||||
int numcells = mGlobalMapImage->s() / 18; // NB truncating, doesn't divide perfectly
|
||||
// with the 512x512 map the game has by default
|
||||
int cellSize = mGlobalMapImage.getWidth()/numcells;
|
||||
int cellSize = mGlobalMapImage->s()/numcells;
|
||||
|
||||
// Note the upper left corner of the (0,0) cell should be at (width/2, height/2)
|
||||
|
||||
@ -90,12 +94,14 @@ namespace ESSImport
|
||||
mContext->mGlobalMapState.mBounds.mMinY = -(numcells-1)/2;
|
||||
mContext->mGlobalMapState.mBounds.mMaxY = numcells/2;
|
||||
|
||||
Ogre::Image image2;
|
||||
std::vector<Ogre::uint8> data;
|
||||
osg::ref_ptr<osg::Image> image2 (new osg::Image);
|
||||
int width = cellSize*numcells;
|
||||
int height = cellSize*numcells;
|
||||
std::vector<unsigned char> data;
|
||||
data.resize(width*height*4, 0);
|
||||
image2.loadDynamicImage(&data[0], width, height, Ogre::PF_BYTE_RGBA);
|
||||
|
||||
image2->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
memcpy(image2->data(), &data[0], data.size());
|
||||
|
||||
for (std::set<std::pair<int, int> >::const_iterator it = mContext->mExploredCells.begin(); it != mContext->mExploredCells.end(); ++it)
|
||||
{
|
||||
@ -108,8 +114,8 @@ namespace ESSImport
|
||||
continue;
|
||||
}
|
||||
|
||||
int imageLeftSrc = mGlobalMapImage.getWidth()/2;
|
||||
int imageTopSrc = mGlobalMapImage.getHeight()/2;
|
||||
int imageLeftSrc = mGlobalMapImage->s()/2;
|
||||
int imageTopSrc = mGlobalMapImage->t()/2;
|
||||
imageLeftSrc += it->first * cellSize;
|
||||
imageTopSrc -= it->second * cellSize;
|
||||
int imageLeftDst = width/2;
|
||||
@ -118,13 +124,31 @@ namespace ESSImport
|
||||
imageTopDst -= it->second * cellSize;
|
||||
for (int x=0; x<cellSize; ++x)
|
||||
for (int y=0; y<cellSize; ++y)
|
||||
image2.setColourAt(mGlobalMapImage.getColourAt(imageLeftSrc+x, imageTopSrc+y, 0)
|
||||
, imageLeftDst+x, imageTopDst+y, 0);
|
||||
{
|
||||
unsigned int col = *(unsigned int*)mGlobalMapImage->data(imageLeftSrc+x, imageTopSrc+y, 0);
|
||||
*(unsigned int*)image2->data(imageLeftDst+x, imageTopDst+y, 0) = col;
|
||||
}
|
||||
}
|
||||
|
||||
Ogre::DataStreamPtr encoded = image2.encode("png");
|
||||
mContext->mGlobalMapState.mImageData.resize(encoded->size());
|
||||
encoded->read(&mContext->mGlobalMapState.mImageData[0], encoded->size());
|
||||
std::stringstream ostream;
|
||||
osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png");
|
||||
if (!readerwriter)
|
||||
{
|
||||
std::cerr << "can't write global map image, no png readerwriter found" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
image2->flipVertical();
|
||||
|
||||
osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*image2, ostream);
|
||||
if (!result.success())
|
||||
{
|
||||
std::cerr << "can't write global map image: " << result.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string outData = ostream.str();
|
||||
mContext->mGlobalMapState.mImageData = std::vector<char>(outData.begin(), outData.end());
|
||||
|
||||
esm.startRecord(ESM::REC_GMAP);
|
||||
mContext->mGlobalMapState.save(esm);
|
||||
@ -194,7 +218,7 @@ namespace ESSImport
|
||||
std::ostringstream filename;
|
||||
filename << "fog_" << cell.mData.mX << "_" << cell.mData.mY << ".tga";
|
||||
|
||||
convertImage((char*)&newcell.mFogOfWar[0], newcell.mFogOfWar.size()*4, 16, 16, Ogre::PF_BYTE_RGBA, filename.str());
|
||||
convertImage((char*)&newcell.mFogOfWar[0], newcell.mFogOfWar.size()*4, 16, 16, GL_RGBA, filename.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
#ifndef OPENMW_ESSIMPORT_CONVERTER_H
|
||||
#define OPENMW_ESSIMPORT_CONVERTER_H
|
||||
|
||||
#include <OgreImage.h>
|
||||
#include <limits>
|
||||
|
||||
#include <osg/Image>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/esmwriter.hpp>
|
||||
@ -311,7 +314,7 @@ public:
|
||||
virtual void write(ESM::ESMWriter &esm);
|
||||
|
||||
private:
|
||||
Ogre::Image mGlobalMapImage;
|
||||
osg::ref_ptr<osg::Image> mGlobalMapImage;
|
||||
};
|
||||
|
||||
class ConvertCell : public Converter
|
||||
|
@ -1,7 +1,11 @@
|
||||
#include "importer.hpp"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osg/ImageUtils>
|
||||
|
||||
#include <components/esm/esmreader.hpp>
|
||||
#include <components/esm/esmwriter.hpp>
|
||||
@ -32,13 +36,48 @@ namespace
|
||||
|
||||
void writeScreenshot(const ESM::Header& fileHeader, ESM::SavedGame& out)
|
||||
{
|
||||
Ogre::Image screenshot;
|
||||
std::vector<unsigned char> screenshotData = fileHeader.mSCRS; // MemoryDataStream doesn't work with const data :(
|
||||
Ogre::DataStreamPtr screenshotStream (new Ogre::MemoryDataStream(&screenshotData[0], screenshotData.size()));
|
||||
screenshot.loadRawData(screenshotStream, 128, 128, 1, Ogre::PF_BYTE_BGRA);
|
||||
Ogre::DataStreamPtr encoded = screenshot.encode("jpg");
|
||||
out.mScreenshot.resize(encoded->size());
|
||||
encoded->read(&out.mScreenshot[0], encoded->size());
|
||||
if (fileHeader.mSCRS.size() != 128*128*4)
|
||||
{
|
||||
std::cerr << "unexpected screenshot size " << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Image> image (new osg::Image);
|
||||
image->allocateImage(128, 128, 1, GL_RGB, GL_UNSIGNED_BYTE);
|
||||
|
||||
// need to convert pixel format from BGRA to RGB as the jpg readerwriter doesn't support it otherwise
|
||||
std::vector<unsigned char>::const_iterator it = fileHeader.mSCRS.begin();
|
||||
for (int y=0; y<128; ++y)
|
||||
{
|
||||
for (int x=0; x<128; ++x)
|
||||
{
|
||||
*(image->data(x,y)+2) = *it++;
|
||||
*(image->data(x,y)+1) = *it++;
|
||||
*image->data(x,y) = *it++;
|
||||
it++; // skip alpha
|
||||
}
|
||||
}
|
||||
|
||||
image->flipVertical();
|
||||
|
||||
std::stringstream ostream;
|
||||
|
||||
osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("jpg");
|
||||
if (!readerwriter)
|
||||
{
|
||||
std::cerr << "can't write screenshot: no jpg readerwriter found" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*image, ostream);
|
||||
if (!result.success())
|
||||
{
|
||||
std::cerr << "can't write screenshot: " << result.message() << " code " << result.status() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string data = ostream.str();
|
||||
out.mScreenshot = std::vector<char>(data.begin(), data.end());
|
||||
}
|
||||
|
||||
}
|
||||
@ -203,10 +242,6 @@ namespace ESSImport
|
||||
|
||||
void Importer::run()
|
||||
{
|
||||
// construct Ogre::Root to gain access to image codecs
|
||||
Ogre::LogManager logman;
|
||||
Ogre::Root root;
|
||||
|
||||
ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(mEncoding));
|
||||
ESM::ESMReader esm;
|
||||
esm.open(mEssFile);
|
||||
|
@ -92,8 +92,6 @@ add_executable(openmw-launcher
|
||||
)
|
||||
|
||||
target_link_libraries(openmw-launcher
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
${SDL2_LIBRARY_ONLY}
|
||||
components
|
||||
)
|
||||
|
@ -12,9 +12,6 @@
|
||||
|
||||
#include <SDL_video.h>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderSystem.h>
|
||||
|
||||
#include <boost/math/common_factor.hpp>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
@ -37,10 +34,6 @@ QString getAspect(int x, int y)
|
||||
|
||||
Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, mOgre(NULL)
|
||||
, mSelectedRenderSystem(NULL)
|
||||
, mOpenGLRenderSystem(NULL)
|
||||
, mDirect3DRenderSystem(NULL)
|
||||
, mCfgMgr(cfg)
|
||||
, mGraphicsSettings(graphicsSetting)
|
||||
{
|
||||
@ -52,79 +45,12 @@ Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsS
|
||||
customWidthSpinBox->setMaximum(res.width());
|
||||
customHeightSpinBox->setMaximum(res.height());
|
||||
|
||||
connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
||||
connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int)));
|
||||
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool)));
|
||||
connect(screenComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(screenChanged(int)));
|
||||
|
||||
}
|
||||
|
||||
bool Launcher::GraphicsPage::setupOgre()
|
||||
{
|
||||
try
|
||||
{
|
||||
mOgre = mOgreInit.init(mCfgMgr.getLogPath().string() + "/launcherOgre.log");
|
||||
}
|
||||
catch(Ogre::Exception &ex)
|
||||
{
|
||||
QString ogreError = QString::fromUtf8(ex.getFullDescription().c_str());
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("Error creating Ogre::Root");
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Failed to create the Ogre::Root object</b><br><br> \
|
||||
Press \"Show Details...\" for more information.<br>"));
|
||||
msgBox.setDetailedText(ogreError);
|
||||
msgBox.exec();
|
||||
|
||||
qCritical("Error creating Ogre::Root, the error reported was:\n %s", qPrintable(ogreError));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the available renderers and put them in the combobox
|
||||
const Ogre::RenderSystemList &renderers = mOgre->getAvailableRenderers();
|
||||
|
||||
for (Ogre::RenderSystemList::const_iterator r = renderers.begin(); r != renderers.end(); ++r) {
|
||||
mSelectedRenderSystem = *r;
|
||||
rendererComboBox->addItem((*r)->getName().c_str());
|
||||
}
|
||||
|
||||
QString openGLName = QString("OpenGL Rendering Subsystem");
|
||||
QString direct3DName = QString("Direct3D9 Rendering Subsystem");
|
||||
|
||||
// Create separate rendersystems
|
||||
mOpenGLRenderSystem = mOgre->getRenderSystemByName(openGLName.toStdString());
|
||||
mDirect3DRenderSystem = mOgre->getRenderSystemByName(direct3DName.toStdString());
|
||||
|
||||
if (!mOpenGLRenderSystem && !mDirect3DRenderSystem) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Error creating renderer"));
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>Could not select a valid render system</b><br><br> \
|
||||
Please make sure Ogre plugins were installed correctly.<br>"));
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now fill the GUI elements
|
||||
int index = rendererComboBox->findText(mGraphicsSettings.value(QString("Video/render system")));
|
||||
if ( index != -1) {
|
||||
rendererComboBox->setCurrentIndex(index);
|
||||
} else {
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
rendererComboBox->setCurrentIndex(rendererComboBox->findText(direct3DName));
|
||||
#else
|
||||
rendererComboBox->setCurrentIndex(rendererComboBox->findText(openGLName));
|
||||
#endif
|
||||
}
|
||||
|
||||
antiAliasingComboBox->clear();
|
||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Launcher::GraphicsPage::setupSDL()
|
||||
{
|
||||
int displays = SDL_GetNumVideoDisplays();
|
||||
@ -153,8 +79,6 @@ bool Launcher::GraphicsPage::loadSettings()
|
||||
{
|
||||
if (!setupSDL())
|
||||
return false;
|
||||
if (!mOgre && !setupOgre())
|
||||
return false;
|
||||
|
||||
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
||||
vSyncCheckBox->setCheckState(Qt::Checked);
|
||||
@ -203,7 +127,6 @@ void Launcher::GraphicsPage::saveSettings()
|
||||
: mGraphicsSettings.setValue(QString("Video/window border"), QString("false"));
|
||||
|
||||
mGraphicsSettings.setValue(QString("Video/antialiasing"), antiAliasingComboBox->currentText());
|
||||
mGraphicsSettings.setValue(QString("Video/render system"), rendererComboBox->currentText());
|
||||
|
||||
|
||||
if (standardRadioButton->isChecked()) {
|
||||
@ -221,39 +144,6 @@ void Launcher::GraphicsPage::saveSettings()
|
||||
mGraphicsSettings.setValue(QString("Video/screen"), QString::number(screenComboBox->currentIndex()));
|
||||
}
|
||||
|
||||
QStringList Launcher::GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer)
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
uint row = 0;
|
||||
Ogre::ConfigOptionMap options = renderer->getConfigOptions();
|
||||
|
||||
for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); ++i, ++row)
|
||||
{
|
||||
Ogre::StringVector::iterator opt_it;
|
||||
uint idx = 0;
|
||||
|
||||
for (opt_it = i->second.possibleValues.begin();
|
||||
opt_it != i->second.possibleValues.end(); ++opt_it, ++idx)
|
||||
{
|
||||
if (strcmp (key.toStdString().c_str(), i->first.c_str()) == 0) {
|
||||
result << ((key == "FSAA") ? QString("MSAA ") : QString("")) + QString::fromUtf8((*opt_it).c_str()).simplified();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort ascending
|
||||
qSort(result.begin(), result.end(), naturalSortLessThanCI);
|
||||
|
||||
// Replace the zero option with Off
|
||||
int index = result.indexOf("MSAA 0");
|
||||
|
||||
if (index != -1)
|
||||
result.replace(index, tr("Off"));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen)
|
||||
{
|
||||
QStringList result;
|
||||
@ -316,15 +206,6 @@ QRect Launcher::GraphicsPage::getMaximumResolution()
|
||||
return max;
|
||||
}
|
||||
|
||||
void Launcher::GraphicsPage::rendererChanged(const QString &renderer)
|
||||
{
|
||||
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
||||
|
||||
antiAliasingComboBox->clear();
|
||||
|
||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
}
|
||||
|
||||
void Launcher::GraphicsPage::screenChanged(int screen)
|
||||
{
|
||||
if (screen >= 0) {
|
||||
|
@ -3,12 +3,8 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <components/ogreinit/ogreinit.hpp>
|
||||
|
||||
#include "ui_graphicspage.h"
|
||||
|
||||
namespace Ogre { class Root; class RenderSystem; }
|
||||
|
||||
namespace Files { struct ConfigurationManager; }
|
||||
|
||||
namespace Launcher
|
||||
@ -26,7 +22,6 @@ namespace Launcher
|
||||
bool loadSettings();
|
||||
|
||||
public slots:
|
||||
void rendererChanged(const QString &renderer);
|
||||
void screenChanged(int screen);
|
||||
|
||||
private slots:
|
||||
@ -34,20 +29,12 @@ namespace Launcher
|
||||
void slotStandardToggled(bool checked);
|
||||
|
||||
private:
|
||||
OgreInit::OgreInit mOgreInit;
|
||||
Ogre::Root *mOgre;
|
||||
Ogre::RenderSystem *mSelectedRenderSystem;
|
||||
Ogre::RenderSystem *mOpenGLRenderSystem;
|
||||
Ogre::RenderSystem *mDirect3DRenderSystem;
|
||||
|
||||
Files::ConfigurationManager &mCfgMgr;
|
||||
GraphicsSettings &mGraphicsSettings;
|
||||
|
||||
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
||||
QStringList getAvailableResolutions(int screen);
|
||||
QRect getMaximumResolution();
|
||||
|
||||
bool setupOgre();
|
||||
bool setupSDL();
|
||||
};
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ bool Launcher::MainDialog::setup()
|
||||
// Now create the pages as they need the settings
|
||||
createPages();
|
||||
|
||||
// Call this so we can exit on Ogre/SDL errors before mainwindow is shown
|
||||
// Call this so we can exit on SDL errors before mainwindow is shown
|
||||
if (!mGraphicsPage->loadSettings())
|
||||
return false;
|
||||
|
||||
|
@ -69,7 +69,7 @@ opencs_units (view/world
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
scripthighlighter idvalidator dialoguecreator physicssystem idcompletiondelegate
|
||||
scripthighlighter idvalidator dialoguecreator idcompletiondelegate
|
||||
colordelegate dragdroputils
|
||||
)
|
||||
|
||||
@ -84,8 +84,8 @@ opencs_units (view/render
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
||||
lightingbright object cell terrainstorage textoverlay overlaymask overlaysystem mousestate
|
||||
lighting lightingday lightingnight
|
||||
lightingbright object cell terrainstorage
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (view/render
|
||||
@ -199,16 +199,10 @@ if(APPLE)
|
||||
endif(APPLE)
|
||||
|
||||
target_link_libraries(openmw-cs
|
||||
${OENGINE_LIBRARY}
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_Overlay_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
${SHINY_LIBRARIES}
|
||||
${OPENSCENEGRAPH_LIBRARIES}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||
${Boost_WAVE_LIBRARY}
|
||||
${BULLET_LIBRARIES}
|
||||
components
|
||||
)
|
||||
|
||||
@ -216,14 +210,14 @@ if (DESIRED_QT_VERSION MATCHES 4)
|
||||
target_link_libraries(openmw-cs
|
||||
${QT_QTGUI_LIBRARY}
|
||||
${QT_QTCORE_LIBRARY}
|
||||
${QT_QTNETWORK_LIBRARY})
|
||||
${QT_QTNETWORK_LIBRARY}
|
||||
${QT_QTOPENGL_LIBRARY})
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(openmw-cs ${QT_QTMAIN_LIBRARY})
|
||||
endif()
|
||||
|
||||
else()
|
||||
qt5_use_modules(openmw-cs Widgets Core Network)
|
||||
qt5_use_modules(openmw-cs Widgets Core Network OpenGL)
|
||||
if (WIN32)
|
||||
target_link_libraries(Qt5::WinMain)
|
||||
endif()
|
||||
|
@ -1,28 +1,25 @@
|
||||
|
||||
#include "editor.hpp"
|
||||
|
||||
#include <openengine/bullet/BulletShapeLoader.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
#include <components/vfs/manager.hpp>
|
||||
#include <components/vfs/registerarchives.hpp>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
||||
|
||||
#include <components/ogreinit/ogreinit.hpp>
|
||||
#include <components/nifogre/ogrenifloader.hpp>
|
||||
#include <components/bsa/resources.hpp>
|
||||
#include <components/nifosg/nifloader.hpp>
|
||||
|
||||
#include "model/doc/document.hpp"
|
||||
#include "model/world/data.hpp"
|
||||
|
||||
CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||
: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr),
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
CS::Editor::Editor ()
|
||||
: mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr),
|
||||
mViewManager (mDocumentManager), mPid(""),
|
||||
mLock(), mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
|
||||
{
|
||||
@ -33,16 +30,13 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||
CSMSettings::UserSettings::instance().loadSettings ("opencs.ini");
|
||||
mSettings.setModel (CSMSettings::UserSettings::instance());
|
||||
|
||||
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
||||
NifOsg::Loader::setShowMarkers(true);
|
||||
|
||||
NifOgre::Loader::setShowMarkers(true);
|
||||
mVFS.reset(new VFS::Manager(mFsStrict));
|
||||
|
||||
mOverlaySystem.reset (new CSVRender::OverlaySystem);
|
||||
VFS::registerArchives(mVFS.get(), Files::Collections(config.first, !mFsStrict), config.second, true);
|
||||
|
||||
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
||||
mFsStrict);
|
||||
|
||||
mDocumentManager.listResources();
|
||||
mDocumentManager.setVFS(mVFS.get());
|
||||
|
||||
mNewGame.setLocalData (mLocal);
|
||||
mFileDialog.setLocalData (mLocal);
|
||||
@ -81,9 +75,6 @@ CS::Editor::~Editor ()
|
||||
if(mServer && boost::filesystem::exists(mPid))
|
||||
static_cast<void> ( // silence coverity warning
|
||||
remove(mPid.string().c_str())); // ignore any error
|
||||
|
||||
// cleanup global resources used by OEngine
|
||||
delete OEngine::Physic::BulletShapeManager::getSingletonPtr();
|
||||
}
|
||||
|
||||
void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
||||
@ -364,114 +355,6 @@ int CS::Editor::run()
|
||||
return QApplication::exec();
|
||||
}
|
||||
|
||||
std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
|
||||
{
|
||||
std::string renderer =
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
"Direct3D9 Rendering Subsystem";
|
||||
#else
|
||||
"OpenGL Rendering Subsystem";
|
||||
#endif
|
||||
std::string renderSystem = mUserSettings.setting("Video/render system", renderer.c_str()).toStdString();
|
||||
|
||||
Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName(renderSystem));
|
||||
|
||||
// Initialise Ogre::OverlaySystem after Ogre::Root but before initialisation
|
||||
mOverlaySystem.get();
|
||||
|
||||
Ogre::Root::getSingleton().initialise(false);
|
||||
|
||||
// Create a hidden background window to keep resources
|
||||
Ogre::NameValuePairList params;
|
||||
params.insert(std::make_pair("title", ""));
|
||||
|
||||
std::string antialiasing = mUserSettings.settingValue("Video/antialiasing").toStdString();
|
||||
if(antialiasing == "MSAA 16") antialiasing = "16";
|
||||
else if(antialiasing == "MSAA 8") antialiasing = "8";
|
||||
else if(antialiasing == "MSAA 4") antialiasing = "4";
|
||||
else if(antialiasing == "MSAA 2") antialiasing = "2";
|
||||
else antialiasing = "0";
|
||||
params.insert(std::make_pair("FSAA", antialiasing));
|
||||
|
||||
params.insert(std::make_pair("vsync", "false"));
|
||||
params.insert(std::make_pair("hidden", "true"));
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
params.insert(std::make_pair("macAPI", "cocoa"));
|
||||
#endif
|
||||
// NOTE: fullscreen mode not supported (doesn't really make sense for opencs)
|
||||
Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms);
|
||||
hiddenWindow->setActive(false);
|
||||
|
||||
sh::OgrePlatform* platform =
|
||||
new sh::OgrePlatform ("General", (mResources / "materials").string());
|
||||
|
||||
// for font used in overlays
|
||||
Ogre::Root::getSingleton().addResourceLocation ((mResources / "mygui").string(),
|
||||
"FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
|
||||
|
||||
if (!boost::filesystem::exists (mCfgMgr.getCachePath()))
|
||||
boost::filesystem::create_directories (mCfgMgr.getCachePath());
|
||||
|
||||
platform->setCacheFolder (mCfgMgr.getCachePath().string());
|
||||
|
||||
std::auto_ptr<sh::Factory> factory (new sh::Factory (platform));
|
||||
|
||||
QString shLang = mUserSettings.settingValue("General/shader mode");
|
||||
QString rend = renderSystem.c_str();
|
||||
bool openGL = rend.contains(QRegExp("^OpenGL", Qt::CaseInsensitive));
|
||||
bool glES = rend.contains(QRegExp("^OpenGL ES", Qt::CaseInsensitive));
|
||||
|
||||
// force shader language based on render system
|
||||
if(shLang == ""
|
||||
|| (openGL && shLang == "hlsl")
|
||||
|| (!openGL && shLang == "glsl")
|
||||
|| (glES && shLang != "glsles"))
|
||||
{
|
||||
shLang = openGL ? (glES ? "glsles" : "glsl") : "hlsl";
|
||||
//no group means "General" group in the "ini" file standard
|
||||
mUserSettings.setDefinitions("shader mode", (QStringList() << shLang));
|
||||
}
|
||||
enum sh::Language lang;
|
||||
if(shLang == "glsl") lang = sh::Language_GLSL;
|
||||
else if(shLang == "glsles") lang = sh::Language_GLSLES;
|
||||
else if(shLang == "hlsl") lang = sh::Language_HLSL;
|
||||
else lang = sh::Language_CG;
|
||||
|
||||
factory->setCurrentLanguage (lang);
|
||||
factory->setWriteSourceCache (true);
|
||||
factory->setReadSourceCache (true);
|
||||
factory->setReadMicrocodeCache (true);
|
||||
factory->setWriteMicrocodeCache (true);
|
||||
|
||||
factory->loadAllFiles();
|
||||
|
||||
bool shaders = mUserSettings.setting("3d-render/shaders", QString("true")) == "true" ? true : false;
|
||||
sh::Factory::getInstance ().setShadersEnabled (shaders);
|
||||
|
||||
std::string fog = mUserSettings.setting("Shader/fog", QString("true")).toStdString();
|
||||
sh::Factory::getInstance().setGlobalSetting ("fog", fog);
|
||||
|
||||
|
||||
std::string shadows = mUserSettings.setting("Shader/shadows", QString("false")).toStdString();
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows", shadows);
|
||||
|
||||
std::string shadows_pssm = mUserSettings.setting("Shader/shadows_pssm", QString("false")).toStdString();
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", shadows_pssm);
|
||||
|
||||
std::string render_refraction = mUserSettings.setting("Shader/render_refraction", QString("false")).toStdString();
|
||||
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", render_refraction);
|
||||
|
||||
// internal setting - may be switched on or off by the use of shader configurations
|
||||
sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
|
||||
|
||||
std::string num_lights = mUserSettings.setting("3d-render-adv/num_lights", QString("8")).toStdString();
|
||||
sh::Factory::getInstance ().setGlobalSetting ("num_lights", num_lights);
|
||||
|
||||
/// \todo add more configurable shiny settings
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
void CS::Editor::documentAdded (CSMDoc::Document *document)
|
||||
{
|
||||
mViewManager.addView (document);
|
||||
|
@ -11,16 +11,12 @@
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
|
||||
#include <components/files/multidircollection.hpp>
|
||||
|
||||
#include <components/nifcache/nifcache.hpp>
|
||||
|
||||
#include "model/settings/usersettings.hpp"
|
||||
#include "model/doc/documentmanager.hpp"
|
||||
|
||||
@ -30,11 +26,10 @@
|
||||
#include "view/doc/newgame.hpp"
|
||||
|
||||
#include "view/settings/dialog.hpp"
|
||||
#include "view/render/overlaysystem.hpp"
|
||||
|
||||
namespace OgreInit
|
||||
namespace VFS
|
||||
{
|
||||
class OgreInit;
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace CS
|
||||
@ -43,10 +38,11 @@ namespace CS
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Nif::Cache mNifCache;
|
||||
// FIXME: should be moved to document, so we can have different resources for each opened project
|
||||
std::auto_ptr<VFS::Manager> mVFS;
|
||||
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
CSMSettings::UserSettings mUserSettings;
|
||||
std::auto_ptr<CSVRender::OverlaySystem> mOverlaySystem;
|
||||
CSMDoc::DocumentManager mDocumentManager;
|
||||
CSVDoc::ViewManager mViewManager;
|
||||
CSVDoc::StartupDialogue mStartup;
|
||||
@ -71,7 +67,7 @@ namespace CS
|
||||
|
||||
public:
|
||||
|
||||
Editor (OgreInit::OgreInit& ogreInit);
|
||||
Editor ();
|
||||
~Editor ();
|
||||
|
||||
bool makeIPCServer();
|
||||
@ -80,9 +76,6 @@ namespace CS
|
||||
int run();
|
||||
///< \return error status
|
||||
|
||||
std::auto_ptr<sh::Factory> setupGraphics();
|
||||
///< The returned factory must persist at least as long as *this.
|
||||
|
||||
private slots:
|
||||
|
||||
void createGame();
|
||||
|
@ -9,10 +9,6 @@
|
||||
#include <QIcon>
|
||||
#include <QMetaType>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
#include <components/ogreinit/ogreinit.hpp>
|
||||
|
||||
#include "model/doc/messages.hpp"
|
||||
|
||||
#include "model/world/universalid.hpp"
|
||||
@ -50,16 +46,15 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// To allow background thread drawing in OSG
|
||||
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
|
||||
|
||||
Q_INIT_RESOURCE (resources);
|
||||
|
||||
qRegisterMetaType<std::string> ("std::string");
|
||||
qRegisterMetaType<CSMWorld::UniversalId> ("CSMWorld::UniversalId");
|
||||
qRegisterMetaType<CSMDoc::Message> ("CSMDoc::Message");
|
||||
|
||||
OgreInit::OgreInit ogreInit;
|
||||
|
||||
std::auto_ptr<sh::Factory> shinyFactory;
|
||||
|
||||
Application application (argc, argv);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
@ -83,15 +78,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
application.setWindowIcon (QIcon (":./openmw-cs.png"));
|
||||
|
||||
CS::Editor editor (ogreInit);
|
||||
CS::Editor editor;
|
||||
|
||||
if(!editor.makeIPCServer())
|
||||
{
|
||||
editor.connectToIPCServer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
shinyFactory = editor.setupGraphics();
|
||||
return editor.run();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
@ -9,8 +10,6 @@
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
|
||||
#include "../../view/world/physicssystem.hpp"
|
||||
|
||||
void CSMDoc::Document::addGmsts()
|
||||
{
|
||||
static const char *gmstFloats[] =
|
||||
@ -2245,20 +2244,19 @@ void CSMDoc::Document::createBase()
|
||||
}
|
||||
}
|
||||
|
||||
CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
||||
CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration,
|
||||
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
||||
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
||||
const std::vector<std::string>& blacklistedScripts)
|
||||
: mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
|
||||
: mVFS(vfs), mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
|
||||
mTools (*this),
|
||||
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
||||
(savePath.filename().string() + ".project")),
|
||||
mSavingOperation (*this, mProjectPath, encoding),
|
||||
mSaving (&mSavingOperation),
|
||||
mResDir(resDir),
|
||||
mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()),
|
||||
mIdCompletionManager(mData)
|
||||
mRunner (mProjectPath), mIdCompletionManager(mData)
|
||||
{
|
||||
if (mContentFiles.empty())
|
||||
throw std::runtime_error ("Empty content file sequence");
|
||||
@ -2311,6 +2309,11 @@ CSMDoc::Document::~Document()
|
||||
{
|
||||
}
|
||||
|
||||
const VFS::Manager *CSMDoc::Document::getVFS() const
|
||||
{
|
||||
return mVFS;
|
||||
}
|
||||
|
||||
QUndoStack& CSMDoc::Document::getUndoStack()
|
||||
{
|
||||
return mUndoStack;
|
||||
@ -2478,14 +2481,6 @@ void CSMDoc::Document::progress (int current, int max, int type)
|
||||
emit progress (current, max, type, 1, this);
|
||||
}
|
||||
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> CSMDoc::Document::getPhysics ()
|
||||
{
|
||||
if(!mPhysics)
|
||||
mPhysics = boost::shared_ptr<CSVWorld::PhysicsSystem> (new CSVWorld::PhysicsSystem());
|
||||
|
||||
return mPhysics;
|
||||
}
|
||||
|
||||
CSMWorld::IdCompletionManager &CSMDoc::Document::getIdCompletionManager()
|
||||
{
|
||||
return mIdCompletionManager;
|
||||
|
@ -25,6 +25,12 @@
|
||||
|
||||
class QAbstractItemModel;
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct GameSetting;
|
||||
@ -42,11 +48,6 @@ namespace CSMWorld
|
||||
class ResourcesManager;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class PhysicsSystem;
|
||||
}
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document : public QObject
|
||||
@ -55,6 +56,7 @@ namespace CSMDoc
|
||||
|
||||
private:
|
||||
|
||||
const VFS::Manager* mVFS;
|
||||
boost::filesystem::path mSavePath;
|
||||
std::vector<boost::filesystem::path> mContentFiles;
|
||||
bool mNew;
|
||||
@ -66,7 +68,7 @@ namespace CSMDoc
|
||||
boost::filesystem::path mResDir;
|
||||
Blacklist mBlacklist;
|
||||
Runner mRunner;
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||
|
||||
CSMWorld::IdCompletionManager mIdCompletionManager;
|
||||
|
||||
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
|
||||
@ -95,7 +97,7 @@ namespace CSMDoc
|
||||
|
||||
public:
|
||||
|
||||
Document (const Files::ConfigurationManager& configuration,
|
||||
Document (const VFS::Manager* vfs, const Files::ConfigurationManager& configuration,
|
||||
const std::vector< boost::filesystem::path >& files, bool new_,
|
||||
const boost::filesystem::path& savePath, const boost::filesystem::path& resDir,
|
||||
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
|
||||
@ -103,6 +105,8 @@ namespace CSMDoc
|
||||
|
||||
~Document();
|
||||
|
||||
const VFS::Manager* getVFS() const;
|
||||
|
||||
QUndoStack& getUndoStack();
|
||||
|
||||
int getState() const;
|
||||
@ -144,8 +148,6 @@ namespace CSMDoc
|
||||
|
||||
QTextDocument *getRunLog();
|
||||
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> getPhysics();
|
||||
|
||||
CSMWorld::IdCompletionManager &getIdCompletionManager();
|
||||
|
||||
signals:
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "document.hpp"
|
||||
|
||||
CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration)
|
||||
: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252)
|
||||
: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252), mVFS(NULL)
|
||||
{
|
||||
boost::filesystem::path projectPath = configuration.getUserDataPath() / "projects";
|
||||
|
||||
@ -57,7 +57,7 @@ bool CSMDoc::DocumentManager::isEmpty()
|
||||
void CSMDoc::DocumentManager::addDocument (const std::vector<boost::filesystem::path>& files, const boost::filesystem::path& savePath,
|
||||
bool new_)
|
||||
{
|
||||
Document *document = new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts);
|
||||
Document *document = new Document (mVFS, mConfiguration, files, new_, savePath, mResDir, mEncoding, mResourcesManager, mBlacklistedScripts);
|
||||
|
||||
mDocuments.push_back (document);
|
||||
|
||||
@ -95,11 +95,6 @@ void CSMDoc::DocumentManager::setBlacklistedScripts (const std::vector<std::stri
|
||||
mBlacklistedScripts = scriptIds;
|
||||
}
|
||||
|
||||
void CSMDoc::DocumentManager::listResources()
|
||||
{
|
||||
mResourcesManager.listResources();
|
||||
}
|
||||
|
||||
void CSMDoc::DocumentManager::documentLoaded (Document *document)
|
||||
{
|
||||
emit documentAdded (document);
|
||||
@ -113,3 +108,9 @@ void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::
|
||||
if (error.empty()) // do not remove the document yet, if we have an error
|
||||
removeDocument (document);
|
||||
}
|
||||
|
||||
void CSMDoc::DocumentManager::setVFS(const VFS::Manager *vfs)
|
||||
{
|
||||
mResourcesManager.setVFS(vfs);
|
||||
mVFS = vfs;
|
||||
}
|
||||
|
@ -15,6 +15,11 @@
|
||||
|
||||
#include "loader.hpp"
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace Files
|
||||
{
|
||||
struct ConfigurationManager;
|
||||
@ -35,6 +40,7 @@ namespace CSMDoc
|
||||
ToUTF8::FromType mEncoding;
|
||||
CSMWorld::ResourcesManager mResourcesManager;
|
||||
std::vector<std::string> mBlacklistedScripts;
|
||||
const VFS::Manager* mVFS;
|
||||
|
||||
DocumentManager (const DocumentManager&);
|
||||
DocumentManager& operator= (const DocumentManager&);
|
||||
@ -56,8 +62,7 @@ namespace CSMDoc
|
||||
|
||||
void setBlacklistedScripts (const std::vector<std::string>& scriptIds);
|
||||
|
||||
/// Ask OGRE for a list of available resources.
|
||||
void listResources();
|
||||
void setVFS(const VFS::Manager* vfs);
|
||||
|
||||
bool isEmpty();
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include <QTextCodec>
|
||||
#include <QDebug>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
/**
|
||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||
*/
|
||||
@ -44,13 +42,9 @@ CSMSettings::UserSettings *CSMSettings::UserSettings::sUserSettingsInstance = 0;
|
||||
|
||||
void CSMSettings::UserSettings::buildSettingModelDefaults()
|
||||
{
|
||||
QString section;
|
||||
|
||||
/*
|
||||
declareSection ("3d-render", "3D Rendering");
|
||||
{
|
||||
Setting *shaders = createSetting (Type_CheckBox, "shaders", "Enable Shaders");
|
||||
shaders->setDefaultValue ("true");
|
||||
|
||||
Setting *farClipDist = createSetting (Type_DoubleSpinBox, "far-clip-distance", "Far clipping distance");
|
||||
farClipDist->setDefaultValue (300000);
|
||||
farClipDist->setRange (0, 1000000);
|
||||
@ -62,23 +56,11 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
||||
<< defaultValue << "MSAA 2" << "MSAA 4" << "MSAA 8" << "MSAA 16");
|
||||
antialiasing->setDefaultValue (defaultValue);
|
||||
}
|
||||
*/
|
||||
|
||||
declareSection ("3d-render-adv", "3D Rendering (Advanced)");
|
||||
{
|
||||
Setting *numLights = createSetting (Type_SpinBox, "num_lights",
|
||||
"Number of lights per pass");
|
||||
numLights->setDefaultValue (8);
|
||||
numLights->setRange (1, 100);
|
||||
}
|
||||
|
||||
/*
|
||||
declareSection ("scene-input", "Scene Input");
|
||||
{
|
||||
Setting *timer = createSetting (Type_SpinBox, "timer", "Input responsiveness");
|
||||
timer->setDefaultValue (20);
|
||||
timer->setRange (1, 100);
|
||||
timer->setToolTip ("The time between two checks for user input in milliseconds.<p>"
|
||||
"Lower value result in higher responsiveness.");
|
||||
|
||||
Setting *fastFactor = createSetting (Type_SpinBox, "fast-factor",
|
||||
"Fast movement factor");
|
||||
fastFactor->setDefaultValue (4);
|
||||
@ -86,6 +68,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
|
||||
fastFactor->setToolTip (
|
||||
"Factor by which movement is speed up while the shift key is held down.");
|
||||
}
|
||||
*/
|
||||
|
||||
declareSection ("window", "Window");
|
||||
{
|
||||
@ -626,15 +609,6 @@ void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey,
|
||||
{
|
||||
mSettingDefinitions->setValue (settingKey ,list);
|
||||
|
||||
if(settingKey == "3d-render-adv/num_lights" && !list.empty())
|
||||
{
|
||||
sh::Factory::getInstance ().setGlobalSetting ("num_lights", list.at(0).toStdString());
|
||||
}
|
||||
else if(settingKey == "3d-render/shaders" && !list.empty())
|
||||
{
|
||||
sh::Factory::getInstance ().setShadersEnabled (list.at(0).toStdString() == "true" ? true : false);
|
||||
}
|
||||
|
||||
emit userSettingUpdated (settingKey, list);
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,25 @@ void CSMWorld::CreateCommand::applyModifications()
|
||||
{
|
||||
for (std::map<int, QVariant>::const_iterator iter (mValues.begin()); iter!=mValues.end(); ++iter)
|
||||
mModel.setData (mModel.getModelIndex (mId, iter->first), iter->second);
|
||||
|
||||
if (!mNestedValues.empty())
|
||||
{
|
||||
CSMWorld::IdTree *tree = dynamic_cast<CSMWorld::IdTree *>(&mModel);
|
||||
if (tree == NULL)
|
||||
{
|
||||
throw std::logic_error("CSMWorld::CreateCommand: Attempt to add nested values to the non-nested model");
|
||||
}
|
||||
|
||||
std::map<int, std::pair<int, QVariant> >::const_iterator current = mNestedValues.begin();
|
||||
std::map<int, std::pair<int, QVariant> >::const_iterator end = mNestedValues.end();
|
||||
for (; current != end; ++current)
|
||||
{
|
||||
QModelIndex index = tree->index(0,
|
||||
current->second.first,
|
||||
tree->getNestedModelIndex(mId, current->first));
|
||||
tree->setData(index, current->second.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSMWorld::CreateCommand::CreateCommand (IdTable& model, const std::string& id, QUndoCommand* parent)
|
||||
@ -71,6 +90,11 @@ void CSMWorld::CreateCommand::addValue (int column, const QVariant& value)
|
||||
mValues[column] = value;
|
||||
}
|
||||
|
||||
void CSMWorld::CreateCommand::addNestedValue(int parentColumn, int nestedColumn, const QVariant &value)
|
||||
{
|
||||
mNestedValues[parentColumn] = std::make_pair(nestedColumn, value);
|
||||
}
|
||||
|
||||
void CSMWorld::CreateCommand::setType (UniversalId::Type type)
|
||||
{
|
||||
mType = type;
|
||||
|
@ -48,6 +48,9 @@ namespace CSMWorld
|
||||
class CreateCommand : public QUndoCommand
|
||||
{
|
||||
std::map<int, QVariant> mValues;
|
||||
std::map<int, std::pair<int, QVariant> > mNestedValues;
|
||||
///< Parameter order: a parent column, a nested column, a data.
|
||||
///< A nested row has index of 0.
|
||||
|
||||
protected:
|
||||
|
||||
@ -68,6 +71,8 @@ namespace CSMWorld
|
||||
|
||||
void addValue (int column, const QVariant& value);
|
||||
|
||||
void addNestedValue(int parentColumn, int nestedColumn, const QVariant &value);
|
||||
|
||||
virtual void redo();
|
||||
|
||||
virtual void undo();
|
||||
|
@ -62,7 +62,7 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
|
||||
|
||||
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
||||
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
||||
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0)
|
||||
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0), mResourceSystem(resourcesManager.getVFS())
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@ -536,6 +536,16 @@ CSMWorld::Data::~Data()
|
||||
delete mReader;
|
||||
}
|
||||
|
||||
Resource::ResourceSystem* CSMWorld::Data::getResourceSystem()
|
||||
{
|
||||
return &mResourceSystem;
|
||||
}
|
||||
|
||||
const Resource::ResourceSystem* CSMWorld::Data::getResourceSystem() const
|
||||
{
|
||||
return &mResourceSystem;
|
||||
}
|
||||
|
||||
const CSMWorld::IdCollection<ESM::Global>& CSMWorld::Data::getGlobals() const
|
||||
{
|
||||
return mGlobals;
|
||||
@ -1161,3 +1171,8 @@ void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end)
|
||||
{
|
||||
emit idListChanged();
|
||||
}
|
||||
|
||||
const VFS::Manager* CSMWorld::Data::getVFS() const
|
||||
{
|
||||
return mResourcesManager.getVFS();
|
||||
}
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <components/esm/debugprofile.hpp>
|
||||
#include <components/esm/filter.hpp>
|
||||
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
#include "../doc/stage.hpp"
|
||||
@ -51,6 +53,11 @@
|
||||
|
||||
class QAbstractItemModel;
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class ESMReader;
|
||||
@ -106,6 +113,8 @@ namespace CSMWorld
|
||||
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
|
||||
int mReaderIndex;
|
||||
|
||||
Resource::ResourceSystem mResourceSystem;
|
||||
|
||||
std::vector<boost::shared_ptr<ESM::ESMReader> > mReaders;
|
||||
|
||||
// not implemented
|
||||
@ -127,6 +136,12 @@ namespace CSMWorld
|
||||
|
||||
virtual ~Data();
|
||||
|
||||
const VFS::Manager* getVFS() const;
|
||||
|
||||
Resource::ResourceSystem* getResourceSystem();
|
||||
|
||||
const Resource::ResourceSystem* getResourceSystem() const;
|
||||
|
||||
const IdCollection<ESM::Global>& getGlobals() const;
|
||||
|
||||
IdCollection<ESM::Global>& getGlobals();
|
||||
|
@ -261,3 +261,13 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::IdTree::nestedTable(const QModelInde
|
||||
|
||||
return mNestedCollection->nestedTable(index.row(), index.column());
|
||||
}
|
||||
|
||||
int CSMWorld::IdTree::searchNestedColumnIndex(int parentColumn, Columns::ColumnId id)
|
||||
{
|
||||
return mNestedCollection->searchNestedColumnIndex(parentColumn, id);
|
||||
}
|
||||
|
||||
int CSMWorld::IdTree::findNestedColumnIndex(int parentColumn, Columns::ColumnId id)
|
||||
{
|
||||
return mNestedCollection->findNestedColumnIndex(parentColumn, id);
|
||||
}
|
||||
|
@ -73,6 +73,12 @@ namespace CSMWorld
|
||||
|
||||
virtual bool hasChildren (const QModelIndex& index) const;
|
||||
|
||||
virtual int searchNestedColumnIndex(int parentColumn, Columns::ColumnId id);
|
||||
///< \return the column index or -1 if the requested column wasn't found.
|
||||
|
||||
virtual int findNestedColumnIndex(int parentColumn, Columns::ColumnId id);
|
||||
///< \return the column index or throws an exception if the requested column wasn't found.
|
||||
|
||||
signals:
|
||||
|
||||
void resetStart(const QString& id);
|
||||
|
@ -906,7 +906,7 @@ namespace CSMWorld
|
||||
|
||||
NestedTableWrapperBase* RaceAttributeAdapter::table(const Record<ESM::Race>& record) const
|
||||
{
|
||||
std::vector<typename ESM::Race::RADTstruct> wrap;
|
||||
std::vector<ESM::Race::RADTstruct> wrap;
|
||||
wrap.push_back(record.get().mData);
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<std::vector<ESM::Race::RADTstruct> >(wrap);
|
||||
@ -983,7 +983,7 @@ namespace CSMWorld
|
||||
|
||||
NestedTableWrapperBase* RaceSkillsBonusAdapter::table(const Record<ESM::Race>& record) const
|
||||
{
|
||||
std::vector<typename ESM::Race::RADTstruct> wrap;
|
||||
std::vector<ESM::Race::RADTstruct> wrap;
|
||||
wrap.push_back(record.get().mData);
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<std::vector<ESM::Race::RADTstruct> >(wrap);
|
||||
|
@ -15,3 +15,28 @@ int CSMWorld::NestedCollection::getNestedColumnsCount(int row, int column) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CSMWorld::NestedCollection::searchNestedColumnIndex(int parentColumn, Columns::ColumnId id)
|
||||
{
|
||||
// Assumed that the parentColumn is always a valid index
|
||||
const NestableColumn *parent = getNestableColumn(parentColumn);
|
||||
int nestedColumnCount = getNestedColumnsCount(0, parentColumn);
|
||||
for (int i = 0; i < nestedColumnCount; ++i)
|
||||
{
|
||||
if (parent->nestedColumn(i).mColumnId == id)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CSMWorld::NestedCollection::findNestedColumnIndex(int parentColumn, Columns::ColumnId id)
|
||||
{
|
||||
int index = searchNestedColumnIndex(parentColumn, id);
|
||||
if (index == -1)
|
||||
{
|
||||
throw std::logic_error("CSMWorld::NestedCollection: No such nested column");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef CSM_WOLRD_NESTEDCOLLECTION_H
|
||||
#define CSM_WOLRD_NESTEDCOLLECTION_H
|
||||
|
||||
#include "columns.hpp"
|
||||
|
||||
class QVariant;
|
||||
|
||||
namespace CSMWorld
|
||||
@ -33,6 +35,12 @@ namespace CSMWorld
|
||||
virtual int getNestedColumnsCount(int row, int column) const;
|
||||
|
||||
virtual NestableColumn *getNestableColumn(int column) = 0;
|
||||
|
||||
virtual int searchNestedColumnIndex(int parentColumn, Columns::ColumnId id);
|
||||
///< \return the column index or -1 if the requested column wasn't found.
|
||||
|
||||
virtual int findNestedColumnIndex(int parentColumn, Columns::ColumnId id);
|
||||
///< \return the column index or throws an exception if the requested column wasn't found.
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -667,7 +667,7 @@ void CSMWorld::NpcAttributesRefIdAdapter::setNestedTable (const RefIdColumn* col
|
||||
|
||||
// store the whole struct
|
||||
npc.mNpdt52 =
|
||||
static_cast<const NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
|
||||
static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
|
||||
|
||||
record.setModified (npc);
|
||||
}
|
||||
@ -679,10 +679,10 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::NpcAttributesRefIdAdapter::nestedTab
|
||||
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||
|
||||
// return the whole struct
|
||||
std::vector<typename ESM::NPC::NPDTstruct52> wrap;
|
||||
std::vector<ESM::NPC::NPDTstruct52> wrap;
|
||||
wrap.push_back(record.get().mNpdt52);
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> >(wrap);
|
||||
return new NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> >(wrap);
|
||||
}
|
||||
|
||||
QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData (const RefIdColumn *column,
|
||||
@ -785,7 +785,7 @@ void CSMWorld::NpcSkillsRefIdAdapter::setNestedTable (const RefIdColumn* column,
|
||||
|
||||
// store the whole struct
|
||||
npc.mNpdt52 =
|
||||
static_cast<const NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
|
||||
static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
|
||||
|
||||
record.setModified (npc);
|
||||
}
|
||||
@ -797,10 +797,10 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::NpcSkillsRefIdAdapter::nestedTable (
|
||||
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||
|
||||
// return the whole struct
|
||||
std::vector<typename ESM::NPC::NPDTstruct52> wrap;
|
||||
std::vector<ESM::NPC::NPDTstruct52> wrap;
|
||||
wrap.push_back(record.get().mNpdt52);
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<std::vector<typename ESM::NPC::NPDTstruct52> >(wrap);
|
||||
return new NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> >(wrap);
|
||||
}
|
||||
|
||||
QVariant CSMWorld::NpcSkillsRefIdAdapter::getNestedData (const RefIdColumn *column,
|
||||
|
@ -5,61 +5,49 @@
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include <components/vfs/manager.hpp>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
CSMWorld::Resources::Resources (const std::string& baseDirectory, UniversalId::Type type,
|
||||
CSMWorld::Resources::Resources (const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type,
|
||||
const char * const *extensions)
|
||||
: mBaseDirectory (baseDirectory), mType (type)
|
||||
{
|
||||
int baseSize = mBaseDirectory.size();
|
||||
|
||||
Ogre::StringVector resourcesGroups =
|
||||
Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
|
||||
|
||||
for (Ogre::StringVector::iterator iter (resourcesGroups.begin());
|
||||
iter!=resourcesGroups.end(); ++iter)
|
||||
const std::map<std::string, VFS::File*>& index = vfs->getIndex();
|
||||
for (std::map<std::string, VFS::File*>::const_iterator it = index.begin(); it != index.end(); ++it)
|
||||
{
|
||||
if (*iter=="General" || *iter=="Internal" || *iter=="Autodetect")
|
||||
std::string filepath = it->first;
|
||||
if (static_cast<int> (filepath.size())<baseSize+1 ||
|
||||
filepath.substr (0, baseSize)!=mBaseDirectory ||
|
||||
(filepath[baseSize]!='/' && filepath[baseSize]!='\\'))
|
||||
continue;
|
||||
|
||||
Ogre::StringVectorPtr resources =
|
||||
Ogre::ResourceGroupManager::getSingleton().listResourceNames (*iter);
|
||||
|
||||
for (Ogre::StringVector::const_iterator iter (resources->begin());
|
||||
iter!=resources->end(); ++iter)
|
||||
if (extensions)
|
||||
{
|
||||
if (static_cast<int> (iter->size())<baseSize+1 ||
|
||||
iter->substr (0, baseSize)!=mBaseDirectory ||
|
||||
((*iter)[baseSize]!='/' && (*iter)[baseSize]!='\\'))
|
||||
std::string::size_type index = filepath.find_last_of ('.');
|
||||
|
||||
if (index==std::string::npos)
|
||||
continue;
|
||||
|
||||
if (extensions)
|
||||
{
|
||||
std::string::size_type index = iter->find_last_of ('.');
|
||||
std::string extension = filepath.substr (index+1);
|
||||
|
||||
if (index==std::string::npos)
|
||||
continue;
|
||||
int i = 0;
|
||||
|
||||
std::string extension = iter->substr (index+1);
|
||||
for (; extensions[i]; ++i)
|
||||
if (extensions[i]==extension)
|
||||
break;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (; extensions[i]; ++i)
|
||||
if (extensions[i]==extension)
|
||||
break;
|
||||
|
||||
if (!extensions[i])
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string file = iter->substr (baseSize+1);
|
||||
mFiles.push_back (file);
|
||||
std::replace (file.begin(), file.end(), '\\', '/');
|
||||
mIndex.insert (std::make_pair (
|
||||
Misc::StringUtils::lowerCase (file), static_cast<int> (mFiles.size())-1));
|
||||
if (!extensions[i])
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string file = filepath.substr (baseSize+1);
|
||||
mFiles.push_back (file);
|
||||
std::replace (file.begin(), file.end(), '\\', '/');
|
||||
mIndex.insert (std::make_pair (
|
||||
Misc::StringUtils::lowerCase (file), static_cast<int> (mFiles.size())-1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,11 @@
|
||||
|
||||
#include "universalid.hpp"
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Resources
|
||||
@ -19,7 +24,7 @@ namespace CSMWorld
|
||||
public:
|
||||
|
||||
/// \param type Type of resources in this table.
|
||||
Resources (const std::string& baseDirectory, UniversalId::Type type,
|
||||
Resources (const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type,
|
||||
const char * const *extensions = 0);
|
||||
|
||||
int getSize() const;
|
||||
|
@ -3,6 +3,11 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
CSMWorld::ResourcesManager::ResourcesManager()
|
||||
: mVFS(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void CSMWorld::ResourcesManager::addResources (const Resources& resources)
|
||||
{
|
||||
mResources.insert (std::make_pair (resources.getType(), resources));
|
||||
@ -10,16 +15,24 @@ void CSMWorld::ResourcesManager::addResources (const Resources& resources)
|
||||
resources));
|
||||
}
|
||||
|
||||
void CSMWorld::ResourcesManager::listResources()
|
||||
void CSMWorld::ResourcesManager::setVFS(const VFS::Manager *vfs)
|
||||
{
|
||||
mVFS = vfs;
|
||||
mResources.clear();
|
||||
|
||||
static const char * const sMeshTypes[] = { "nif", 0 };
|
||||
|
||||
addResources (Resources ("meshes", UniversalId::Type_Mesh, sMeshTypes));
|
||||
addResources (Resources ("icons", UniversalId::Type_Icon));
|
||||
addResources (Resources ("music", UniversalId::Type_Music));
|
||||
addResources (Resources ("sound", UniversalId::Type_SoundRes));
|
||||
addResources (Resources ("textures", UniversalId::Type_Texture));
|
||||
addResources (Resources ("videos", UniversalId::Type_Video));
|
||||
addResources (Resources (vfs, "meshes", UniversalId::Type_Mesh, sMeshTypes));
|
||||
addResources (Resources (vfs, "icons", UniversalId::Type_Icon));
|
||||
addResources (Resources (vfs, "music", UniversalId::Type_Music));
|
||||
addResources (Resources (vfs, "sound", UniversalId::Type_SoundRes));
|
||||
addResources (Resources (vfs, "textures", UniversalId::Type_Texture));
|
||||
addResources (Resources (vfs, "videos", UniversalId::Type_Video));
|
||||
}
|
||||
|
||||
const VFS::Manager* CSMWorld::ResourcesManager::getVFS() const
|
||||
{
|
||||
return mVFS;
|
||||
}
|
||||
|
||||
const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type type) const
|
||||
|
@ -6,11 +6,17 @@
|
||||
#include "universalid.hpp"
|
||||
#include "resources.hpp"
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class ResourcesManager
|
||||
{
|
||||
std::map<UniversalId::Type, Resources> mResources;
|
||||
const VFS::Manager* mVFS;
|
||||
|
||||
private:
|
||||
|
||||
@ -18,8 +24,11 @@ namespace CSMWorld
|
||||
|
||||
public:
|
||||
|
||||
/// Ask OGRE for a list of available resources.
|
||||
void listResources();
|
||||
ResourcesManager();
|
||||
|
||||
const VFS::Manager* getVFS() const;
|
||||
|
||||
void setVFS(const VFS::Manager* vfs);
|
||||
|
||||
const Resources& get (UniversalId::Type type) const;
|
||||
};
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
#include "cell.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <osg/Group>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/esm/loadland.hpp>
|
||||
@ -11,7 +10,6 @@
|
||||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/refcollection.hpp"
|
||||
#include "../world/physicssystem.hpp"
|
||||
|
||||
#include "elements.hpp"
|
||||
#include "terrainstorage.hpp"
|
||||
@ -45,7 +43,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||
{
|
||||
std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId);
|
||||
|
||||
mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics)));
|
||||
mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false)));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
@ -53,12 +51,11 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||
return modified;
|
||||
}
|
||||
|
||||
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
||||
const std::string& id, boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin)
|
||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mPhysics(physics), mSceneMgr(sceneManager), mX(0), mY(0)
|
||||
CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id)
|
||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mX(0), mY(0)
|
||||
{
|
||||
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();
|
||||
mCellNode->setPosition (origin);
|
||||
mCellNode = new osg::Group;
|
||||
rootNode->addChild(mCellNode);
|
||||
|
||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||
@ -74,31 +71,23 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
||||
const ESM::Land* esmLand = land.getRecord(mId).get().mLand.get();
|
||||
if(esmLand && esmLand->mDataTypes&ESM::Land::DATA_VHGT)
|
||||
{
|
||||
mTerrain.reset(new Terrain::TerrainGrid(sceneManager, new TerrainStorage(mData), Element_Terrain, true,
|
||||
Terrain::Align_XY));
|
||||
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem(), NULL, new TerrainStorage(mData), Element_Terrain<<1));
|
||||
mTerrain->loadCell(esmLand->mX,
|
||||
esmLand->mY);
|
||||
|
||||
float verts = ESM::Land::LAND_SIZE;
|
||||
float worldsize = ESM::Land::REAL_SIZE;
|
||||
mX = esmLand->mX;
|
||||
mY = esmLand->mY;
|
||||
mPhysics->addHeightField(sceneManager,
|
||||
esmLand->mLandData->mHeights, mX, mY, 0, worldsize / (verts-1), verts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CSVRender::Cell::~Cell()
|
||||
{
|
||||
if (mTerrain.get())
|
||||
mPhysics->removeHeightField(mSceneMgr, mX, mY);
|
||||
|
||||
for (std::map<std::string, Object *>::iterator iter (mObjects.begin());
|
||||
iter!=mObjects.end(); ++iter)
|
||||
delete iter->second;
|
||||
|
||||
mCellNode->getCreator()->destroySceneNode (mCellNode);
|
||||
mCellNode->getParent(0)->removeChild(mCellNode);
|
||||
}
|
||||
|
||||
bool CSVRender::Cell::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
@ -186,7 +175,7 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
|
||||
for (std::map<std::string, bool>::iterator iter (ids.begin()); iter!=ids.end(); ++iter)
|
||||
{
|
||||
mObjects.insert (std::make_pair (
|
||||
iter->first, new Object (mData, mCellNode, iter->first, false, mPhysics)));
|
||||
iter->first, new Object (mData, mCellNode, iter->first, false)));
|
||||
|
||||
modified = true;
|
||||
}
|
||||
@ -222,11 +211,3 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int
|
||||
|
||||
return addObjects (start, end);
|
||||
}
|
||||
|
||||
float CSVRender::Cell::getTerrainHeightAt(const Ogre::Vector3 &pos) const
|
||||
{
|
||||
if(mTerrain.get() != NULL)
|
||||
return mTerrain->getHeightAt(pos);
|
||||
else
|
||||
return -std::numeric_limits<float>::max();
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <OgreVector3.h>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/terrain/terraingrid.hpp>
|
||||
@ -17,10 +17,9 @@
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
namespace Ogre
|
||||
namespace osg
|
||||
{
|
||||
class SceneManager;
|
||||
class SceneNode;
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
@ -28,22 +27,15 @@ namespace CSMWorld
|
||||
class Data;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class PhysicsSystem;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Cell
|
||||
{
|
||||
CSMWorld::Data& mData;
|
||||
std::string mId;
|
||||
Ogre::SceneNode *mCellNode;
|
||||
osg::ref_ptr<osg::Group> mCellNode;
|
||||
std::map<std::string, Object *> mObjects;
|
||||
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||
Ogre::SceneManager *mSceneMgr;
|
||||
int mX;
|
||||
int mY;
|
||||
|
||||
@ -59,8 +51,7 @@ namespace CSVRender
|
||||
|
||||
public:
|
||||
|
||||
Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id,
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0));
|
||||
Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id);
|
||||
|
||||
~Cell();
|
||||
|
||||
@ -84,8 +75,6 @@ namespace CSVRender
|
||||
/// \return Did this call result in a modification of the visual representation of
|
||||
/// this cell?
|
||||
bool referenceAdded (const QModelIndex& parent, int start, int end);
|
||||
|
||||
float getTerrainHeightAt(const Ogre::Vector3 &pos) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
#include "lighting.hpp"
|
||||
|
||||
#include <osg/LightSource>
|
||||
|
||||
CSVRender::Lighting::~Lighting() {}
|
||||
|
@ -1,10 +1,13 @@
|
||||
#ifndef OPENCS_VIEW_LIGHTING_H
|
||||
#define OPENCS_VIEW_LIGHTING_H
|
||||
|
||||
namespace Ogre
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class SceneManager;
|
||||
class ColourValue;
|
||||
class Vec4f;
|
||||
class LightSource;
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
@ -13,14 +16,19 @@ namespace CSVRender
|
||||
{
|
||||
public:
|
||||
|
||||
Lighting() : mRootNode(0) {}
|
||||
virtual ~Lighting();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0) = 0;
|
||||
virtual void activate (osg::Group* rootNode) = 0;
|
||||
|
||||
virtual void deactivate() = 0;
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour) = 0;
|
||||
virtual osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<osg::LightSource> mLightSource;
|
||||
osg::Group* mRootNode;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,30 +1,35 @@
|
||||
|
||||
#include "lightingbright.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <osg/LightSource>
|
||||
|
||||
CSVRender::LightingBright::LightingBright() : mSceneManager (0), mLight (0) {}
|
||||
CSVRender::LightingBright::LightingBright() {}
|
||||
|
||||
void CSVRender::LightingBright::activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient)
|
||||
void CSVRender::LightingBright::activate (osg::Group* rootNode)
|
||||
{
|
||||
mSceneManager = sceneManager;
|
||||
mRootNode = rootNode;
|
||||
|
||||
mSceneManager->setAmbientLight (Ogre::ColourValue (1.0, 1.0, 1.0, 1));
|
||||
mLightSource = (new osg::LightSource);
|
||||
|
||||
mLight = mSceneManager->createLight();
|
||||
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||
mLight->setDiffuseColour (Ogre::ColourValue (1.0, 1.0, 1.0));
|
||||
osg::ref_ptr<osg::Light> light (new osg::Light);
|
||||
light->setAmbient(osg::Vec4f(0.f, 0.f, 0.f, 1.f));
|
||||
light->setPosition(osg::Vec4f(0.f, 0.f, 1.f, 0.f));
|
||||
light->setDiffuse(osg::Vec4f(1.f, 1.f, 1.f, 1.f));
|
||||
light->setSpecular(osg::Vec4f(0.f, 0.f, 0.f, 0.f));
|
||||
light->setConstantAttenuation(1.f);
|
||||
|
||||
mLightSource->setLight(light);
|
||||
|
||||
mRootNode->addChild(mLightSource);
|
||||
}
|
||||
|
||||
void CSVRender::LightingBright::deactivate()
|
||||
{
|
||||
if (mLight)
|
||||
{
|
||||
mSceneManager->destroyLight (mLight);
|
||||
mLight = 0;
|
||||
}
|
||||
if (mRootNode && mLightSource.get())
|
||||
mRootNode->removeChild(mLightSource);
|
||||
}
|
||||
|
||||
void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {}
|
||||
osg::Vec4f CSVRender::LightingBright::getAmbientColour(osg::Vec4f* /*defaultAmbient*/)
|
||||
{
|
||||
return osg::Vec4f(1.f, 1.f, 1.f, 1.f);
|
||||
}
|
||||
|
@ -3,28 +3,25 @@
|
||||
|
||||
#include "lighting.hpp"
|
||||
|
||||
namespace Ogre
|
||||
namespace osg
|
||||
{
|
||||
class Light;
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class LightingBright : public Lighting
|
||||
{
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
Ogre::Light *mLight;
|
||||
|
||||
public:
|
||||
|
||||
LightingBright();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0);
|
||||
virtual void activate (osg::Group* rootNode);
|
||||
|
||||
virtual void deactivate();
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
virtual osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,36 +1,36 @@
|
||||
|
||||
#include "lightingday.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <osg/LightSource>
|
||||
|
||||
CSVRender::LightingDay::LightingDay() : mSceneManager (0), mLight (0) {}
|
||||
CSVRender::LightingDay::LightingDay(){}
|
||||
|
||||
void CSVRender::LightingDay::activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient)
|
||||
void CSVRender::LightingDay::activate (osg::Group* rootNode)
|
||||
{
|
||||
mSceneManager = sceneManager;
|
||||
mRootNode = rootNode;
|
||||
|
||||
if (defaultAmbient)
|
||||
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||
else
|
||||
mSceneManager->setAmbientLight (Ogre::ColourValue (0.7, 0.7, 0.7, 1));
|
||||
mLightSource = new osg::LightSource;
|
||||
|
||||
mLight = mSceneManager->createLight();
|
||||
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||
mLight->setDiffuseColour (Ogre::ColourValue (1, 1, 1));
|
||||
osg::ref_ptr<osg::Light> light (new osg::Light);
|
||||
light->setPosition(osg::Vec4f(0.f, 0.f, 1.f, 0.f));
|
||||
light->setAmbient(osg::Vec4f(0.f, 0.f, 0.f, 1.f));
|
||||
light->setDiffuse(osg::Vec4f(1.f, 1.f, 1.f, 1.f));
|
||||
light->setSpecular(osg::Vec4f(0.f, 0.f, 0.f, 0.f));
|
||||
light->setConstantAttenuation(1.f);
|
||||
|
||||
mLightSource->setLight(light);
|
||||
mRootNode->addChild(mLightSource);
|
||||
}
|
||||
|
||||
void CSVRender::LightingDay::deactivate()
|
||||
{
|
||||
if (mLight)
|
||||
{
|
||||
mSceneManager->destroyLight (mLight);
|
||||
mLight = 0;
|
||||
}
|
||||
if (mRootNode && mLightSource.get())
|
||||
mRootNode->removeChild(mLightSource);
|
||||
}
|
||||
|
||||
void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||
osg::Vec4f CSVRender::LightingDay::getAmbientColour(osg::Vec4f *defaultAmbient)
|
||||
{
|
||||
mSceneManager->setAmbientLight (colour);
|
||||
if (defaultAmbient)
|
||||
return *defaultAmbient;
|
||||
else
|
||||
return osg::Vec4f(0.7f, 0.7f, 0.7f, 1.f);
|
||||
}
|
||||
|
@ -3,28 +3,19 @@
|
||||
|
||||
#include "lighting.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Light;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class LightingDay : public Lighting
|
||||
{
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
Ogre::Light *mLight;
|
||||
|
||||
public:
|
||||
|
||||
LightingDay();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0);
|
||||
virtual void activate (osg::Group* rootNode);
|
||||
|
||||
virtual void deactivate();
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
virtual osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,36 +1,37 @@
|
||||
|
||||
#include "lightingnight.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <osg/LightSource>
|
||||
|
||||
CSVRender::LightingNight::LightingNight() : mSceneManager (0), mLight (0) {}
|
||||
CSVRender::LightingNight::LightingNight() {}
|
||||
|
||||
void CSVRender::LightingNight::activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient)
|
||||
void CSVRender::LightingNight::activate (osg::Group* rootNode)
|
||||
{
|
||||
mSceneManager = sceneManager;
|
||||
mRootNode = rootNode;
|
||||
|
||||
if (defaultAmbient)
|
||||
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||
else
|
||||
mSceneManager->setAmbientLight (Ogre::ColourValue (0.2, 0.2, 0.2, 1));
|
||||
mLightSource = new osg::LightSource;
|
||||
|
||||
mLight = mSceneManager->createLight();
|
||||
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||
mLight->setDiffuseColour (Ogre::ColourValue (0.2, 0.2, 0.2));
|
||||
osg::ref_ptr<osg::Light> light (new osg::Light);
|
||||
light->setPosition(osg::Vec4f(0.f, 0.f, 1.f, 0.f));
|
||||
light->setAmbient(osg::Vec4f(0.f, 0.f, 0.f, 1.f));
|
||||
light->setDiffuse(osg::Vec4f(0.2f, 0.2f, 0.2f, 1.f));
|
||||
light->setSpecular(osg::Vec4f(0.f, 0.f, 0.f, 0.f));
|
||||
light->setConstantAttenuation(1.f);
|
||||
|
||||
mLightSource->setLight(light);
|
||||
|
||||
mRootNode->addChild(mLightSource);
|
||||
}
|
||||
|
||||
void CSVRender::LightingNight::deactivate()
|
||||
{
|
||||
if (mLight)
|
||||
{
|
||||
mSceneManager->destroyLight (mLight);
|
||||
mLight = 0;
|
||||
}
|
||||
if (mRootNode && mLightSource.get())
|
||||
mRootNode->removeChild(mLightSource);
|
||||
}
|
||||
|
||||
void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||
osg::Vec4f CSVRender::LightingNight::getAmbientColour(osg::Vec4f *defaultAmbient)
|
||||
{
|
||||
mSceneManager->setAmbientLight (colour);
|
||||
if (defaultAmbient)
|
||||
return *defaultAmbient;
|
||||
else
|
||||
return osg::Vec4f(0.2f, 0.2f, 0.2f, 1.f);
|
||||
}
|
||||
|
@ -3,28 +3,18 @@
|
||||
|
||||
#include "lighting.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Light;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class LightingNight : public Lighting
|
||||
{
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
Ogre::Light *mLight;
|
||||
|
||||
public:
|
||||
|
||||
LightingNight();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0);
|
||||
|
||||
virtual void activate (osg::Group* rootNode);
|
||||
virtual void deactivate();
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
virtual osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,463 +0,0 @@
|
||||
#include "mousestate.hpp"
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreMeshManager.h>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QElapsedTimer>
|
||||
#include <QObject>
|
||||
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../world/physicssystem.hpp"
|
||||
|
||||
#include "elements.hpp"
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
// mouse picking
|
||||
// FIXME: need to virtualise mouse buttons
|
||||
//
|
||||
// State machine:
|
||||
//
|
||||
// [default] mousePressEvent->check if the mouse is pointing at an object
|
||||
// if yes, create collision planes then go to [grab]
|
||||
// else check for terrain
|
||||
//
|
||||
// [grab] mouseReleaseEvent->if same button and new obj, go to [edit]
|
||||
// mouseMoveEvent->if same button, go to [drag]
|
||||
// other mouse events or buttons, go back to [default] (i.e. like 'cancel')
|
||||
//
|
||||
// [drag] mouseReleaseEvent->if same button, place the object at the new
|
||||
// location, update the document then go to [edit]
|
||||
// mouseMoveEvent->update position to the user based on ray to the collision
|
||||
// planes and render the object at the new location, but do not update
|
||||
// the document yet
|
||||
//
|
||||
// [edit] TODO, probably fine positional adjustments or rotations; clone/delete?
|
||||
//
|
||||
//
|
||||
// press press (obj)
|
||||
// [default] --------> [grab] <-------------------- [edit]
|
||||
// ^ (obj) | | ------> [drag] -----> ^
|
||||
// | | | move ^ | release |
|
||||
// | | | | | |
|
||||
// | | | +-+ |
|
||||
// | | | move |
|
||||
// +----------------+ +--------------------------+
|
||||
// release release
|
||||
// (same obj) (new obj)
|
||||
//
|
||||
//
|
||||
|
||||
MouseState::MouseState(WorldspaceWidget *parent)
|
||||
: mMouseState(Mouse_Default), mParent(parent), mPhysics(parent->mDocument.getPhysics())
|
||||
, mSceneManager(parent->getSceneManager()), mOldPos(0,0), mCurrentObj(""), mGrabbedSceneNode("")
|
||||
, mMouseEventTimer(0), mPlane(0), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3())
|
||||
, mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f), mIdTableModel(0), mColIndexPosX(0)
|
||||
, mColIndexPosY(0), mColIndexPosZ(0)
|
||||
{
|
||||
const CSMWorld::RefCollection& references = mParent->mDocument.getData().getReferences();
|
||||
|
||||
mColIndexPosX = references.findColumnIndex(CSMWorld::Columns::ColumnId_PositionXPos);
|
||||
mColIndexPosY = references.findColumnIndex(CSMWorld::Columns::ColumnId_PositionYPos);
|
||||
mColIndexPosZ = references.findColumnIndex(CSMWorld::Columns::ColumnId_PositionZPos);
|
||||
|
||||
mIdTableModel = static_cast<CSMWorld::IdTable *>(
|
||||
mParent->mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_Reference));
|
||||
|
||||
mMouseEventTimer = new QElapsedTimer();
|
||||
mMouseEventTimer->invalidate();
|
||||
|
||||
std::pair<Ogre::Vector3, Ogre::Vector3> planeRes = planeAxis();
|
||||
mPlane = new Ogre::Plane(planeRes.first, 0);
|
||||
Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createPlane("mouse",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
*mPlane,
|
||||
300000,300000, // FIXME: use far clip dist?
|
||||
1,1, // segments
|
||||
true, // normals
|
||||
1, // numTexCoordSets
|
||||
1,1, // uTile, vTile
|
||||
planeRes.second // upVector
|
||||
);
|
||||
}
|
||||
|
||||
MouseState::~MouseState ()
|
||||
{
|
||||
delete mMouseEventTimer;
|
||||
delete mPlane;
|
||||
}
|
||||
|
||||
void MouseState::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
switch(mMouseState)
|
||||
{
|
||||
case Mouse_Grab:
|
||||
{
|
||||
// check if min elapsed time to stop false detection of drag
|
||||
if(!mMouseEventTimer->isValid() || !mMouseEventTimer->hasExpired(100)) // ms
|
||||
break;
|
||||
|
||||
mMouseEventTimer->invalidate();
|
||||
mMouseState = Mouse_Drag;
|
||||
|
||||
/* FALL_THROUGH */
|
||||
}
|
||||
case Mouse_Drag:
|
||||
{
|
||||
if(event->pos() != mOldPos) // TODO: maybe don't update less than a quantum?
|
||||
{
|
||||
mOldPos = event->pos();
|
||||
|
||||
// ray test against the plane to provide feedback to the user the
|
||||
// relative movement of the object on the x-y plane
|
||||
std::pair<bool, Ogre::Vector3> planeResult = mousePositionOnPlane(event->pos(), *mPlane);
|
||||
if(planeResult.first)
|
||||
{
|
||||
if(mGrabbedSceneNode != "")
|
||||
{
|
||||
std::pair<Ogre::Vector3, Ogre::Vector3> planeRes = planeAxis();
|
||||
Ogre::Vector3 pos = mOrigObjPos + planeRes.first*mOffset;
|
||||
mSceneManager->getSceneNode(mGrabbedSceneNode)->setPosition(pos+planeResult.second-mOrigMousePos);
|
||||
mCurrentMousePos = planeResult.second;
|
||||
mPhysics->moveSceneNodes(mGrabbedSceneNode, pos+planeResult.second-mOrigMousePos);
|
||||
updateSceneWidgets();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mouse_Edit:
|
||||
case Mouse_Default:
|
||||
{
|
||||
break; // error event, ignore
|
||||
}
|
||||
/* NO_DEFAULT_CASE */
|
||||
}
|
||||
}
|
||||
|
||||
void MouseState::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
switch(mMouseState)
|
||||
{
|
||||
case Mouse_Grab:
|
||||
case Mouse_Drag:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case Mouse_Edit:
|
||||
case Mouse_Default:
|
||||
{
|
||||
if(event->buttons() & Qt::RightButton)
|
||||
{
|
||||
std::pair<std::string, Ogre::Vector3> result = objectUnderCursor(event->x(), event->y());
|
||||
if(result.first == "")
|
||||
break;
|
||||
|
||||
mGrabbedSceneNode = result.first;
|
||||
// ray test agaist the plane to get a starting position of the
|
||||
// mouse in relation to the object position
|
||||
std::pair<Ogre::Vector3, Ogre::Vector3> planeRes = planeAxis();
|
||||
mPlane->redefine(planeRes.first, result.second);
|
||||
std::pair<bool, Ogre::Vector3> planeResult = mousePositionOnPlane(event->pos(), *mPlane);
|
||||
if(planeResult.first)
|
||||
{
|
||||
mOrigMousePos = planeResult.second;
|
||||
mCurrentMousePos = planeResult.second;
|
||||
mOffset = 0.0f;
|
||||
}
|
||||
|
||||
mOrigObjPos = mSceneManager->getSceneNode(mGrabbedSceneNode)->getPosition();
|
||||
mMouseEventTimer->start();
|
||||
|
||||
mMouseState = Mouse_Grab;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* NO_DEFAULT_CASE */
|
||||
}
|
||||
}
|
||||
|
||||
void MouseState::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
switch(mMouseState)
|
||||
{
|
||||
case Mouse_Grab:
|
||||
{
|
||||
std::pair<std::string, Ogre::Vector3> result = objectUnderCursor(event->x(), event->y());
|
||||
if(result.first != "")
|
||||
{
|
||||
if(result.first == mCurrentObj)
|
||||
{
|
||||
// unselect object
|
||||
mMouseState = Mouse_Default;
|
||||
mCurrentObj = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
// select object
|
||||
mMouseState = Mouse_Edit;
|
||||
mCurrentObj = result.first;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mouse_Drag:
|
||||
{
|
||||
// final placement
|
||||
std::pair<bool, Ogre::Vector3> planeResult = mousePositionOnPlane(event->pos(), *mPlane);
|
||||
if(planeResult.first)
|
||||
{
|
||||
if(mGrabbedSceneNode != "")
|
||||
{
|
||||
std::pair<Ogre::Vector3, Ogre::Vector3> planeRes = planeAxis();
|
||||
Ogre::Vector3 pos = mOrigObjPos+planeRes.first*mOffset+planeResult.second-mOrigMousePos;
|
||||
// use the saved scene node name since the physics model has not moved yet
|
||||
std::string referenceId = mPhysics->sceneNodeToRefId(mGrabbedSceneNode);
|
||||
|
||||
mParent->mDocument.getUndoStack().beginMacro (QObject::tr("Move Object"));
|
||||
mParent->mDocument.getUndoStack().push(new CSMWorld::ModifyCommand(*mIdTableModel,
|
||||
mIdTableModel->getModelIndex(referenceId, mColIndexPosX), pos.x));
|
||||
mParent->mDocument.getUndoStack().push(new CSMWorld::ModifyCommand(*mIdTableModel,
|
||||
mIdTableModel->getModelIndex(referenceId, mColIndexPosY), pos.y));
|
||||
mParent->mDocument.getUndoStack().push(new CSMWorld::ModifyCommand(*mIdTableModel,
|
||||
mIdTableModel->getModelIndex(referenceId, mColIndexPosZ), pos.z));
|
||||
mParent->mDocument.getUndoStack().endMacro();
|
||||
|
||||
// FIXME: highlight current object?
|
||||
//mCurrentObj = mGrabbedSceneNode; // FIXME: doesn't work?
|
||||
mCurrentObj = ""; // whether the object is selected
|
||||
|
||||
mMouseState = Mouse_Edit;
|
||||
|
||||
// reset states
|
||||
mCurrentMousePos = Ogre::Vector3(); // mouse pos to use in wheel event
|
||||
mOrigMousePos = Ogre::Vector3(); // starting pos of mouse in world space
|
||||
mOrigObjPos = Ogre::Vector3(); // starting pos of object in world space
|
||||
mGrabbedSceneNode = ""; // id of the object
|
||||
mOffset = 0.0f; // used for z-axis movement
|
||||
mOldPos = QPoint(0, 0); // to calculate relative movement of mouse
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mouse_Edit:
|
||||
case Mouse_Default:
|
||||
{
|
||||
// probably terrain, check
|
||||
std::pair<std::string, Ogre::Vector3> result = terrainUnderCursor(event->x(), event->y());
|
||||
if(result.first != "")
|
||||
{
|
||||
// FIXME: terrain editing goes here
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* NO_DEFAULT_CASE */
|
||||
}
|
||||
mMouseEventTimer->invalidate();
|
||||
}
|
||||
|
||||
void MouseState::mouseDoubleClickEvent (QMouseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
//mPhysics->toggleDebugRendering(mSceneManager);
|
||||
//mParent->flagAsModified();
|
||||
}
|
||||
|
||||
bool MouseState::wheelEvent (QWheelEvent *event)
|
||||
{
|
||||
switch(mMouseState)
|
||||
{
|
||||
case Mouse_Grab:
|
||||
mMouseState = Mouse_Drag;
|
||||
|
||||
/* FALL_THROUGH */
|
||||
case Mouse_Drag:
|
||||
{
|
||||
// move the object along the z axis during Mouse_Drag or Mouse_Grab
|
||||
if (event->delta())
|
||||
{
|
||||
// seems positive is up and negative is down
|
||||
mOffset += (event->delta()/1); // FIXME: arbitrary number, make config option?
|
||||
|
||||
std::pair<Ogre::Vector3, Ogre::Vector3> planeRes = planeAxis();
|
||||
Ogre::Vector3 pos = mOrigObjPos + planeRes.first*mOffset;
|
||||
mSceneManager->getSceneNode(mGrabbedSceneNode)->setPosition(pos+mCurrentMousePos-mOrigMousePos);
|
||||
mPhysics->moveSceneNodes(mGrabbedSceneNode, pos+mCurrentMousePos-mOrigMousePos);
|
||||
updateSceneWidgets();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mouse_Edit:
|
||||
case Mouse_Default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/* NO_DEFAULT_CASE */
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MouseState::cancelDrag()
|
||||
{
|
||||
switch(mMouseState)
|
||||
{
|
||||
case Mouse_Grab:
|
||||
case Mouse_Drag:
|
||||
{
|
||||
// cancel operation & return the object to the original position
|
||||
mSceneManager->getSceneNode(mGrabbedSceneNode)->setPosition(mOrigObjPos);
|
||||
// update all SceneWidgets and their SceneManagers
|
||||
mPhysics->moveSceneNodes(mGrabbedSceneNode, mOrigObjPos);
|
||||
updateSceneWidgets();
|
||||
|
||||
// reset states
|
||||
mMouseState = Mouse_Default;
|
||||
mCurrentMousePos = Ogre::Vector3();
|
||||
mOrigMousePos = Ogre::Vector3();
|
||||
mOrigObjPos = Ogre::Vector3();
|
||||
mGrabbedSceneNode = "";
|
||||
mCurrentObj = "";
|
||||
mOldPos = QPoint(0, 0);
|
||||
mMouseEventTimer->invalidate();
|
||||
mOffset = 0.0f;
|
||||
|
||||
break;
|
||||
}
|
||||
case Mouse_Edit:
|
||||
case Mouse_Default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* NO_DEFAULT_CASE */
|
||||
}
|
||||
}
|
||||
|
||||
//plane Z, upvector Y, mOffset z : x-y plane, wheel up/down
|
||||
//plane Y, upvector X, mOffset y : y-z plane, wheel left/right
|
||||
//plane X, upvector Y, mOffset x : x-z plane, wheel closer/further
|
||||
std::pair<Ogre::Vector3, Ogre::Vector3> MouseState::planeAxis()
|
||||
{
|
||||
const bool screenCoord = true;
|
||||
Ogre::Vector3 dir = getCamera()->getDerivedDirection();
|
||||
|
||||
QString wheelDir = "Closer/Further";
|
||||
if(wheelDir == "Left/Right")
|
||||
{
|
||||
if(screenCoord)
|
||||
return std::make_pair(getCamera()->getDerivedRight(), getCamera()->getDerivedUp());
|
||||
else
|
||||
return std::make_pair(Ogre::Vector3::UNIT_Y, Ogre::Vector3::UNIT_Z);
|
||||
}
|
||||
else if(wheelDir == "Up/Down")
|
||||
{
|
||||
if(screenCoord)
|
||||
return std::make_pair(getCamera()->getDerivedUp(), Ogre::Vector3(-dir.x, -dir.y, -dir.z));
|
||||
else
|
||||
return std::make_pair(Ogre::Vector3::UNIT_Z, Ogre::Vector3::UNIT_X);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(screenCoord)
|
||||
return std::make_pair(Ogre::Vector3(-dir.x, -dir.y, -dir.z), getCamera()->getDerivedRight());
|
||||
else
|
||||
return std::make_pair(Ogre::Vector3::UNIT_X, Ogre::Vector3::UNIT_Y);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, Ogre::Vector3> MouseState::mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane)
|
||||
{
|
||||
// using a really small value seems to mess up with the projections
|
||||
float nearClipDistance = getCamera()->getNearClipDistance(); // save existing
|
||||
getCamera()->setNearClipDistance(10.0f); // arbitrary number
|
||||
Ogre::Ray mouseRay = getCamera()->getCameraToViewportRay(
|
||||
(float) pos.x() / getViewport()->getActualWidth(),
|
||||
(float) pos.y() / getViewport()->getActualHeight());
|
||||
getCamera()->setNearClipDistance(nearClipDistance); // restore
|
||||
std::pair<bool, float> planeResult = mouseRay.intersects(plane);
|
||||
|
||||
if(planeResult.first)
|
||||
return std::make_pair(true, mouseRay.getPoint(planeResult.second));
|
||||
else
|
||||
return std::make_pair(false, Ogre::Vector3()); // should only happen if the plane is too small
|
||||
}
|
||||
|
||||
std::pair<std::string, Ogre::Vector3> MouseState::terrainUnderCursor(const int mouseX, const int mouseY)
|
||||
{
|
||||
if(!getViewport())
|
||||
return std::make_pair("", Ogre::Vector3());
|
||||
|
||||
float x = (float) mouseX / getViewport()->getActualWidth();
|
||||
float y = (float) mouseY / getViewport()->getActualHeight();
|
||||
|
||||
std::pair<std::string, Ogre::Vector3> result = mPhysics->castRay(x, y, mSceneManager, getCamera());
|
||||
if(result.first != "")
|
||||
{
|
||||
// FIXME: is there a better way to distinguish terrain from objects?
|
||||
QString name = QString(result.first.c_str());
|
||||
if(name.contains(QRegExp("^HeightField")))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair("", Ogre::Vector3());
|
||||
}
|
||||
|
||||
std::pair<std::string, Ogre::Vector3> MouseState::objectUnderCursor(const int mouseX, const int mouseY)
|
||||
{
|
||||
if(!getViewport())
|
||||
return std::make_pair("", Ogre::Vector3());
|
||||
|
||||
float x = (float) mouseX / getViewport()->getActualWidth();
|
||||
float y = (float) mouseY / getViewport()->getActualHeight();
|
||||
|
||||
std::pair<std::string, Ogre::Vector3> result = mPhysics->castRay(x, y, mSceneManager, getCamera());
|
||||
if(result.first != "")
|
||||
{
|
||||
// NOTE: anything not terrain is assumed to be an object
|
||||
QString name = QString(result.first.c_str());
|
||||
if(!name.contains(QRegExp("^HeightField")))
|
||||
{
|
||||
uint32_t visibilityMask = getViewport()->getVisibilityMask();
|
||||
bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference);
|
||||
|
||||
if(!ignoreObjects && mSceneManager->hasSceneNode(result.first))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair("", Ogre::Vector3());
|
||||
}
|
||||
|
||||
void MouseState::updateSceneWidgets()
|
||||
{
|
||||
std::map<Ogre::SceneManager*, CSVRender::SceneWidget *> sceneWidgets = mPhysics->sceneWidgets();
|
||||
|
||||
std::map<Ogre::SceneManager*, CSVRender::SceneWidget *>::iterator iter = sceneWidgets.begin();
|
||||
for(; iter != sceneWidgets.end(); ++iter)
|
||||
{
|
||||
(*iter).second->updateScene();
|
||||
}
|
||||
}
|
||||
|
||||
Ogre::Camera *MouseState::getCamera()
|
||||
{
|
||||
return mParent->getCamera();
|
||||
}
|
||||
|
||||
Ogre::Viewport *MouseState::getViewport()
|
||||
{
|
||||
return mParent->getCamera()->getViewport();
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_MOUSESTATE_H
|
||||
#define OPENCS_VIEW_MOUSESTATE_H
|
||||
|
||||
#include <map>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <QPoint>
|
||||
#include <OgreVector3.h>
|
||||
|
||||
class QElapsedTimer;
|
||||
class QMouseEvent;
|
||||
class QWheelEvent;
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Plane;
|
||||
class SceneManager;
|
||||
class Camera;
|
||||
class Viewport;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class PhysicsSystem;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTable;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class WorldspaceWidget;
|
||||
|
||||
class MouseState
|
||||
{
|
||||
enum MouseStates
|
||||
{
|
||||
Mouse_Grab,
|
||||
Mouse_Drag,
|
||||
Mouse_Edit,
|
||||
Mouse_Default
|
||||
};
|
||||
MouseStates mMouseState;
|
||||
|
||||
WorldspaceWidget *mParent;
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||
Ogre::SceneManager *mSceneManager; // local copy
|
||||
|
||||
QPoint mOldPos;
|
||||
std::string mCurrentObj;
|
||||
std::string mGrabbedSceneNode;
|
||||
QElapsedTimer *mMouseEventTimer;
|
||||
Ogre::Plane *mPlane;
|
||||
Ogre::Vector3 mOrigObjPos;
|
||||
Ogre::Vector3 mOrigMousePos;
|
||||
Ogre::Vector3 mCurrentMousePos;
|
||||
float mOffset;
|
||||
|
||||
CSMWorld::IdTable *mIdTableModel;
|
||||
int mColIndexPosX;
|
||||
int mColIndexPosY;
|
||||
int mColIndexPosZ;
|
||||
|
||||
public:
|
||||
|
||||
MouseState(WorldspaceWidget *parent);
|
||||
~MouseState();
|
||||
|
||||
void mouseMoveEvent (QMouseEvent *event);
|
||||
void mousePressEvent (QMouseEvent *event);
|
||||
void mouseReleaseEvent (QMouseEvent *event);
|
||||
void mouseDoubleClickEvent (QMouseEvent *event);
|
||||
bool wheelEvent (QWheelEvent *event);
|
||||
|
||||
void cancelDrag();
|
||||
|
||||
private:
|
||||
|
||||
std::pair<bool, Ogre::Vector3> mousePositionOnPlane(const QPoint &pos, const Ogre::Plane &plane);
|
||||
std::pair<std::string, Ogre::Vector3> terrainUnderCursor(const int mouseX, const int mouseY);
|
||||
std::pair<std::string, Ogre::Vector3> objectUnderCursor(const int mouseX, const int mouseY);
|
||||
std::pair<Ogre::Vector3, Ogre::Vector3> planeAxis();
|
||||
void updateSceneWidgets();
|
||||
|
||||
Ogre::Camera *getCamera(); // friend access
|
||||
Ogre::Viewport *getViewport(); // friend access
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OPENCS_VIEW_MOUSESTATE_H
|
@ -1,24 +0,0 @@
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
float CSVRender::Navigation::getFactor (bool mouse) const
|
||||
{
|
||||
float factor = mFastModeFactor;
|
||||
|
||||
if (mouse)
|
||||
factor /= 2; /// \todo make this configurable
|
||||
|
||||
return factor;
|
||||
}
|
||||
|
||||
CSVRender::Navigation::Navigation()
|
||||
: mFastModeFactor(1)
|
||||
{
|
||||
}
|
||||
|
||||
CSVRender::Navigation::~Navigation() {}
|
||||
|
||||
void CSVRender::Navigation::setFastModeFactor (float factor)
|
||||
{
|
||||
mFastModeFactor = factor;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATION_H
|
||||
#define OPENCS_VIEW_NAVIGATION_H
|
||||
|
||||
class QPoint;
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Camera;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Navigation
|
||||
{
|
||||
float mFastModeFactor;
|
||||
|
||||
protected:
|
||||
|
||||
float getFactor (bool mouse) const;
|
||||
|
||||
public:
|
||||
|
||||
Navigation();
|
||||
virtual ~Navigation();
|
||||
|
||||
void setFastModeFactor (float factor);
|
||||
///< Set currently applying fast mode factor.
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera) = 0;
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta) = 0;
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode) = 0;
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal) = 0;
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta) = 0;
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,86 +0,0 @@
|
||||
|
||||
#include "navigation1st.hpp"
|
||||
|
||||
#include <OgreCamera.h>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
CSVRender::Navigation1st::Navigation1st() : mCamera (0) {}
|
||||
|
||||
bool CSVRender::Navigation1st::activate (Ogre::Camera *camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mCamera->setFixedYawAxis (true, Ogre::Vector3::UNIT_Z);
|
||||
|
||||
Ogre::Radian pitch = mCamera->getOrientation().getPitch();
|
||||
|
||||
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
||||
|
||||
if (pitch>limit)
|
||||
mCamera->pitch (-(pitch-limit));
|
||||
else if (pitch<-limit)
|
||||
mCamera->pitch (pitch-limit);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::wheelMoved (int delta)
|
||||
{
|
||||
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::mouseMoved (const QPoint& delta, int mode)
|
||||
{
|
||||
if (mode==0)
|
||||
{
|
||||
// turn camera
|
||||
if (delta.x())
|
||||
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||
|
||||
if (delta.y())
|
||||
{
|
||||
Ogre::Radian oldPitch = mCamera->getOrientation().getPitch();
|
||||
float deltaPitch = getFactor (true) * delta.y();
|
||||
Ogre::Radian newPitch = oldPitch + Ogre::Degree (deltaPitch);
|
||||
|
||||
if ((deltaPitch>0 && newPitch<Ogre::Radian(Ogre::Math::PI-0.5)) ||
|
||||
(deltaPitch<0 && newPitch>Ogre::Radian(0.5)))
|
||||
{
|
||||
mCamera->pitch (Ogre::Degree (deltaPitch));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (mode==1)
|
||||
{
|
||||
// pan camera
|
||||
if (delta.x())
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||
|
||||
if (delta.y())
|
||||
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::handleMovementKeys (int vertical, int horizontal)
|
||||
{
|
||||
if (vertical)
|
||||
mCamera->move (getFactor (false) * mCamera->getDirection() * vertical);
|
||||
|
||||
if (horizontal)
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::Navigation1st::handleRollKeys (int delta)
|
||||
{
|
||||
// we don't roll this way in 1st person mode
|
||||
return false;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATION1ST_H
|
||||
#define OPENCS_VIEW_NAVIGATION1ST_H
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
/// \brief First person-like camera controls
|
||||
class Navigation1st : public Navigation
|
||||
{
|
||||
Ogre::Camera *mCamera;
|
||||
|
||||
public:
|
||||
|
||||
Navigation1st();
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta);
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,66 +0,0 @@
|
||||
|
||||
#include "navigationfree.hpp"
|
||||
|
||||
#include <OgreCamera.h>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
CSVRender::NavigationFree::NavigationFree() : mCamera (0) {}
|
||||
|
||||
bool CSVRender::NavigationFree::activate (Ogre::Camera *camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mCamera->setFixedYawAxis (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::wheelMoved (int delta)
|
||||
{
|
||||
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::mouseMoved (const QPoint& delta, int mode)
|
||||
{
|
||||
if (mode==0)
|
||||
{
|
||||
// turn camera
|
||||
if (delta.x())
|
||||
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||
|
||||
if (delta.y())
|
||||
mCamera->pitch (Ogre::Degree (getFactor (true) * delta.y()));
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (mode==1)
|
||||
{
|
||||
// pan camera
|
||||
if (delta.x())
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||
|
||||
if (delta.y())
|
||||
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::handleMovementKeys (int vertical, int horizontal)
|
||||
{
|
||||
if (vertical)
|
||||
mCamera->move (getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||
|
||||
if (horizontal)
|
||||
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationFree::handleRollKeys (int delta)
|
||||
{
|
||||
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||
return true;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATIONFREE_H
|
||||
#define OPENCS_VIEW_NAVIGATIONFREE_H
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
/// \brief Free camera controls
|
||||
class NavigationFree : public Navigation
|
||||
{
|
||||
Ogre::Camera *mCamera;
|
||||
|
||||
public:
|
||||
|
||||
NavigationFree();
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta);
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,100 +0,0 @@
|
||||
|
||||
#include "navigationorbit.hpp"
|
||||
|
||||
#include <OgreCamera.h>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
void CSVRender::NavigationOrbit::rotateCamera (const Ogre::Vector3& diff)
|
||||
{
|
||||
Ogre::Vector3 pos = mCamera->getPosition();
|
||||
|
||||
float distance = (pos-mCentre).length();
|
||||
|
||||
Ogre::Vector3 direction = (pos+diff)-mCentre;
|
||||
direction.normalise();
|
||||
|
||||
mCamera->setPosition (mCentre + direction*distance);
|
||||
mCamera->lookAt (mCentre);
|
||||
}
|
||||
|
||||
CSVRender::NavigationOrbit::NavigationOrbit() : mCamera (0), mCentre (0, 0, 0), mDistance (100)
|
||||
{}
|
||||
|
||||
bool CSVRender::NavigationOrbit::activate (Ogre::Camera *camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mCamera->setFixedYawAxis (false);
|
||||
|
||||
if ((mCamera->getPosition()-mCentre).length()<mDistance)
|
||||
{
|
||||
// move camera out of the centre area
|
||||
Ogre::Vector3 direction = mCentre-mCamera->getPosition();
|
||||
direction.normalise();
|
||||
|
||||
if (direction.length()==0)
|
||||
direction = Ogre::Vector3 (1, 0, 0);
|
||||
|
||||
mCamera->setPosition (mCentre - direction * mDistance);
|
||||
}
|
||||
|
||||
mCamera->lookAt (mCentre);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::wheelMoved (int delta)
|
||||
{
|
||||
Ogre::Vector3 diff = getFactor (true) * mCamera->getDirection() * delta;
|
||||
|
||||
Ogre::Vector3 pos = mCamera->getPosition();
|
||||
|
||||
if (delta>0 && diff.length()>=(pos-mCentre).length()-mDistance)
|
||||
{
|
||||
pos = mCentre-(mCamera->getDirection() * mDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos += diff;
|
||||
}
|
||||
|
||||
mCamera->setPosition (pos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::mouseMoved (const QPoint& delta, int mode)
|
||||
{
|
||||
Ogre::Vector3 diff =
|
||||
getFactor (true) * -mCamera->getDerivedRight() * delta.x()
|
||||
+ getFactor (true) * mCamera->getDerivedUp() * delta.y();
|
||||
|
||||
if (mode==0)
|
||||
{
|
||||
rotateCamera (diff);
|
||||
return true;
|
||||
}
|
||||
else if (mode==1)
|
||||
{
|
||||
mCamera->move (diff);
|
||||
mCentre += diff;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::handleMovementKeys (int vertical, int horizontal)
|
||||
{
|
||||
rotateCamera (
|
||||
- getFactor (false) * -mCamera->getDerivedRight() * horizontal
|
||||
+ getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSVRender::NavigationOrbit::handleRollKeys (int delta)
|
||||
{
|
||||
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||
return true;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||
#define OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||
|
||||
#include "navigation.hpp"
|
||||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
/// \brief Orbiting camera controls
|
||||
class NavigationOrbit : public Navigation
|
||||
{
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::Vector3 mCentre;
|
||||
int mDistance;
|
||||
|
||||
void rotateCamera (const Ogre::Vector3& diff);
|
||||
///< Rotate camera around centre.
|
||||
|
||||
public:
|
||||
|
||||
NavigationOrbit();
|
||||
|
||||
virtual bool activate (Ogre::Camera *camera);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool wheelMoved (int delta);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||
/// \return Update required?
|
||||
|
||||
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||
///< \return Update required?
|
||||
|
||||
virtual bool handleRollKeys (int delta);
|
||||
///< \return Update required?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,53 +1,51 @@
|
||||
|
||||
#include "object.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/Shape>
|
||||
#include <osg/Geode>
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/ref.hpp"
|
||||
#include "../../model/world/refidcollection.hpp"
|
||||
|
||||
#include "../world/physicssystem.hpp"
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/sceneutil/clone.hpp>
|
||||
|
||||
#include "elements.hpp"
|
||||
|
||||
void CSVRender::Object::clearSceneNode (Ogre::SceneNode *node)
|
||||
namespace
|
||||
{
|
||||
for (Ogre::SceneNode::ObjectIterator iter = node->getAttachedObjectIterator();
|
||||
iter.hasMoreElements(); )
|
||||
|
||||
osg::ref_ptr<osg::Geode> createErrorCube()
|
||||
{
|
||||
Ogre::MovableObject* object = dynamic_cast<Ogre::MovableObject*> (iter.getNext());
|
||||
node->getCreator()->destroyMovableObject (object);
|
||||
osg::ref_ptr<osg::Box> shape(new osg::Box(osg::Vec3f(0,0,0), 50.f));
|
||||
osg::ref_ptr<osg::ShapeDrawable> shapedrawable(new osg::ShapeDrawable);
|
||||
shapedrawable->setShape(shape);
|
||||
|
||||
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
||||
geode->addDrawable(shapedrawable);
|
||||
return geode;
|
||||
}
|
||||
|
||||
for (Ogre::SceneNode::ChildNodeIterator iter = node->getChildIterator();
|
||||
iter.hasMoreElements(); )
|
||||
{
|
||||
Ogre::SceneNode* childNode = dynamic_cast<Ogre::SceneNode*> (iter.getNext());
|
||||
clearSceneNode (childNode);
|
||||
node->getCreator()->destroySceneNode (childNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSVRender::Object::clear()
|
||||
{
|
||||
mObject.setNull();
|
||||
|
||||
if (mBase)
|
||||
clearSceneNode (mBase);
|
||||
}
|
||||
|
||||
void CSVRender::Object::update()
|
||||
{
|
||||
if(!mObject.isNull())
|
||||
mPhysics->removePhysicsObject(mBase->getName());
|
||||
|
||||
clear();
|
||||
|
||||
std::string model;
|
||||
int error = 0; // 1 referemceanöe does not exist, 2 referenceable does not specify a mesh
|
||||
int error = 0; // 1 referenceable does not exist, 2 referenceable does not specify a mesh
|
||||
|
||||
const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables();
|
||||
|
||||
@ -67,39 +65,29 @@ void CSVRender::Object::update()
|
||||
error = 2;
|
||||
}
|
||||
|
||||
mBaseNode->removeChildren(0, mBaseNode->getNumChildren());
|
||||
|
||||
if (error)
|
||||
{
|
||||
Ogre::Entity* entity = mBase->getCreator()->createEntity (Ogre::SceneManager::PT_CUBE);
|
||||
entity->setMaterialName("BaseWhite"); /// \todo adjust material according to error
|
||||
entity->setVisibilityFlags (Element_Reference);
|
||||
|
||||
mBase->attachObject (entity);
|
||||
mBaseNode->addChild(createErrorCube());
|
||||
}
|
||||
else
|
||||
{
|
||||
mObject = NifOgre::Loader::createObjects (mBase, "Meshes\\" + model);
|
||||
mObject->setVisibilityFlags (Element_Reference);
|
||||
|
||||
if (mPhysics && !mReferenceId.empty())
|
||||
try
|
||||
{
|
||||
const CSMWorld::CellRef& reference = getReference();
|
||||
std::string path = "meshes\\" + model;
|
||||
|
||||
// position
|
||||
Ogre::Vector3 position;
|
||||
if (!mForceBaseToZero)
|
||||
position = Ogre::Vector3(reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]);
|
||||
|
||||
// orientation
|
||||
Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.rot[0]), Ogre::Vector3::UNIT_X);
|
||||
Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.rot[1]), Ogre::Vector3::UNIT_Y);
|
||||
Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||
|
||||
mPhysics->addObject("meshes\\" + model, mBase->getName(), mReferenceId, reference.mScale, position, xr*yr*zr);
|
||||
mResourceSystem->getSceneManager()->createInstance(path, mBaseNode);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
// TODO: use error marker mesh
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::Object::adjust()
|
||||
void CSVRender::Object::adjustTransform()
|
||||
{
|
||||
if (mReferenceId.empty())
|
||||
return;
|
||||
@ -107,21 +95,15 @@ void CSVRender::Object::adjust()
|
||||
const CSMWorld::CellRef& reference = getReference();
|
||||
|
||||
// position
|
||||
if (!mForceBaseToZero)
|
||||
mBase->setPosition (Ogre::Vector3 (
|
||||
reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]));
|
||||
mBaseNode->setPosition(mForceBaseToZero ? osg::Vec3() : osg::Vec3f(reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]));
|
||||
|
||||
// orientation
|
||||
Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.rot[0]), Ogre::Vector3::UNIT_X);
|
||||
osg::Quat xr (-reference.mPos.rot[0], osg::Vec3f(1,0,0));
|
||||
osg::Quat yr (-reference.mPos.rot[1], osg::Vec3f(0,1,0));
|
||||
osg::Quat zr (-reference.mPos.rot[2], osg::Vec3f(0,0,1));
|
||||
mBaseNode->setAttitude(zr*yr*xr);
|
||||
|
||||
Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.rot[1]), Ogre::Vector3::UNIT_Y);
|
||||
|
||||
Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||
|
||||
mBase->setOrientation (xr*yr*zr);
|
||||
|
||||
// scale
|
||||
mBase->setScale (reference.mScale, reference.mScale, reference.mScale);
|
||||
mBaseNode->setScale(osg::Vec3(reference.mScale, reference.mScale, reference.mScale));
|
||||
}
|
||||
|
||||
const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||
@ -132,12 +114,15 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||
return mData.getReferences().getRecord (mReferenceId).get();
|
||||
}
|
||||
|
||||
CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
||||
const std::string& id, bool referenceable, boost::shared_ptr<CSVWorld::PhysicsSystem> physics,
|
||||
bool forceBaseToZero)
|
||||
: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics)
|
||||
CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
||||
const std::string& id, bool referenceable, bool forceBaseToZero)
|
||||
: mData (data), mBaseNode(0), mParentNode(parentNode), mResourceSystem(data.getResourceSystem()), mForceBaseToZero (forceBaseToZero)
|
||||
{
|
||||
mBase = cellNode->createChildSceneNode();
|
||||
mBaseNode = new osg::PositionAttitudeTransform;
|
||||
parentNode->addChild(mBaseNode);
|
||||
|
||||
// 0x1 reserved for separating cull and update visitors
|
||||
mBaseNode->setNodeMask(Element_Reference<<1);
|
||||
|
||||
if (referenceable)
|
||||
{
|
||||
@ -149,21 +134,15 @@ CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode
|
||||
mReferenceableId = getReference().mRefID;
|
||||
}
|
||||
|
||||
adjustTransform();
|
||||
update();
|
||||
adjust();
|
||||
}
|
||||
|
||||
CSVRender::Object::~Object()
|
||||
{
|
||||
clear();
|
||||
|
||||
if (mBase)
|
||||
{
|
||||
if(mPhysics) // preview may not have physics enabled
|
||||
mPhysics->removeObject(mBase->getName());
|
||||
|
||||
mBase->getCreator()->destroySceneNode (mBase);
|
||||
}
|
||||
mParentNode->removeChild(mBaseNode);
|
||||
}
|
||||
|
||||
bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
@ -175,8 +154,8 @@ bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
|
||||
if (index!=-1 && index>=topLeft.row() && index<=bottomRight.row())
|
||||
{
|
||||
adjustTransform();
|
||||
update();
|
||||
adjust();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -195,8 +174,8 @@ bool CSVRender::Object::referenceableAboutToBeRemoved (const QModelIndex& parent
|
||||
// Deletion of referenceable-type objects is handled outside of Object.
|
||||
if (!mReferenceId.empty())
|
||||
{
|
||||
adjustTransform();
|
||||
update();
|
||||
adjust();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -219,6 +198,8 @@ bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft,
|
||||
int columnIndex =
|
||||
references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
|
||||
|
||||
adjustTransform();
|
||||
|
||||
if (columnIndex>=topLeft.column() && columnIndex<=bottomRight.row())
|
||||
{
|
||||
mReferenceableId =
|
||||
@ -227,8 +208,6 @@ bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft,
|
||||
update();
|
||||
}
|
||||
|
||||
adjust();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,24 @@
|
||||
#ifndef OPENCS_VIEW_OBJECT_H
|
||||
#define OPENCS_VIEW_OBJECT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/nifogre/ogrenifloader.hpp>
|
||||
#endif
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
namespace Ogre
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class SceneNode;
|
||||
class PositionAttitudeTransform;
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
class ResourceSystem;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
@ -20,11 +27,6 @@ namespace CSMWorld
|
||||
struct CellRef;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class PhysicsSystem;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Object
|
||||
@ -32,10 +34,10 @@ namespace CSVRender
|
||||
const CSMWorld::Data& mData;
|
||||
std::string mReferenceId;
|
||||
std::string mReferenceableId;
|
||||
Ogre::SceneNode *mBase;
|
||||
NifOgre::ObjectScenePtr mObject;
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||
osg::Group* mParentNode;
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
bool mForceBaseToZero;
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||
|
||||
/// Not implemented
|
||||
Object (const Object&);
|
||||
@ -43,26 +45,23 @@ namespace CSVRender
|
||||
/// Not implemented
|
||||
Object& operator= (const Object&);
|
||||
|
||||
/// Destroy all scene nodes and movable objects attached to node.
|
||||
static void clearSceneNode (Ogre::SceneNode *node);
|
||||
|
||||
/// Remove object from node (includes deleting)
|
||||
void clear();
|
||||
|
||||
/// Update model
|
||||
/// @note Make sure adjustTransform() was called first so world space particles get positioned correctly
|
||||
void update();
|
||||
|
||||
/// Adjust position, orientation and scale
|
||||
void adjust();
|
||||
void adjustTransform();
|
||||
|
||||
/// Throws an exception if *this was constructed with referenceable
|
||||
const CSMWorld::CellRef& getReference() const;
|
||||
|
||||
public:
|
||||
|
||||
Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
||||
Object (CSMWorld::Data& data, osg::Group *cellNode,
|
||||
const std::string& id, bool referenceable,
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> physics = boost::shared_ptr<CSVWorld::PhysicsSystem> (),
|
||||
bool forceBaseToZero = false);
|
||||
/// \param forceBaseToZero If this is a reference ignore the coordinates and place
|
||||
/// it at 0, 0, 0 instead.
|
||||
|
@ -1,52 +0,0 @@
|
||||
#include "overlaymask.hpp"
|
||||
|
||||
#include <OgreOverlayManager.h>
|
||||
#include <OgreOverlayContainer.h>
|
||||
|
||||
#include "textoverlay.hpp"
|
||||
#include "../../model/world/cellcoordinates.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
// ideas from http://www.ogre3d.org/forums/viewtopic.php?f=5&t=44828#p486334
|
||||
OverlayMask::OverlayMask(std::map<CSMWorld::CellCoordinates, TextOverlay *> &overlays, Ogre::Viewport* viewport)
|
||||
: mTextOverlays(overlays), mViewport(viewport)
|
||||
{
|
||||
}
|
||||
|
||||
OverlayMask::~OverlayMask()
|
||||
{
|
||||
}
|
||||
|
||||
void OverlayMask::setViewport(Ogre::Viewport *viewport)
|
||||
{
|
||||
mViewport = viewport;
|
||||
}
|
||||
|
||||
void OverlayMask::preViewportUpdate(const Ogre::RenderTargetViewportEvent &event)
|
||||
{
|
||||
if(event.source == mViewport)
|
||||
{
|
||||
Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton();
|
||||
for(Ogre::OverlayManager::OverlayMapIterator iter = overlayMgr.getOverlayIterator();
|
||||
iter.hasMoreElements();)
|
||||
{
|
||||
Ogre::Overlay* item = iter.getNext();
|
||||
for(Ogre::Overlay::Overlay2DElementsIterator it = item->get2DElementsIterator();
|
||||
it.hasMoreElements();)
|
||||
{
|
||||
Ogre::OverlayContainer* container = it.getNext();
|
||||
if(container) container->hide();
|
||||
}
|
||||
}
|
||||
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *>::iterator it = mTextOverlays.begin();
|
||||
for(; it != mTextOverlays.end(); ++it)
|
||||
{
|
||||
it->second->show(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_OVERLAYMASK_H
|
||||
#define OPENCS_VIEW_OVERLAYMASK_H
|
||||
|
||||
#include <OgreRenderTargetListener.h>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Viewport;
|
||||
class RendertargetViewportEvent;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class CellCoordinates;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class TextOverlay;
|
||||
|
||||
class OverlayMask : public Ogre::RenderTargetListener
|
||||
{
|
||||
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *> &mTextOverlays;
|
||||
Ogre::Viewport* mViewport;
|
||||
|
||||
public:
|
||||
|
||||
OverlayMask(std::map<CSMWorld::CellCoordinates, TextOverlay *> &overlays,
|
||||
Ogre::Viewport* viewport);
|
||||
|
||||
virtual ~OverlayMask();
|
||||
|
||||
void setViewport(Ogre::Viewport *viewport);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void preViewportUpdate(const Ogre::RenderTargetViewportEvent &event);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OPENCS_VIEW_OVERLAYMASK_H
|
@ -1,34 +0,0 @@
|
||||
#include "overlaysystem.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <OgreOverlaySystem.h>
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
OverlaySystem *OverlaySystem::mOverlaySystemInstance = 0;
|
||||
|
||||
OverlaySystem::OverlaySystem()
|
||||
{
|
||||
assert(!mOverlaySystemInstance);
|
||||
mOverlaySystemInstance = this;
|
||||
mOverlaySystem = new Ogre::OverlaySystem();
|
||||
}
|
||||
|
||||
OverlaySystem::~OverlaySystem()
|
||||
{
|
||||
delete mOverlaySystem;
|
||||
}
|
||||
|
||||
OverlaySystem &OverlaySystem::instance()
|
||||
{
|
||||
assert(mOverlaySystemInstance);
|
||||
return *mOverlaySystemInstance;
|
||||
}
|
||||
|
||||
Ogre::OverlaySystem *OverlaySystem::get()
|
||||
{
|
||||
return mOverlaySystem;
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_OVERLAYSYSTEM_H
|
||||
#define OPENCS_VIEW_OVERLAYSYSTEM_H
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class OverlaySystem;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class OverlaySystem
|
||||
{
|
||||
Ogre::OverlaySystem *mOverlaySystem;
|
||||
static OverlaySystem *mOverlaySystemInstance;
|
||||
|
||||
public:
|
||||
|
||||
OverlaySystem();
|
||||
~OverlaySystem();
|
||||
static OverlaySystem &instance();
|
||||
|
||||
Ogre::OverlaySystem *get();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OPENCS_VIEW_OVERLAYSYSTEM_H
|
@ -5,17 +5,9 @@
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreManualObject.h>
|
||||
#include <OgreOverlayContainer.h>
|
||||
#include <OgreOverlayManager.h>
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreSceneQuery.h>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include <components/esm/loadland.hpp>
|
||||
#include "textoverlay.hpp"
|
||||
#include "overlaymask.hpp"
|
||||
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
@ -30,7 +22,6 @@
|
||||
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||
{
|
||||
bool modified = false;
|
||||
bool setCamera = false;
|
||||
|
||||
const CSMWorld::IdCollection<CSMWorld::Cell>& cells = mDocument.getData().getCells();
|
||||
|
||||
@ -45,17 +36,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||
if (!mSelection.has (iter->first) || index==-1 ||
|
||||
cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted)
|
||||
{
|
||||
// delete overlays
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *>::iterator itOverlay = mTextOverlays.find(iter->first);
|
||||
if(itOverlay != mTextOverlays.end())
|
||||
{
|
||||
delete itOverlay->second;
|
||||
mTextOverlays.erase(itOverlay);
|
||||
}
|
||||
|
||||
// destroy manual objects
|
||||
getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace));
|
||||
|
||||
delete iter->second;
|
||||
mCells.erase (iter++);
|
||||
|
||||
@ -65,43 +45,16 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||
{
|
||||
// check if name or region field has changed
|
||||
// FIXME: config setting
|
||||
std::string name = cells.getRecord(index).get().mName;
|
||||
std::string region = cells.getRecord(index).get().mRegion;
|
||||
//std::string name = cells.getRecord(index).get().mName;
|
||||
//std::string region = cells.getRecord(index).get().mRegion;
|
||||
|
||||
// cell marker update goes here
|
||||
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *>::iterator it = mTextOverlays.find(iter->first);
|
||||
if(it != mTextOverlays.end())
|
||||
{
|
||||
if(it->second->getDesc() != "") // previously had name
|
||||
{
|
||||
if(name != it->second->getDesc()) // new name
|
||||
{
|
||||
if(name != "")
|
||||
it->second->setDesc(name);
|
||||
else // name deleted, use region
|
||||
it->second->setDesc(region);
|
||||
it->second->update();
|
||||
}
|
||||
}
|
||||
else if(name != "") // name added
|
||||
{
|
||||
it->second->setDesc(name);
|
||||
it->second->update();
|
||||
}
|
||||
else if(region != it->second->getDesc()) // new region
|
||||
{
|
||||
it->second->setDesc(region);
|
||||
it->second->update();
|
||||
}
|
||||
modified = true;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mCells.begin()==mCells.end())
|
||||
setCamera = true;
|
||||
|
||||
// add
|
||||
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
|
||||
++iter)
|
||||
@ -111,108 +64,20 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||
if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted &&
|
||||
mCells.find (*iter)==mCells.end())
|
||||
{
|
||||
Cell *cell = new Cell (mDocument.getData(), getSceneManager(),
|
||||
iter->getId (mWorldspace), mDocument.getPhysics());
|
||||
Cell *cell = new Cell (mDocument.getData(), mRootNode,
|
||||
iter->getId (mWorldspace));
|
||||
mCells.insert (std::make_pair (*iter, cell));
|
||||
|
||||
float height = cell->getTerrainHeightAt(Ogre::Vector3(
|
||||
ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2,
|
||||
ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2,
|
||||
0));
|
||||
if (setCamera)
|
||||
{
|
||||
setCamera = false;
|
||||
getCamera()->setPosition (
|
||||
ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2,
|
||||
ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2,
|
||||
height);
|
||||
// better camera position at the start
|
||||
getCamera()->move(getCamera()->getDirection() * -6000); // FIXME: config setting
|
||||
}
|
||||
|
||||
Ogre::ManualObject* manual =
|
||||
getSceneManager()->createManualObject("manual" + iter->getId(mWorldspace));
|
||||
manual->begin("BaseWhite", Ogre::RenderOperation::OT_LINE_LIST);
|
||||
// define start and end point (x, y, z)
|
||||
manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2,
|
||||
ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2,
|
||||
height);
|
||||
manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2,
|
||||
ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2,
|
||||
height+200); // FIXME: config setting
|
||||
manual->end();
|
||||
manual->setBoundingBox(Ogre::AxisAlignedBox(
|
||||
ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2,
|
||||
ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2,
|
||||
height,
|
||||
ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2,
|
||||
ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2,
|
||||
height+200));
|
||||
getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
|
||||
manual->setVisible(false);
|
||||
|
||||
CSVRender::TextOverlay *textDisp =
|
||||
new CSVRender::TextOverlay(manual, getCamera(), iter->getId(mWorldspace));
|
||||
textDisp->enable(true);
|
||||
textDisp->setCaption(iter->getId(mWorldspace));
|
||||
std::string desc = cells.getRecord(index).get().mName;
|
||||
if(desc == "") desc = cells.getRecord(index).get().mRegion;
|
||||
textDisp->setDesc(desc); // FIXME: config setting
|
||||
textDisp->update();
|
||||
mTextOverlays.insert(std::make_pair(*iter, textDisp));
|
||||
if(!mOverlayMask)
|
||||
{
|
||||
mOverlayMask = new OverlayMask(mTextOverlays, getViewport());
|
||||
addRenderTargetListener(mOverlayMask);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (modified)
|
||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::RightButton)
|
||||
{
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *>::iterator iter = mTextOverlays.begin();
|
||||
for(; iter != mTextOverlays.end(); ++iter)
|
||||
{
|
||||
if(mDisplayCellCoord &&
|
||||
iter->second->isEnabled() && iter->second->container().contains(event->x(), event->y()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
WorldspaceWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::RightButton)
|
||||
{
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *>::iterator iter = mTextOverlays.begin();
|
||||
for(; iter != mTextOverlays.end(); ++iter)
|
||||
{
|
||||
if(mDisplayCellCoord &&
|
||||
iter->second->isEnabled() && iter->second->container().contains(event->x(), event->y()))
|
||||
{
|
||||
std::cout << "clicked: " << iter->second->getCaption() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
WorldspaceWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event)
|
||||
{
|
||||
WorldspaceWidget::mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons (
|
||||
CSVWidget::SceneToolToggle2 *tool)
|
||||
{
|
||||
@ -241,28 +106,6 @@ void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
|
||||
"terrain-move");
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::updateOverlay()
|
||||
{
|
||||
if(getCamera()->getViewport())
|
||||
{
|
||||
if((uint32_t)getCamera()->getViewport()->getVisibilityMask()
|
||||
& (uint32_t)CSVRender::Element_CellMarker)
|
||||
mDisplayCellCoord = true;
|
||||
else
|
||||
mDisplayCellCoord = false;
|
||||
}
|
||||
|
||||
if(!mTextOverlays.empty())
|
||||
{
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *>::iterator it = mTextOverlays.begin();
|
||||
for(; it != mTextOverlays.end(); ++it)
|
||||
{
|
||||
it->second->enable(mDisplayCellCoord);
|
||||
it->second->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
@ -328,13 +171,12 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent
|
||||
|
||||
std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
||||
{
|
||||
Ogre::Vector3 position = getCamera()->getPosition();
|
||||
|
||||
osg::Vec3d position = mView->getCamera()->getViewMatrix().getTrans();
|
||||
std::ostringstream stream;
|
||||
|
||||
stream
|
||||
<< "player->position "
|
||||
<< position.x << ", " << position.y << ", " << position.z
|
||||
<< position.x() << ", " << position.y() << ", " << position.z()
|
||||
<< ", 0";
|
||||
|
||||
return stream.str();
|
||||
@ -342,7 +184,7 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction()
|
||||
|
||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
||||
: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"),
|
||||
mControlElements(NULL), mDisplayCellCoord(true), mOverlayMask(NULL)
|
||||
mControlElements(NULL), mDisplayCellCoord(true)
|
||||
{
|
||||
QAbstractItemModel *cells =
|
||||
document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells);
|
||||
@ -361,20 +203,6 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
|
||||
iter!=mCells.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
|
||||
getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace));
|
||||
}
|
||||
|
||||
for (std::map<CSMWorld::CellCoordinates, TextOverlay *>::iterator iter (mTextOverlays.begin());
|
||||
iter != mTextOverlays.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
|
||||
if(mOverlayMask)
|
||||
{
|
||||
removeRenderTargetListener(mOverlayMask);
|
||||
delete mOverlayMask;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,6 @@ namespace CSVRender
|
||||
std::string mWorldspace;
|
||||
CSVWidget::SceneToolToggle *mControlElements;
|
||||
bool mDisplayCellCoord;
|
||||
std::map<CSMWorld::CellCoordinates, TextOverlay *> mTextOverlays;
|
||||
OverlayMask *mOverlayMask;
|
||||
|
||||
private:
|
||||
|
||||
@ -87,14 +85,6 @@ namespace CSVRender
|
||||
|
||||
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
||||
|
||||
virtual void updateOverlay();
|
||||
|
||||
virtual void mousePressEvent (QMouseEvent *event);
|
||||
|
||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||
|
||||
virtual void mouseDoubleClickEvent (QMouseEvent *event);
|
||||
|
||||
signals:
|
||||
|
||||
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
||||
|
@ -1,18 +1,16 @@
|
||||
|
||||
#include "previewwidget.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||
const std::string& id, bool referenceable, QWidget *parent)
|
||||
: SceneWidget (parent), mData (data),
|
||||
mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, boost::shared_ptr<CSVWorld::PhysicsSystem>(), true)
|
||||
: SceneWidget (data.getResourceSystem()->getSceneManager(), parent), mData (data), mObject(data, mRootNode, id, referenceable)
|
||||
{
|
||||
setNavigation (&mOrbit);
|
||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||
|
||||
QAbstractItemModel *referenceables =
|
||||
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
||||
|
@ -3,11 +3,15 @@
|
||||
|
||||
#include "scenewidget.hpp"
|
||||
|
||||
#include "navigationorbit.hpp"
|
||||
#include "object.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
@ -20,8 +24,7 @@ namespace CSVRender
|
||||
Q_OBJECT
|
||||
|
||||
CSMWorld::Data& mData;
|
||||
CSVRender::NavigationOrbit mOrbit;
|
||||
Object mObject;
|
||||
CSVRender::Object mObject;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -4,467 +4,221 @@
|
||||
#include <QResizeEvent>
|
||||
#include <QTimer>
|
||||
#include <QShortcut>
|
||||
#include <QLayout>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreOverlaySystem.h>
|
||||
#include <osgQt/GraphicsWindowQt>
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osg/LightModel>
|
||||
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
|
||||
#include "../widget/scenetoolmode.hpp"
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
#include "navigation.hpp"
|
||||
#include "lighting.hpp"
|
||||
#include "overlaysystem.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
SceneWidget::SceneWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, mCamera(NULL)
|
||||
, mSceneMgr(NULL)
|
||||
, mWindow(NULL)
|
||||
, mViewport(NULL)
|
||||
, mNavigation (0), mLighting (0), mUpdate (false), mKeyForward (false)
|
||||
, mKeyBackward (false), mKeyLeft (false), mKeyRight (false)
|
||||
, mKeyRollLeft (false), mKeyRollRight (false)
|
||||
, mFast (false), mDragging (false), mMod1 (false)
|
||||
, mFastFactor (4)
|
||||
, mDefaultAmbient (0, 0, 0, 0), mHasDefaultAmbient (false)
|
||||
{
|
||||
setAttribute(Qt::WA_PaintOnScreen);
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
|
||||
setFocusPolicy (Qt::StrongFocus);
|
||||
RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f)
|
||||
: QWidget(parent, f)
|
||||
, mRootNode(0)
|
||||
{
|
||||
|
||||
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
|
||||
osgViewer::CompositeViewer& viewer = CompositeViewer::get();
|
||||
|
||||
mSceneMgr->setAmbientLight (Ogre::ColourValue (0,0,0,1));
|
||||
osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
|
||||
//ds->setNumMultiSamples(8);
|
||||
|
||||
mCamera = mSceneMgr->createCamera("foo");
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
||||
traits->windowName = "";
|
||||
traits->windowDecoration = true;
|
||||
traits->x = 0;
|
||||
traits->y = 0;
|
||||
traits->width = width();
|
||||
traits->height = height();
|
||||
traits->doubleBuffer = true;
|
||||
traits->alpha = ds->getMinimumNumAlphaBits();
|
||||
traits->stencil = ds->getMinimumNumStencilBits();
|
||||
traits->sampleBuffers = ds->getMultiSamples();
|
||||
traits->samples = ds->getNumMultiSamples();
|
||||
// Doesn't make much sense as we're running on demand updates, and there seems to be a bug with the refresh rate when running multiple QGLWidgets
|
||||
traits->vsync = false;
|
||||
|
||||
mCamera->setPosition (300, 0, 0);
|
||||
mCamera->lookAt (0, 0, 0);
|
||||
mCamera->setNearClipDistance (0.1);
|
||||
mView = new osgViewer::View;
|
||||
|
||||
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
|
||||
osg::ref_ptr<osgQt::GraphicsWindowQt> window = new osgQt::GraphicsWindowQt(traits.get());
|
||||
QLayout* layout = new QHBoxLayout(this);
|
||||
layout->addWidget(window->getGLWidget());
|
||||
setLayout(layout);
|
||||
|
||||
float farClipDist = userSettings.setting("3d-render/far-clip-distance", QString("300000")).toFloat();
|
||||
mCamera->setFarClipDistance (farClipDist);
|
||||
mView->getCamera()->setGraphicsContext(window);
|
||||
mView->getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) );
|
||||
mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );
|
||||
mView->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );
|
||||
|
||||
mFastFactor = userSettings.setting("scene-input/fast-factor", QString("4")).toInt();
|
||||
mRootNode = new osg::Group;
|
||||
|
||||
mCamera->roll (Ogre::Degree (90));
|
||||
mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
|
||||
mView->getCamera()->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
|
||||
|
||||
setLighting (&mLightingDay);
|
||||
mView->setSceneData(mRootNode);
|
||||
|
||||
mOverlaySystem = OverlaySystem::instance().get();
|
||||
mSceneMgr->addRenderQueueListener(mOverlaySystem);
|
||||
// Press S to reveal profiling stats
|
||||
mView->addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
QTimer *timer = new QTimer (this);
|
||||
mView->getCamera()->setCullMask(~(0x1));
|
||||
|
||||
viewer.addView(mView);
|
||||
viewer.setDone(false);
|
||||
viewer.realize();
|
||||
}
|
||||
|
||||
RenderWidget::~RenderWidget()
|
||||
{
|
||||
CompositeViewer::get().removeView(mView);
|
||||
}
|
||||
|
||||
void RenderWidget::flagAsModified()
|
||||
{
|
||||
mView->requestRedraw();
|
||||
}
|
||||
|
||||
void RenderWidget::setVisibilityMask(int mask)
|
||||
{
|
||||
// 0x1 reserved for separating cull and update visitors
|
||||
mView->getCamera()->setCullMask(mask<<1);
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
|
||||
CompositeViewer::CompositeViewer()
|
||||
: mSimulationTime(0.0)
|
||||
{
|
||||
#if QT_VERSION >= 0x050000
|
||||
// Qt5 is currently crashing and reporting "Cannot make QOpenGLContext current in a different thread" when the viewer is run multi-threaded, this is regression from Qt4
|
||||
osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::SingleThreaded;
|
||||
#else
|
||||
osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;
|
||||
#endif
|
||||
|
||||
setThreadingModel(threadingModel);
|
||||
|
||||
// disable the default setting of viewer.done() by pressing Escape.
|
||||
setKeyEventSetsDone(0);
|
||||
|
||||
// Only render when the camera position changed, or content flagged dirty
|
||||
//setRunFrameScheme(osgViewer::ViewerBase::ON_DEMAND);
|
||||
setRunFrameScheme(osgViewer::ViewerBase::CONTINUOUS);
|
||||
|
||||
connect( &mTimer, SIGNAL(timeout()), this, SLOT(update()) );
|
||||
mTimer.start( 10 );
|
||||
}
|
||||
|
||||
CompositeViewer &CompositeViewer::get()
|
||||
{
|
||||
static CompositeViewer sThis;
|
||||
return sThis;
|
||||
}
|
||||
|
||||
void CompositeViewer::update()
|
||||
{
|
||||
mSimulationTime += mFrameTimer.time_s();
|
||||
mFrameTimer.setStartTick();
|
||||
frame(mSimulationTime);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
SceneWidget::SceneWidget(Resource::SceneManager* sceneManager, QWidget *parent, Qt::WindowFlags f)
|
||||
: RenderWidget(parent, f)
|
||||
, mSceneManager(sceneManager)
|
||||
, mLighting(NULL)
|
||||
, mHasDefaultAmbient(false)
|
||||
{
|
||||
// we handle lighting manually
|
||||
mView->setLightingMode(osgViewer::View::NO_LIGHT);
|
||||
|
||||
setLighting(&mLightingDay);
|
||||
}
|
||||
|
||||
SceneWidget::~SceneWidget()
|
||||
{
|
||||
// Since we're holding on to the scene templates past the existance of this graphics context, we'll need to manually release the created objects
|
||||
mSceneManager->releaseGLObjects(mView->getCamera()->getGraphicsContext()->getState());
|
||||
}
|
||||
|
||||
void SceneWidget::setLighting(Lighting *lighting)
|
||||
{
|
||||
if (mLighting)
|
||||
mLighting->deactivate();
|
||||
|
||||
mLighting = lighting;
|
||||
mLighting->activate (mRootNode);
|
||||
|
||||
osg::Vec4f ambient = mLighting->getAmbientColour(mHasDefaultAmbient ? &mDefaultAmbient : 0);
|
||||
setAmbient(ambient);
|
||||
|
||||
flagAsModified();
|
||||
}
|
||||
|
||||
void SceneWidget::setAmbient(const osg::Vec4f& ambient)
|
||||
{
|
||||
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
|
||||
osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
|
||||
lightmodel->setAmbientIntensity(ambient);
|
||||
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
|
||||
stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON);
|
||||
stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON);
|
||||
mRootNode->setStateSet(stateset);
|
||||
}
|
||||
|
||||
void SceneWidget::selectLightingMode (const std::string& mode)
|
||||
{
|
||||
if (mode=="day")
|
||||
setLighting (&mLightingDay);
|
||||
else if (mode=="night")
|
||||
setLighting (&mLightingNight);
|
||||
else if (mode=="bright")
|
||||
setLighting (&mLightingBright);
|
||||
}
|
||||
|
||||
CSVWidget::SceneToolMode *SceneWidget::makeLightingSelector (CSVWidget::SceneToolbar *parent)
|
||||
{
|
||||
CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Lighting Mode");
|
||||
|
||||
/// \todo replace icons
|
||||
tool->addButton (":scenetoolbar/day", "day",
|
||||
"Day"
|
||||
"<ul><li>Cell specific ambient in interiors</li>"
|
||||
"<li>Low ambient in exteriors</li>"
|
||||
"<li>Strong directional light source</li>"
|
||||
"<li>This mode closely resembles day time in-game</li></ul>");
|
||||
tool->addButton (":scenetoolbar/night", "night",
|
||||
"Night"
|
||||
"<ul><li>Cell specific ambient in interiors</li>"
|
||||
"<li>Low ambient in exteriors</li>"
|
||||
"<li>Weak directional light source</li>"
|
||||
"<li>This mode closely resembles night time in-game</li></ul>");
|
||||
tool->addButton (":scenetoolbar/bright", "bright",
|
||||
"Bright"
|
||||
"<ul><li>Maximum ambient</li>"
|
||||
"<li>Strong directional light source</li></ul>");
|
||||
|
||||
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||
this, SLOT (selectLightingMode (const std::string&)));
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour)
|
||||
{
|
||||
mDefaultAmbient = colour;
|
||||
mHasDefaultAmbient = true;
|
||||
|
||||
setAmbient(mLighting->getAmbientColour(&mDefaultAmbient));
|
||||
}
|
||||
|
||||
connect (timer, SIGNAL (timeout()), this, SLOT (update()));
|
||||
|
||||
int timerStart = userSettings.setting("scene-input/timer", QString("20")).toInt();
|
||||
timer->start (timerStart);
|
||||
|
||||
/// \todo make shortcut configurable
|
||||
QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut);
|
||||
connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest()));
|
||||
}
|
||||
|
||||
CSVWidget::SceneToolMode *SceneWidget::makeLightingSelector (CSVWidget::SceneToolbar *parent)
|
||||
{
|
||||
CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Lighting Mode");
|
||||
|
||||
/// \todo replace icons
|
||||
tool->addButton (":scenetoolbar/day", "day",
|
||||
"Day"
|
||||
"<ul><li>Cell specific ambient in interiors</li>"
|
||||
"<li>Low ambient in exteriors</li>"
|
||||
"<li>Strong directional light source/lir>"
|
||||
"<li>This mode closely resembles day time in-game</li></ul>");
|
||||
tool->addButton (":scenetoolbar/night", "night",
|
||||
"Night"
|
||||
"<ul><li>Cell specific ambient in interiors</li>"
|
||||
"<li>Low ambient in exteriors</li>"
|
||||
"<li>Weak directional light source</li>"
|
||||
"<li>This mode closely resembles night time in-game</li></ul>");
|
||||
tool->addButton (":scenetoolbar/bright", "bright",
|
||||
"Bright"
|
||||
"<ul><li>Maximum ambient</li>"
|
||||
"<li>Strong directional light source</li></ul>");
|
||||
|
||||
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||
this, SLOT (selectLightingMode (const std::string&)));
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
void SceneWidget::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||
{
|
||||
mDefaultAmbient = colour;
|
||||
mHasDefaultAmbient = true;
|
||||
|
||||
if (mLighting)
|
||||
mLighting->setDefaultAmbient (colour);
|
||||
}
|
||||
|
||||
void SceneWidget::updateOgreWindow()
|
||||
{
|
||||
if (mWindow)
|
||||
{
|
||||
Ogre::Root::getSingleton().destroyRenderTarget(mWindow);
|
||||
mWindow = NULL;
|
||||
}
|
||||
|
||||
std::stringstream windowHandle;
|
||||
#ifdef WIN32
|
||||
windowHandle << Ogre::StringConverter::toString((uintptr_t)(this->winId()));
|
||||
#else
|
||||
windowHandle << this->winId();
|
||||
#endif
|
||||
std::stringstream windowTitle;
|
||||
static int count=0;
|
||||
windowTitle << ++count;
|
||||
|
||||
Ogre::NameValuePairList params;
|
||||
|
||||
params.insert(std::make_pair("externalWindowHandle", windowHandle.str()));
|
||||
params.insert(std::make_pair("title", windowTitle.str()));
|
||||
|
||||
std::string antialiasing =
|
||||
CSMSettings::UserSettings::instance().settingValue("3d-render/antialiasing").toStdString();
|
||||
if(antialiasing == "MSAA 16") antialiasing = "16";
|
||||
else if(antialiasing == "MSAA 8") antialiasing = "8";
|
||||
else if(antialiasing == "MSAA 4") antialiasing = "4";
|
||||
else if(antialiasing == "MSAA 2") antialiasing = "2";
|
||||
else antialiasing = "0";
|
||||
params.insert(std::make_pair("FSAA", antialiasing));
|
||||
|
||||
params.insert(std::make_pair("vsync", "false")); // TODO setting
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
params.insert(std::make_pair("macAPI", "cocoa"));
|
||||
params.insert(std::make_pair("macAPICocoaUseNSView", "true"));
|
||||
#endif
|
||||
|
||||
mWindow = Ogre::Root::getSingleton().createRenderWindow(windowTitle.str(), this->width(), this->height(), false, ¶ms);
|
||||
|
||||
mViewport = mWindow->addViewport (mCamera);
|
||||
mViewport->setBackgroundColour (Ogre::ColourValue (0.3,0.3,0.3,1));
|
||||
|
||||
Ogre::Real aspectRatio = Ogre::Real(width()) / Ogre::Real(height());
|
||||
mCamera->setAspectRatio(aspectRatio);
|
||||
}
|
||||
|
||||
SceneWidget::~SceneWidget()
|
||||
{
|
||||
if (mWindow)
|
||||
Ogre::Root::getSingleton().destroyRenderTarget (mWindow);
|
||||
|
||||
if (mSceneMgr)
|
||||
mSceneMgr->removeRenderQueueListener (mOverlaySystem);
|
||||
|
||||
if (mSceneMgr)
|
||||
Ogre::Root::getSingleton().destroySceneManager (mSceneMgr);
|
||||
|
||||
}
|
||||
|
||||
void SceneWidget::setVisibilityMask (unsigned int mask)
|
||||
{
|
||||
mViewport->setVisibilityMask (mask);
|
||||
}
|
||||
|
||||
void SceneWidget::setNavigation (Navigation *navigation)
|
||||
{
|
||||
if ((mNavigation = navigation))
|
||||
{
|
||||
mNavigation->setFastModeFactor (mFast ? mFastFactor : 1);
|
||||
if (mNavigation->activate (mCamera))
|
||||
mUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::addRenderTargetListener(Ogre::RenderTargetListener *listener)
|
||||
{
|
||||
mWindow->addListener(listener);
|
||||
}
|
||||
|
||||
void SceneWidget::removeRenderTargetListener(Ogre::RenderTargetListener *listener)
|
||||
{
|
||||
mWindow->removeListener(listener);
|
||||
}
|
||||
|
||||
Ogre::Viewport *SceneWidget::getViewport()
|
||||
{
|
||||
if (!mWindow)
|
||||
updateOgreWindow();
|
||||
|
||||
return mViewport;
|
||||
}
|
||||
|
||||
Ogre::SceneManager *SceneWidget::getSceneManager()
|
||||
{
|
||||
return mSceneMgr;
|
||||
}
|
||||
|
||||
Ogre::Camera *SceneWidget::getCamera()
|
||||
{
|
||||
return mCamera;
|
||||
}
|
||||
|
||||
void SceneWidget::flagAsModified()
|
||||
{
|
||||
mUpdate = true;
|
||||
}
|
||||
|
||||
void SceneWidget::paintEvent(QPaintEvent* e)
|
||||
{
|
||||
if (!mWindow)
|
||||
updateOgreWindow();
|
||||
|
||||
mWindow->update();
|
||||
e->accept();
|
||||
}
|
||||
|
||||
QPaintEngine* SceneWidget::paintEngine() const
|
||||
{
|
||||
// We don't want another paint engine to get in the way.
|
||||
// So we return nothing.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SceneWidget::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
if (!mWindow)
|
||||
return;
|
||||
|
||||
const QSize &newSize = e->size();
|
||||
|
||||
// TODO: Fix Ogre to handle this more consistently (fixed in 1.9)
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
||||
mWindow->resize(newSize.width(), newSize.height());
|
||||
#else
|
||||
mWindow->windowMovedOrResized();
|
||||
#endif
|
||||
|
||||
Ogre::Real aspectRatio = Ogre::Real(newSize.width()) / Ogre::Real(newSize.height());
|
||||
mCamera->setAspectRatio(aspectRatio);
|
||||
}
|
||||
|
||||
bool SceneWidget::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::WinIdChange)
|
||||
{
|
||||
// I haven't actually seen this happen yet.
|
||||
if (mWindow)
|
||||
updateOgreWindow();
|
||||
}
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
void SceneWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
switch (event->key())
|
||||
{
|
||||
case Qt::Key_W: mKeyForward = true; break;
|
||||
case Qt::Key_S: mKeyBackward = true; break;
|
||||
case Qt::Key_A: mKeyLeft = true; break;
|
||||
case Qt::Key_D: mKeyRight = true; break;
|
||||
case Qt::Key_Q: mKeyRollLeft = true; break;
|
||||
case Qt::Key_E: mKeyRollRight = true; break;
|
||||
case Qt::Key_Control: mMod1 = true; break;
|
||||
|
||||
case Qt::Key_Shift:
|
||||
|
||||
mFast = true;
|
||||
|
||||
if (mNavigation)
|
||||
mNavigation->setFastModeFactor (mFastFactor);
|
||||
|
||||
break;
|
||||
|
||||
default: QWidget::keyPressEvent (event);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::keyReleaseEvent (QKeyEvent *event)
|
||||
{
|
||||
switch (event->key())
|
||||
{
|
||||
case Qt::Key_W: mKeyForward = false; break;
|
||||
case Qt::Key_S: mKeyBackward = false; break;
|
||||
case Qt::Key_A: mKeyLeft = false; break;
|
||||
case Qt::Key_D: mKeyRight = false; break;
|
||||
case Qt::Key_Q: mKeyRollLeft = false; break;
|
||||
case Qt::Key_E: mKeyRollRight = false; break;
|
||||
case Qt::Key_Control: mMod1 = false; break;
|
||||
|
||||
case Qt::Key_Shift:
|
||||
|
||||
mFast = false;
|
||||
|
||||
if (mNavigation)
|
||||
mNavigation->setFastModeFactor (1);
|
||||
|
||||
break;
|
||||
|
||||
default: QWidget::keyReleaseEvent (event);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::wheelEvent (QWheelEvent *event)
|
||||
{
|
||||
if (mNavigation)
|
||||
if (event->delta())
|
||||
if (mNavigation->wheelMoved (event->delta()))
|
||||
mUpdate = true;
|
||||
}
|
||||
|
||||
void SceneWidget::leaveEvent (QEvent *event)
|
||||
{
|
||||
mDragging = false;
|
||||
}
|
||||
|
||||
void SceneWidget::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
if (mDragging)
|
||||
{
|
||||
QPoint diff = mOldPos-event->pos();
|
||||
mOldPos = event->pos();
|
||||
|
||||
if (mNavigation)
|
||||
if (mNavigation->mouseMoved (diff, mMod1 ? 1 : 0))
|
||||
mUpdate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDragging = true;
|
||||
mOldPos = event->pos();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
mDragging = false;
|
||||
}
|
||||
|
||||
void SceneWidget::focusOutEvent (QFocusEvent *event)
|
||||
{
|
||||
mKeyForward = false;
|
||||
mKeyBackward = false;
|
||||
mKeyLeft = false;
|
||||
mKeyRight = false;
|
||||
mFast = false;
|
||||
mMod1 = false;
|
||||
|
||||
QWidget::focusOutEvent (event);
|
||||
}
|
||||
|
||||
void SceneWidget::update()
|
||||
{
|
||||
if (mNavigation)
|
||||
{
|
||||
int horizontal = 0;
|
||||
int vertical = 0;
|
||||
|
||||
if (mKeyForward && !mKeyBackward)
|
||||
vertical = 1;
|
||||
else if (!mKeyForward && mKeyBackward)
|
||||
vertical = -1;
|
||||
|
||||
if (mKeyLeft && !mKeyRight)
|
||||
horizontal = -1;
|
||||
else if (!mKeyLeft && mKeyRight)
|
||||
horizontal = 1;
|
||||
|
||||
if (horizontal || vertical)
|
||||
if (mNavigation->handleMovementKeys (vertical, horizontal))
|
||||
mUpdate = true;
|
||||
|
||||
int roll = 0;
|
||||
|
||||
if (mKeyRollLeft && !mKeyRollRight)
|
||||
roll = 1;
|
||||
else if (!mKeyRollLeft && mKeyRollRight)
|
||||
roll = -1;
|
||||
|
||||
if (roll)
|
||||
if (mNavigation->handleRollKeys (roll))
|
||||
mUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
if (mUpdate && mWindow)
|
||||
{
|
||||
mUpdate = false;
|
||||
mWindow->update();
|
||||
updateOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneWidget::updateScene()
|
||||
{
|
||||
flagAsModified();
|
||||
}
|
||||
|
||||
void SceneWidget::updateOverlay()
|
||||
{ }
|
||||
|
||||
void SceneWidget::setLighting (Lighting *lighting)
|
||||
{
|
||||
if (mLighting)
|
||||
mLighting->deactivate();
|
||||
|
||||
mLighting = lighting;
|
||||
mLighting->activate (mSceneMgr, mHasDefaultAmbient ? &mDefaultAmbient : 0);
|
||||
|
||||
if (mWindow)
|
||||
mWindow->update();
|
||||
}
|
||||
|
||||
void SceneWidget::selectLightingMode (const std::string& mode)
|
||||
{
|
||||
if (mode=="day")
|
||||
setLighting (&mLightingDay);
|
||||
else if (mode=="night")
|
||||
setLighting (&mLightingNight);
|
||||
else if (mode=="bright")
|
||||
setLighting (&mLightingBright);
|
||||
}
|
||||
|
||||
void SceneWidget::updateUserSetting (const QString &key, const QStringList &list)
|
||||
{
|
||||
if(key.contains(QRegExp("^\\b(Objects|Shader|Scene)", Qt::CaseInsensitive)))
|
||||
flagAsModified();
|
||||
|
||||
if(key == "3d-render/far-clip-distance" && !list.empty())
|
||||
{
|
||||
if(mCamera->getFarClipDistance() != list.at(0).toFloat())
|
||||
mCamera->setFarClipDistance(list.at(0).toFloat());
|
||||
}
|
||||
|
||||
// minimise unnecessary ogre window creation by updating only when there is a change
|
||||
if(key == "3d-render/antialiasing")
|
||||
{
|
||||
unsigned int aa = mWindow->getFSAA();
|
||||
unsigned int antialiasing = 0;
|
||||
if(!list.empty())
|
||||
{
|
||||
if(list.at(0) == "MSAA 16") antialiasing = 16;
|
||||
else if(list.at(0) == "MSAA 8") antialiasing = 8;
|
||||
else if(list.at(0) == "MSAA 4") antialiasing = 4;
|
||||
else if(list.at(0) == "MSAA 2") antialiasing = 2;
|
||||
}
|
||||
if(aa != antialiasing)
|
||||
updateOgreWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,21 +2,23 @@
|
||||
#define OPENCS_VIEW_SCENEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <OgreColourValue.h>
|
||||
#include <QTimer>
|
||||
|
||||
#include "lightingday.hpp"
|
||||
#include "lightingnight.hpp"
|
||||
#include "lightingbright.hpp"
|
||||
|
||||
namespace Ogre
|
||||
#include <osgViewer/View>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
class Camera;
|
||||
class SceneManager;
|
||||
class RenderWindow;
|
||||
class Viewport;
|
||||
class OverlaySystem;
|
||||
class RenderTargetListener;
|
||||
}
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Group;
|
||||
}
|
||||
|
||||
namespace CSVWidget
|
||||
@ -27,114 +29,85 @@ namespace CSVWidget
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Navigation;
|
||||
class Lighting;
|
||||
|
||||
class SceneWidget : public QWidget
|
||||
class RenderWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~RenderWidget();
|
||||
|
||||
SceneWidget(QWidget *parent);
|
||||
virtual ~SceneWidget();
|
||||
void flagAsModified();
|
||||
|
||||
QPaintEngine* paintEngine() const;
|
||||
void setVisibilityMask(int mask);
|
||||
|
||||
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);
|
||||
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||
/// is the responsibility of the calling function.
|
||||
protected:
|
||||
|
||||
virtual void setVisibilityMask (unsigned int mask);
|
||||
osg::ref_ptr<osgViewer::View> mView;
|
||||
|
||||
virtual void updateScene();
|
||||
osg::Group* mRootNode;
|
||||
|
||||
protected:
|
||||
|
||||
void setNavigation (Navigation *navigation);
|
||||
///< \attention The ownership of \a navigation is not transferred to *this.
|
||||
|
||||
void addRenderTargetListener(Ogre::RenderTargetListener *listener);
|
||||
|
||||
void removeRenderTargetListener(Ogre::RenderTargetListener *listener);
|
||||
|
||||
Ogre::Viewport *getViewport();
|
||||
|
||||
Ogre::SceneManager *getSceneManager();
|
||||
|
||||
Ogre::Camera *getCamera();
|
||||
|
||||
void flagAsModified();
|
||||
|
||||
void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
///< \note The actual ambient colour may differ based on lighting settings.
|
||||
|
||||
virtual void updateOverlay();
|
||||
|
||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||
|
||||
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||
|
||||
void wheelEvent (QWheelEvent *event);
|
||||
|
||||
void keyPressEvent (QKeyEvent *event);
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent* e);
|
||||
void resizeEvent(QResizeEvent* e);
|
||||
bool event(QEvent* e);
|
||||
|
||||
void keyReleaseEvent (QKeyEvent *event);
|
||||
|
||||
void focusOutEvent (QFocusEvent *event);
|
||||
|
||||
void leaveEvent (QEvent *event);
|
||||
|
||||
void updateOgreWindow();
|
||||
|
||||
void setLighting (Lighting *lighting);
|
||||
///< \attention The ownership of \a lighting is not transferred to *this.
|
||||
|
||||
Ogre::Camera* mCamera;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
Ogre::RenderWindow* mWindow;
|
||||
Ogre::Viewport *mViewport;
|
||||
Ogre::OverlaySystem *mOverlaySystem;
|
||||
|
||||
Navigation *mNavigation;
|
||||
Lighting *mLighting;
|
||||
bool mUpdate;
|
||||
bool mKeyForward;
|
||||
bool mKeyBackward;
|
||||
bool mKeyLeft;
|
||||
bool mKeyRight;
|
||||
bool mKeyRollLeft;
|
||||
bool mKeyRollRight;
|
||||
bool mFast;
|
||||
bool mDragging;
|
||||
bool mMod1;
|
||||
QPoint mOldPos;
|
||||
int mFastFactor;
|
||||
Ogre::ColourValue mDefaultAmbient;
|
||||
bool mHasDefaultAmbient;
|
||||
LightingDay mLightingDay;
|
||||
LightingNight mLightingNight;
|
||||
LightingBright mLightingBright;
|
||||
|
||||
public slots:
|
||||
|
||||
void updateUserSetting (const QString &key, const QStringList &list);
|
||||
|
||||
private slots:
|
||||
|
||||
void update();
|
||||
|
||||
void selectLightingMode (const std::string& mode);
|
||||
|
||||
signals:
|
||||
|
||||
void focusToolbarRequest();
|
||||
QTimer mTimer;
|
||||
};
|
||||
|
||||
// Extension of RenderWidget to support lighting mode selection & toolbar
|
||||
class SceneWidget : public RenderWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SceneWidget(Resource::SceneManager* sceneManager, QWidget* parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~SceneWidget();
|
||||
|
||||
CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent);
|
||||
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||
/// is the responsibility of the calling function.
|
||||
|
||||
void setDefaultAmbient (const osg::Vec4f& colour);
|
||||
///< \note The actual ambient colour may differ based on lighting settings.
|
||||
|
||||
protected:
|
||||
void setLighting (Lighting *lighting);
|
||||
///< \attention The ownership of \a lighting is not transferred to *this.
|
||||
|
||||
void setAmbient(const osg::Vec4f& ambient);
|
||||
|
||||
Resource::SceneManager* mSceneManager;
|
||||
|
||||
Lighting* mLighting;
|
||||
|
||||
osg::Vec4f mDefaultAmbient;
|
||||
bool mHasDefaultAmbient;
|
||||
LightingDay mLightingDay;
|
||||
LightingNight mLightingNight;
|
||||
LightingBright mLightingBright;
|
||||
|
||||
private slots:
|
||||
|
||||
void selectLightingMode (const std::string& mode);
|
||||
};
|
||||
|
||||
|
||||
// There are rendering glitches when using multiple Viewer instances, work around using CompositeViewer with multiple views
|
||||
class CompositeViewer : public QObject, public osgViewer::CompositeViewer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CompositeViewer();
|
||||
|
||||
static CompositeViewer& get();
|
||||
|
||||
QTimer mTimer;
|
||||
|
||||
private:
|
||||
osg::Timer mFrameTimer;
|
||||
double mSimulationTime;
|
||||
|
||||
public slots:
|
||||
void update();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,8 @@ namespace CSVRender
|
||||
{
|
||||
|
||||
TerrainStorage::TerrainStorage(const CSMWorld::Data &data)
|
||||
: mData(data)
|
||||
: ESMTerrain::Storage(data.getResourceSystem()->getVFS())
|
||||
, mData(data)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,359 +0,0 @@
|
||||
#include "textoverlay.hpp"
|
||||
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreMaterialManager.h>
|
||||
#include <OgreTechnique.h>
|
||||
|
||||
#include <OgreOverlayManager.h>
|
||||
#include <OgreOverlayContainer.h>
|
||||
#include <OgreFontManager.h>
|
||||
#include <OgreTextAreaOverlayElement.h>
|
||||
#include <OgreEntity.h>
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
// Things to do:
|
||||
// - configurable font size in pixels (automatically calulate everything else from it)
|
||||
// - configurable texture to use
|
||||
// - try material script
|
||||
// - decide whether to use QPaint (http://www.ogre3d.org/tikiwiki/Ogre+overlays+using+Qt)
|
||||
|
||||
// http://www.ogre3d.org/tikiwiki/ObjectTextDisplay
|
||||
// http://www.ogre3d.org/tikiwiki/MovableTextOverlay
|
||||
// http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures
|
||||
// http://www.ogre3d.org/tikiwiki/ManualObject
|
||||
TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id)
|
||||
: mOverlay(0), mCaption(""), mDesc(""), mObj(obj), mCamera(camera), mFontHeight(16), mId(id)
|
||||
, mEnabled(true), mOnScreen(false), mInstance(0) // FIXME: make font height configurable
|
||||
{
|
||||
if(id == "" || !camera || !obj)
|
||||
throw std::runtime_error("TextOverlay could not be created.");
|
||||
|
||||
// setup font
|
||||
Ogre::FontManager &fontMgr = Ogre::FontManager::getSingleton();
|
||||
if (fontMgr.resourceExists("DejaVuLGC"))
|
||||
mFont = fontMgr.getByName("DejaVuLGC","General");
|
||||
else
|
||||
{
|
||||
mFont = fontMgr.create("DejaVuLGC","General");
|
||||
mFont->setType(Ogre::FT_TRUETYPE);
|
||||
mFont->setSource("DejaVuLGCSansMono.ttf");
|
||||
mFont->setTrueTypeSize(mFontHeight);
|
||||
mFont->setTrueTypeResolution(96);
|
||||
}
|
||||
if(!mFont.isNull())
|
||||
mFont->load();
|
||||
else
|
||||
throw std::runtime_error("TextOverlay font not loaded.");
|
||||
|
||||
// setup overlay
|
||||
Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton();
|
||||
mOverlay = overlayMgr.getByName("CellIDPanel"+mId+Ogre::StringConverter::toString(mInstance));
|
||||
// FIXME: this logic is badly broken as it is possible to delete an earlier instance
|
||||
while(mOverlay != NULL)
|
||||
{
|
||||
mInstance++;
|
||||
mOverlay = overlayMgr.getByName("CellIDPanel"+mId+Ogre::StringConverter::toString(mInstance));
|
||||
}
|
||||
mOverlay = overlayMgr.create("CellIDPanel"+mId+Ogre::StringConverter::toString(mInstance));
|
||||
|
||||
// create texture
|
||||
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("DynamicTransBlue");
|
||||
if(texture.isNull())
|
||||
{
|
||||
texture = Ogre::TextureManager::getSingleton().createManual(
|
||||
"DynamicTransBlue", // name
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
Ogre::TEX_TYPE_2D, // type
|
||||
8, 8, // width & height
|
||||
0, // number of mipmaps
|
||||
Ogre::PF_BYTE_BGRA, // pixel format
|
||||
Ogre::TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for
|
||||
// textures updated very often (e.g. each frame)
|
||||
|
||||
Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
|
||||
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
|
||||
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
|
||||
|
||||
Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
|
||||
|
||||
// Fill in some pixel data. This will give a semi-transparent blue,
|
||||
// but this is of course dependent on the chosen pixel format.
|
||||
for (size_t j = 0; j < 8; j++)
|
||||
{
|
||||
for(size_t i = 0; i < 8; i++)
|
||||
{
|
||||
*pDest++ = 255; // B
|
||||
*pDest++ = 0; // G
|
||||
*pDest++ = 0; // R
|
||||
*pDest++ = 63; // A
|
||||
}
|
||||
|
||||
pDest += pixelBox.getRowSkip() * Ogre::PixelUtil::getNumElemBytes(pixelBox.format);
|
||||
}
|
||||
pixelBuffer->unlock();
|
||||
}
|
||||
|
||||
// setup material for containers
|
||||
Ogre::MaterialPtr mQuadMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"TransOverlayMaterial");
|
||||
if(mQuadMaterial.isNull())
|
||||
{
|
||||
Ogre::MaterialPtr mQuadMaterial = Ogre::MaterialManager::getSingleton().create(
|
||||
"TransOverlayMaterial",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true );
|
||||
Ogre::Pass *pass = mQuadMaterial->getTechnique( 0 )->getPass( 0 );
|
||||
pass->setLightingEnabled( false );
|
||||
pass->setDepthWriteEnabled( false );
|
||||
pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
|
||||
|
||||
Ogre::TextureUnitState *tex = pass->createTextureUnitState("MyCustomState", 0);
|
||||
tex->setTextureName("DynamicTransBlue");
|
||||
tex->setTextureFiltering( Ogre::TFO_ANISOTROPIC );
|
||||
mQuadMaterial->load();
|
||||
}
|
||||
|
||||
mContainer = static_cast<Ogre::OverlayContainer*>(overlayMgr.createOverlayElement(
|
||||
"Panel", "container"+mId +"#"+Ogre::StringConverter::toString(mInstance)));
|
||||
mContainer->setMaterialName("TransOverlayMaterial");
|
||||
mOverlay->add2D(mContainer);
|
||||
|
||||
// setup text area overlay element
|
||||
mElement = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr.createOverlayElement(
|
||||
"TextArea", "text"+mId +"#"+Ogre::StringConverter::toString(mInstance)));
|
||||
mElement->setMetricsMode(Ogre::GMM_RELATIVE);
|
||||
mElement->setDimensions(1.0, 1.0);
|
||||
mElement->setMetricsMode(Ogre::GMM_PIXELS);
|
||||
mElement->setPosition(2*fontHeight()/3, 1.3*fontHeight()/3); // 1.3 & 2 = fudge factor
|
||||
|
||||
mElement->setFontName("DejaVuLGC");
|
||||
mElement->setCharHeight(fontHeight()); // NOTE: seems that this is required as well as font->setTrueTypeSize()
|
||||
mElement->setHorizontalAlignment(Ogre::GHA_LEFT);
|
||||
//mElement->setColour(Ogre::ColourValue(1.0, 1.0, 1.0)); // R, G, B
|
||||
mElement->setColour(Ogre::ColourValue(1.0, 1.0, 0)); // yellow
|
||||
|
||||
mContainer->addChild(mElement);
|
||||
mOverlay->show();
|
||||
}
|
||||
|
||||
void TextOverlay::getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real& x, Ogre::Real& y)
|
||||
{
|
||||
Ogre::Vector3 hcsPosition = mCamera->getProjectionMatrix() * (mCamera->getViewMatrix() * position);
|
||||
|
||||
x = 1.0f - ((hcsPosition.x * 0.5f) + 0.5f); // 0 <= x <= 1 // left := 0,right := 1
|
||||
y = ((hcsPosition.y * 0.5f) + 0.5f); // 0 <= y <= 1 // bottom := 0,top := 1
|
||||
}
|
||||
|
||||
void TextOverlay::getMinMaxEdgesOfAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY,
|
||||
bool top)
|
||||
{
|
||||
MinX = 0, MinY = 0, MaxX = 0, MaxY = 0;
|
||||
float X[4]; // the 2D dots of the AABB in screencoordinates
|
||||
float Y[4];
|
||||
|
||||
if(!mObj->isInScene())
|
||||
return;
|
||||
|
||||
const Ogre::AxisAlignedBox &AABB = mObj->getWorldBoundingBox(true); // the AABB of the target
|
||||
Ogre::Vector3 cornersOfAABB[4];
|
||||
if(top)
|
||||
{
|
||||
cornersOfAABB[0] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_LEFT_TOP);
|
||||
cornersOfAABB[1] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_RIGHT_TOP);
|
||||
cornersOfAABB[2] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_LEFT_TOP);
|
||||
cornersOfAABB[3] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_RIGHT_TOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
cornersOfAABB[0] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_LEFT_BOTTOM);
|
||||
cornersOfAABB[1] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_RIGHT_BOTTOM);
|
||||
cornersOfAABB[2] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_LEFT_BOTTOM);
|
||||
cornersOfAABB[3] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_RIGHT_BOTTOM);
|
||||
}
|
||||
|
||||
//The normal vector of the plane. This points directly infront of the camera.
|
||||
Ogre::Vector3 cameraPlainNormal = mCamera->getDerivedOrientation().zAxis();
|
||||
|
||||
//the plane that devides the space before and behind the camera.
|
||||
Ogre::Plane CameraPlane = Ogre::Plane(cameraPlainNormal, mCamera->getDerivedPosition());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
X[i] = 0;
|
||||
Y[i] = 0;
|
||||
|
||||
getScreenCoordinates(cornersOfAABB[i],X[i],Y[i]); // transfor into 2d dots
|
||||
|
||||
if (CameraPlane.getSide(cornersOfAABB[i]) == Ogre::Plane::NEGATIVE_SIDE)
|
||||
{
|
||||
if (i == 0) // accept the first set of values, no matter how bad it might be.
|
||||
{
|
||||
MinX = X[i];
|
||||
MinY = Y[i];
|
||||
MaxX = X[i];
|
||||
MaxY = Y[i];
|
||||
}
|
||||
else // now compare if you get "better" values
|
||||
{
|
||||
if (MinX > X[i]) MinX = X[i];
|
||||
if (MinY > Y[i]) MinY = Y[i];
|
||||
if (MaxX < X[i]) MaxX = X[i];
|
||||
if (MaxY < Y[i]) MaxY = Y[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MinX = 0;
|
||||
MinY = 0;
|
||||
MaxX = 0;
|
||||
MaxY = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextOverlay::~TextOverlay()
|
||||
{
|
||||
Ogre::OverlayManager::OverlayMapIterator iter = Ogre::OverlayManager::getSingleton().getOverlayIterator();
|
||||
if(!iter.hasMoreElements())
|
||||
mOverlay->hide();
|
||||
|
||||
Ogre::OverlayManager *overlayMgr = Ogre::OverlayManager::getSingletonPtr();
|
||||
mContainer->removeChild("text"+mId+"#"+Ogre::StringConverter::toString(mInstance));
|
||||
mOverlay->remove2D(mContainer);
|
||||
|
||||
if(!iter.hasMoreElements())
|
||||
overlayMgr->destroy(mOverlay);
|
||||
}
|
||||
|
||||
void TextOverlay::show(bool show)
|
||||
{
|
||||
if(show && mOnScreen)
|
||||
mContainer->show();
|
||||
else
|
||||
mContainer->hide();
|
||||
}
|
||||
|
||||
void TextOverlay::enable(bool enable)
|
||||
{
|
||||
if(enable == mOverlay->isVisible())
|
||||
return;
|
||||
|
||||
mEnabled = enable;
|
||||
if(enable)
|
||||
mOverlay->show();
|
||||
else
|
||||
mOverlay->hide();
|
||||
}
|
||||
|
||||
bool TextOverlay::isEnabled()
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
void TextOverlay::setCaption(const Ogre::String& text)
|
||||
{
|
||||
if(mCaption == text)
|
||||
return;
|
||||
|
||||
mCaption = text;
|
||||
mElement->setCaption(text);
|
||||
}
|
||||
|
||||
void TextOverlay::setDesc(const Ogre::String& text)
|
||||
{
|
||||
if(mDesc == text)
|
||||
return;
|
||||
|
||||
mDesc = text;
|
||||
mElement->setCaption(mCaption + ((text == "") ? "" : ("\n" + text)));
|
||||
}
|
||||
|
||||
Ogre::FontPtr TextOverlay::getFont()
|
||||
{
|
||||
return mFont;
|
||||
}
|
||||
|
||||
int TextOverlay::textWidth()
|
||||
{
|
||||
float captionWidth = 0;
|
||||
float descWidth = 0;
|
||||
|
||||
for(Ogre::String::const_iterator i = mCaption.begin(); i < mCaption.end(); ++i)
|
||||
{
|
||||
if(*i == 0x0020)
|
||||
captionWidth += getFont()->getGlyphAspectRatio(0x0030);
|
||||
else
|
||||
captionWidth += getFont()->getGlyphAspectRatio(*i);
|
||||
}
|
||||
|
||||
for(Ogre::String::const_iterator i = mDesc.begin(); i < mDesc.end(); ++i)
|
||||
{
|
||||
if(*i == 0x0020)
|
||||
descWidth += getFont()->getGlyphAspectRatio(0x0030);
|
||||
else
|
||||
descWidth += getFont()->getGlyphAspectRatio(*i);
|
||||
}
|
||||
|
||||
captionWidth *= fontHeight();
|
||||
descWidth *= fontHeight();
|
||||
|
||||
return (int) std::max(captionWidth, descWidth);
|
||||
}
|
||||
|
||||
int TextOverlay::fontHeight()
|
||||
{
|
||||
return mFontHeight;
|
||||
}
|
||||
|
||||
void TextOverlay::update()
|
||||
{
|
||||
float min_x, max_x, min_y, max_y;
|
||||
getMinMaxEdgesOfAABBIn2D(min_x, min_y, max_x, max_y, false);
|
||||
|
||||
if ((min_x>0.0) && (max_x<1.0) && (min_y>0.0) && (max_y<1.0))
|
||||
{
|
||||
mOnScreen = true;
|
||||
mContainer->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
mOnScreen = false;
|
||||
mContainer->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
getMinMaxEdgesOfAABBIn2D(min_x, min_y, max_x, max_y);
|
||||
|
||||
Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton();
|
||||
float viewportWidth = std::max(overlayMgr.getViewportWidth(), 1); // zero at the start
|
||||
float viewportHeight = std::max(overlayMgr.getViewportHeight(), 1); // zero at the start
|
||||
|
||||
int width = fontHeight()*2/3 + textWidth() + fontHeight()*2/3; // add margins
|
||||
int height = fontHeight()/3 + fontHeight() + fontHeight()/3;
|
||||
if(mDesc != "")
|
||||
height = fontHeight()/3 + 2*fontHeight() + fontHeight()/3;
|
||||
|
||||
float relTextWidth = width / viewportWidth;
|
||||
float relTextHeight = height / viewportHeight;
|
||||
|
||||
float posX = 1 - (min_x + max_x + relTextWidth)/2;
|
||||
float posY = 1 - max_y - (relTextHeight-fontHeight()/3/viewportHeight);
|
||||
|
||||
mContainer->setMetricsMode(Ogre::GMM_RELATIVE);
|
||||
mContainer->setPosition(posX, posY);
|
||||
mContainer->setDimensions(relTextWidth, relTextHeight);
|
||||
|
||||
mPos = QRect(posX*viewportWidth, posY*viewportHeight, width, height);
|
||||
}
|
||||
|
||||
QRect TextOverlay::container()
|
||||
{
|
||||
return mPos;
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
#ifndef OPENCS_VIEW_TEXTOVERLAY_H
|
||||
#define OPENCS_VIEW_TEXTOVERLAY_H
|
||||
|
||||
#include <QRect>
|
||||
|
||||
#include <OgreString.h>
|
||||
#include <OgreFont.h>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class MovableObject;
|
||||
class Camera;
|
||||
class Font;
|
||||
class Overlay;
|
||||
class OverlayContainer;
|
||||
class TextAreaOverlayElement;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
||||
class TextOverlay
|
||||
{
|
||||
Ogre::Overlay* mOverlay;
|
||||
Ogre::OverlayContainer* mContainer;
|
||||
Ogre::TextAreaOverlayElement* mElement;
|
||||
Ogre::String mCaption;
|
||||
Ogre::String mDesc;
|
||||
|
||||
const Ogre::MovableObject* mObj;
|
||||
const Ogre::Camera* mCamera;
|
||||
Ogre::FontPtr mFont;
|
||||
int mFontHeight; // in pixels
|
||||
Ogre::String mId;
|
||||
QRect mPos;
|
||||
|
||||
bool mEnabled;
|
||||
bool mOnScreen;
|
||||
int mInstance;
|
||||
|
||||
Ogre::FontPtr getFont();
|
||||
int textWidth();
|
||||
int fontHeight();
|
||||
void getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real& x, Ogre::Real& y);
|
||||
void getMinMaxEdgesOfAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY,
|
||||
bool top = true);
|
||||
|
||||
public:
|
||||
|
||||
TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String &id);
|
||||
virtual ~TextOverlay();
|
||||
|
||||
void enable(bool enable); // controlled from scene widget toolbar visibility mask
|
||||
void show(bool show); // for updating from render target listener
|
||||
bool isEnabled();
|
||||
void setCaption(const Ogre::String& text);
|
||||
void setDesc(const Ogre::String& text);
|
||||
void update();
|
||||
QRect container(); // for detection of mouse click on the overlay
|
||||
Ogre::String getCaption() { return mCaption; } // FIXME: debug
|
||||
Ogre::String getDesc() { return mDesc; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // OPENCS_VIEW_TEXTOVERLAY_H
|
@ -3,11 +3,12 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <OgreColourValue.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include <QEvent>
|
||||
|
||||
#include <components/sceneutil/util.hpp>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
@ -24,8 +25,8 @@ void CSVRender::UnpagedWorldspaceWidget::update()
|
||||
const CSMWorld::Record<CSMWorld::Cell>& record =
|
||||
dynamic_cast<const CSMWorld::Record<CSMWorld::Cell>&> (mCellsModel->getRecord (mCellId));
|
||||
|
||||
Ogre::ColourValue colour;
|
||||
colour.setAsABGR (record.get().mAmbi.mAmbient);
|
||||
osg::Vec4f colour = SceneUtil::colourFromRGB(record.get().mAmbi.mAmbient);
|
||||
|
||||
setDefaultAmbient (colour);
|
||||
|
||||
/// \todo deal with mSunlight and mFog/mForDensity
|
||||
@ -49,7 +50,9 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
|
||||
|
||||
update();
|
||||
|
||||
mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, document.getPhysics()));
|
||||
mCell.reset (new Cell (document.getData(), mRootNode, mCellId));
|
||||
|
||||
mView->setCameraManipulator(new osgGA::TrackballManipulator);
|
||||
}
|
||||
|
||||
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
||||
@ -91,7 +94,8 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector<CSMWorld:
|
||||
return false;
|
||||
|
||||
mCellId = data.begin()->getId();
|
||||
mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getDocument().getPhysics()));
|
||||
|
||||
mCell.reset (new Cell (getDocument().getData(), mRootNode, mCellId));
|
||||
|
||||
update();
|
||||
emit cellChanged(*data.begin());
|
||||
@ -163,13 +167,13 @@ void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
|
||||
|
||||
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()
|
||||
{
|
||||
Ogre::Vector3 position = getCamera()->getPosition();
|
||||
osg::Vec3d position = mView->getCamera()->getViewMatrix().getTrans();
|
||||
|
||||
std::ostringstream stream;
|
||||
|
||||
stream
|
||||
<< "player->positionCell "
|
||||
<< position.x << ", " << position.y << ", " << position.z
|
||||
<< position.x() << ", " << position.y() << ", " << position.z()
|
||||
<< ", 0, \"" << mCellId << "\"";
|
||||
|
||||
return stream.str();
|
||||
|
@ -3,10 +3,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreEntity.h>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QDragMoveEvent>
|
||||
@ -14,6 +10,9 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgGA/FirstPersonManipulator>
|
||||
|
||||
#include "../../model/world/universalid.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
@ -21,13 +20,11 @@
|
||||
#include "../widget/scenetooltoggle2.hpp"
|
||||
#include "../widget/scenetoolrun.hpp"
|
||||
|
||||
#include "../world/physicssystem.hpp"
|
||||
|
||||
#include "elements.hpp"
|
||||
#include "editmode.hpp"
|
||||
|
||||
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
||||
: SceneWidget (parent), mSceneElements(0), mRun(0), mDocument(document), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()), mMouse(0),
|
||||
: SceneWidget (document.getData().getResourceSystem()->getSceneManager(), parent), mSceneElements(0), mRun(0), mDocument(document),
|
||||
mInteractionMask (0)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
@ -59,33 +56,27 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
||||
this, SLOT (debugProfileDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
|
||||
mPhysics = document.getPhysics(); // create physics if one doesn't exist
|
||||
mPhysics->addSceneManager(getSceneManager(), this);
|
||||
mMouse = new MouseState(this);
|
||||
}
|
||||
|
||||
CSVRender::WorldspaceWidget::~WorldspaceWidget ()
|
||||
{
|
||||
delete mMouse;
|
||||
mPhysics->removeSceneManager(getSceneManager());
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||
{
|
||||
if (mode=="1st")
|
||||
setNavigation (&m1st);
|
||||
mView->setCameraManipulator(new osgGA::FirstPersonManipulator);
|
||||
else if (mode=="free")
|
||||
setNavigation (&mFree);
|
||||
mView->setCameraManipulator(new osgGA::FirstPersonManipulator);
|
||||
else if (mode=="orbit")
|
||||
setNavigation (&mOrbit);
|
||||
mView->setCameraManipulator(new osgGA::OrbitManipulator);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::useViewHint (const std::string& hint) {}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectDefaultNavigationMode()
|
||||
{
|
||||
setNavigation (&m1st);
|
||||
mView->setCameraManipulator(new osgGA::FirstPersonManipulator);
|
||||
}
|
||||
|
||||
CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||
@ -373,16 +364,16 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
if(event->buttons() & Qt::RightButton)
|
||||
{
|
||||
mMouse->mouseMoveEvent(event);
|
||||
//mMouse->mouseMoveEvent(event);
|
||||
}
|
||||
SceneWidget::mouseMoveEvent(event);
|
||||
RenderWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
if(event->buttons() & Qt::RightButton)
|
||||
{
|
||||
mMouse->mousePressEvent(event);
|
||||
//mMouse->mousePressEvent(event);
|
||||
}
|
||||
//SceneWidget::mousePressEvent(event);
|
||||
}
|
||||
@ -391,37 +382,39 @@ void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::RightButton)
|
||||
{
|
||||
/*
|
||||
if(!getViewport())
|
||||
{
|
||||
SceneWidget::mouseReleaseEvent(event);
|
||||
return;
|
||||
}
|
||||
mMouse->mouseReleaseEvent(event);
|
||||
*/
|
||||
//mMouse->mouseReleaseEvent(event);
|
||||
}
|
||||
SceneWidget::mouseReleaseEvent(event);
|
||||
RenderWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event)
|
||||
{
|
||||
if(event->button() == Qt::RightButton)
|
||||
{
|
||||
mMouse->mouseDoubleClickEvent(event);
|
||||
//mMouse->mouseDoubleClickEvent(event);
|
||||
}
|
||||
//SceneWidget::mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event)
|
||||
{
|
||||
if(!mMouse->wheelEvent(event))
|
||||
SceneWidget::wheelEvent(event);
|
||||
//if(!mMouse->wheelEvent(event))
|
||||
RenderWidget::wheelEvent(event);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Escape)
|
||||
{
|
||||
mMouse->cancelDrag();
|
||||
//mMouse->cancelDrag();
|
||||
}
|
||||
else
|
||||
SceneWidget::keyPressEvent(event);
|
||||
RenderWidget::keyPressEvent(event);
|
||||
}
|
||||
|
@ -4,11 +4,7 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "scenewidget.hpp"
|
||||
#include "mousestate.hpp"
|
||||
|
||||
#include "navigation1st.hpp"
|
||||
#include "navigationfree.hpp"
|
||||
#include "navigationorbit.hpp"
|
||||
#include <apps/opencs/model/doc/document.hpp>
|
||||
#include <apps/opencs/model/world/tablemimedata.hpp>
|
||||
|
||||
@ -25,25 +21,15 @@ namespace CSVWidget
|
||||
class SceneToolRun;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class PhysicsSystem;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class WorldspaceWidget : public SceneWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSVRender::Navigation1st m1st;
|
||||
CSVRender::NavigationFree mFree;
|
||||
CSVRender::NavigationOrbit mOrbit;
|
||||
CSVWidget::SceneToolToggle2 *mSceneElements;
|
||||
CSVWidget::SceneToolRun *mRun;
|
||||
CSMDoc::Document& mDocument;
|
||||
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||
MouseState *mMouse;
|
||||
unsigned int mInteractionMask;
|
||||
|
||||
public:
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include <QSpinBox>
|
||||
#include <QLabel>
|
||||
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/idtree.hpp"
|
||||
|
||||
std::string CSVWorld::CellCreator::getId() const
|
||||
{
|
||||
if (mType->currentIndex()==0)
|
||||
@ -20,6 +23,15 @@ std::string CSVWorld::CellCreator::getId() const
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void CSVWorld::CellCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const
|
||||
{
|
||||
CSMWorld::IdTree *model = dynamic_cast<CSMWorld::IdTree *>(getData().getTableModel(getCollectionId()));
|
||||
Q_ASSERT(model != NULL);
|
||||
int parentIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Cell);
|
||||
int index = model->findNestedColumnIndex(parentIndex, CSMWorld::Columns::ColumnId_Interior);
|
||||
command.addNestedValue(parentIndex, index, mType->currentIndex() == 0);
|
||||
}
|
||||
|
||||
CSVWorld::CellCreator::CellCreator (CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
const CSMWorld::UniversalId& id)
|
||||
: GenericCreator (data, undoStack, id)
|
||||
@ -95,9 +107,16 @@ void CSVWorld::CellCreator::cloneMode(const std::string& originId,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSVWorld::CellCreator::toggleWidgets(bool active)
|
||||
std::string CSVWorld::CellCreator::getErrors() const
|
||||
{
|
||||
CSVWorld::GenericCreator::toggleWidgets(active);
|
||||
mType->setEnabled(active);
|
||||
std::string errors;
|
||||
if (mType->currentIndex() == 0)
|
||||
{
|
||||
errors = GenericCreator::getErrors();
|
||||
}
|
||||
else if (getData().hasId(getId()))
|
||||
{
|
||||
errors = "The Exterior Cell is already exist";
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
@ -23,17 +23,22 @@ namespace CSVWorld
|
||||
|
||||
virtual std::string getId() const;
|
||||
|
||||
/// Allow subclasses to add additional data to \a command.
|
||||
virtual void configureCreateCommand(CSMWorld::CreateCommand& command) const;
|
||||
|
||||
public:
|
||||
|
||||
CellCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id);
|
||||
|
||||
virtual void reset();
|
||||
|
||||
virtual void toggleWidgets(bool active = true);
|
||||
|
||||
virtual void cloneMode(const std::string& originId,
|
||||
const CSMWorld::UniversalId::Type type);
|
||||
|
||||
virtual std::string getErrors() const;
|
||||
///< Return formatted error descriptions for the current state of the creator. if an empty
|
||||
/// string is returned, there is no error.
|
||||
|
||||
private slots:
|
||||
|
||||
void setType (int index);
|
||||
|
@ -161,6 +161,8 @@ CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undo
|
||||
connect (mCreate, SIGNAL (clicked (bool)), this, SLOT (create()));
|
||||
|
||||
connect (mId, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&)));
|
||||
|
||||
connect (&mData, SIGNAL (idListChanged()), this, SLOT (dataIdListChanged()));
|
||||
}
|
||||
|
||||
void CSVWorld::GenericCreator::setEditLock (bool locked)
|
||||
@ -291,3 +293,12 @@ void CSVWorld::GenericCreator::scopeChanged (int index)
|
||||
update();
|
||||
updateNamespace();
|
||||
}
|
||||
|
||||
void CSVWorld::GenericCreator::dataIdListChanged()
|
||||
{
|
||||
// If the original ID of cloned record was removed, cancel the creator
|
||||
if (mCloneMode && !mData.hasId(mClonedId))
|
||||
{
|
||||
emit done();
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ namespace CSVWorld
|
||||
void create();
|
||||
|
||||
void scopeChanged (int index);
|
||||
|
||||
void dataIdListChanged();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,324 +0,0 @@
|
||||
#include "physicssystem.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <OgreRay.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreSceneManager.h>
|
||||
|
||||
#include <openengine/bullet/physic.hpp>
|
||||
#include <components/nifbullet/bulletnifloader.hpp>
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "../render/elements.hpp"
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
PhysicsSystem::PhysicsSystem()
|
||||
{
|
||||
// Create physics. shapeLoader is deleted by the physic engine
|
||||
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(true);
|
||||
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
||||
}
|
||||
|
||||
PhysicsSystem::~PhysicsSystem()
|
||||
{
|
||||
delete mEngine;
|
||||
}
|
||||
|
||||
// looks up the scene manager based on the scene node name (inefficient)
|
||||
// NOTE: referenceId is assumed to be unique per document
|
||||
// NOTE: searching is done here rather than after rayTest, hence slower to load but
|
||||
// faster to find (guessing, not verified w/ perf test)
|
||||
void PhysicsSystem::addObject(const std::string &mesh,
|
||||
const std::string &sceneNodeName, const std::string &referenceId, float scale,
|
||||
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, bool placeable)
|
||||
{
|
||||
Ogre::SceneManager *sceneManager = findSceneManager(sceneNodeName);
|
||||
if(sceneManager)
|
||||
{
|
||||
// update maps (NOTE: sometimes replaced)
|
||||
mSceneNodeToRefId[sceneNodeName] = referenceId;
|
||||
mSceneNodeToMesh[sceneNodeName] = mesh;
|
||||
mRefIdToSceneNode[referenceId][sceneManager] = sceneNodeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Attempt to add an object without a corresponding SceneManager: "
|
||||
+ referenceId + " : " + sceneNodeName << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// update physics, only one physics model per referenceId
|
||||
if(mEngine->getRigidBody(referenceId, true) == NULL)
|
||||
{
|
||||
mEngine->createAndAdjustRigidBody(mesh,
|
||||
referenceId, scale, position, rotation,
|
||||
0, // scaledBoxTranslation
|
||||
0, // boxRotation
|
||||
true, // raycasting
|
||||
placeable);
|
||||
}
|
||||
}
|
||||
|
||||
// normal delete (e.g closing a scene subview or ~Object())
|
||||
// the scene node is destroyed so the mappings should be removed
|
||||
//
|
||||
// TODO: should think about using some kind of reference counting within RigidBody
|
||||
void PhysicsSystem::removeObject(const std::string &sceneNodeName)
|
||||
{
|
||||
std::string referenceId = mSceneNodeToRefId[sceneNodeName];
|
||||
|
||||
if(referenceId != "")
|
||||
{
|
||||
mSceneNodeToRefId.erase(sceneNodeName);
|
||||
mSceneNodeToMesh.erase(sceneNodeName);
|
||||
|
||||
// find which SceneManager has this object
|
||||
Ogre::SceneManager *sceneManager = findSceneManager(sceneNodeName);
|
||||
if(!sceneManager)
|
||||
{
|
||||
std::cerr << "Attempt to remove an object without a corresponding SceneManager: "
|
||||
+ sceneNodeName << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// illustration: erase the object "K" from the object map
|
||||
//
|
||||
// RidigBody SubView Ogre
|
||||
// --------------- -------------- -------------
|
||||
// ReferenceId "A" (SceneManager X SceneNode "J")
|
||||
// (SceneManager Y SceneNode "K") <--- erase
|
||||
// (SceneManager Z SceneNode "L")
|
||||
//
|
||||
// ReferenceId "B" (SceneManager X SceneNode "M")
|
||||
// (SceneManager Y SceneNode "N") <--- notice not deleted
|
||||
// (SceneManager Z SceneNode "O")
|
||||
std::map<std::string, std::map<Ogre::SceneManager *, std::string> >::iterator itRef =
|
||||
mRefIdToSceneNode.begin();
|
||||
for(; itRef != mRefIdToSceneNode.end(); ++itRef)
|
||||
{
|
||||
if((*itRef).second.find(sceneManager) != (*itRef).second.end())
|
||||
{
|
||||
(*itRef).second.erase(sceneManager);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check whether the physics model should be deleted
|
||||
if(mRefIdToSceneNode.find(referenceId) == mRefIdToSceneNode.end())
|
||||
{
|
||||
mEngine->removeRigidBody(referenceId);
|
||||
mEngine->deleteRigidBody(referenceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Object::clear() is called when reference data is changed. It clears all
|
||||
// contents of the SceneNode and removes the physics object
|
||||
//
|
||||
// A new physics object will be created and assigned to this sceneNodeName by
|
||||
// Object::update()
|
||||
void PhysicsSystem::removePhysicsObject(const std::string &sceneNodeName)
|
||||
{
|
||||
std::string referenceId = mSceneNodeToRefId[sceneNodeName];
|
||||
|
||||
if(referenceId != "")
|
||||
{
|
||||
mEngine->removeRigidBody(referenceId);
|
||||
mEngine->deleteRigidBody(referenceId);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::replaceObject(const std::string &sceneNodeName, float scale,
|
||||
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, bool placeable)
|
||||
{
|
||||
std::string referenceId = mSceneNodeToRefId[sceneNodeName];
|
||||
std::string mesh = mSceneNodeToMesh[sceneNodeName];
|
||||
|
||||
if(referenceId != "")
|
||||
{
|
||||
// delete the physics object
|
||||
mEngine->removeRigidBody(referenceId);
|
||||
mEngine->deleteRigidBody(referenceId);
|
||||
|
||||
// create a new physics object
|
||||
mEngine->createAndAdjustRigidBody(mesh, referenceId, scale, position, rotation,
|
||||
0, 0, true, placeable);
|
||||
|
||||
// update other scene managers if they have the referenceId
|
||||
// FIXME: rotation or scale not updated
|
||||
moveSceneNodeImpl(sceneNodeName, referenceId, position);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: adjustRigidBody() seems to lose objects, work around by deleting and recreating objects
|
||||
void PhysicsSystem::moveObject(const std::string &sceneNodeName,
|
||||
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation)
|
||||
{
|
||||
mEngine->adjustRigidBody(mEngine->getRigidBody(sceneNodeName, true /*raycasting*/),
|
||||
position, rotation);
|
||||
}
|
||||
|
||||
void PhysicsSystem::moveSceneNodeImpl(const std::string sceneNodeName,
|
||||
const std::string referenceId, const Ogre::Vector3 &position)
|
||||
{
|
||||
std::map<Ogre::SceneManager *, CSVRender::SceneWidget *>::const_iterator iter = mSceneWidgets.begin();
|
||||
for(; iter != mSceneWidgets.end(); ++iter)
|
||||
{
|
||||
std::string name = refIdToSceneNode(referenceId, (*iter).first);
|
||||
if(name != sceneNodeName && (*iter).first->hasSceneNode(name))
|
||||
{
|
||||
(*iter).first->getSceneNode(name)->setPosition(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::moveSceneNodes(const std::string sceneNodeName, const Ogre::Vector3 &position)
|
||||
{
|
||||
moveSceneNodeImpl(sceneNodeName, sceneNodeToRefId(sceneNodeName), position);
|
||||
}
|
||||
|
||||
void PhysicsSystem::addHeightField(Ogre::SceneManager *sceneManager,
|
||||
float* heights, int x, int y, float yoffset, float triSize, float sqrtVerts)
|
||||
{
|
||||
std::string name = "HeightField_"
|
||||
+ QString::number(x).toStdString() + "_" + QString::number(y).toStdString();
|
||||
|
||||
if(mTerrain.find(name) == mTerrain.end())
|
||||
mEngine->addHeightField(heights, x, y, yoffset, triSize, sqrtVerts);
|
||||
|
||||
mTerrain.insert(std::pair<std::string, Ogre::SceneManager *>(name, sceneManager));
|
||||
}
|
||||
|
||||
void PhysicsSystem::removeHeightField(Ogre::SceneManager *sceneManager, int x, int y)
|
||||
{
|
||||
std::string name = "HeightField_"
|
||||
+ QString::number(x).toStdString() + "_" + QString::number(y).toStdString();
|
||||
|
||||
if(mTerrain.count(name) == 1)
|
||||
mEngine->removeHeightField(x, y);
|
||||
|
||||
std::multimap<std::string, Ogre::SceneManager *>::iterator iter = mTerrain.begin();
|
||||
for(; iter != mTerrain.end(); ++iter)
|
||||
{
|
||||
if((*iter).second == sceneManager)
|
||||
{
|
||||
mTerrain.erase(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sceneMgr: to lookup the scene node name from the object's referenceId
|
||||
// camera: primarily used to get the visibility mask for the viewport
|
||||
//
|
||||
// returns the found object's scene node name and its position in the world space
|
||||
//
|
||||
// WARNING: far clip distance is a global setting, if it changes in future
|
||||
// this method will need to be updated
|
||||
std::pair<std::string, Ogre::Vector3> PhysicsSystem::castRay(float mouseX,
|
||||
float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera)
|
||||
{
|
||||
// NOTE: there could be more than one camera for the scene manager
|
||||
// TODO: check whether camera belongs to sceneMgr
|
||||
if(!sceneMgr || !camera || !camera->getViewport())
|
||||
return std::make_pair("", Ogre::Vector3(0,0,0)); // FIXME: this should be an exception
|
||||
|
||||
// using a really small value seems to mess up with the projections
|
||||
float nearClipDistance = camera->getNearClipDistance(); // save existing
|
||||
camera->setNearClipDistance(10.0f); // arbitrary number
|
||||
Ogre::Ray ray = camera->getCameraToViewportRay(mouseX, mouseY);
|
||||
camera->setNearClipDistance(nearClipDistance); // restore
|
||||
|
||||
Ogre::Vector3 from = ray.getOrigin();
|
||||
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
|
||||
float farClipDist = userSettings.setting("Scene/far clip distance", QString("300000")).toFloat();
|
||||
Ogre::Vector3 to = ray.getPoint(farClipDist);
|
||||
|
||||
btVector3 _from, _to;
|
||||
_from = btVector3(from.x, from.y, from.z);
|
||||
_to = btVector3(to.x, to.y, to.z);
|
||||
|
||||
uint32_t visibilityMask = camera->getViewport()->getVisibilityMask();
|
||||
bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain);
|
||||
bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference);
|
||||
|
||||
Ogre::Vector3 norm; // not used
|
||||
std::pair<std::string, float> result =
|
||||
mEngine->rayTest(_from, _to, !ignoreObjects, ignoreHeightMap, &norm);
|
||||
|
||||
// result.first is the object's referenceId
|
||||
if(result.first == "")
|
||||
return std::make_pair("", Ogre::Vector3(0,0,0));
|
||||
else
|
||||
{
|
||||
std::string name = refIdToSceneNode(result.first, sceneMgr);
|
||||
if(name == "")
|
||||
name = result.first;
|
||||
else
|
||||
name = refIdToSceneNode(result.first, sceneMgr);
|
||||
|
||||
return std::make_pair(name, ray.getPoint(farClipDist*result.second));
|
||||
}
|
||||
}
|
||||
|
||||
std::string PhysicsSystem::refIdToSceneNode(std::string referenceId, Ogre::SceneManager *sceneMgr)
|
||||
{
|
||||
return mRefIdToSceneNode[referenceId][sceneMgr];
|
||||
}
|
||||
|
||||
std::string PhysicsSystem::sceneNodeToRefId(std::string sceneNodeName)
|
||||
{
|
||||
return mSceneNodeToRefId[sceneNodeName];
|
||||
}
|
||||
|
||||
void PhysicsSystem::addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget *sceneWidget)
|
||||
{
|
||||
mSceneWidgets[sceneMgr] = sceneWidget;
|
||||
|
||||
mEngine->createDebugDraw(sceneMgr);
|
||||
}
|
||||
|
||||
std::map<Ogre::SceneManager*, CSVRender::SceneWidget *> PhysicsSystem::sceneWidgets()
|
||||
{
|
||||
return mSceneWidgets;
|
||||
}
|
||||
|
||||
void PhysicsSystem::removeSceneManager(Ogre::SceneManager *sceneMgr)
|
||||
{
|
||||
mEngine->removeDebugDraw(sceneMgr);
|
||||
|
||||
mSceneWidgets.erase(sceneMgr);
|
||||
}
|
||||
|
||||
Ogre::SceneManager *PhysicsSystem::findSceneManager(std::string sceneNodeName)
|
||||
{
|
||||
std::map<Ogre::SceneManager *, CSVRender::SceneWidget *>::const_iterator iter = mSceneWidgets.begin();
|
||||
for(; iter != mSceneWidgets.end(); ++iter)
|
||||
{
|
||||
if((*iter).first->hasSceneNode(sceneNodeName))
|
||||
{
|
||||
return (*iter).first;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PhysicsSystem::toggleDebugRendering(Ogre::SceneManager *sceneMgr)
|
||||
{
|
||||
// FIXME: should check if sceneMgr is in the list
|
||||
if(!sceneMgr)
|
||||
return;
|
||||
|
||||
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
|
||||
if(!(userSettings.setting("debug/mouse-picking", QString("false")) == "true" ? true : false))
|
||||
{
|
||||
std::cerr << "Turn on mouse-picking debug option to see collision shapes." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
mEngine->toggleDebugRendering(sceneMgr);
|
||||
mEngine->stepDebug(sceneMgr);
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
#ifndef CSV_WORLD_PHYSICSSYSTEM_H
|
||||
#define CSV_WORLD_PHYSICSSYSTEM_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
class Quaternion;
|
||||
class SceneManager;
|
||||
class Camera;
|
||||
}
|
||||
|
||||
namespace OEngine
|
||||
{
|
||||
namespace Physic
|
||||
{
|
||||
class PhysicEngine;
|
||||
}
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class SceneWidget;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class PhysicsSystem
|
||||
{
|
||||
std::map<std::string, std::string> mSceneNodeToRefId;
|
||||
std::map<std::string, std::map<Ogre::SceneManager *, std::string> > mRefIdToSceneNode;
|
||||
std::map<std::string, std::string> mSceneNodeToMesh;
|
||||
std::map<Ogre::SceneManager*, CSVRender::SceneWidget *> mSceneWidgets;
|
||||
OEngine::Physic::PhysicEngine* mEngine;
|
||||
std::multimap<std::string, Ogre::SceneManager *> mTerrain;
|
||||
|
||||
public:
|
||||
|
||||
PhysicsSystem();
|
||||
~PhysicsSystem();
|
||||
|
||||
void addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget * scene);
|
||||
|
||||
void removeSceneManager(Ogre::SceneManager *sceneMgr);
|
||||
|
||||
void addObject(const std::string &mesh,
|
||||
const std::string &sceneNodeName, const std::string &referenceId, float scale,
|
||||
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
|
||||
bool placeable=false);
|
||||
|
||||
void removeObject(const std::string &sceneNodeName);
|
||||
void removePhysicsObject(const std::string &sceneNodeName);
|
||||
|
||||
void replaceObject(const std::string &sceneNodeName,
|
||||
float scale, const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &rotation, bool placeable=false);
|
||||
|
||||
void moveObject(const std::string &sceneNodeName,
|
||||
const Ogre::Vector3 &position, const Ogre::Quaternion &rotation);
|
||||
|
||||
void moveSceneNodes(const std::string sceneNodeName, const Ogre::Vector3 &position);
|
||||
|
||||
void addHeightField(Ogre::SceneManager *sceneManager,
|
||||
float* heights, int x, int y, float yoffset, float triSize, float sqrtVerts);
|
||||
|
||||
void removeHeightField(Ogre::SceneManager *sceneManager, int x, int y);
|
||||
|
||||
void toggleDebugRendering(Ogre::SceneManager *sceneMgr);
|
||||
|
||||
// return the object's SceneNode name and position for the given SceneManager
|
||||
std::pair<std::string, Ogre::Vector3> castRay(float mouseX,
|
||||
float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera);
|
||||
|
||||
std::string sceneNodeToRefId(std::string sceneNodeName);
|
||||
|
||||
// for multi-scene manager per physics engine
|
||||
std::map<Ogre::SceneManager*, CSVRender::SceneWidget *> sceneWidgets();
|
||||
|
||||
private:
|
||||
|
||||
void moveSceneNodeImpl(const std::string sceneNodeName,
|
||||
const std::string referenceId, const Ogre::Vector3 &position);
|
||||
|
||||
void updateSelectionHighlight(std::string sceneNode, const Ogre::Vector3 &position);
|
||||
|
||||
std::string refIdToSceneNode(std::string referenceId, Ogre::SceneManager *sceneMgr);
|
||||
|
||||
Ogre::SceneManager *findSceneManager(std::string sceneNodeName);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CSV_WORLD_PHYSICSSYSTEM_H
|
@ -447,7 +447,7 @@ void CSVWorld::Table::cloneRecord()
|
||||
{
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
const CSMWorld::UniversalId& toClone = getUniversalId(selectedRows.begin()->row());
|
||||
if (selectedRows.size()==1 && !mModel->isDeleted (toClone.getId()))
|
||||
if (selectedRows.size() == 1)
|
||||
{
|
||||
emit cloneRequest (toClone);
|
||||
}
|
||||
|
@ -20,10 +20,9 @@ set(GAME_HEADER
|
||||
source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||
|
||||
add_openmw_dir (mwrender
|
||||
renderingmanager debugging sky camera animation npcanimation creatureanimation activatoranimation
|
||||
actors objects renderinginterface localmap occlusionquery water shadows
|
||||
characterpreview globalmap ripplesimulation refraction
|
||||
terrainstorage renderconst effectmanager weaponanimation
|
||||
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
|
||||
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
|
||||
bulletdebugdraw globalmap characterpreview camera localmap water terrainstorage ripplesimulation
|
||||
)
|
||||
|
||||
add_openmw_dir (mwinput
|
||||
@ -31,7 +30,7 @@ add_openmw_dir (mwinput
|
||||
)
|
||||
|
||||
add_openmw_dir (mwgui
|
||||
textinput widgets race class birth review windowmanagerimp console dialogue
|
||||
layout textinput widgets race class birth review windowmanagerimp console dialogue
|
||||
windowbase statswindow messagebox journalwindow charactercreation
|
||||
mapwindow windowpinnablebase tooltips scrollwindow bookwindow
|
||||
formatting inventorywindow container hud countdialog tradewindow settingswindow
|
||||
@ -61,12 +60,16 @@ add_openmw_dir (mwsound
|
||||
)
|
||||
|
||||
add_openmw_dir (mwworld
|
||||
refdata worldimp physicssystem scene globals class action nullaction actionteleport
|
||||
refdata worldimp scene globals class action nullaction actionteleport
|
||||
containerstore actiontalk actiontake manualref player cellfunctors failedaction
|
||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||
cells localscripts customdata inventorystore ptr actionopen actionread
|
||||
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
|
||||
contentloader esmloader actiontrap cellreflist projectilemanager cellref
|
||||
contentloader esmloader actiontrap cellreflist cellref physicssystem weather projectilemanager
|
||||
)
|
||||
|
||||
add_openmw_dir (mwphysics
|
||||
physicssystem trace collisiontype actor convert
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
@ -75,10 +78,11 @@ add_openmw_dir (mwclass
|
||||
)
|
||||
|
||||
add_openmw_dir (mwmechanics
|
||||
mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
|
||||
mechanicsmanagerimp stat creaturestats magiceffects movement
|
||||
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor
|
||||
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
|
||||
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning
|
||||
character actors objects aistate
|
||||
)
|
||||
|
||||
add_openmw_dir (mwstate
|
||||
@ -111,40 +115,30 @@ endif ()
|
||||
include_directories(${SOUND_INPUT_INCLUDES})
|
||||
|
||||
target_link_libraries(openmw
|
||||
${OENGINE_LIBRARY}
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
${SHINY_LIBRARIES}
|
||||
${OPENAL_LIBRARY}
|
||||
${SOUND_INPUT_LIBRARY}
|
||||
${BULLET_LIBRARIES}
|
||||
${OPENSCENEGRAPH_LIBRARIES}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_THREAD_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||
${Boost_WAVE_LIBRARY}
|
||||
${OPENAL_LIBRARY}
|
||||
${SOUND_INPUT_LIBRARY}
|
||||
${BULLET_LIBRARIES}
|
||||
${MYGUI_LIBRARIES}
|
||||
${SDL2_LIBRARY}
|
||||
${MYGUI_PLATFORM_LIBRARIES}
|
||||
"ogre-ffmpeg-videoplayer"
|
||||
"osg-ffmpeg-videoplayer"
|
||||
"oics"
|
||||
"sdl4ogre"
|
||||
components
|
||||
)
|
||||
|
||||
if (ANDROID)
|
||||
target_link_libraries(openmw
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
EGL
|
||||
android
|
||||
log
|
||||
dl
|
||||
MyGUI.OgrePlatform
|
||||
MyGUIEngineStatic
|
||||
Plugin_StrangeButtonStatic
|
||||
cpufeatures
|
||||
BulletCollision
|
||||
BulletDynamics
|
||||
LinearMath
|
||||
)
|
||||
endif (ANDROID)
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
/// \namespace MWRender
|
||||
/// \ingroup openmw
|
||||
/// \brief Rendering via Ogre
|
||||
/// \brief Rendering
|
||||
|
||||
/// \namespace MWWorld
|
||||
/// \ingroup openmw
|
||||
|
@ -3,24 +3,29 @@
|
||||
#include <stdexcept>
|
||||
#include <iomanip>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <MyGUI_WidgetManager.h>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <openengine/misc/rng.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
|
||||
#include <components/vfs/manager.hpp>
|
||||
#include <components/vfs/registerarchives.hpp>
|
||||
|
||||
#include <components/sdlutil/sdlgraphicswindow.hpp>
|
||||
#include <components/sdlutil/imagetosurface.hpp>
|
||||
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/texturemanager.hpp>
|
||||
|
||||
#include <components/compiler/extensions0.hpp>
|
||||
|
||||
#include <components/bsa/resources.hpp>
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/translation/translation.hpp>
|
||||
#include <components/nifoverrides/nifoverrides.hpp>
|
||||
|
||||
#include <components/nifbullet/bulletnifloader.hpp>
|
||||
#include <components/nifogre/ogrenifloader.hpp>
|
||||
|
||||
#include <components/esm/loadcell.hpp>
|
||||
|
||||
@ -38,6 +43,8 @@
|
||||
#include "mwworld/player.hpp"
|
||||
#include "mwworld/worldimp.hpp"
|
||||
|
||||
#include "mwrender/vismask.hpp"
|
||||
|
||||
#include "mwclass/classes.hpp"
|
||||
|
||||
#include "mwdialogue/dialoguemanagerimp.hpp"
|
||||
@ -48,6 +55,15 @@
|
||||
|
||||
#include "mwstate/statemanagerimp.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
void checkSDLError(int ret)
|
||||
{
|
||||
if (ret != 0)
|
||||
std::cerr << "SDL error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void OMW::Engine::executeLocalScripts()
|
||||
{
|
||||
MWWorld::LocalScripts& localScripts = MWBase::Environment::get().getWorld()->getLocalScripts();
|
||||
@ -66,23 +82,11 @@ void OMW::Engine::executeLocalScripts()
|
||||
localScripts.setIgnore (MWWorld::Ptr());
|
||||
}
|
||||
|
||||
bool OMW::Engine::frameStarted (const Ogre::FrameEvent& evt)
|
||||
{
|
||||
if (MWBase::Environment::get().getStateManager()->getState()!=
|
||||
MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
bool paused = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||
MWBase::Environment::get().getWorld()->frameStarted(evt.timeSinceLastFrame, paused);
|
||||
MWBase::Environment::get().getWindowManager ()->frameStarted(evt.timeSinceLastFrame);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||
void OMW::Engine::frame(float frametime)
|
||||
{
|
||||
try
|
||||
{
|
||||
float frametime = evt.timeSinceLastFrame;
|
||||
mStartTick = mViewer->getStartTick();
|
||||
mEnvironment.setFrameDuration (frametime);
|
||||
|
||||
// update input
|
||||
@ -90,22 +94,22 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||
|
||||
// When the window is minimized, pause everything. Currently this *has* to be here to work around a MyGUI bug.
|
||||
// If we are not currently rendering, then RenderItems will not be reused resulting in a memory leak upon changing widget textures.
|
||||
if (!mOgre->getWindow()->isActive() || !mOgre->getWindow()->isVisible())
|
||||
return true;
|
||||
//if (!mOgre->getWindow()->isActive() || !mOgre->getWindow()->isVisible())
|
||||
// return true;
|
||||
|
||||
// sound
|
||||
if (mUseSound)
|
||||
MWBase::Environment::get().getSoundManager()->update(frametime);
|
||||
|
||||
// GUI active? Most game processing will be paused, but scripts still run.
|
||||
bool guiActive = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||
|
||||
// Main menu opened? Then scripts are also paused.
|
||||
bool paused = MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu);
|
||||
|
||||
// update game state
|
||||
MWBase::Environment::get().getStateManager()->update (frametime);
|
||||
|
||||
bool guiActive = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||
|
||||
osg::Timer_t beforeScriptTick = osg::Timer::instance()->tick();
|
||||
if (MWBase::Environment::get().getStateManager()->getState()==
|
||||
MWBase::StateManager::State_Running)
|
||||
{
|
||||
@ -127,15 +131,17 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||
MWBase::Environment::get().getWorld()->advanceTime(
|
||||
frametime*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600);
|
||||
}
|
||||
|
||||
osg::Timer_t afterScriptTick = osg::Timer::instance()->tick();
|
||||
|
||||
// update actors
|
||||
osg::Timer_t beforeMechanicsTick = osg::Timer::instance()->tick();
|
||||
if (MWBase::Environment::get().getStateManager()->getState()!=
|
||||
MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
MWBase::Environment::get().getMechanicsManager()->update(frametime,
|
||||
guiActive);
|
||||
}
|
||||
osg::Timer_t afterMechanicsTick = osg::Timer::instance()->tick();
|
||||
|
||||
if (MWBase::Environment::get().getStateManager()->getState()==
|
||||
MWBase::StateManager::State_Running)
|
||||
@ -146,37 +152,50 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||
}
|
||||
|
||||
// update world
|
||||
osg::Timer_t beforePhysicsTick = osg::Timer::instance()->tick();;
|
||||
if (MWBase::Environment::get().getStateManager()->getState()!=
|
||||
MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->update(frametime, guiActive);
|
||||
}
|
||||
osg::Timer_t afterPhysicsTick = osg::Timer::instance()->tick();
|
||||
|
||||
// update GUI
|
||||
MWBase::Environment::get().getWindowManager()->onFrame(frametime);
|
||||
if (MWBase::Environment::get().getStateManager()->getState()!=
|
||||
MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
Ogre::RenderWindow* window = mOgre->getWindow();
|
||||
unsigned int tri, batch;
|
||||
MWBase::Environment::get().getWorld()->getTriangleBatchCount(tri, batch);
|
||||
MWBase::Environment::get().getWindowManager()->wmUpdateFps(window->getLastFPS(), tri, batch);
|
||||
|
||||
#if 0
|
||||
MWBase::Environment::get().getWindowManager()->wmUpdateFps(fps);
|
||||
#endif
|
||||
MWBase::Environment::get().getWindowManager()->update();
|
||||
}
|
||||
|
||||
int frameNumber = mViewer->getFrameStamp()->getFrameNumber();
|
||||
osg::Stats* stats = mViewer->getViewerStats();
|
||||
stats->setAttribute(frameNumber, "script_time_begin", osg::Timer::instance()->delta_s(mStartTick, beforeScriptTick));
|
||||
stats->setAttribute(frameNumber, "script_time_taken", osg::Timer::instance()->delta_s(beforeScriptTick, afterScriptTick));
|
||||
stats->setAttribute(frameNumber, "script_time_end", osg::Timer::instance()->delta_s(mStartTick, afterScriptTick));
|
||||
|
||||
stats->setAttribute(frameNumber, "mechanics_time_begin", osg::Timer::instance()->delta_s(mStartTick, beforeMechanicsTick));
|
||||
stats->setAttribute(frameNumber, "mechanics_time_taken", osg::Timer::instance()->delta_s(beforeMechanicsTick, afterMechanicsTick));
|
||||
stats->setAttribute(frameNumber, "mechanics_time_end", osg::Timer::instance()->delta_s(mStartTick, afterMechanicsTick));
|
||||
|
||||
stats->setAttribute(frameNumber, "physics_time_begin", osg::Timer::instance()->delta_s(mStartTick, beforePhysicsTick));
|
||||
stats->setAttribute(frameNumber, "physics_time_taken", osg::Timer::instance()->delta_s(beforePhysicsTick, afterPhysicsTick));
|
||||
stats->setAttribute(frameNumber, "physics_time_end", osg::Timer::instance()->delta_s(mStartTick, afterPhysicsTick));
|
||||
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cerr << "Error in framelistener: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||
: mEncoding(ToUTF8::WINDOWS_1252)
|
||||
: mWindow(NULL)
|
||||
, mEncoding(ToUTF8::WINDOWS_1252)
|
||||
, mEncoder(NULL)
|
||||
, mOgre (0)
|
||||
, mVerboseScripts (false)
|
||||
, mSkipMenu (false)
|
||||
, mUseSound (true)
|
||||
@ -193,8 +212,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||
, mNewGame (false)
|
||||
, mCfgMgr(configurationManager)
|
||||
{
|
||||
OEngine::Misc::Rng::init();
|
||||
std::srand ( static_cast<unsigned int>(std::time(NULL)) );
|
||||
Misc::Rng::init();
|
||||
MWClass::registerClasses();
|
||||
|
||||
Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE|SDL_INIT_GAMECONTROLLER|SDL_INIT_JOYSTICK;
|
||||
@ -206,33 +224,30 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||
throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
mStartTick = osg::Timer::instance()->tick();
|
||||
}
|
||||
|
||||
OMW::Engine::~Engine()
|
||||
{
|
||||
if (mOgre)
|
||||
mOgre->restoreWindowGammaRamp();
|
||||
mEnvironment.cleanup();
|
||||
|
||||
delete mScriptContext;
|
||||
delete mOgre;
|
||||
mScriptContext = NULL;
|
||||
|
||||
mResourceSystem.reset();
|
||||
|
||||
mViewer = NULL;
|
||||
|
||||
if (mWindow)
|
||||
{
|
||||
SDL_DestroyWindow(mWindow);
|
||||
mWindow = NULL;
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
// add resources directory
|
||||
// \note This function works recursively.
|
||||
|
||||
void OMW::Engine::addResourcesDirectory (const boost::filesystem::path& path)
|
||||
{
|
||||
mOgre->getRoot()->addResourceLocation (path.string(), "FileSystem",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
|
||||
}
|
||||
|
||||
void OMW::Engine::addZipResource (const boost::filesystem::path& path)
|
||||
{
|
||||
mOgre->getRoot()->addResourceLocation (path.string(), "Zip",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false);
|
||||
}
|
||||
|
||||
void OMW::Engine::enableFSStrict(bool fsStrict)
|
||||
{
|
||||
mFSStrict = fsStrict;
|
||||
@ -299,71 +314,149 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
||||
if (boost::filesystem::exists(settingspath))
|
||||
settings.loadUser(settingspath);
|
||||
|
||||
// load nif overrides
|
||||
NifOverrides::Overrides nifOverrides;
|
||||
std::string transparencyOverrides = "/transparency-overrides.cfg";
|
||||
std::string materialOverrides = "/material-overrides.cfg";
|
||||
if (boost::filesystem::exists(mCfgMgr.getLocalPath().string() + transparencyOverrides))
|
||||
nifOverrides.loadTransparencyOverrides(mCfgMgr.getLocalPath().string() + transparencyOverrides);
|
||||
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + transparencyOverrides))
|
||||
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + transparencyOverrides);
|
||||
if (boost::filesystem::exists(mCfgMgr.getLocalPath().string() + materialOverrides))
|
||||
nifOverrides.loadMaterialOverrides(mCfgMgr.getLocalPath().string() + materialOverrides);
|
||||
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + materialOverrides))
|
||||
nifOverrides.loadMaterialOverrides(mCfgMgr.getGlobalPath().string() + materialOverrides);
|
||||
|
||||
return settingspath;
|
||||
}
|
||||
|
||||
void OMW::Engine::createWindow(Settings::Manager& settings)
|
||||
{
|
||||
int screen = settings.getInt("screen", "Video");
|
||||
int width = settings.getInt("resolution x", "Video");
|
||||
int height = settings.getInt("resolution y", "Video");
|
||||
bool fullscreen = settings.getBool("fullscreen", "Video");
|
||||
bool windowBorder = settings.getBool("window border", "Video");
|
||||
bool vsync = settings.getBool("vsync", "Video");
|
||||
int antialiasing = settings.getInt("antialiasing", "Video");
|
||||
|
||||
int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(screen),
|
||||
pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(screen);
|
||||
|
||||
if(fullscreen)
|
||||
{
|
||||
pos_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen);
|
||||
pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen);
|
||||
}
|
||||
|
||||
Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE;
|
||||
if(fullscreen)
|
||||
flags |= SDL_WINDOW_FULLSCREEN;
|
||||
|
||||
if (!windowBorder)
|
||||
flags |= SDL_WINDOW_BORDERLESS;
|
||||
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,
|
||||
settings.getBool("minimize on focus loss", "Video") ? "1" : "0");
|
||||
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8));
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8));
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8));
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0));
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24));
|
||||
|
||||
if (antialiasing > 0)
|
||||
{
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1));
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing));
|
||||
}
|
||||
|
||||
while (!mWindow)
|
||||
{
|
||||
mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags);
|
||||
if (!mWindow)
|
||||
{
|
||||
// Try with a lower AA
|
||||
if (antialiasing > 0)
|
||||
{
|
||||
std::cout << "Note: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2 << std::endl;
|
||||
antialiasing /= 2;
|
||||
Settings::Manager::setInt("antialiasing", "Video", antialiasing);
|
||||
checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream error;
|
||||
error << "Failed to create SDL window: " << SDL_GetError() << std::endl;
|
||||
throw std::runtime_error(error.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setWindowIcon();
|
||||
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
||||
SDL_GetWindowPosition(mWindow, &traits->x, &traits->y);
|
||||
SDL_GetWindowSize(mWindow, &traits->width, &traits->height);
|
||||
traits->windowName = SDL_GetWindowTitle(mWindow);
|
||||
traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS);
|
||||
traits->screenNum = SDL_GetWindowDisplayIndex(mWindow);
|
||||
// FIXME: Some way to get these settings back from the SDL window?
|
||||
traits->red = 8;
|
||||
traits->green = 8;
|
||||
traits->blue = 8;
|
||||
traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel
|
||||
traits->depth = 24;
|
||||
traits->stencil = 8;
|
||||
traits->vsync = vsync;
|
||||
traits->doubleBuffer = true;
|
||||
traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow);
|
||||
|
||||
osg::ref_ptr<SDLUtil::GraphicsWindowSDL2> graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits);
|
||||
if(!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext");
|
||||
|
||||
osg::ref_ptr<osg::Camera> camera = mViewer->getCamera();
|
||||
camera->setGraphicsContext(graphicsWindow);
|
||||
camera->setViewport(0, 0, width, height);
|
||||
|
||||
mViewer->realize();
|
||||
}
|
||||
|
||||
void OMW::Engine::setWindowIcon()
|
||||
{
|
||||
boost::filesystem::ifstream windowIconStream;
|
||||
std::string windowIcon = (mResDir / "mygui" / "openmw.png").string();
|
||||
windowIconStream.open(windowIcon);
|
||||
if (windowIconStream.fail())
|
||||
std::cerr << "Failed to open " << windowIcon << std::endl;
|
||||
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("png");
|
||||
if (!reader)
|
||||
{
|
||||
std::cerr << "Failed to read window icon, no png readerwriter found" << std::endl;
|
||||
return;
|
||||
}
|
||||
osgDB::ReaderWriter::ReadResult result = reader->readImage(windowIconStream);
|
||||
if (!result.success())
|
||||
std::cerr << "Failed to read " << windowIcon << ": " << result.message() << std::endl;
|
||||
else
|
||||
{
|
||||
osg::ref_ptr<osg::Image> image = result.getImage();
|
||||
SDL_Surface* surface = SDLUtil::imageToSurface(image, true);
|
||||
SDL_SetWindowIcon(mWindow, surface);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
{
|
||||
mEnvironment.setStateManager (
|
||||
new MWState::StateManager (mCfgMgr.getUserDataPath() / "saves", mContentFiles.at (0)));
|
||||
|
||||
std::string renderSystem = settings.getString("render system", "Video");
|
||||
if (renderSystem == "")
|
||||
{
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||
renderSystem = "Direct3D9 Rendering Subsystem";
|
||||
#else
|
||||
renderSystem = "OpenGL Rendering Subsystem";
|
||||
#endif
|
||||
}
|
||||
createWindow(settings);
|
||||
|
||||
mOgre = new OEngine::Render::OgreRenderer;
|
||||
osg::ref_ptr<osg::Group> rootNode (new osg::Group);
|
||||
mViewer->setSceneData(rootNode);
|
||||
|
||||
mOgre->configure(
|
||||
mCfgMgr.getLogPath().string(),
|
||||
renderSystem,
|
||||
Settings::Manager::getString("opengl rtt mode", "Video"));
|
||||
mVFS.reset(new VFS::Manager(mFSStrict));
|
||||
|
||||
// This has to be added BEFORE MyGUI is initialized, as it needs
|
||||
// to find core.xml here.
|
||||
VFS::registerArchives(mVFS.get(), mFileCollections, mArchives, true);
|
||||
|
||||
addResourcesDirectory(mCfgMgr.getCachePath ().string());
|
||||
|
||||
addResourcesDirectory(mResDir / "mygui");
|
||||
addResourcesDirectory(mResDir / "water");
|
||||
addResourcesDirectory(mResDir / "shadows");
|
||||
addResourcesDirectory(mResDir / "materials");
|
||||
|
||||
OEngine::Render::WindowSettings windowSettings;
|
||||
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
|
||||
windowSettings.window_border = settings.getBool("window border", "Video");
|
||||
windowSettings.window_x = settings.getInt("resolution x", "Video");
|
||||
windowSettings.window_y = settings.getInt("resolution y", "Video");
|
||||
windowSettings.screen = settings.getInt("screen", "Video");
|
||||
windowSettings.vsync = settings.getBool("vsync", "Video");
|
||||
windowSettings.icon = "openmw.png";
|
||||
std::string aa = settings.getString("antialiasing", "Video");
|
||||
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
||||
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,
|
||||
settings.getBool("minimize on focus loss", "Video") ? "1" : "0");
|
||||
|
||||
mOgre->createWindow("OpenMW", windowSettings);
|
||||
|
||||
Bsa::registerResources (mFileCollections, mArchives, true, mFSStrict);
|
||||
mResourceSystem.reset(new Resource::ResourceSystem(mVFS.get()));
|
||||
mResourceSystem->getTextureManager()->setUnRefImageDataAfterApply(true);
|
||||
osg::Texture::FilterMode min = osg::Texture::LINEAR_MIPMAP_NEAREST;
|
||||
osg::Texture::FilterMode mag = osg::Texture::LINEAR;
|
||||
if (Settings::Manager::getString("texture filtering", "General") == "trilinear")
|
||||
min = osg::Texture::LINEAR_MIPMAP_LINEAR;
|
||||
int maxAnisotropy = Settings::Manager::getInt("anisotropy", "General");
|
||||
mResourceSystem->getTextureManager()->setFilterSettings(min, mag, maxAnisotropy);
|
||||
|
||||
// Create input and UI first to set up a bootstrapping environment for
|
||||
// showing a loading screen and keeping the window responsive while doing so
|
||||
@ -390,29 +483,32 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
else
|
||||
gameControllerdb = ""; //if it doesn't exist, pass in an empty string
|
||||
|
||||
MWInput::InputManager* input = new MWInput::InputManager (*mOgre, *this, keybinderUser, keybinderUserExists, gameControllerdb, mGrab);
|
||||
// FIXME: shouldn't depend on Engine
|
||||
MWInput::InputManager* input = new MWInput::InputManager (mWindow, mViewer, *this, keybinderUser, keybinderUserExists, gameControllerdb, mGrab);
|
||||
mEnvironment.setInputManager (input);
|
||||
|
||||
MWGui::WindowManager* window = new MWGui::WindowManager(
|
||||
mExtensions, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap);
|
||||
std::string myguiResources = (mResDir / "mygui").string();
|
||||
osg::ref_ptr<osg::Group> guiRoot = new osg::Group;
|
||||
guiRoot->setNodeMask(MWRender::Mask_GUI);
|
||||
rootNode->addChild(guiRoot);
|
||||
MWGui::WindowManager* window = new MWGui::WindowManager(mViewer, guiRoot, mResourceSystem.get(),
|
||||
mCfgMgr.getLogPath().string() + std::string("/"), myguiResources,
|
||||
mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, mFallbackMap);
|
||||
mEnvironment.setWindowManager (window);
|
||||
|
||||
// Create sound system
|
||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
||||
|
||||
mOgre->setWindowGammaContrast(Settings::Manager::getFloat("gamma", "General"), Settings::Manager::getFloat("contrast", "General"));
|
||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mUseSound));
|
||||
|
||||
if (!mSkipMenu)
|
||||
{
|
||||
std::string logo = mFallbackMap["Movies_Company_Logo"];
|
||||
if (!logo.empty())
|
||||
window->playVideo(logo, 1);
|
||||
window->playVideo(logo, true);
|
||||
}
|
||||
|
||||
// Create the world
|
||||
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles,
|
||||
mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap,
|
||||
mEnvironment.setWorld( new MWWorld::World (mViewer, rootNode, mResourceSystem.get(),
|
||||
mFileCollections, mContentFiles, mEncoder, mFallbackMap,
|
||||
mActivationDistanceOverride, mCellName, mStartupScript));
|
||||
MWBase::Environment::get().getWorld()->setupPlayer();
|
||||
input->setPlayer(&mEnvironment.getWorld()->getPlayer());
|
||||
@ -443,8 +539,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
mEnvironment.setJournal (new MWDialogue::Journal);
|
||||
mEnvironment.setDialogueManager (new MWDialogue::DialogueManager (mExtensions, mVerboseScripts, mTranslationDataStorage));
|
||||
|
||||
mOgre->getRoot()->addFrameListener (this);
|
||||
|
||||
// scripts
|
||||
if (mCompileAll)
|
||||
{
|
||||
@ -468,18 +562,83 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
}
|
||||
}
|
||||
|
||||
class WriteScreenshotToFileOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation
|
||||
{
|
||||
public:
|
||||
WriteScreenshotToFileOperation(const std::string& screenshotPath, const std::string& screenshotFormat)
|
||||
: mScreenshotPath(screenshotPath)
|
||||
, mScreenshotFormat(screenshotFormat)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()(const osg::Image& image, const unsigned int context_id)
|
||||
{
|
||||
// Count screenshots.
|
||||
int shotCount = 0;
|
||||
|
||||
// Find the first unused filename with a do-while
|
||||
std::ostringstream stream;
|
||||
do
|
||||
{
|
||||
// Reset the stream
|
||||
stream.str("");
|
||||
stream.clear();
|
||||
|
||||
stream << mScreenshotPath << "/screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << "." << mScreenshotFormat;
|
||||
|
||||
} while (boost::filesystem::exists(stream.str()));
|
||||
|
||||
boost::filesystem::ofstream outStream;
|
||||
outStream.open(boost::filesystem::path(stream.str()), std::ios::binary);
|
||||
|
||||
osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension(mScreenshotFormat);
|
||||
if (!readerwriter)
|
||||
{
|
||||
std::cerr << "Can't write screenshot, no '" << mScreenshotFormat << "' readerwriter found" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(image, outStream);
|
||||
if (!result.success())
|
||||
{
|
||||
std::cerr << "Can't write screenshot: " << result.message() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string mScreenshotPath;
|
||||
std::string mScreenshotFormat;
|
||||
};
|
||||
|
||||
// Initialise and enter main loop.
|
||||
|
||||
void OMW::Engine::go()
|
||||
{
|
||||
assert (!mContentFiles.empty());
|
||||
assert (!mOgre);
|
||||
|
||||
mViewer = new osgViewer::Viewer;
|
||||
|
||||
osg::ref_ptr<osgViewer::StatsHandler> statshandler = new osgViewer::StatsHandler;
|
||||
statshandler->setKeyEventTogglesOnScreenStats(osgGA::GUIEventAdapter::KEY_F3);
|
||||
|
||||
statshandler->addUserStatsLine("Script", osg::Vec4f(1.f, 1.f, 1.f, 1.f), osg::Vec4f(1.f, 1.f, 1.f, 1.f),
|
||||
"script_time_taken", 1000.0, true, false, "script_time_begin", "script_time_end", 10000);
|
||||
statshandler->addUserStatsLine("Mechanics", osg::Vec4f(1.f, 1.f, 1.f, 1.f), osg::Vec4f(1.f, 1.f, 1.f, 1.f),
|
||||
"mechanics_time_taken", 1000.0, true, false, "mechanics_time_begin", "mechanics_time_end", 10000);
|
||||
statshandler->addUserStatsLine("Physics", osg::Vec4f(1.f, 1.f, 1.f, 1.f), osg::Vec4f(1.f, 1.f, 1.f, 1.f),
|
||||
"physics_time_taken", 1000.0, true, false, "physics_time_begin", "physics_time_end", 10000);
|
||||
|
||||
mViewer->addEventHandler(statshandler);
|
||||
|
||||
Settings::Manager settings;
|
||||
std::string settingspath;
|
||||
|
||||
settingspath = loadSettings (settings);
|
||||
|
||||
mScreenCaptureHandler = new osgViewer::ScreenCaptureHandler(new WriteScreenshotToFileOperation(mCfgMgr.getUserDataPath().string(),
|
||||
Settings::Manager::getString("screenshot format", "General")));
|
||||
mViewer->addEventHandler(mScreenCaptureHandler);
|
||||
|
||||
// Create encoder
|
||||
ToUTF8::Utf8Encoder encoder (mEncoding);
|
||||
mEncoder = &encoder;
|
||||
@ -514,15 +673,27 @@ void OMW::Engine::go()
|
||||
}
|
||||
|
||||
// Start the main rendering loop
|
||||
Ogre::Timer timer;
|
||||
while (!MWBase::Environment::get().getStateManager()->hasQuitRequest())
|
||||
osg::Timer frameTimer;
|
||||
double simulationTime = 0.0;
|
||||
while (!mViewer->done() && !MWBase::Environment::get().getStateManager()->hasQuitRequest())
|
||||
{
|
||||
float dt = timer.getMilliseconds()/1000.f;
|
||||
dt = std::min(dt, 0.2f);
|
||||
double dt = frameTimer.time_s();
|
||||
frameTimer.setStartTick();
|
||||
dt = std::min(dt, 0.2);
|
||||
|
||||
timer.reset();
|
||||
Ogre::Root::getSingleton().renderOneFrame(dt);
|
||||
bool guiActive = MWBase::Environment::get().getWindowManager()->isGuiMode();
|
||||
if (!guiActive)
|
||||
simulationTime += dt;
|
||||
|
||||
mViewer->advance(simulationTime);
|
||||
|
||||
frame(dt);
|
||||
|
||||
mViewer->eventTraversal();
|
||||
mViewer->updateTraversal();
|
||||
mViewer->renderingTraversals();
|
||||
}
|
||||
|
||||
// Save user settings
|
||||
settings.saveUser(settingspath);
|
||||
|
||||
@ -560,24 +731,8 @@ void OMW::Engine::activate()
|
||||
|
||||
void OMW::Engine::screenshot()
|
||||
{
|
||||
// Count screenshots.
|
||||
int shotCount = 0;
|
||||
|
||||
const std::string& screenshotPath = mCfgMgr.getUserDataPath().string();
|
||||
std::string format = Settings::Manager::getString("screenshot format", "General");
|
||||
// Find the first unused filename with a do-while
|
||||
std::ostringstream stream;
|
||||
do
|
||||
{
|
||||
// Reset the stream
|
||||
stream.str("");
|
||||
stream.clear();
|
||||
|
||||
stream << screenshotPath << "screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << "." << format;
|
||||
|
||||
} while (boost::filesystem::exists(stream.str()));
|
||||
|
||||
mOgre->screenshot(stream.str(), format);
|
||||
mScreenCaptureHandler->setFramesToCapture(1);
|
||||
mScreenCaptureHandler->captureNextFrame(*mViewer);
|
||||
}
|
||||
|
||||
void OMW::Engine::setCompileAll (bool all)
|
||||
|
@ -1,19 +1,28 @@
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include <OgreFrameListener.h>
|
||||
|
||||
#include <components/compiler/extensions.hpp>
|
||||
#include <components/files/collections.hpp>
|
||||
#include <components/translation/translation.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <components/nifcache/nifcache.hpp>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
|
||||
#include "mwbase/environment.hpp"
|
||||
|
||||
#include "mwworld/ptr.hpp"
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
class ResourceSystem;
|
||||
}
|
||||
|
||||
namespace VFS
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
class Context;
|
||||
@ -39,36 +48,34 @@ namespace MWGui
|
||||
class WindowManager;
|
||||
}
|
||||
|
||||
namespace OEngine
|
||||
{
|
||||
namespace GUI
|
||||
{
|
||||
class MyGUIManager;
|
||||
}
|
||||
|
||||
namespace Render
|
||||
{
|
||||
class OgreRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Files
|
||||
{
|
||||
struct ConfigurationManager;
|
||||
}
|
||||
|
||||
namespace osgViewer
|
||||
{
|
||||
class ScreenCaptureHandler;
|
||||
}
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
namespace OMW
|
||||
{
|
||||
/// \brief Main engine class, that brings together all the components of OpenMW
|
||||
class Engine : private Ogre::FrameListener
|
||||
class Engine
|
||||
{
|
||||
SDL_Window* mWindow;
|
||||
std::auto_ptr<VFS::Manager> mVFS;
|
||||
std::auto_ptr<Resource::ResourceSystem> mResourceSystem;
|
||||
MWBase::Environment mEnvironment;
|
||||
ToUTF8::FromType mEncoding;
|
||||
ToUTF8::Utf8Encoder* mEncoder;
|
||||
Files::PathContainer mDataDirs;
|
||||
std::vector<std::string> mArchives;
|
||||
boost::filesystem::path mResDir;
|
||||
OEngine::Render::OgreRenderer *mOgre;
|
||||
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> mScreenCaptureHandler;
|
||||
std::string mCellName;
|
||||
std::vector<std::string> mContentFiles;
|
||||
bool mVerboseScripts;
|
||||
@ -98,23 +105,15 @@ namespace OMW
|
||||
bool mScriptBlacklistUse;
|
||||
bool mNewGame;
|
||||
|
||||
Nif::Cache mNifCache;
|
||||
osg::Timer_t mStartTick;
|
||||
|
||||
// not implemented
|
||||
Engine (const Engine&);
|
||||
Engine& operator= (const Engine&);
|
||||
|
||||
/// add resources directory
|
||||
/// \note This function works recursively.
|
||||
void addResourcesDirectory (const boost::filesystem::path& path);
|
||||
|
||||
/// add a .zip resource
|
||||
void addZipResource (const boost::filesystem::path& path);
|
||||
|
||||
void executeLocalScripts();
|
||||
|
||||
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
||||
virtual bool frameStarted (const Ogre::FrameEvent& evt);
|
||||
void frame (float dt);
|
||||
|
||||
/// Load settings from various files, returns the path to the user settings file
|
||||
std::string loadSettings (Settings::Manager & settings);
|
||||
@ -122,6 +121,9 @@ namespace OMW
|
||||
/// Prepare engine for game play
|
||||
void prepareEngine (Settings::Manager & settings);
|
||||
|
||||
void createWindow(Settings::Manager& settings);
|
||||
void setWindowIcon();
|
||||
|
||||
public:
|
||||
Engine(Files::ConfigurationManager& configurationManager);
|
||||
virtual ~Engine();
|
||||
|
@ -21,17 +21,18 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
#if (defined(__APPLE__) || defined(__linux) || defined(__unix) || defined(__posix))
|
||||
#define USE_CRASH_CATCHER 1
|
||||
#else
|
||||
#define USE_CRASH_CATCHER 0
|
||||
#endif
|
||||
|
||||
#if USE_CRASH_CATCHER
|
||||
#include <csignal>
|
||||
extern int cc_install_handlers(int argc, char **argv, int num_signals, int *sigs, const char *logfile, int (*user_info)(char*, char*));
|
||||
extern int is_debugger_attached(void);
|
||||
#endif
|
||||
|
||||
// for Ogre::macBundlePath
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
#include <OSX/macUtils.h>
|
||||
#endif
|
||||
|
||||
#include <boost/version.hpp>
|
||||
/**
|
||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||
@ -362,7 +363,7 @@ int main(int argc, char**argv)
|
||||
#endif
|
||||
|
||||
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
#if USE_CRASH_CATCHER
|
||||
// Unix crash catcher
|
||||
if ((argc == 2 && strcmp(argv[1], "--cc-handle-crash") == 0) || !is_debugger_attached())
|
||||
{
|
||||
@ -374,10 +375,10 @@ int main(int argc, char**argv)
|
||||
std::cout << "Running in a debugger, not installing crash catcher" << std::endl;
|
||||
#endif
|
||||
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
// set current dir to bundle path
|
||||
boost::filesystem::path bundlePath = boost::filesystem::path(Ogre::macBundlePath()).parent_path();
|
||||
boost::filesystem::current_path(bundlePath);
|
||||
#ifdef __APPLE__
|
||||
// FIXME: set current dir to bundle path
|
||||
//boost::filesystem::path bundlePath = boost::filesystem::path(Ogre::macBundlePath()).parent_path();
|
||||
//boost::filesystem::current_path(bundlePath);
|
||||
#endif
|
||||
|
||||
engine.reset(new OMW::Engine(cfgMgr));
|
||||
@ -389,7 +390,7 @@ int main(int argc, char**argv)
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
#if (defined(__APPLE__) || defined(__linux) || defined(__unix) || defined(__posix))
|
||||
if (!isatty(fileno(stdin)))
|
||||
#endif
|
||||
SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL);
|
||||
|
@ -6,9 +6,9 @@
|
||||
#include <list>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Ogre
|
||||
namespace osg
|
||||
{
|
||||
class Vector3;
|
||||
class Vec3f;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
@ -174,8 +174,8 @@ namespace MWBase
|
||||
virtual bool toggleAI() = 0;
|
||||
virtual bool isAIActive() = 0;
|
||||
|
||||
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
|
||||
virtual void getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects) = 0;
|
||||
virtual void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
|
||||
virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector<MWWorld::Ptr> &objects) = 0;
|
||||
|
||||
///return the list of actors which are following the given actor
|
||||
/**ie AiFollow is active and the target is the actor**/
|
||||
|
@ -7,11 +7,6 @@
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class CellStore;
|
||||
@ -125,7 +120,7 @@ namespace MWBase
|
||||
///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified.
|
||||
///< @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
|
||||
|
||||
virtual MWBase::SoundPtr playManualSound3D(const Ogre::Vector3& initialPos, const std::string& soundId,
|
||||
virtual MWBase::SoundPtr playManualSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
|
||||
float volume, float pitch, PlayType type, PlayMode mode, float offset=0) = 0;
|
||||
///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated manually using Sound::setPosition.
|
||||
|
||||
@ -162,7 +157,7 @@ namespace MWBase
|
||||
|
||||
virtual void update(float duration) = 0;
|
||||
|
||||
virtual void setListenerPosDir(const Ogre::Vector3 &pos, const Ogre::Vector3 &dir, const Ogre::Vector3 &up) = 0;
|
||||
virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up) = 0;
|
||||
|
||||
virtual void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated) = 0;
|
||||
|
||||
|
@ -26,14 +26,6 @@ namespace MyGUI
|
||||
class UString;
|
||||
}
|
||||
|
||||
namespace OEngine
|
||||
{
|
||||
namespace GUI
|
||||
{
|
||||
class Layout;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct Class;
|
||||
@ -58,6 +50,8 @@ namespace MWWorld
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class Layout;
|
||||
|
||||
class Console;
|
||||
class SpellWindow;
|
||||
class TradeWindow;
|
||||
@ -158,7 +152,7 @@ namespace MWBase
|
||||
|
||||
virtual void setConsoleSelectedObject(const MWWorld::Ptr& object) = 0;
|
||||
|
||||
virtual void wmUpdateFps(float fps, unsigned int triangleCount, unsigned int batchCount) = 0;
|
||||
virtual void wmUpdateFps(float fps) = 0;
|
||||
|
||||
/// Set value for the given ID.
|
||||
virtual void setValue (const std::string& id, const MWMechanics::AttributeValue& value) = 0;
|
||||
@ -184,12 +178,6 @@ namespace MWBase
|
||||
virtual void changeCell(MWWorld::CellStore* cell) = 0;
|
||||
///< change the active cell
|
||||
|
||||
virtual void setPlayerPos(int cellX, int cellY, const float x, const float y) = 0;
|
||||
///< set player position in map space
|
||||
|
||||
virtual void setPlayerDir(const float x, const float y) = 0;
|
||||
///< set player view direction in map space
|
||||
|
||||
virtual void setFocusObject(const MWWorld::Ptr& focus) = 0;
|
||||
virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0;
|
||||
|
||||
@ -241,7 +229,7 @@ namespace MWBase
|
||||
virtual void addVisitedLocation(const std::string& name, int x, int y) = 0;
|
||||
|
||||
/// Hides dialog and schedules dialog to be deleted.
|
||||
virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
|
||||
virtual void removeDialog(MWGui::Layout* dialog) = 0;
|
||||
|
||||
///Gracefully attempts to exit the topmost GUI mode
|
||||
/** No guarentee of actually closing the window **/
|
||||
@ -303,8 +291,6 @@ namespace MWBase
|
||||
|
||||
virtual void showSoulgemDialog (MWWorld::Ptr item) = 0;
|
||||
|
||||
virtual void frameStarted(float dt) = 0;
|
||||
|
||||
virtual void changePointer (const std::string& name) = 0;
|
||||
|
||||
virtual void setEnemy (const MWWorld::Ptr& enemy) = 0;
|
||||
@ -361,6 +347,15 @@ namespace MWBase
|
||||
virtual void cycleSpell(bool next) = 0;
|
||||
/// Cycle to next or previous weapon
|
||||
virtual void cycleWeapon(bool next) = 0;
|
||||
|
||||
// In WindowManager for now since there isn't a VFS singleton
|
||||
virtual std::string correctIconPath(const std::string& path) = 0;
|
||||
virtual std::string correctBookartPath(const std::string& path, int width, int height) = 0;
|
||||
virtual std::string correctTexturePath(const std::string& path) = 0;
|
||||
|
||||
virtual void requestMap(std::set<MWWorld::CellStore*> cells) = 0;
|
||||
virtual void removeCell(MWWorld::CellStore* cell) = 0;
|
||||
virtual void writeFog(MWWorld::CellStore* cell) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,12 @@
|
||||
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace Ogre
|
||||
#include "../mwrender/rendermode.hpp"
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Vector2;
|
||||
class Vector3;
|
||||
class Quaternion;
|
||||
class Vec3f;
|
||||
class Quat;
|
||||
class Image;
|
||||
}
|
||||
|
||||
@ -78,14 +79,6 @@ namespace MWBase
|
||||
|
||||
public:
|
||||
|
||||
enum RenderMode
|
||||
{
|
||||
Render_CollisionDebug,
|
||||
Render_Wireframe,
|
||||
Render_Pathgrid,
|
||||
Render_BoundingBoxes
|
||||
};
|
||||
|
||||
struct DoorMarker
|
||||
{
|
||||
std::string name;
|
||||
@ -125,8 +118,6 @@ namespace MWBase
|
||||
|
||||
virtual void adjustSky() = 0;
|
||||
|
||||
virtual void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) = 0;
|
||||
|
||||
virtual const MWWorld::Fallback *getFallback () const = 0;
|
||||
|
||||
virtual MWWorld::Player& getPlayer() = 0;
|
||||
@ -145,21 +136,12 @@ namespace MWBase
|
||||
|
||||
virtual bool isCellQuasiExterior() const = 0;
|
||||
|
||||
virtual Ogre::Vector2 getNorthVector (MWWorld::CellStore* cell) = 0;
|
||||
virtual osg::Vec2f getNorthVector (MWWorld::CellStore* cell) = 0;
|
||||
///< get north vector for given interior cell
|
||||
|
||||
virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector<DoorMarker>& out) = 0;
|
||||
///< get a list of teleport door markers for a given cell, to be displayed on the local map
|
||||
|
||||
virtual void worldToInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y) = 0;
|
||||
///< see MWRender::LocalMap::worldToInteriorMapPosition
|
||||
|
||||
virtual Ogre::Vector2 interiorMapToWorldPosition (float nX, float nY, int x, int y) = 0;
|
||||
///< see MWRender::LocalMap::interiorMapToWorldPosition
|
||||
|
||||
virtual bool isPositionExplored (float nX, float nY, int x, int y, bool interior) = 0;
|
||||
///< see MWRender::LocalMap::isPositionExplored
|
||||
|
||||
virtual void setGlobalInt (const std::string& name, int value) = 0;
|
||||
///< Set value independently from real type.
|
||||
|
||||
@ -192,12 +174,6 @@ namespace MWBase
|
||||
///< Return a pointer to a liveCellRef with the given name.
|
||||
/// \param activeOnly do non search inactive cells.
|
||||
|
||||
virtual MWWorld::Ptr getPtrViaHandle (const std::string& handle) = 0;
|
||||
///< Return a pointer to a liveCellRef with the given Ogre handle.
|
||||
|
||||
virtual MWWorld::Ptr searchPtrViaHandle (const std::string& handle) = 0;
|
||||
///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found
|
||||
|
||||
virtual MWWorld::Ptr searchPtrViaActorId (int actorId) = 0;
|
||||
///< Search is limited to the active cells.
|
||||
|
||||
@ -271,7 +247,7 @@ namespace MWBase
|
||||
/// Returns a pointer to the object the provided object would hit (if within the
|
||||
/// specified distance), and the point where the hit occurs. This will attempt to
|
||||
/// use the "Head" node, or alternatively the "Bip01 Head" node as a basis.
|
||||
virtual std::pair<MWWorld::Ptr,Ogre::Vector3> getHitContact(const MWWorld::Ptr &ptr, float distance) = 0;
|
||||
virtual std::pair<MWWorld::Ptr,osg::Vec3f> getHitContact(const MWWorld::Ptr &ptr, float distance) = 0;
|
||||
|
||||
virtual void adjustPosition (const MWWorld::Ptr& ptr, bool force) = 0;
|
||||
///< Adjust position after load to be on ground. Must be called after model load.
|
||||
@ -305,7 +281,7 @@ namespace MWBase
|
||||
virtual void positionToIndex (float x, float y, int &cellX, int &cellY) const = 0;
|
||||
///< Convert position to cell numbers
|
||||
|
||||
virtual void queueMovement(const MWWorld::Ptr &ptr, const Ogre::Vector3 &velocity) = 0;
|
||||
virtual void queueMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity) = 0;
|
||||
///< Queues movement for \a ptr (in local space), to be applied in the next call to
|
||||
/// doPhysics.
|
||||
|
||||
@ -317,7 +293,7 @@ namespace MWBase
|
||||
/// collisions and gravity.
|
||||
/// \return Resulting mode
|
||||
|
||||
virtual bool toggleRenderMode (RenderMode mode) = 0;
|
||||
virtual bool toggleRenderMode (MWRender::RenderMode mode) = 0;
|
||||
///< Toggle a render mode.
|
||||
///< \return Resulting mode
|
||||
|
||||
@ -395,7 +371,7 @@ namespace MWBase
|
||||
virtual bool isWading(const MWWorld::Ptr &object) const = 0;
|
||||
///Is the head of the creature underwater?
|
||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
|
||||
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const = 0;
|
||||
virtual bool isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const = 0;
|
||||
virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;
|
||||
|
||||
virtual void togglePOV() = 0;
|
||||
@ -439,7 +415,7 @@ namespace MWBase
|
||||
virtual bool getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor) = 0;
|
||||
///< get Line of Sight (morrowind stupid implementation)
|
||||
|
||||
virtual float getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist) = 0;
|
||||
virtual float getDistToNearestRayHit(const osg::Vec3f& from, const osg::Vec3f& dir, float maxDist) = 0;
|
||||
|
||||
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||
|
||||
@ -455,8 +431,7 @@ namespace MWBase
|
||||
virtual void reattachPlayerCamera() = 0;
|
||||
|
||||
/// \todo this does not belong here
|
||||
virtual void frameStarted (float dt, bool paused) = 0;
|
||||
virtual void screenshot (Ogre::Image& image, int w, int h) = 0;
|
||||
virtual void screenshot (osg::Image* image, int w, int h) = 0;
|
||||
|
||||
/// Find default position inside exterior cell specified by name
|
||||
/// \return false if exterior with given name not exists, true otherwise
|
||||
@ -503,9 +478,9 @@ namespace MWBase
|
||||
|
||||
virtual void launchMagicBolt (const std::string& model, const std::string& sound, const std::string& spellId,
|
||||
float speed, bool stack, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection) = 0;
|
||||
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection) = 0;
|
||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
||||
const Ogre::Vector3& worldPos, const Ogre::Quaternion& orient, MWWorld::Ptr bow, float speed) = 0;
|
||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength) = 0;
|
||||
|
||||
virtual const std::vector<std::string>& getContentFiles() const = 0;
|
||||
|
||||
@ -514,7 +489,7 @@ namespace MWBase
|
||||
// Are we in an exterior or pseudo-exterior cell and it's night?
|
||||
virtual bool isDark() const = 0;
|
||||
|
||||
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, Ogre::Vector3& result) = 0;
|
||||
virtual bool findInteriorPositionInWorldSpace(MWWorld::CellStore* cell, osg::Vec3f& result) = 0;
|
||||
|
||||
/// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker)
|
||||
/// @note id must be lower case
|
||||
@ -546,11 +521,11 @@ namespace MWBase
|
||||
virtual void spawnRandomCreature(const std::string& creatureList) = 0;
|
||||
|
||||
/// Spawn a blood effect for \a ptr at \a worldPosition
|
||||
virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const Ogre::Vector3& worldPosition) = 0;
|
||||
virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) = 0;
|
||||
|
||||
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const Ogre::Vector3& worldPos) = 0;
|
||||
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos) = 0;
|
||||
|
||||
virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects,
|
||||
virtual void explodeSpell (const osg::Vec3f& origin, const ESM::EffectList& effects,
|
||||
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName) = 0;
|
||||
|
||||
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
||||
@ -559,7 +534,7 @@ namespace MWBase
|
||||
virtual bool isInStorm() const = 0;
|
||||
|
||||
/// @see MWWorld::WeatherManager::getStormDirection
|
||||
virtual Ogre::Vector3 getStormDirection() const = 0;
|
||||
virtual osg::Vec3f getStormDirection() const = 0;
|
||||
|
||||
/// Resets all actors in the current active cells to their original location within that cell.
|
||||
virtual void resetActors() = 0;
|
||||
|
@ -11,12 +11,13 @@
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/action.hpp"
|
||||
#include "../mwworld/failedaction.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
|
||||
#include "../mwrender/actors.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwrender/renderinginterface.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
@ -34,12 +35,11 @@ namespace MWClass
|
||||
void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
|
||||
{
|
||||
if (!model.empty()) {
|
||||
MWRender::Actors& actors = renderingInterface.getActors();
|
||||
actors.insertActivator(ptr, model);
|
||||
renderingInterface.getObjects().insertModel(ptr, model, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const
|
||||
void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
|
||||
{
|
||||
if(!model.empty())
|
||||
physics.addObject(ptr, model);
|
||||
|
@ -19,7 +19,7 @@ namespace MWClass
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const;
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const;
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/actionalchemy.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
@ -33,10 +33,9 @@ namespace MWClass
|
||||
}
|
||||
}
|
||||
|
||||
void Apparatus::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const
|
||||
void Apparatus::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
|
||||
{
|
||||
if(!model.empty())
|
||||
physics.addObject(ptr, model, true);
|
||||
// TODO: add option somewhere to enable collision for placeable objects
|
||||
}
|
||||
|
||||
std::string Apparatus::getModel(const MWWorld::Ptr &ptr) const
|
||||
|
@ -21,7 +21,7 @@ namespace MWClass
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const;
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const;
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
@ -38,10 +38,9 @@ namespace MWClass
|
||||
}
|
||||
}
|
||||
|
||||
void Armor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const
|
||||
void Armor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
|
||||
{
|
||||
if(!model.empty())
|
||||
physics.addObject(ptr, model, true);
|
||||
// TODO: add option somewhere to enable collision for placeable objects
|
||||
}
|
||||
|
||||
std::string Armor::getModel(const MWWorld::Ptr &ptr) const
|
||||
|
@ -20,7 +20,7 @@ namespace MWClass
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const;
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const;
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "../mwworld/failedaction.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwrender/renderinginterface.hpp"
|
||||
@ -35,10 +35,9 @@ namespace MWClass
|
||||
}
|
||||
}
|
||||
|
||||
void Book::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const
|
||||
void Book::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
|
||||
{
|
||||
if(!model.empty())
|
||||
physics.addObject(ptr, model, true);
|
||||
// TODO: add option somewhere to enable collision for placeable objects
|
||||
}
|
||||
|
||||
std::string Book::getModel(const MWWorld::Ptr &ptr) const
|
||||
|
@ -18,7 +18,7 @@ namespace MWClass
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const;
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const;
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
#include "../mwworld/nullaction.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
@ -35,10 +35,9 @@ namespace MWClass
|
||||
}
|
||||
}
|
||||
|
||||
void Clothing::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const
|
||||
void Clothing::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
|
||||
{
|
||||
if(!model.empty())
|
||||
physics.addObject(ptr, model, true);
|
||||
// TODO: add option somewhere to enable collision for placeable objects
|
||||
}
|
||||
|
||||
std::string Clothing::getModel(const MWWorld::Ptr &ptr) const
|
||||
|
@ -18,7 +18,7 @@ namespace MWClass
|
||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const;
|
||||
virtual void insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const;
|
||||
|
||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||
|
@ -18,12 +18,12 @@
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/actionopen.hpp"
|
||||
#include "../mwworld/actiontrap.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwphysics/physicssystem.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
#include "../mwrender/actors.hpp"
|
||||
#include "../mwrender/objects.hpp"
|
||||
#include "../mwrender/renderinginterface.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
@ -93,12 +93,11 @@ namespace MWClass
|
||||
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
|
||||
{
|
||||
if (!model.empty()) {
|
||||
MWRender::Actors& actors = renderingInterface.getActors();
|
||||
actors.insertActivator(ptr, model);
|
||||
renderingInterface.getObjects().insertModel(ptr, model, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWWorld::PhysicsSystem& physics) const
|
||||
void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
|
||||
{
|
||||
if(!model.empty())
|
||||
physics.addObject(ptr, model);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user