diff --git a/.travis.yml b/.travis.yml index 839dbccd4..3641459de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,26 @@ env: # via the "travis encrypt" command using the project repo's public key - secure: "jybGzAdUbqt9vWR/GEnRd96BgAi/7Zd1+2HK68j/i/8+/1YH2XxLOy4Jv/DUBhBlJIkxs/Xv8dRcUlFOclZDHX1d/9Qnsqd3oUVkD7k1y7cTOWy9TBQaE/v/kZo3LpzA3xPwwthrb0BvqIbOfIELi5fS5s8ba85WFRg3AX70wWE=" addons: + apt: + sources: + - sourceline: 'ppa:openmw/openmw' + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.6 + packages: [ + # Dev + clang-3.6, libunshield-dev, libtinyxml-dev, + # Tests + libgtest-dev, google-mock, + # Boost + libboost-filesystem-dev, libboost-program-options-dev, libboost-system-dev, libboost-thread-dev, + # FFmpeg + libavcodec-dev, libavformat-dev, libavutil-dev, libswscale-dev, + # Audio & Video + libsdl2-dev, libqt4-dev, libopenal-dev, + # The other from OpenMW ppa + libbullet-dev, libswresample-dev, libopenscenegraph-dev, libmygui-dev + ] + coverity_scan: project: name: "OpenMW/openmw" @@ -33,12 +53,8 @@ matrix: allow_failures: - env: ANALYZE="scan-build-3.6 --use-cc clang-3.6 --use-c++ clang++-3.6 " -before_install: - - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_install.linux.sh; fi - - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_install.osx.sh; fi -before_script: - - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./CI/before_script.linux.sh; fi - - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then ./CI/before_script.osx.sh; fi +before_install: ./CI/before_install.${TRAVIS_OS_NAME}.sh +before_script: ./CI/before_script.${TRAVIS_OS_NAME}.sh script: - cd ./build - if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then ${ANALYZE}make -j3; fi diff --git a/CI/before_install.linux.sh b/CI/before_install.linux.sh index 1c02bc8d9..cbc293dab 100755 --- a/CI/before_install.linux.sh +++ b/CI/before_install.linux.sh @@ -1,18 +1,6 @@ #!/bin/sh -if [ "${ANALYZE}" ]; then - echo "yes" | sudo add-apt-repository "deb http://llvm.org/apt/`lsb_release -sc`/ llvm-toolchain-`lsb_release -sc`-3.6 main" - wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add - -fi - -echo "yes" | sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse" -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 -sudo apt-get install -qq libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev -sudo apt-get install -qq libbullet-dev libopenscenegraph-dev libmygui-dev libsdl2-dev libunshield-dev libtinyxml-dev libopenal-dev libqt4-dev -if [ "${ANALYZE}" ]; then sudo apt-get install -qq clang-3.6; fi +# build libgtest & libgtest_main sudo mkdir /usr/src/gtest/build cd /usr/src/gtest/build sudo cmake .. -DBUILD_SHARED_LIBS=1 diff --git a/CI/before_script.msvc.sh b/CI/before_script.msvc.sh index 6cd39fd0e..6ed4365a4 100644 --- a/CI/before_script.msvc.sh +++ b/CI/before_script.msvc.sh @@ -557,12 +557,9 @@ printf "SDL 2.0.3... " eval 7z x -y SDL2-2.0.3.zip $STRIP fi - SDL_SDK="`real_pwd`/SDL2-2.0.3" - add_cmake_opts -DSDL2_INCLUDE_DIR="$SDL_SDK/include" \ - -DSDL2MAIN_LIBRARY="$SDL_SDK/lib/x$ARCHSUFFIX/SDL2main.lib" \ - -DSDL2_LIBRARY_PATH="$SDL_SDK/lib/x$ARCHSUFFIX/SDL2.lib" + export SDL2DIR="`real_pwd`/SDL2-2.0.3" - add_runtime_dlls `pwd`/SDL2-2.0.3/lib/x$ARCHSUFFIX/SDL2.dll + add_runtime_dlls $SDL2DIR/lib/x$ARCHSUFFIX/SDL2.dll echo Done. } diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index 164208f49..c3822291d 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -17,7 +17,6 @@ cmake \ -D CMAKE_BUILD_TYPE=Debug \ -D OPENMW_OSX_DEPLOYMENT=TRUE \ -D DESIRED_QT_VERSION=5 \ --D OSG_PLUGIN_LIB_SEARCH_PATH="$DEPENDENCIES_ROOT/lib/osgPlugins-3.4.0" \ -D BUILD_ESMTOOL=FALSE \ -D BUILD_MYGUI_PLUGIN=FALSE \ -G"Unix Makefiles" \ diff --git a/CMakeLists.txt b/CMakeLists.txt index a5a934624..ea729c3bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,55 +229,16 @@ endif() IF(BUILD_OPENMW OR BUILD_OPENCS) find_package(OpenSceneGraph 3.3.4 REQUIRED osgDB osgViewer osgText osgGA osgAnimation osgParticle osgUtil osgFX) - include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}) + get_filename_component(OSG_LIB_DIR ${OSGDB_LIBRARY} DIRECTORY) + set(OSGPlugins_LIB_DIR "${OSG_LIB_DIR}/osgPlugins-${OPENSCENEGRAPH_VERSION}") + if(OSG_STATIC) - macro(use_static_osg_plugin_library PLUGIN_NAME) - set(PLUGIN_NAME_DBG ${PLUGIN_NAME}d ${PLUGIN_NAME}D ${PLUGIN_NAME}_d ${PLUGIN_NAME}_D ${PLUGIN_NAME}_debug ${PLUGIN_NAME}) + add_definitions(-DOSG_LIBRARY_STATIC) - # For now, users wishing to do a static build will need to pass the path to where the plugins reside - # More clever logic would need to deduce the path, probably installed under /lib/osgPlugins- - include(FindPkgMacros) - find_library(${PLUGIN_NAME}_LIBRARY_REL NAMES ${PLUGIN_NAME} HINTS ${OSG_PLUGIN_LIB_SEARCH_PATH}) - find_library(${PLUGIN_NAME}_LIBRARY_DBG NAMES ${PLUGIN_NAME_DBG} HINTS ${OSG_PLUGIN_LIB_SEARCH_PATH}) - make_library_set(${PLUGIN_NAME}_LIBRARY) - - if("${${PLUGIN_NAME}_LIBRARY}" STREQUAL "") - message(FATAL_ERROR "Unable to find static OpenSceneGraph plugin: ${PLUGIN_NAME}") - endif() - - set(OPENSCENEGRAPH_LIBRARIES ${OPENSCENEGRAPH_LIBRARIES} ${${PLUGIN_NAME}_LIBRARY}) - endmacro() - - add_definitions(-DOSG_LIBRARY_STATIC) - - set(PLUGIN_LIST - osgdb_png # depends on libpng, zlib - osgdb_tga - osgdb_dds - osgdb_jpeg # depends on libjpeg - ) - - foreach(PLUGIN ${PLUGIN_LIST}) - use_static_osg_plugin_library(${PLUGIN}) - endforeach() - - # OSG static plugins need to linked against their respective dependencies - set(PLUGIN_DEPS_LIST - PNG # needed by osgdb_png - ZLIB # needed by osgdb_png - JPEG # needed by osgdb_jpeg - ) - - macro(use_static_osg_plugin_dep DEPENDENCY) - find_package(${DEPENDENCY} REQUIRED) - - set(OPENSCENEGRAPH_LIBRARIES ${OPENSCENEGRAPH_LIBRARIES} ${${DEPENDENCY}_LIBRARIES}) - endmacro() - foreach(DEPENDENCY ${PLUGIN_DEPS_LIST}) - use_static_osg_plugin_dep(${DEPENDENCY}) - endforeach() + find_package(OSGPlugins REQUIRED COMPONENTS osgdb_png osgdb_tga osgdb_dds osgdb_jpeg) + list(APPEND OPENSCENEGRAPH_LIBRARIES ${OSGPlugins_LIBRARIES}) endif() if(QT_STATIC) @@ -793,11 +754,14 @@ if (APPLE) ) foreach (PLUGIN_NAME ${USED_OSG_PLUGINS}) - set(PLUGIN_ABS "${OSG_PLUGIN_LIB_SEARCH_PATH}/${PLUGIN_NAME}.so") + set(PLUGIN_ABS "${OSGPlugins_LIB_DIR}/${PLUGIN_NAME}.so") set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS}) endforeach () - get_filename_component(OSG_PLUGIN_PREFIX_DIR "${OSG_PLUGIN_LIB_SEARCH_PATH}" NAME) + get_filename_component(OSG_PLUGIN_PREFIX_DIR "${OSGPlugins_LIB_DIR}" NAME) + if (NOT OSG_PLUGIN_PREFIX_DIR) + message(FATAL_ERROR "Can't get directory name for OSG plugins from '${OSGPlugins_LIB_DIR}'") + endif() # 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 diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 718d9a107..b8d6102ac 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -188,6 +188,7 @@ void CSMPrefs::State::declare() "Shift-acceleration factor during drag operations", 4.0). setTooltip ("Acceleration factor during drag operations while holding down shift"). setRange (0.001, 100.0); + declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); declareCategory ("Tooltips"); declareBool ("scene", "Show Tooltips in 3D scenes", true); diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 8b644edbe..394e6772d 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -27,6 +27,68 @@ int CSVRender::InstanceMode::getSubModeFromId (const std::string& id) const return id=="move" ? 0 : (id=="rotate" ? 1 : 2); } +osg::Vec3f CSVRender::InstanceMode::quatToEuler(const osg::Quat& rot) const +{ + const float Pi = 3.14159265f; + + float x, y, z; + float test = 2 * (rot.w() * rot.y() + rot.x() * rot.z()); + + if (std::abs(test) >= 1.f) + { + x = atan2(rot.x(), rot.w()); + y = (test > 0) ? (Pi / 2) : (-Pi / 2); + z = 0; + } + else + { + x = std::atan2(2 * (rot.w() * rot.x() - rot.y() * rot.z()), 1 - 2 * (rot.x() * rot.x() + rot.y() * rot.y())); + y = std::asin(test); + z = std::atan2(2 * (rot.w() * rot.z() - rot.x() * rot.y()), 1 - 2 * (rot.y() * rot.y() + rot.z() * rot.z())); + } + + return osg::Vec3f(-x, -y, -z); +} + +osg::Quat CSVRender::InstanceMode::eulerToQuat(const osg::Vec3f& euler) const +{ + osg::Quat xr = osg::Quat(-euler[0], osg::Vec3f(1,0,0)); + osg::Quat yr = osg::Quat(-euler[1], osg::Vec3f(0,1,0)); + osg::Quat zr = osg::Quat(-euler[2], osg::Vec3f(0,0,1)); + + return zr * yr * xr; +} + +osg::Vec3f CSVRender::InstanceMode::getSelectionCenter(const std::vector >& selection) const +{ + osg::Vec3f center = osg::Vec3f(0, 0, 0); + int objectCount = 0; + + for (std::vector >::const_iterator iter (selection.begin()); iter!=selection.end(); ++iter) + { + if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) + { + const ESM::Position& position = objectTag->mObject->getPosition(); + center += osg::Vec3f(position.pos[0], position.pos[1], position.pos[2]); + + ++objectCount; + } + } + center /= objectCount; + + return center; +} + +osg::Vec3f CSVRender::InstanceMode::getScreenCoords(const osg::Vec3f& pos) +{ + osg::Matrix viewMatrix = getWorldspaceWidget().getCamera()->getViewMatrix(); + osg::Matrix projMatrix = getWorldspaceWidget().getCamera()->getProjectionMatrix(); + osg::Matrix windowMatrix = getWorldspaceWidget().getCamera()->getViewport()->computeWindowMatrix(); + osg::Matrix combined = viewMatrix * projMatrix * windowMatrix; + + return pos * combined; +} + CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) : EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference, "Instance editing", parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None), @@ -44,14 +106,16 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar) "Rotate selected instances" "
  • Use {scene-edit-primary} to rotate instances freely
  • " "
  • Use {scene-edit-secondary} to rotate instances within the grid
  • " + "
  • The center of the view acts as the axis of rotation
  • " "
" - "Not implemented yet"); + "Grid rotate not implemented yet"); mSubMode->addButton (":placeholder", "scale", "Scale selected instances" "
  • Use {scene-edit-primary} to scale instances freely
  • " "
  • Use {scene-edit-secondary} to scale instances along the grid
  • " + "
  • The scaling rate is based on how close the start of a drag is to the center of the screen
  • " "
" - "Not implemented yet"); + "Grid scale not implemented yet"); mSubMode->setButton (mSubModeId); @@ -152,33 +216,60 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos) return false; WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) - { - getWorldspaceWidget().clearSelection (Mask_Reference); - if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) - { - CSVRender::Object* object = objectTag->mObject; - object->setSelected (true); - } - } - - std::vector > selection = - getWorldspaceWidget().getSelection (Mask_Reference); + std::vector > selection = getWorldspaceWidget().getSelection (Mask_Reference); if (selection.empty()) - return false; + { + // Only change selection at the start of drag if no object is already selected + if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) + { + getWorldspaceWidget().clearSelection (Mask_Reference); + if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) + { + CSVRender::Object* object = objectTag->mObject; + object->setSelected (true); + } + } + + selection = getWorldspaceWidget().getSelection (Mask_Reference); + if (selection.empty()) + return false; + } for (std::vector >::iterator iter (selection.begin()); iter!=selection.end(); ++iter) { if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) { - objectTag->mObject->setEdited (Object::Override_Position); + if (mSubModeId == "move") + { + objectTag->mObject->setEdited (Object::Override_Position); + mDragMode = DragMode_Move; + } + else if (mSubModeId == "rotate") + { + objectTag->mObject->setEdited (Object::Override_Rotation); + mDragMode = DragMode_Rotate; + } + else if (mSubModeId == "scale") + { + objectTag->mObject->setEdited (Object::Override_Scale); + mDragMode = DragMode_Scale; + + // Calculate scale factor + std::vector > selection = getWorldspaceWidget().getEdited (Mask_Reference); + osg::Vec3f center = getScreenCoords(getSelectionCenter(selection)); + + int widgetHeight = getWorldspaceWidget().height(); + + float dx = pos.x() - center.x(); + float dy = (widgetHeight - pos.y()) - center.y(); + + mUnitScaleDist = std::sqrt(dx * dx + dy * dy); + } } } - // \todo check for sub-mode - if (CSVRender::ObjectMarkerTag *objectTag = dynamic_cast (hit.tag.get())) { mDragAxis = objectTag->mAxis; @@ -186,8 +277,6 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos) else mDragAxis = -1; - mDragMode = DragMode_Move; - return true; } @@ -201,48 +290,160 @@ bool CSVRender::InstanceMode::secondaryEditStartDrag (const QPoint& pos) void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) { - osg::Vec3f eye; - osg::Vec3f centre; - osg::Vec3f up; - - getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, centre, up); - osg::Vec3f offset; + osg::Quat rotation; - if (diffY) - offset += up * diffY * speedFactor; + std::vector > selection = getWorldspaceWidget().getEdited (Mask_Reference); - if (diffX) - offset += ((centre-eye) ^ up) * diffX * speedFactor; - - switch (mDragMode) + if (mDragMode == DragMode_Move) { - case DragMode_Move: + osg::Vec3f eye, centre, up; + getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, centre, up); + + if (diffY) { - if (mDragAxis!=-1) - for (int i=0; i<3; ++i) - if (i!=mDragAxis) - offset[i] = 0; - - std::vector > selection = - getWorldspaceWidget().getEdited (Mask_Reference); - - for (std::vector >::iterator iter (selection.begin()); - iter!=selection.end(); ++iter) - { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) - { - ESM::Position position = objectTag->mObject->getPosition(); - for (int i=0; i<3; ++i) - position.pos[i] += offset[i]; - objectTag->mObject->setPosition (position.pos); - } - } - - break; + offset += up * diffY * speedFactor; + } + if (diffX) + { + offset += ((centre-eye) ^ up) * diffX * speedFactor; } - case DragMode_None: break; + if (mDragAxis!=-1) + { + for (int i=0; i<3; ++i) + { + if (i!=mDragAxis) + offset[i] = 0; + } + } + } + else if (mDragMode == DragMode_Rotate) + { + osg::Vec3f eye, centre, up; + getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, centre, up); + + float angle; + osg::Vec3f axis; + + if (mDragAxis == -1) + { + // Free rotate + float rotationFactor = CSMPrefs::get()["3D Scene Input"]["rotate-factor"].toDouble() * speedFactor; + + osg::Quat cameraRotation = getWorldspaceWidget().getCamera()->getInverseViewMatrix().getRotate(); + + osg::Vec3f camForward = centre - eye; + osg::Vec3f screenDir = cameraRotation * osg::Vec3f(diffX, diffY, 0); + screenDir.normalize(); + + angle = std::sqrt(diffX*diffX + diffY*diffY) * rotationFactor; + axis = screenDir ^ camForward; + } + else + { + // Global axis rotation + osg::Vec3f camBack = eye - centre; + + for (int i = 0; i < 3; ++i) + { + if (i == mDragAxis) + axis[i] = 1; + else + axis[i] = 0; + } + + // Flip axis if facing opposite side + if (camBack * axis < 0) + axis *= -1; + + // Convert coordinate system + osg::Vec3f screenCenter = getScreenCoords(getSelectionCenter(selection)); + + int widgetHeight = getWorldspaceWidget().height(); + + float newX = pos.x() - screenCenter.x(); + float newY = (widgetHeight - pos.y()) - screenCenter.y(); + + float oldX = newX - diffX; + float oldY = newY - diffY; // diffY appears to already be flipped + + osg::Vec3f oldVec = osg::Vec3f(oldX, oldY, 0); + oldVec.normalize(); + + osg::Vec3f newVec = osg::Vec3f(newX, newY, 0); + newVec.normalize(); + + // Find angle and axis of rotation + angle = std::acos(oldVec * newVec) * speedFactor; + if (((oldVec ^ newVec) * camBack < 0) ^ (camBack.z() < 0)) + angle *= -1; + } + + rotation = osg::Quat(angle, axis); + } + else if (mDragMode == DragMode_Scale) + { + osg::Vec3f center = getScreenCoords(getSelectionCenter(selection)); + + // Calculate scaling distance/rate + int widgetHeight = getWorldspaceWidget().height(); + + float dx = pos.x() - center.x(); + float dy = (widgetHeight - pos.y()) - center.y(); + + float dist = std::sqrt(dx * dx + dy * dy); + float scale = dist / mUnitScaleDist; + + // Only uniform scaling is currently supported + offset = osg::Vec3f(scale, scale, scale); + } + + // Apply + for (std::vector >::iterator iter (selection.begin()); iter!=selection.end(); ++iter) + { + if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) + { + if (mDragMode == DragMode_Move) + { + ESM::Position position = objectTag->mObject->getPosition(); + for (int i=0; i<3; ++i) + { + position.pos[i] += offset[i]; + } + + objectTag->mObject->setPosition(position.pos); + } + else if (mDragMode == DragMode_Rotate) + { + ESM::Position position = objectTag->mObject->getPosition(); + + osg::Quat currentRot = eulerToQuat(osg::Vec3f(position.rot[0], position.rot[1], position.rot[2])); + osg::Quat combined = currentRot * rotation; + + osg::Vec3f euler = quatToEuler(combined); + // There appears to be a very rare rounding error that can cause asin to return NaN + if (!euler.isNaN()) + { + position.rot[0] = euler.x(); + position.rot[1] = euler.y(); + position.rot[2] = euler.z(); + } + + objectTag->mObject->setRotation(position.rot); + } + else if (mDragMode == DragMode_Scale) + { + // Reset scale + objectTag->mObject->setEdited(0); + objectTag->mObject->setEdited(Object::Override_Scale); + + float scale = objectTag->mObject->getScale(); + scale *= offset.x(); + + objectTag->mObject->setScale (scale); + } + } } } @@ -258,6 +459,8 @@ void CSVRender::InstanceMode::dragCompleted(const QPoint& pos) switch (mDragMode) { case DragMode_Move: description = "Move Instances"; break; + case DragMode_Rotate: description = "Rotate Instances"; break; + case DragMode_Scale: description = "Scale Instances"; break; case DragMode_None: break; } diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index 4f7937b51..933cae529 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -1,6 +1,10 @@ #ifndef CSV_RENDER_INSTANCEMODE_H #define CSV_RENDER_INSTANCEMODE_H +#include +#include +#include + #include "editmode.hpp" namespace CSVWidget @@ -10,6 +14,7 @@ namespace CSVWidget namespace CSVRender { + class TagBase; class InstanceSelectionMode; class InstanceMode : public EditMode @@ -19,7 +24,9 @@ namespace CSVRender enum DragMode { DragMode_None, - DragMode_Move + DragMode_Move, + DragMode_Rotate, + DragMode_Scale }; CSVWidget::SceneToolMode *mSubMode; @@ -28,9 +35,16 @@ namespace CSVRender DragMode mDragMode; int mDragAxis; bool mLocked; + float mUnitScaleDist; int getSubModeFromId (const std::string& id) const; + osg::Vec3f quatToEuler(const osg::Quat& quat) const; + osg::Quat eulerToQuat(const osg::Vec3f& euler) const; + + osg::Vec3f getSelectionCenter(const std::vector >& selection) const; + osg::Vec3f getScreenCoords(const osg::Vec3f& pos); + public: InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index cc151ead9..3a6640c54 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -29,6 +29,13 @@ #include "mask.hpp" + +const float CSVRender::Object::MarkerShaftWidth = 30; +const float CSVRender::Object::MarkerShaftBaseLength = 70; +const float CSVRender::Object::MarkerHeadWidth = 50; +const float CSVRender::Object::MarkerHeadLength = 50; + + namespace { @@ -179,7 +186,21 @@ void CSVRender::Object::updateMarker() { if (mSubMode==0) { - mMarker[i] = makeMarker (i); + mMarker[i] = makeMoveOrScaleMarker (i); + mMarker[i]->setUserData(new ObjectMarkerTag (this, i)); + + mRootNode->addChild (mMarker[i]); + } + else if (mSubMode==1) + { + mMarker[i] = makeRotateMarker (i); + mMarker[i]->setUserData(new ObjectMarkerTag (this, i)); + + mRootNode->addChild (mMarker[i]); + } + else if (mSubMode==2) + { + mMarker[i] = makeMoveOrScaleMarker (i); mMarker[i]->setUserData(new ObjectMarkerTag (this, i)); mRootNode->addChild (mMarker[i]); @@ -188,16 +209,11 @@ void CSVRender::Object::updateMarker() } } -osg::ref_ptr CSVRender::Object::makeMarker (int axis) +osg::ref_ptr CSVRender::Object::makeMoveOrScaleMarker (int axis) { osg::ref_ptr geometry (new osg::Geometry); - const float shaftWidth = 10; - const float shaftBaseLength = 50; - const float headWidth = 30; - const float headLength = 30; - - float shaftLength = shaftBaseLength + mBaseNode->getBound().radius(); + float shaftLength = MarkerShaftBaseLength + mBaseNode->getBound().radius(); // shaft osg::Vec3Array *vertices = new osg::Vec3Array; @@ -206,20 +222,20 @@ osg::ref_ptr CSVRender::Object::makeMarker (int axis) { float length = i ? shaftLength : 0; - vertices->push_back (getMarkerPosition (-shaftWidth/2, -shaftWidth/2, length, axis)); - vertices->push_back (getMarkerPosition (-shaftWidth/2, shaftWidth/2, length, axis)); - vertices->push_back (getMarkerPosition (shaftWidth/2, shaftWidth/2, length, axis)); - vertices->push_back (getMarkerPosition (shaftWidth/2, -shaftWidth/2, length, axis)); + vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis)); + vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis)); + vertices->push_back (getMarkerPosition (MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis)); + vertices->push_back (getMarkerPosition (MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis)); } // head backside - vertices->push_back (getMarkerPosition (-headWidth/2, -headWidth/2, shaftLength, axis)); - vertices->push_back (getMarkerPosition (-headWidth/2, headWidth/2, shaftLength, axis)); - vertices->push_back (getMarkerPosition (headWidth/2, headWidth/2, shaftLength, axis)); - vertices->push_back (getMarkerPosition (headWidth/2, -headWidth/2, shaftLength, axis)); + vertices->push_back (getMarkerPosition (-MarkerHeadWidth/2, -MarkerHeadWidth/2, shaftLength, axis)); + vertices->push_back (getMarkerPosition (-MarkerHeadWidth/2, MarkerHeadWidth/2, shaftLength, axis)); + vertices->push_back (getMarkerPosition (MarkerHeadWidth/2, MarkerHeadWidth/2, shaftLength, axis)); + vertices->push_back (getMarkerPosition (MarkerHeadWidth/2, -MarkerHeadWidth/2, shaftLength, axis)); // head - vertices->push_back (getMarkerPosition (0, 0, shaftLength+headLength, axis)); + vertices->push_back (getMarkerPosition (0, 0, shaftLength+MarkerHeadLength, axis)); geometry->setVertexArray (vertices); @@ -285,6 +301,87 @@ osg::ref_ptr CSVRender::Object::makeMarker (int axis) return geode; } +osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) +{ + const float Pi = 3.14159265f; + + const float InnerRadius = mBaseNode->getBound().radius(); + const float OuterRadius = InnerRadius + MarkerShaftWidth; + + const float SegmentDistance = 100.f; + const size_t SegmentCount = std::min(64, std::max(8, (int)(OuterRadius * 2 * Pi / SegmentDistance))); + const size_t VerticesPerSegment = 4; + const size_t IndicesPerSegment = 24; + + const size_t VertexCount = SegmentCount * VerticesPerSegment; + const size_t IndexCount = SegmentCount * IndicesPerSegment; + + const float Angle = 2 * Pi / SegmentCount; + + const unsigned short IndexPattern[IndicesPerSegment] = + { + 0, 4, 5, 0, 5, 1, + 2, 6, 4, 2, 4, 0, + 3, 7, 6, 3, 6, 2, + 1, 5, 7, 1, 7, 3 + }; + + + osg::ref_ptr geometry = new osg::Geometry(); + + osg::ref_ptr vertices = new osg::Vec3Array(VertexCount); + osg::ref_ptr colors = new osg::Vec4Array(1); + osg::ref_ptr primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, + IndexCount); + + for (size_t i = 0; i < SegmentCount; ++i) + { + size_t index = i * VerticesPerSegment; + + float innerX = InnerRadius * std::cos(i * Angle); + float innerY = InnerRadius * std::sin(i * Angle); + + float outerX = OuterRadius * std::cos(i * Angle); + float outerY = OuterRadius * std::sin(i * Angle); + + vertices->at(index++) = getMarkerPosition(innerX, innerY, MarkerShaftWidth / 2, axis); + vertices->at(index++) = getMarkerPosition(innerX, innerY, -MarkerShaftWidth / 2, axis); + vertices->at(index++) = getMarkerPosition(outerX, outerY, MarkerShaftWidth / 2, axis); + vertices->at(index++) = getMarkerPosition(outerX, outerY, -MarkerShaftWidth / 2, axis); + } + + colors->at(0) = osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f, axis==2 ? 1.0f : 0.2f, 1.0f); + + for (size_t i = 0; i < SegmentCount; ++i) + { + size_t indices[IndicesPerSegment]; + for (size_t j = 0; j < IndicesPerSegment; ++j) + { + indices[j] = i * VerticesPerSegment + j; + + if (indices[j] >= VertexCount) + indices[j] -= VertexCount; + } + + size_t offset = i * IndicesPerSegment; + for (size_t j = 0; j < IndicesPerSegment; ++j) + { + primitives->setElement(offset++, indices[IndexPattern[j]]); + } + } + + geometry->setVertexArray(vertices); + geometry->setColorArray(colors, osg::Array::BIND_OVERALL); + geometry->addPrimitiveSet(primitives); + + geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF); + + osg::ref_ptr geode = new osg::Geode(); + geode->addDrawable (geometry); + + return geode; +} + osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int axis) { switch (axis) @@ -494,7 +591,7 @@ ESM::Position CSVRender::Object::getPosition() const float CSVRender::Object::getScale() const { - return mOverrideFlags & Override_Scale ? mScaleOverride : getReference().mScale; + return (mOverrideFlags & Override_Scale) ? mScaleOverride : getReference().mScale; } void CSVRender::Object::setPosition (const float position[3]) diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 54a284fa3..d3cba6c55 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -78,6 +78,11 @@ namespace CSVRender private: + static const float MarkerShaftWidth; + static const float MarkerShaftBaseLength; + static const float MarkerHeadWidth; + static const float MarkerHeadLength; + CSMWorld::Data& mData; std::string mReferenceId; std::string mReferenceableId; @@ -89,7 +94,7 @@ namespace CSVRender Resource::ResourceSystem* mResourceSystem; bool mForceBaseToZero; ESM::Position mPositionOverride; - int mScaleOverride; + float mScaleOverride; int mOverrideFlags; osg::ref_ptr mMarker[3]; int mSubMode; @@ -115,7 +120,8 @@ namespace CSVRender void updateMarker(); - osg::ref_ptr makeMarker (int axis); + osg::ref_ptr makeMoveOrScaleMarker (int axis); + osg::ref_ptr makeRotateMarker (int axis); osg::Vec3f getMarkerPosition (float x, float y, float z, int axis); diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index a880bca45..9a1b43678 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -62,8 +62,8 @@ namespace namespace MWGui { - CharacterCreation::CharacterCreation(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem) - : mViewer(viewer) + CharacterCreation::CharacterCreation(osg::Group* parent, Resource::ResourceSystem* resourceSystem) + : mParent(parent) , mResourceSystem(resourceSystem) , mNameDialog(0) , mRaceDialog(0) @@ -152,7 +152,7 @@ namespace MWGui case GM_Race: MWBase::Environment::get().getWindowManager()->removeDialog(mRaceDialog); mRaceDialog = 0; - mRaceDialog = new RaceDialog(mViewer, mResourceSystem); + mRaceDialog = new RaceDialog(mParent, mResourceSystem); mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen); mRaceDialog->setRaceId(mPlayerRaceId); mRaceDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogDone); diff --git a/apps/openmw/mwgui/charactercreation.hpp b/apps/openmw/mwgui/charactercreation.hpp index 7fb67caf6..75f3a7016 100644 --- a/apps/openmw/mwgui/charactercreation.hpp +++ b/apps/openmw/mwgui/charactercreation.hpp @@ -8,9 +8,9 @@ #include "../mwmechanics/stat.hpp" -namespace osgViewer +namespace osg { - class Viewer; + class Group; } namespace Resource @@ -39,7 +39,7 @@ namespace MWGui public: typedef std::vector SkillList; - CharacterCreation(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem); + CharacterCreation(osg::Group* parent, Resource::ResourceSystem* resourceSystem); ~CharacterCreation(); //Show a dialog @@ -51,7 +51,7 @@ namespace MWGui void configureSkills (const SkillList& major, const SkillList& minor); private: - osgViewer::Viewer* mViewer; + osg::Group* mParent; Resource::ResourceSystem* mResourceSystem; //Dialogs diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 4599132e3..bd864b45b 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -56,7 +56,7 @@ namespace namespace MWGui { - InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop, osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem) + InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem) : WindowPinnableBase("openmw_inventory_window.layout") , mDragAndDrop(dragAndDrop) , mSelectedItem(-1) @@ -65,7 +65,7 @@ namespace MWGui , mGuiMode(GM_Inventory) , mLastXSize(0) , mLastYSize(0) - , mPreview(new MWRender::InventoryPreview(viewer, resourceSystem, MWMechanics::getPlayer())) + , mPreview(new MWRender::InventoryPreview(parent, resourceSystem, MWMechanics::getPlayer())) , mTrading(false) { mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture())); diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index b7ae067ac..651bda590 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -6,9 +6,9 @@ #include "../mwworld/ptr.hpp" -namespace osgViewer +namespace osg { - class Viewer; + class Group; } namespace Resource @@ -37,7 +37,7 @@ namespace MWGui class InventoryWindow : public WindowPinnableBase { public: - InventoryWindow(DragAndDrop* dragAndDrop, osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem); + InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem); virtual void open(); diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 6c08f7dc1..daa07d5c4 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -41,9 +41,9 @@ namespace namespace MWGui { - RaceDialog::RaceDialog(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem) + RaceDialog::RaceDialog(osg::Group* parent, Resource::ResourceSystem* resourceSystem) : WindowModal("openmw_chargen_race.layout") - , mViewer(viewer) + , mParent(parent) , mResourceSystem(resourceSystem) , mGenderIndex(0) , mFaceIndex(0) @@ -136,7 +136,7 @@ namespace MWGui mPreview.reset(NULL); mPreviewTexture.reset(NULL); - mPreview.reset(new MWRender::RaceSelectionPreview(mViewer, mResourceSystem)); + mPreview.reset(new MWRender::RaceSelectionPreview(mParent, mResourceSystem)); mPreview->rebuild(); mPreview->setAngle (mCurrentAngle); diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index b3de9bef0..42e758983 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -19,9 +19,9 @@ namespace ESM struct NPC; } -namespace osgViewer +namespace osg { - class Viewer; + class Group; } namespace Resource @@ -34,7 +34,7 @@ namespace MWGui class RaceDialog : public WindowModal { public: - RaceDialog(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem); + RaceDialog(osg::Group* parent, Resource::ResourceSystem* resourceSystem); enum Gender { @@ -93,7 +93,7 @@ namespace MWGui void getBodyParts (int part, std::vector& out); - osgViewer::Viewer* mViewer; + osg::Group* mParent; Resource::ResourceSystem* mResourceSystem; std::vector mAvailableHeads; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 54fd31acd..09b72ad3d 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -282,7 +282,7 @@ namespace MWGui mRecharge = new Recharge(); mMenu = new MainMenu(w, h, mResourceSystem->getVFS(), mVersionDescription); - mLocalMapRender = new MWRender::LocalMap(mViewer); + mLocalMapRender = new MWRender::LocalMap(mViewer->getSceneData()->asGroup()); mMap = new MapWindow(mCustomMarkers, mDragAndDrop, mLocalMapRender); trackWindow(mMap, "map"); mStatsWindow = new StatsWindow(mDragAndDrop); @@ -293,7 +293,7 @@ namespace MWGui bool questList = mResourceSystem->getVFS()->exists("textures/tx_menubook_options_over.dds"); mJournal = JournalWindow::create(JournalViewModel::create (), questList); mMessageBoxManager = new MessageBoxManager(mStore->get().find("fMessageTimePerChar")->getFloat()); - mInventoryWindow = new InventoryWindow(mDragAndDrop, mViewer, mResourceSystem); + mInventoryWindow = new InventoryWindow(mDragAndDrop, mViewer->getSceneData()->asGroup(), mResourceSystem); mTradeWindow = new TradeWindow(); trackWindow(mTradeWindow, "barter"); mSpellBuyingWindow = new SpellBuyingWindow(); @@ -350,7 +350,7 @@ namespace MWGui mHud->setVisible(mHudEnabled); - mCharGen = new CharacterCreation(mViewer, mResourceSystem); + mCharGen = new CharacterCreation(mViewer->getSceneData()->asGroup(), mResourceSystem); // Setup player stats for (int i = 0; i < ESM::Attribute::Length; ++i) @@ -384,7 +384,7 @@ namespace MWGui { disallowAll(); delete mCharGen; - mCharGen = new CharacterCreation(mViewer, mResourceSystem); + mCharGen = new CharacterCreation(mViewer->getSceneData()->asGroup(), mResourceSystem); mGuiModes.clear(); MWBase::Environment::get().getInputManager()->changeInputMode(false); mHud->unsetSelectedWeapon(); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index e65195531..c92530259 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1542,9 +1542,10 @@ void CharacterController::update(float duration) mAnimation->disable(mAnimQueue.front().mGroup); mAnimQueue.pop_front(); + bool loopfallback = (mAnimQueue.front().mGroup.compare(0,4,"idle") == 0); mAnimation->play(mAnimQueue.front().mGroup, Priority_Default, MWRender::Animation::BlendMask_All, false, - 1.0f, "start", "stop", 0.0f, mAnimQueue.front().mLoopCount); + 1.0f, "start", "stop", 0.0f, mAnimQueue.front().mLoopCount, loopfallback); } } } @@ -1822,9 +1823,10 @@ void CharacterController::update(float duration) mAnimation->disable(mAnimQueue.front().mGroup); mAnimQueue.pop_front(); + bool loopfallback = (mAnimQueue.front().mGroup.compare(0,4,"idle") == 0); mAnimation->play(mAnimQueue.front().mGroup, Priority_Default, MWRender::Animation::BlendMask_All, false, - 1.0f, "start", "stop", 0.0f, mAnimQueue.front().mLoopCount); + 1.0f, "start", "stop", 0.0f, mAnimQueue.front().mLoopCount, loopfallback); } } @@ -2023,9 +2025,10 @@ bool CharacterController::playGroup(const std::string &groupname, int mode, int mCurrentIdle.clear(); mIdleState = CharState_SpecialIdle; + bool loopfallback = (entry.mGroup.compare(0,4,"idle") == 0); mAnimation->play(groupname, Priority_Default, MWRender::Animation::BlendMask_All, false, 1.0f, - ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1); + ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1, loopfallback); } else if(mode == 0) { diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 95de8430d..954d195dd 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -591,40 +591,28 @@ namespace MWPhysics btCompoundShape* compound = static_cast(mShapeInstance->getCollisionShape()); - for (std::map::iterator it = mShapeInstance->mAnimatedShapes.begin(); it != mShapeInstance->mAnimatedShapes.end();) + for (std::map::const_iterator it = mShapeInstance->mAnimatedShapes.begin(); it != mShapeInstance->mAnimatedShapes.end(); ++it) { int recIndex = it->first; int shapeIndex = it->second; - NifOsg::FindGroupByRecIndex visitor(recIndex); - mPtr.getRefData().getBaseNode()->accept(visitor); - if (!visitor.mFound) + std::map::iterator nodePathFound = mRecIndexToNodePath.find(recIndex); + if (nodePathFound == mRecIndexToNodePath.end()) { - std::cerr << "animateCollisionShapes: Can't find node " << recIndex << std::endl; - return; + NifOsg::FindGroupByRecIndex visitor(recIndex); + mPtr.getRefData().getBaseNode()->accept(visitor); + if (!visitor.mFound) + { + std::cerr << "animateCollisionShapes: Can't find node " << recIndex << std::endl; + return; + } + osg::NodePath nodePath = visitor.mFoundPath; + nodePath.erase(nodePath.begin()); + nodePathFound = mRecIndexToNodePath.insert(std::make_pair(recIndex, nodePath)).first; } - osg::NodePath path = visitor.mFoundPath; - path.erase(path.begin()); - - // Attempt to remove "animated" shapes that are not actually animated - // We may get these because the BulletNifLoader does not know if a .kf file with additional controllers will be attached later on. - // On the first animateCollisionShapes call, we'll consider the graph completely loaded (with extra controllers and what not), - // so now we can better decide if the shape is really animated. - bool animated = false; - for (osg::NodePath::iterator nodePathIt = path.begin(); nodePathIt != path.end(); ++nodePathIt) - { - osg::Node* node = *nodePathIt; - if (node->getUpdateCallback()) - animated = true; - } - if (!animated) - { - mShapeInstance->mAnimatedShapes.erase(it++); - break; - } - - osg::Matrixf matrix = osg::computeLocalToWorld(path); + osg::NodePath& nodePath = nodePathFound->second; + osg::Matrixf matrix = osg::computeLocalToWorld(nodePath); osg::Vec3f scale = matrix.getScale(); matrix.orthoNormalize(matrix); @@ -634,10 +622,10 @@ namespace MWPhysics for (int j=0; j<3; ++j) transform.getBasis()[i][j] = matrix(j,i); // NB column/row major difference - compound->getChildShape(shapeIndex)->setLocalScaling(compound->getLocalScaling() * toBullet(scale)); - compound->updateChildTransform(shapeIndex, transform); - - ++it; + if (compound->getLocalScaling() * toBullet(scale) != compound->getChildShape(shapeIndex)->getLocalScaling()) + compound->getChildShape(shapeIndex)->setLocalScaling(compound->getLocalScaling() * toBullet(scale)); + if (!(transform == compound->getChildTransform(shapeIndex))) + compound->updateChildTransform(shapeIndex, transform); } collisionWorld->updateSingleAabb(mCollisionObject.get()); @@ -646,6 +634,7 @@ namespace MWPhysics private: std::auto_ptr mCollisionObject; osg::ref_ptr mShapeInstance; + std::map mRecIndexToNodePath; bool mSolid; }; diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 566a8d6ba..ed61334bb 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include #include @@ -65,9 +65,9 @@ namespace MWRender unsigned int mLastRenderedFrame; }; - CharacterPreview::CharacterPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, + CharacterPreview::CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character, int sizeX, int sizeY, const osg::Vec3f& position, const osg::Vec3f& lookAt) - : mViewer(viewer) + : mParent(parent) , mResourceSystem(resourceSystem) , mPosition(position) , mLookAt(lookAt) @@ -93,7 +93,6 @@ namespace MWRender mCamera->setViewport(0, 0, sizeX, sizeY); mCamera->setRenderOrder(osg::Camera::PRE_RENDER); mCamera->attach(osg::Camera::COLOR_BUFFER, mTexture); - mCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext()); mCamera->setNodeMask(Mask_RenderToTexture); @@ -140,7 +139,7 @@ namespace MWRender mDrawOnceCallback = new DrawOnceCallback; mCamera->addUpdateCallback(mDrawOnceCallback); - mViewer->getSceneData()->asGroup()->addChild(mCamera); + mParent->addChild(mCamera); mCharacter.mCell = NULL; } @@ -148,7 +147,7 @@ namespace MWRender CharacterPreview::~CharacterPreview () { mCamera->removeChildren(0, mCamera->getNumChildren()); - mViewer->getSceneData()->asGroup()->removeChild(mCamera); + mParent->removeChild(mCamera); } int CharacterPreview::getTextureWidth() const @@ -191,8 +190,8 @@ namespace MWRender // -------------------------------------------------------------------------------------------------- - InventoryPreview::InventoryPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character) - : CharacterPreview(viewer, resourceSystem, character, 512, 1024, osg::Vec3f(0, 700, 71), osg::Vec3f(0,0,71)) + InventoryPreview::InventoryPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character) + : CharacterPreview(parent, resourceSystem, character, 512, 1024, osg::Vec3f(0, 700, 71), osg::Vec3f(0,0,71)) { } @@ -320,8 +319,8 @@ namespace MWRender // -------------------------------------------------------------------------------------------------- - RaceSelectionPreview::RaceSelectionPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem) - : CharacterPreview(viewer, resourceSystem, MWMechanics::getPlayer(), + RaceSelectionPreview::RaceSelectionPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem) + : CharacterPreview(parent, resourceSystem, MWMechanics::getPlayer(), 512, 512, osg::Vec3f(0, 125, 8), osg::Vec3f(0,0,8)) , mBase (*mCharacter.get()->mBase) , mRef(&mBase) diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index 2b7984b00..2a4ef9877 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -16,11 +16,7 @@ namespace osg { class Texture2D; class Camera; -} - -namespace osgViewer -{ - class Viewer; + class Group; } namespace MWRender @@ -32,7 +28,7 @@ namespace MWRender class CharacterPreview { public: - CharacterPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character, int sizeX, int sizeY, + CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character, int sizeX, int sizeY, const osg::Vec3f& position, const osg::Vec3f& lookAt); virtual ~CharacterPreview(); @@ -53,7 +49,7 @@ namespace MWRender virtual bool renderHeadOnly() { return false; } virtual void onSetup(); - osg::ref_ptr mViewer; + osg::ref_ptr mParent; Resource::ResourceSystem* mResourceSystem; osg::ref_ptr mTexture; osg::ref_ptr mCamera; @@ -76,7 +72,7 @@ namespace MWRender { public: - InventoryPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character); + InventoryPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character); void updatePtr(const MWWorld::Ptr& ptr); @@ -102,7 +98,7 @@ namespace MWRender virtual void onSetup(); public: - RaceSelectionPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem); + RaceSelectionPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem); virtual ~RaceSelectionPreview(); void setAngle(float angleRadians); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 833e2717b..3b45a3c60 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -7,11 +7,10 @@ #include #include #include +#include #include -#include - #include #include #include @@ -68,16 +67,14 @@ namespace namespace MWRender { -LocalMap::LocalMap(osgViewer::Viewer* viewer) - : mViewer(viewer) +LocalMap::LocalMap(osg::Group* root) + : mRoot(root) , mMapResolution(Settings::Manager::getInt("local map resolution", "Map")) , mMapWorldSize(8192.f) , mCellDistance(Settings::Manager::getInt("local map cell distance", "Map")) , mAngle(0.f) , mInterior(false) { - mRoot = mViewer->getSceneData()->asGroup(); - SceneUtil::FindByNameVisitor find("Scene Root"); mRoot->accept(find); mSceneRoot = find.mFoundNode; @@ -208,7 +205,6 @@ osg::ref_ptr LocalMap::createOrthographicCamera(float x, float y, f camera->addChild(lightSource); camera->setStateSet(stateset); - camera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext()); camera->setViewport(0, 0, mMapResolution, mMapResolution); camera->setUpdateCallback(new CameraLocalUpdateCallback(this)); @@ -311,7 +307,7 @@ void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell) int x = cell->getCell()->getGridX(); int y = cell->getCell()->getGridY(); - osg::BoundingSphere bound = mViewer->getSceneData()->getBound(); + osg::BoundingSphere bound = mSceneRoot->getBound(); float zmin = bound.center().z() - bound.radius(); float zmax = bound.center().z() + bound.radius(); diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 2516c063e..1928871ca 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -19,11 +19,6 @@ namespace ESM struct FogTexture; } -namespace osgViewer -{ - class Viewer; -} - namespace osg { class Texture2D; @@ -41,7 +36,7 @@ namespace MWRender class LocalMap { public: - LocalMap(osgViewer::Viewer* viewer); + LocalMap(osg::Group* root); ~LocalMap(); /** @@ -106,8 +101,6 @@ namespace MWRender osg::Group* getRoot(); private: - osg::ref_ptr mViewer; - osg::ref_ptr mRoot; osg::ref_ptr mSceneRoot; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 8f73036e9..d74bac0b3 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -620,7 +620,6 @@ namespace MWRender mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); rttCamera->removeChildren(0, rttCamera->getNumChildren()); - rttCamera->setGraphicsContext(NULL); mRootNode->removeChild(rttCamera); } diff --git a/cmake/FindOSGPlugins.cmake b/cmake/FindOSGPlugins.cmake new file mode 100644 index 000000000..8220f33d4 --- /dev/null +++ b/cmake/FindOSGPlugins.cmake @@ -0,0 +1,50 @@ +# This module accepts the following env variable +# OSGPlugins_LIB_DIR - /lib/osgPlugins- , path to search plugins +# +# Once done this will define +# OSGPlugins_FOUND - System has the all required components. +# OSGPlugins_LIBRARIES - Link these to use the required osg plugins components. +# +# Components: +# - osgdb_png +# - osgdb_tga +# - osgdb_dds +# - osgdb_jpeg + +include(LibFindMacros) +include(Findosg_functions) + +if (NOT OSGPlugins_LIB_DIR) + set(_mode WARNING) + if (OSGPlugins_FIND_REQUIRED) + set(_mode FATAL_ERROR) + endif() + message(${_mode} "OSGPlugins_LIB_DIR variable must be set") +endif() + +foreach(_library ${OSGPlugins_FIND_COMPONENTS}) + string(TOUPPER ${_library} _library_uc) + set(_component OSGPlugins_${_library}) + + set(${_library_uc}_DIR ${OSGPlugins_LIB_DIR}) # to help function osg_find_library + set(_saved_lib_prefix ${CMAKE_FIND_LIBRARY_PREFIXES}) # save CMAKE_FIND_LIBRARY_PREFIXES + set(CMAKE_FIND_LIBRARY_PREFIXES "") # search libraries with no prefix + osg_find_library(${_library_uc} ${_library}) # find it into ${_library_uc}_LIBRARIES + set(CMAKE_FIND_LIBRARY_PREFIXES ${_saved_lib_prefix}) # restore prefix + + if (${_library_uc}_LIBRARIES) + set(${_component}_LIBRARY ${${_library_uc}_LIBRARIES}) # fake as if we call find_library + else() + set(${_component}_LIBRARY ${_component}_LIBRARY-NOTFOUND) + endif() + + list(APPEND OSGPlugins_PROCESS_LIBS ${_component}_LIBRARY) +endforeach() + +foreach(_dependency PNG ZLIB JPEG) # needed by osgdb_png or osgdb_jpeg + libfind_package(OSGPlugins ${_dependency}) + set(${_dependency}_LIBRARY_OPTS ${_dependency}_LIBRARY) + #list(APPEND OSGPlugins_PROCESS_LIBS ${_dependency}_LIBRARY) +endforeach() + +libfind_process(OSGPlugins) diff --git a/cmake/FindPkgMacros.cmake b/cmake/FindPkgMacros.cmake deleted file mode 100644 index 473b27b2a..000000000 --- a/cmake/FindPkgMacros.cmake +++ /dev/null @@ -1,161 +0,0 @@ -#------------------------------------------------------------------- -# This file is part of the CMake build system for OGRE -# (Object-oriented Graphics Rendering Engine) -# For the latest info, see http://www.ogre3d.org/ -# -# The contents of this file are placed in the public domain. Feel -# free to make use of it in any way you like. -#------------------------------------------------------------------- - -################################################################## -# Provides some common functionality for the FindPackage modules -################################################################## - -# Begin processing of package -macro(findpkg_begin PREFIX) - if (NOT ${PREFIX}_FIND_QUIETLY) - message(STATUS "Looking for ${PREFIX}...") - endif () -endmacro(findpkg_begin) - -# Display a status message unless FIND_QUIETLY is set -macro(pkg_message PREFIX) - if (NOT ${PREFIX}_FIND_QUIETLY) - message(STATUS ${ARGN}) - endif () -endmacro(pkg_message) - -# Get environment variable, define it as ENV_$var and make sure backslashes are converted to forward slashes -macro(getenv_path VAR) - set(ENV_${VAR} $ENV{${VAR}}) - # replace won't work if var is blank - if (ENV_${VAR}) - string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} ) - endif () -endmacro(getenv_path) - -# Construct search paths for includes and libraries from a PREFIX_PATH -macro(create_search_paths PREFIX) - foreach(dir ${${PREFIX}_PREFIX_PATH}) - set(${PREFIX}_INC_SEARCH_PATH ${${PREFIX}_INC_SEARCH_PATH} - ${dir}/include ${dir}/Include ${dir}/include/${PREFIX} ${dir}/Headers) - set(${PREFIX}_LIB_SEARCH_PATH ${${PREFIX}_LIB_SEARCH_PATH} - ${dir}/lib ${dir}/Lib ${dir}/lib/${PREFIX} ${dir}/Libs) - set(${PREFIX}_BIN_SEARCH_PATH ${${PREFIX}_BIN_SEARCH_PATH} - ${dir}/bin) - endforeach(dir) - set(${PREFIX}_FRAMEWORK_SEARCH_PATH ${${PREFIX}_PREFIX_PATH}) -endmacro(create_search_paths) - -# clear cache variables if a certain variable changed -macro(clear_if_changed TESTVAR) - # test against internal check variable - # HACK: Apparently, adding a variable to the cache cleans up the list - # a bit. We need to also remove any empty strings from the list, but - # at the same time ensure that we are actually dealing with a list. - list(APPEND ${TESTVAR} "") - list(REMOVE_ITEM ${TESTVAR} "") - if (NOT "${${TESTVAR}}" STREQUAL "${${TESTVAR}_INT_CHECK}") - message(STATUS "${TESTVAR} changed.") - foreach(var ${ARGN}) - set(${var} "NOTFOUND" CACHE STRING "x" FORCE) - endforeach(var) - endif () - set(${TESTVAR}_INT_CHECK ${${TESTVAR}} CACHE INTERNAL "x" FORCE) -endmacro(clear_if_changed) - -# Try to get some hints from pkg-config, if available -macro(use_pkgconfig PREFIX PKGNAME) - find_package(PkgConfig) - if (PKG_CONFIG_FOUND) - pkg_check_modules(${PREFIX} ${PKGNAME}) - endif () -endmacro (use_pkgconfig) - -# Couple a set of release AND debug libraries (or frameworks) -macro(make_library_set PREFIX) - if (${PREFIX}_FWK) - set(${PREFIX} ${${PREFIX}_FWK}) - elseif (${PREFIX}_REL AND ${PREFIX}_DBG) - set(${PREFIX} optimized ${${PREFIX}_REL} debug ${${PREFIX}_DBG}) - elseif (${PREFIX}_REL) - set(${PREFIX} ${${PREFIX}_REL}) - elseif (${PREFIX}_DBG) - set(${PREFIX} ${${PREFIX}_DBG}) - endif () -endmacro(make_library_set) - -# Generate debug names from given release names -macro(get_debug_names PREFIX) - foreach(i ${${PREFIX}}) - set(${PREFIX}_DBG ${${PREFIX}_DBG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i}) - endforeach(i) -endmacro(get_debug_names) - -# Add the parent dir from DIR to VAR -macro(add_parent_dir VAR DIR) - get_filename_component(${DIR}_TEMP "${${DIR}}/.." ABSOLUTE) - set(${VAR} ${${VAR}} ${${DIR}_TEMP}) -endmacro(add_parent_dir) - -# Do the final processing for the package find. -macro(findpkg_finish PREFIX) - # skip if already processed during this run - if (NOT ${PREFIX}_FOUND) - if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) - set(${PREFIX}_FOUND TRUE) - set(${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) - set(${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) - if (NOT ${PREFIX}_FIND_QUIETLY) - message(STATUS "Found ${PREFIX}: ${${PREFIX}_LIBRARIES}") - endif () - else () - if (NOT ${PREFIX}_FIND_QUIETLY) - message(STATUS "Could not locate ${PREFIX}") - endif () - if (${PREFIX}_FIND_REQUIRED) - message(FATAL_ERROR "Required library ${PREFIX} not found! Install the library (including dev packages) and try again. If the library is already installed, set the missing variables manually in cmake.") - endif () - endif () - - mark_as_advanced(${PREFIX}_INCLUDE_DIR ${PREFIX}_LIBRARY ${PREFIX}_LIBRARY_REL ${PREFIX}_LIBRARY_DBG ${PREFIX}_LIBRARY_FWK) - endif () -endmacro(findpkg_finish) - - -# Slightly customised framework finder -MACRO(findpkg_framework fwk) - IF(APPLE) - SET(${fwk}_FRAMEWORK_PATH - ${${fwk}_FRAMEWORK_SEARCH_PATH} - ${CMAKE_FRAMEWORK_PATH} - ~/Library/Frameworks - /Library/Frameworks - /System/Library/Frameworks - /Network/Library/Frameworks - /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/Frameworks/ - ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release - ${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug - ) - # These could be arrays of paths, add each individually to the search paths - foreach(i ${OGRE_PREFIX_PATH}) - set(${fwk}_FRAMEWORK_PATH ${${fwk}_FRAMEWORK_PATH} ${i}/lib/Release ${i}/lib/Debug) - endforeach(i) - - foreach(i ${OGRE_PREFIX_BUILD}) - set(${fwk}_FRAMEWORK_PATH ${${fwk}_FRAMEWORK_PATH} ${i}/lib/Release ${i}/lib/Debug) - endforeach(i) - - FOREACH(dir ${${fwk}_FRAMEWORK_PATH}) - SET(fwkpath ${dir}/${fwk}.framework) - IF(EXISTS ${fwkpath}) - SET(${fwk}_FRAMEWORK_INCLUDES ${${fwk}_FRAMEWORK_INCLUDES} - ${fwkpath}/Headers ${fwkpath}/PrivateHeaders) - SET(${fwk}_FRAMEWORK_PATH ${dir}) - if (NOT ${fwk}_LIBRARY_FWK) - SET(${fwk}_LIBRARY_FWK "-framework ${fwk}") - endif () - ENDIF(EXISTS ${fwkpath}) - ENDFOREACH(dir) - ENDIF(APPLE) -ENDMACRO(findpkg_framework) diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake index 163abf463..25105f1e2 100644 --- a/cmake/FindSDL2.cmake +++ b/cmake/FindSDL2.cmake @@ -1,16 +1,20 @@ # Locate SDL2 library # This module defines -# SDL2_LIBRARY, the name of the library to link against +# SDL2_LIBRARY, the SDL2 library, with no other libraries +# SDL2_LIBRARIES, the SDL library and required components with compiler flags # SDL2_FOUND, if false, do not try to link to SDL2 # SDL2_INCLUDE_DIR, where to find SDL.h +# SDL2_VERSION, the version of the found library # +# This module accepts the following env variables +# SDL2DIR - Can be set to ./configure --prefix=$SDL2DIR used in building SDL2. l.e.galup 9-20-02 # This module responds to the the flag: # SDL2_BUILDING_LIBRARY # If this is defined, then no SDL2_main will be linked in because # only applications need main(). # Otherwise, it is assumed you are building an application and this # module will attempt to locate and set the the proper link flags -# as part of the returned SDL2_LIBRARY variable. +# as part of the returned SDL2_LIBRARIES variable. # # Don't forget to include SDL2main.h and SDL2main.m your project for the # OS X framework based version. (Other versions link to -lSDL2main which @@ -18,20 +22,6 @@ # module will automatically add the -framework Cocoa on your behalf. # # -# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration -# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library -# (SDL2.dll, libsdl2.so, SDL2.framework, etc). -# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. -# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value -# as appropriate. These values are used to generate the final SDL2_LIBRARY -# variable, but when these values are unset, SDL2_LIBRARY does not get created. -# -# -# $SDL2DIR is an environment variable that would -# correspond to the ./configure --prefix=$SDL2DIR -# used in building SDL2. -# l.e.galup 9-20-02 -# # Modified by Eric Wing. # Added code to assist with automated building by using environmental variables # and providing a more controlled/consistent search behavior. @@ -71,126 +61,69 @@ # License text for the above reference.) -FIND_PATH(SDL2_INCLUDE_DIR SDL.h - HINTS - $ENV{SDL2DIR} - PATH_SUFFIXES include/SDL2 include - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local/include/SDL2 - /usr/include/SDL2 - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_sdl_lib_suffix lib/x64) +else() + set(_sdl_lib_suffix lib/x86) +endif() + +libfind_pkg_detect(SDL2 sdl2 + FIND_PATH SDL.h + HINTS $ENV{SDL2DIR} + PATH_SUFFIXES include SDL2 + FIND_LIBRARY SDL2 + HINTS $ENV{SDL2DIR} + PATH_SUFFIXES ${_sdl_lib_suffix} ) -#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}") +libfind_version_n_header(SDL2 NAMES SDL_version.h DEFINES SDL_MAJOR_VERSION SDL_MINOR_VERSION SDL_PATCHLEVEL) -FIND_LIBRARY(SDL2_LIBRARY_PATH - NAMES SDL2 - HINTS - $ENV{SDL2DIR} - PATH_SUFFIXES lib64 lib - PATHS - /sw - /opt/local - /opt/csw - /opt -) - -set(SDL2_LIBRARY_ONLY ${SDL2_LIBRARY_PATH} CACHE STRING "The SDL2 library, with no other libraries.") -set(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_PATH}) - -#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}") - -IF(NOT SDL2_BUILDING_LIBRARY) - IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +IF(NOT SDL2_BUILDING_LIBRARY AND NOT APPLE) # Non-OS X framework versions expect you to also dynamically link to # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms # seem to provide SDL2main for compatibility even though they don't # necessarily need it. - FIND_LIBRARY(SDL2MAIN_LIBRARY - NAMES SDL2main - HINTS - $ENV{SDL2DIR} - PATH_SUFFIXES lib64 lib - PATHS - /sw - /opt/local - /opt/csw - /opt + libfind_pkg_detect(SDL2MAIN sdl2 + FIND_LIBRARY SDL2main + HINTS $ENV{SDL2DIR} + PATH_SUFFIXES ${_sdl_lib_suffix} ) - ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") -ENDIF(NOT SDL2_BUILDING_LIBRARY) + set(SDL2MAIN_FIND_QUIETLY TRUE) + libfind_process(SDL2MAIN) + list(APPEND SDL2_PROCESS_LIBS SDL2MAIN_LIBRARY) +ENDIF() -# SDL2 may require threads on your system. -# The Apple build may not need an explicit flag because one of the -# frameworks may already provide it. -# But for non-OSX systems, I will use the CMake Threads package. -IF(NOT APPLE) - FIND_PACKAGE(Threads) -ENDIF(NOT APPLE) + +set(SDL2_TARGET_SPECIFIC) + +if (APPLE) + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + list(APPEND SDL2_TARGET_SPECIFIC "-framework Cocoa") +else() + # SDL2 may require threads on your system. + # The Apple build may not need an explicit flag because one of the + # frameworks may already provide it. + # But for non-OSX systems, I will use the CMake Threads package. + libfind_package(SDL2 Threads) + list(APPEND SDL2_TARGET_SPECIFIC ${CMAKE_THREAD_LIBS_INIT}) +endif() # MinGW needs an additional library, mwindows # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows # (Actually on second look, I think it only needs one of the m* libraries.) -IF(MINGW) - SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") -ENDIF(MINGW) +if(MINGW) + list(APPEND SDL2_TARGET_SPECIFIC mingw32) +endif() -SET(SDL2_FOUND "NO") -IF(SDL2_LIBRARY_TEMP) - # For SDL2main - IF(NOT SDL2_BUILDING_LIBRARY) - IF(SDL2MAIN_LIBRARY) - SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) - ENDIF(SDL2MAIN_LIBRARY) - ENDIF(NOT SDL2_BUILDING_LIBRARY) +if(WIN32) + list(APPEND SDL2_TARGET_SPECIFIC winmm imm32 version msimg32) +endif() - # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. - # CMake doesn't display the -framework Cocoa string in the UI even - # though it actually is there if I modify a pre-used variable. - # I think it has something to do with the CACHE STRING. - # So I use a temporary variable until the end so I can set the - # "real" variable in one-shot. - IF(APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") - ENDIF(APPLE) +set(SDL2_PROCESS_LIBS SDL2_TARGET_SPECIFIC) - # For threads, as mentioned Apple doesn't need this. - # In fact, there seems to be a problem if I used the Threads package - # and try using this line, so I'm just skipping it entirely for OS X. - IF(NOT APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) - ENDIF(NOT APPLE) +libfind_process(SDL2) - # For MinGW library - IF(MINGW) - SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) - ENDIF(MINGW) - - IF(WIN32) - SET(SDL2_LIBRARY_TEMP winmm imm32 version msimg32 ${SDL2_LIBRARY_TEMP}) - ENDIF(WIN32) - - # Set the final string here so the GUI reflects the final state. - SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") - # Set the temp variable to INTERNAL so it is not seen in the CMake GUI - SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") - - SET(SDL2_FOUND "YES") -ENDIF(SDL2_LIBRARY_TEMP) - -INCLUDE(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 - REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) - -IF(SDL2_STATIC) - if (UNIX AND NOT APPLE) - EXECUTE_PROCESS(COMMAND sdl2-config --static-libs OUTPUT_VARIABLE SDL2_LINK_FLAGS) - STRING(REGEX REPLACE "(\r?\n)+$" "" SDL2_LINK_FLAGS "${SDL2_LINK_FLAGS}") - SET(SDL2_LIBRARY ${SDL2_LINK_FLAGS}) - ENDIF() -ENDIF(SDL2_STATIC) +if (SDL2_STATIC AND UNIX AND NOT APPLE) + execute_process(COMMAND sdl2-config --static-libs OUTPUT_VARIABLE SDL2_STATIC_FLAGS) + string(REGEX REPLACE "(\r?\n)+$" "" SDL2_STATIC_FLAGS "${SDL2_STATIC_FLAGS}") + set(SDL2_LIBRARIES ${SDL2_STATIC_FLAGS}) +endif() diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake index 4607f7806..331598006 100644 --- a/cmake/FindSphinx.cmake +++ b/cmake/FindSphinx.cmake @@ -2,44 +2,36 @@ # Find the Sphinx documentation generator # # This modules defines -# SPHINX_EXECUTABLE -# SPHINX_FOUND - -find_program(SPHINX_EXECUTABLE - NAMES sphinx-build - PATHS - /usr/bin - /usr/local/bin - /opt/local/bin - DOC "Sphinx documentation generator" -) - -if( NOT SPHINX_EXECUTABLE ) - set(_Python_VERSIONS - 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0 1.6 1.5 - ) - - foreach( _version ${_Python_VERSIONS} ) - set( _sphinx_NAMES sphinx-build-${_version} ) - - find_program( SPHINX_EXECUTABLE - NAMES ${_sphinx_NAMES} - PATHS - /usr/bin - /usr/local/bin - /opt/loca/bin - DOC "Sphinx documentation generator" - ) - endforeach() -endif() +# Sphinx_EXECUTABLE +# Sphinx_FOUND +# function Sphinx_add_target +# function Sphinx_add_targets +# include(FindPackageHandleStandardArgs) +include(CMakeParseArguments) -find_package_handle_standard_args(Sphinx DEFAULT_MSG - SPHINX_EXECUTABLE +set(_sphinx_names sphinx-build) +foreach(_version 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0 1.6 1.5) + list(APPEND _sphinx_names sphinx-build-${_version}) +endforeach() + +find_program(Sphinx_EXECUTABLE + NAMES ${_sphinx_names} + PATHS + /usr/bin + /usr/local/bin + /opt/local/bin + DOC "Sphinx documentation generator" ) +mark_as_advanced(Sphinx_EXECUTABLE) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sphinx + FOUND_VAR Sphinx_FOUND + REQUIRED_VARS Sphinx_EXECUTABLE +) + option( SPHINX_HTML_OUTPUT "Build a single HTML with the whole content." ON ) option( SPHINX_DIRHTML_OUTPUT "Build HTML pages, but with a single directory per document." OFF ) option( SPHINX_HTMLHELP_OUTPUT "Build HTML pages with additional information for building a documentation collection in htmlhelp." OFF ) @@ -50,96 +42,43 @@ option( SPHINX_LATEX_OUTPUT "Build LaTeX sources that can be compiled to a PDF d option( SPHINX_MAN_OUTPUT "Build manual pages in groff format for UNIX systems." OFF ) option( SPHINX_TEXT_OUTPUT "Build plain text files." OFF ) - -mark_as_advanced( - SPHINX_EXECUTABLE - SPHINX_HTML_OUTPUT - SPHINX_DIRHTML_OUTPUT - SPHINX_HTMLHELP_OUTPUT - SPHINX_QTHELP_OUTPUT - SPHINX_DEVHELP_OUTPUT - SPHINX_EPUB_OUTPUT - SPHINX_LATEX_OUTPUT - SPHINX_MAN_OUTPUT - SPHINX_TEXT_OUTPUT -) - -function( Sphinx_add_target target_name builder conf source destination ) - add_custom_target( ${target_name} ALL - COMMAND ${SPHINX_EXECUTABLE} -b ${builder} - -c ${conf} - ${source} - ${destination} - COMMENT "Generating sphinx documentation: ${builder}" +function(Sphinx_add_target target_name builder conf source destination) + add_custom_target( ${target_name} ALL + COMMAND ${Sphinx_EXECUTABLE} -b ${builder} -c ${conf} ${source} ${destination} + DEPENDS ${conf}/conf.py + COMMENT "Generating sphinx documentation: ${builder}" ) - set_property( - DIRECTORY APPEND PROPERTY - ADDITIONAL_MAKE_CLEAN_FILES - ${destination} + set_property(DIRECTORY APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES ${destination} ) endfunction() -# Target dependencies can be optionally listed at the end. -function( Sphinx_add_targets target_base_name conf source base_destination ) +# Usage: +# +# Sphinx_add_targets(NAME +# SRC_DIR / +# DST_DIR / +# CONFIG_DIR / +# [DEPENDENCIES dep1 dep2 dep3 ...] +# ) +function(Sphinx_add_targets) + set(options ) + set(one_value_keywords NAME SRC_DIR DST_DIR CONFIG_DIR) + set(multi_value_keywords DEPENDENCIES) + CMAKE_PARSE_ARGUMENTS(OPT "${options}" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN}) - set( _dependencies ) + if (NOT OPT_NAME OR NOT OPT_SRC_DIR OR NOT OPT_DST_DIR OR NOT OPT_CONFIG_DIR) + message(FATAL_ERROR "Arguments NAME, SRC_DIR, DST_DIR, CONFIG_DIR are required!") + endif() - foreach( arg IN LISTS ARGN ) - set( _dependencies ${_dependencies} ${arg} ) - endforeach() - - if( ${SPHINX_HTML_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_html html ${conf} ${source} ${base_destination}/html ) - - add_dependencies( ${target_base_name}_html ${_dependencies} ) - endif() - - if( ${SPHINX_DIRHTML_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_dirhtml dirhtml ${conf} ${source} ${base_destination}/dirhtml ) - - add_dependencies( ${target_base_name}_dirhtml ${_dependencies} ) - endif() - - if( ${SPHINX_QTHELP_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_qthelp qthelp ${conf} ${source} ${base_destination}/qthelp ) - - add_dependencies( ${target_base_name}_qthelp ${_dependencies} ) - endif() - - if( ${SPHINX_DEVHELP_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_devhelp devhelp ${conf} ${source} ${base_destination}/devhelp ) - - add_dependencies( ${target_base_name}_devhelp ${_dependencies} ) - endif() - - if( ${SPHINX_EPUB_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_epub epub ${conf} ${source} ${base_destination}/epub ) - - add_dependencies( ${target_base_name}_epub ${_dependencies} ) - endif() - - if( ${SPHINX_LATEX_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_latex latex ${conf} ${source} ${base_destination}/latex ) - - add_dependencies( ${target_base_name}_latex ${_dependencies} ) - endif() - - if( ${SPHINX_MAN_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_man man ${conf} ${source} ${base_destination}/man ) - - add_dependencies( ${target_base_name}_man ${_dependencies} ) - endif() - - if( ${SPHINX_TEXT_OUTPUT} ) - Sphinx_add_target( ${target_base_name}_text text ${conf} ${source} ${base_destination}/text ) - - add_dependencies( ${target_base_name}_text ${_dependencies} ) - endif() - - if( ${BUILD_TESTING} ) - sphinx_add_target( ${target_base_name}_linkcheck linkcheck ${conf} ${source} ${base_destination}/linkcheck ) - - add_dependencies( ${target_base_name}_linkcheck ${_dependencies} ) - endif() + foreach(_generator html dirhtml qthelp devhelp epub latex man text linkcheck) + string(TOUPPER ${_generator} _generator_uc) + if (SPHINX_${_generator_uc}_OUTPUT) + Sphinx_add_target(${OPT_NAME}_${_generator} ${_generator} ${OPT_CONFIG_DIR} ${OPT_SRC_DIR} ${OPT_DST_DIR}/${_generator}/) + if (OPT_DEPENDENCIES) + add_dependencies(${OPT_NAME}_${_generator} ${OPT_DEPENDENCIES}) + endif() + endif() + endforeach() endfunction() diff --git a/cmake/LibFindMacros.cmake b/cmake/LibFindMacros.cmake index 56b39a1ad..2be27c5fc 100644 --- a/cmake/LibFindMacros.cmake +++ b/cmake/LibFindMacros.cmake @@ -322,7 +322,7 @@ function (libfind_process PREFIX) set(val ${${i}}) if ("${val}" STREQUAL "${i}-NOTFOUND") set (val "") - elseif (val AND NOT EXISTS ${val}) + elseif (val AND NOT EXISTS "${val}") set (val "${val} (does not exist)") else() set(some_files TRUE) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 309dac88b..8a50c2c92 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -868,6 +868,8 @@ namespace NifOsg else return; + osg::BoundingBox box; + int i=0; for (std::vector::const_iterator it = partctrl->particles.begin(); iactiveCount && it != partctrl->particles.end(); ++it, ++i) @@ -882,7 +884,8 @@ namespace NifOsg // Note this position and velocity is not correct for a particle system with absolute reference frame, // which can not be done in this loader since we are not attached to the scene yet. Will be fixed up post-load in the SceneManager. created->setVelocity(particle.velocity); - created->setPosition(particledata->vertices->at(particle.vertex)); + const osg::Vec3f& position = particledata->vertices->at(particle.vertex); + created->setPosition(position); osg::Vec4f partcolor (1.f,1.f,1.f,1.f); if (particle.vertex < int(particledata->colors->size())) @@ -891,10 +894,12 @@ namespace NifOsg float size = particledata->sizes.at(particle.vertex) * partctrl->size; created->setSizeRange(osgParticle::rangef(size, size)); + box.expandBy(osg::BoundingSphere(position, size)); } - osg::BoundingBox box; + // radius may be used to force a larger bounding box box.expandBy(osg::BoundingSphere(osg::Vec3(0,0,0), particledata->radius)); + partsys->setInitialBound(box); } diff --git a/components/resource/imagemanager.hpp b/components/resource/imagemanager.hpp index 8d9ad2c32..2ef601e6b 100644 --- a/components/resource/imagemanager.hpp +++ b/components/resource/imagemanager.hpp @@ -10,11 +10,6 @@ #include "resourcemanager.hpp" -namespace osgViewer -{ - class Viewer; -} - namespace osgDB { class Options;