Merge branch 'master' into next

Conflicts:
	apps/openmw/mwbase/inputmanager.hpp
	apps/openmw/mwinput/inputmanagerimp.cpp
	apps/openmw/mwinput/inputmanagerimp.hpp
	apps/openmw/mwinput/mouselookevent.cpp
actorid
scrawl 13 years ago
commit 19ae30ee68

@ -15,7 +15,7 @@ include (OpenMWMacros)
# Version # Version
set (OPENMW_VERSION_MAJOR 0) set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 16) set (OPENMW_VERSION_MINOR 17)
set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION_RELEASE 0)
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
@ -251,13 +251,15 @@ if (APPLE)
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY)
endif (APPLE) endif (APPLE)
# Set up DEBUG define
set_directory_properties(PROPERTIES COMPILE_DEFINITIONS_DEBUG DEBUG=1)
# Set up Ogre plugin folder & debug suffix # Set up Ogre plugin folder & debug suffix
# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) if (APPLE)
if (DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE) # Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt)
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
else()
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="")
else ()
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
endif() endif()
add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}") add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}")

@ -21,7 +21,6 @@ add_openmw_dir (mwrender
add_openmw_dir (mwinput add_openmw_dir (mwinput
inputmanagerimp inputmanagerimp
mouselookevent
) )
add_openmw_dir (mwgui add_openmw_dir (mwgui

@ -356,6 +356,8 @@ void OMW::Engine::go()
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
pos.pos[2] = 0; pos.pos[2] = 0;
mEnvironment.getWorld()->renderPlayer();
if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName))
{ {
MWBase::Environment::get().getWorld()->indexToPosition (exterior->data.gridX, exterior->data.gridY, MWBase::Environment::get().getWorld()->indexToPosition (exterior->data.gridX, exterior->data.gridY,

@ -248,6 +248,15 @@ namespace MWBase
virtual bool isSwimming(const MWWorld::Ptr &object) = 0; virtual bool isSwimming(const MWWorld::Ptr &object) = 0;
virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0;
virtual void togglePOV() = 0;
virtual void togglePreviewMode(bool enable) = 0;
virtual bool toggleVanityMode(bool enable, bool force) = 0;
virtual void allowVanityMode(bool allow) = 0;
virtual void togglePlayerLooking(bool enable) = 0;
virtual bool isVanityEnabled() = 0;
virtual void renderPlayer() = 0;
}; };
} }

@ -49,6 +49,8 @@ namespace MWInput
Ogre::RenderWindow* window = ogre.getWindow (); Ogre::RenderWindow* window = ogre.getWindow ();
size_t windowHnd; size_t windowHnd;
resetIdleTime();
window->getCustomAttribute("WINDOW", &windowHnd); window->getCustomAttribute("WINDOW", &windowHnd);
std::ostringstream windowHndStr; std::ostringstream windowHndStr;
@ -141,6 +143,8 @@ namespace MWInput
if (mDragDrop) if (mDragDrop)
return; return;
resetIdleTime ();
int action = channel->getNumber(); int action = channel->getNumber();
if (currentValue == 1) if (currentValue == 1)
{ {
@ -245,6 +249,46 @@ namespace MWInput
mPlayer.setUpDown (-1); mPlayer.setUpDown (-1);
else else
mPlayer.setUpDown (0); mPlayer.setUpDown (0);
if (mControlSwitch["playerviewswitch"]) {
if (actionIsActive(A_TogglePOV)) {
if (mPreviewPOVDelay <= 0.5 &&
(mPreviewPOVDelay += dt) > 0.5)
{
mPreviewPOVDelay = 1.f;
MWBase::Environment::get().getWorld()->togglePreviewMode(true);
}
} else {
if (mPreviewPOVDelay > 0.5) {
//disable preview mode
MWBase::Environment::get().getWorld()->togglePreviewMode(false);
} else if (mPreviewPOVDelay > 0.f) {
MWBase::Environment::get().getWorld()->togglePOV();
}
mPreviewPOVDelay = 0.f;
}
}
}
if (actionIsActive(A_MoveLeft)
|| actionIsActive(A_MoveRight)
|| actionIsActive(A_MoveForward)
|| actionIsActive(A_MoveBackward)
|| actionIsActive(A_Jump)
|| actionIsActive(A_Crouch))
{
resetIdleTime ();
}
else
{
if (mTimeIdle >= 0.f) {
mTimeIdle += dt;
}
if (mTimeIdle > 30.f && !mWindows.isGuiMode()) {
MWBase::Environment::get().getWorld()->toggleVanityMode(true, false);
mTimeIdle = -1.f;
}
} }
} }
@ -325,6 +369,14 @@ namespace MWInput
mControlSwitch[sw] = value; mControlSwitch[sw] = value;
} }
void InputManager::resetIdleTime ()
{
if (mTimeIdle < 0) {
MWBase::Environment::get().getWorld()->toggleVanityMode(false, false);
}
mTimeIdle = 0.f;
}
void InputManager::adjustMouseRegion(int width, int height) void InputManager::adjustMouseRegion(int width, int height)
{ {
const OIS::MouseState &ms = mMouse->getMouseState(); const OIS::MouseState &ms = mMouse->getMouseState();
@ -372,6 +424,8 @@ namespace MWInput
{ {
mInputCtrl->mouseMoved (arg); mInputCtrl->mouseMoved (arg);
resetIdleTime ();
if (mGuiCursorEnabled) if (mGuiCursorEnabled)
{ {
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
@ -539,6 +593,7 @@ namespace MWInput
defaultKeyBindings[A_Journal] = OIS::KC_J; defaultKeyBindings[A_Journal] = OIS::KC_J;
defaultKeyBindings[A_Rest] = OIS::KC_T; defaultKeyBindings[A_Rest] = OIS::KC_T;
defaultKeyBindings[A_GameMenu] = OIS::KC_ESCAPE; defaultKeyBindings[A_GameMenu] = OIS::KC_ESCAPE;
defaultKeyBindings[A_TogglePOV] = OIS::KC_TAB;
std::map<int, int> defaultMouseButtonBindings; std::map<int, int> defaultMouseButtonBindings;
defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right; defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right;
@ -588,6 +643,7 @@ namespace MWInput
descriptions[A_Journal] = "sJournal"; descriptions[A_Journal] = "sJournal";
descriptions[A_Rest] = "sRestKey"; descriptions[A_Rest] = "sRestKey";
descriptions[A_Inventory] = "sInventory"; descriptions[A_Inventory] = "sInventory";
descriptions[A_TogglePOV] = "sTogglePOVCmd";
if (descriptions[action] == "") if (descriptions[action] == "")
return ""; // not configurable return ""; // not configurable
@ -617,6 +673,7 @@ namespace MWInput
ret.push_back(A_MoveBackward); ret.push_back(A_MoveBackward);
ret.push_back(A_MoveLeft); ret.push_back(A_MoveLeft);
ret.push_back(A_MoveRight); ret.push_back(A_MoveRight);
ret.push_back(A_TogglePOV);
ret.push_back(A_Crouch); ret.push_back(A_Crouch);
ret.push_back(A_Activate); ret.push_back(A_Activate);
ret.push_back(A_ToggleWeapon); ret.push_back(A_ToggleWeapon);
@ -708,5 +765,4 @@ namespace MWInput
{ {
loadKeyDefaults(true); loadKeyDefaults(true);
} }
} }

@ -146,6 +146,9 @@ namespace MWInput
float mMouseX; float mMouseX;
float mMouseY; float mMouseY;
float mPreviewPOVDelay;
float mTimeIdle;
std::map<std::string, bool> mControlSwitch; std::map<std::string, bool> mControlSwitch;
@ -169,6 +172,8 @@ namespace MWInput
void loadKeyDefaults(bool force = false); void loadKeyDefaults(bool force = false);
void resetIdleTime();
private: private:
enum Actions enum Actions
{ {
@ -213,10 +218,10 @@ namespace MWInput
A_ToggleWeapon, A_ToggleWeapon,
A_ToggleSpell, A_ToggleSpell,
A_TogglePOV,
A_Last // Marker for the last item A_Last // Marker for the last item
}; };
}; };
} }
#endif #endif

@ -290,7 +290,7 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
} }
Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis(); Vector3 playerdirection = mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis();
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z); Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);

@ -4,104 +4,359 @@
#include <OgreCamera.h> #include <OgreCamera.h>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/refdata.hpp" #include "../mwworld/refdata.hpp"
#include "npcanimation.hpp"
namespace MWRender namespace MWRender
{ {
Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node)
: mCamera (camera), : mCamera(camera),
mNode (node), mPlayerNode(node),
mCameraNode(mPlayerNode->createChildSceneNode()),
mFirstPersonView(true), mFirstPersonView(true),
mVanityModeEnabled(false) mPreviewMode(false),
{} mFreeLook(true),
mHeight(128.f),
mCameraDistance(300.f),
mDistanceAdjusted(false)
{
mVanity.enabled = false;
mVanity.allowed = true;
mVanity.forced = false;
bool Player::setRotation(const Ogre::Vector3 &rot) mCameraNode->attachObject(mCamera);
mCameraNode->setPosition(0.f, 0.f, mHeight);
mPreviewCam.yaw = 0.f;
mPreviewCam.offset = 400.f;
}
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
{ {
Ogre::SceneNode *sceneNode = mNode; if (mVanity.enabled) {
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); toggleVanityMode(false);
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); }
Ogre::Vector3 trueRot = rot;
/// \note rotate player on forced vanity
if (mVanity.forced) {
if (mFreeLook) {
float diff = (adjust) ? rot.z : mMainCam.yaw - rot.z;
// we are only interested in X and Y rotation mVanity.enabled = false;
rotateCamera(rot, adjust);
mVanity.enabled = true;
// Rotate around X axis compensateYaw(diff);
Ogre::Radian radx(rot.x); }
if (radx.valueDegrees() > 89.5f) { trueRot.z = 0.f;
radx = Ogre::Degree(89.5f);
} else if (radx.valueDegrees() < -89.5f) {
radx = Ogre::Degree(-89.5f);
} }
Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X);
// Rotate around Y axis if (mFreeLook || mVanity.enabled || mPreviewMode) {
Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y); rotateCamera(trueRot, adjust);
}
pitchNode->setOrientation(xr); /// \note if vanity mode is forced by TVM then rotate player
yawNode->setOrientation(yr); return (!mVanity.enabled && !mPreviewMode) || mVanity.forced;
}
void Player::rotateCamera(const Ogre::Vector3 &rot, bool adjust)
{
if (adjust) {
setYaw(getYaw() + rot.z);
setPitch(getPitch() + rot.x);
} else {
setYaw(rot.z);
setPitch(rot.x);
}
Ogre::Quaternion xr(
Ogre::Radian(getPitch() + Ogre::Math::HALF_PI),
Ogre::Vector3::UNIT_X
);
Ogre::Quaternion zr(
Ogre::Radian(getYaw()),
Ogre::Vector3::NEGATIVE_UNIT_Z
);
if (!mVanity.enabled && !mPreviewMode) {
mPlayerNode->setOrientation(zr);
mCameraNode->setOrientation(xr);
} else {
mCameraNode->setOrientation(zr * xr);
}
updateListener(); updateListener();
return !mVanityModeEnabled;
} }
std::string Player::getHandle() const std::string Player::getHandle() const
{ {
return mNode->getName(); return mPlayerNode->getName();
} }
void Player::attachTo(const MWWorld::Ptr &ptr) void Player::attachTo(const MWWorld::Ptr &ptr)
{ {
ptr.getRefData().setBaseNode(mNode); ptr.getRefData().setBaseNode(mPlayerNode);
}
void Player::updateListener()
{
Ogre::Vector3 pos = mCamera->getRealPosition();
Ogre::Vector3 dir = mCamera->getRealDirection();
Ogre::Real xch;
xch = pos.y, pos.y = -pos.z, pos.z = xch;
xch = dir.y, dir.y = -dir.z, dir.z = xch;
MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir);
}
void Player::update(float duration)
{
if (mAnimation) {
mAnimation->runAnimation(duration);
}
if (mFirstPersonView && !mVanity.enabled) {
return;
}
if (mVanity.enabled) {
Ogre::Vector3 rot(0.f, 0.f, 0.f);
rot.z = Ogre::Degree(3.f * duration).valueRadians();
rotateCamera(rot, true);
}
} }
bool Player::adjustRotation(const Ogre::Vector3 &rot) void Player::toggleViewMode()
{ {
Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); mFirstPersonView = !mFirstPersonView;
Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); if (mFirstPersonView) {
mCamera->setPosition(0.f, 0.f, 0.f);
setLowHeight(false);
} else {
mCamera->setPosition(0.f, 0.f, mCameraDistance);
setLowHeight(true);
}
mPlayerNode->setVisible(!mFirstPersonView, false);
}
void Player::allowVanityMode(bool allow)
{
if (!allow && mVanity.enabled && !mVanity.forced) {
toggleVanityMode(false);
}
mVanity.allowed = allow;
}
float f = controlFlip(Ogre::Radian(rot.x).valueDegrees()); bool Player::toggleVanityMode(bool enable, bool force)
if (f != 0.0) { {
pitchNode->pitch(Ogre::Degree(f)); if ((mVanity.forced && !force) ||
(!mVanity.allowed && (force || enable)))
{
return false;
} else if (mVanity.enabled == enable) {
return true;
} }
yawNode->yaw(Ogre::Radian(-rot.z)); mVanity.enabled = enable;
mVanity.forced = force && enable;
updateListener(); float offset = mPreviewCam.offset;
Ogre::Vector3 rot(0.f, 0.f, 0.f);
if (mVanity.enabled) {
rot.x = Ogre::Degree(-30.f).valueRadians();
mMainCam.offset = mCamera->getPosition().z;
mPlayerNode->setVisible(true, false);
setLowHeight(true);
} else {
rot.x = getPitch();
offset = mMainCam.offset;
return !mVanityModeEnabled; mPlayerNode->setVisible(!mFirstPersonView, false);
setLowHeight(!mFirstPersonView);
}
rot.z = getYaw();
mCamera->setPosition(0.f, 0.f, offset);
rotateCamera(rot, false);
return true;
} }
float Player::controlFlip(float shift) void Player::togglePreviewMode(bool enable)
{ {
Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); if (mPreviewMode == enable) {
Ogre::Quaternion orient = pitchNode->getOrientation(); return;
}
mPreviewMode = enable;
float offset = mCamera->getPosition().z;
if (mPreviewMode) {
mMainCam.offset = offset;
offset = mPreviewCam.offset;
float pitchAngle = mPlayerNode->setVisible(true, false);
(2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees()); setLowHeight(true);
} else {
mPreviewCam.offset = offset;
offset = mMainCam.offset;
if (pitchAngle + shift < 89.5f && pitchAngle + shift > -89.5f) { mPlayerNode->setVisible(!mFirstPersonView, false);
return shift; setLowHeight(!mFirstPersonView);
} }
if (pitchAngle > 0) { mCamera->setPosition(0.f, 0.f, offset);
float f = 89.5f - pitchAngle - shift; rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
return (f > 0.f) ? f : 0.f; }
} else if (pitchAngle < 0) {
float f = -89.5 - pitchAngle - shift; float Player::getYaw()
return (f < 0.f) ? f : 0.f; {
if (mVanity.enabled || mPreviewMode) {
return mPreviewCam.yaw;
} }
return 0.f; return mMainCam.yaw;
} }
void Player::updateListener() void Player::setYaw(float angle)
{ {
Ogre::Vector3 pos = mCamera->getRealPosition(); if (angle > Ogre::Math::PI) {
Ogre::Vector3 dir = mCamera->getRealDirection(); angle -= Ogre::Math::TWO_PI;
} else if (angle < -Ogre::Math::PI) {
angle += Ogre::Math::TWO_PI;
}
if (mVanity.enabled || mPreviewMode) {
mPreviewCam.yaw = angle;
} else {
mMainCam.yaw = angle;
}
}
Ogre::Real xch; float Player::getPitch()
xch = pos.y, pos.y = -pos.z, pos.z = xch; {
xch = dir.y, dir.y = -dir.z, dir.z = xch; if (mVanity.enabled || mPreviewMode) {
return mPreviewCam.pitch;
}
return mMainCam.pitch;
}
MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir); void Player::setPitch(float angle)
{
float limit = Ogre::Math::HALF_PI;
if (mVanity.forced || mPreviewMode) {
limit /= 2;
}
if (angle > limit) {
angle = limit - 0.01;
} else if (angle < -limit) {
angle = -limit + 0.01;
}
if (mVanity.enabled || mPreviewMode) {
mPreviewCam.pitch = angle;
} else {
mMainCam.pitch = angle;
}
}
void Player::setCameraDistance(float dist, bool adjust, bool override)
{
if (mFirstPersonView && !mPreviewMode && !mVanity.enabled) {
return;
}
Ogre::Vector3 v(0.f, 0.f, dist);
if (adjust) {
v += mCamera->getPosition();
}
if (v.z > 800.f) {
v.z = 800.f;
} else if (v.z < 10.f) {
v.z = 10.f;
}
mCamera->setPosition(v);
if (override) {
if (mVanity.enabled || mPreviewMode) {
mPreviewCam.offset = v.z;
} else if (!mFirstPersonView) {
mCameraDistance = v.z;
}
} else {
mDistanceAdjusted = true;
}
}
void Player::setCameraDistance()
{
if (mDistanceAdjusted) {
if (mVanity.enabled || mPreviewMode) {
mCamera->setPosition(0, 0, mPreviewCam.offset);
} else if (!mFirstPersonView) {
mCamera->setPosition(0, 0, mCameraDistance);
}
}
mDistanceAdjusted = false;
}
void Player::setAnimation(NpcAnimation *anim)
{
mAnimation = anim;
mPlayerNode->setVisible(!mFirstPersonView, false);
}
void Player::setHeight(float height)
{
mHeight = height;
mCameraNode->setPosition(0.f, 0.f, mHeight);
}
float Player::getHeight()
{
return mHeight * mPlayerNode->getScale().z;
}
bool Player::getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera)
{
float xch;
camera = mCamera->getRealPosition();
xch = camera.z, camera.z = camera.y, camera.y = -xch;
player = mPlayerNode->getPosition();
return mFirstPersonView && !mVanity.enabled && !mPreviewMode;
}
Ogre::Vector3 Player::getPosition()
{
return mPlayerNode->getPosition();
}
void Player::getSightAngles(float &pitch, float &yaw)
{
pitch = mMainCam.pitch;
yaw = mMainCam.yaw;
}
void Player::compensateYaw(float diff)
{
mPreviewCam.yaw -= diff;
Ogre::Quaternion zr(
Ogre::Radian(mPreviewCam.yaw),
Ogre::Vector3::NEGATIVE_UNIT_Z
);
Ogre::Quaternion xr(
Ogre::Radian(mPreviewCam.pitch),
Ogre::Vector3::UNIT_X);
mCameraNode->setOrientation(zr * xr);
}
void Player::togglePlayerLooking(bool enable)
{
mFreeLook = enable;
}
void Player::setLowHeight(bool low)
{
if (low) {
mCameraNode->setPosition(0.f, 0.f, mHeight * 0.85);
} else {
mCameraNode->setPosition(0.f, 0.f, mHeight);
}
} }
} }

@ -3,9 +3,8 @@
#include <string> #include <string>
namespace Ogre namespace Ogre
{ {
class Vector3; class Vector3;
class Camera; class Camera;
class SceneNode; class SceneNode;
@ -18,20 +17,49 @@ namespace MWWorld
namespace MWRender namespace MWRender
{ {
class NpcAnimation;
/// \brief Player character rendering and camera control /// \brief Player character rendering and camera control
class Player class Player
{ {
struct CamData {
float pitch, yaw, offset;
};
Ogre::Camera *mCamera; Ogre::Camera *mCamera;
Ogre::SceneNode* mNode;
Ogre::SceneNode *mPlayerNode;
Ogre::SceneNode *mCameraNode;
NpcAnimation *mAnimation;
bool mFirstPersonView; bool mFirstPersonView;
bool mVanityModeEnabled; bool mPreviewMode;
bool mFreeLook;
struct {
bool enabled, allowed, forced;
} mVanity;
float mHeight, mCameraDistance;
CamData mMainCam, mPreviewCam;
float controlFlip(float shift = 0.f); bool mDistanceAdjusted;
/// Updates sound manager listener data /// Updates sound manager listener data
void updateListener(); void updateListener();
void rotateCamera(const Ogre::Vector3 &rot, bool adjust);
float getYaw();
void setYaw(float angle);
float getPitch();
void setPitch(float angle);
void compensateYaw(float diff);
void setLowHeight(bool low = true);
public: public:
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
@ -39,11 +67,7 @@ namespace MWRender
/// Set where the player is looking at. Uses Morrowind (euler) angles /// Set where the player is looking at. Uses Morrowind (euler) angles
/// \param rot Rotation angles in radians /// \param rot Rotation angles in radians
/// \return true if player object needs to bo rotated physically /// \return true if player object needs to bo rotated physically
bool setRotation(const Ogre::Vector3 &rot); bool rotate(const Ogre::Vector3 &rot, bool adjust);
/// \param rot Rotation angles in radians
/// \return true if player object needs to bo rotated physically
bool adjustRotation(const Ogre::Vector3 &rot);
std::string getHandle() const; std::string getHandle() const;
@ -52,12 +76,40 @@ namespace MWRender
/// several different objects /// several different objects
void attachTo(const MWWorld::Ptr &); void attachTo(const MWWorld::Ptr &);
void toggleViewMode() { void toggleViewMode();
mFirstPersonView = !mFirstPersonView;
} bool toggleVanityMode(bool enable, bool force = false);
void allowVanityMode(bool allow);
void togglePreviewMode(bool enable);
void update(float duration);
/// Set camera distance for current mode. Don't work on 1st person view.
/// \param adjust Indicates should distance be adjusted or set.
/// \param override If true new distance will be used as default.
/// If false, default distance can be restored with setCameraDistance().
void setCameraDistance(float dist, bool adjust = false, bool override = true);
/// Restore default camera distance for current mode.
void setCameraDistance();
void setAnimation(MWRender::NpcAnimation *anim);
void setHeight(float height);
float getHeight();
/// Stores player and camera world positions in passed arguments
/// \return true if camera at the eye-place
bool getPosition(Ogre::Vector3 &player, Ogre::Vector3 &camera);
Ogre::Vector3 getPosition();
void getSightAngles(float &pitch, float &yaw);
void togglePlayerLooking(bool enable);
void toggleVanityMode() { bool isVanityEnabled() {
mVanityModeEnabled = !mVanityModeEnabled; return mVanity.enabled;
} }
}; };
} }

@ -33,6 +33,7 @@
#include "localmap.hpp" #include "localmap.hpp"
#include "water.hpp" #include "water.hpp"
#include "compositors.hpp" #include "compositors.hpp"
#include "npcanimation.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
@ -40,7 +41,7 @@ using namespace Ogre;
namespace MWRender { namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine) RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine)
:mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine)
{ {
// select best shader mode // select best shader mode
bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos);
@ -130,14 +131,12 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
SceneNode *rt = mRendering.getScene()->getRootSceneNode(); SceneNode *rt = mRendering.getScene()->getRootSceneNode();
mMwRoot = rt->createChildSceneNode(); mMwRoot = rt->createChildSceneNode();
mMwRoot->pitch(Degree(-90)); mMwRoot->pitch(Degree(-90));
mObjects.setMwRoot(mMwRoot); mObjects.setMwRoot(mMwRoot);
mActors.setMwRoot(mMwRoot); mActors.setMwRoot(mMwRoot);
Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player"); Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player");
playerNode->pitch(Degree(90)); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode();
Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode();
cameraPitchNode->attachObject(mRendering.getCamera());
mShadows = new Shadows(&mRendering); mShadows = new Shadows(&mRendering);
@ -147,7 +146,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mSun = 0; mSun = 0;
mDebugging = new Debugging(mMwRoot, engine); mDebugging = new Debugging(mMwRoot, engine);
@ -259,11 +257,7 @@ RenderingManager::rotateObject(
bool force = true; bool force = true;
if (isPlayer) { if (isPlayer) {
if (adjust) { force = mPlayer->rotate(rot, adjust);
force = mPlayer->adjustRotation(rot);
} else {
force = mPlayer->setRotation(rot);
}
} }
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
@ -302,7 +296,22 @@ RenderingManager::moveObjectToCell(
child->setPosition(pos); child->setPosition(pos);
} }
void RenderingManager::update (float duration){ void RenderingManager::update (float duration)
{
Ogre::Vector3 orig, dest;
mPlayer->setCameraDistance();
if (!mPlayer->getPosition(orig, dest)) {
orig.z += mPlayer->getHeight() * mMwRoot->getScale().z;
btVector3 btOrig(orig.x, orig.y, orig.z);
btVector3 btDest(dest.x, dest.y, dest.z);
std::pair<std::string, float> test =
mPhysicsEngine->rayTest(btOrig, btDest);
if (!test.first.empty()) {
mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false);
}
}
mPlayer->update(duration);
mActors.update (duration); mActors.update (duration);
mObjects.update (duration); mObjects.update (duration);
@ -315,7 +324,23 @@ void RenderingManager::update (float duration){
mRendering.update(duration); mRendering.update(duration);
mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); MWWorld::RefData &data =
MWBase::Environment::get()
.getWorld()
->getPlayer()
.getPlayer()
.getRefData();
float *fpos = data.getPosition().pos;
/// \note only for LocalMap::updatePlayer()
Ogre::Vector3 pos(fpos[0], -fpos[2], -fpos[1]);
Ogre::SceneNode *node = data.getBaseNode();
Ogre::Quaternion orient =
node->convertLocalToWorldOrientation(node->_getDerivedOrientation());
mLocalMap->updatePlayer(pos, orient);
if (mWater) { if (mWater) {
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
@ -820,4 +845,22 @@ void RenderingManager::attachCameraTo(const MWWorld::Ptr &ptr)
mPlayer->attachTo(ptr); mPlayer->attachTo(ptr);
} }
void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr)
{
MWRender::NpcAnimation *anim =
new MWRender::NpcAnimation(
ptr,
mRendering,
MWWorld::Class::get(ptr).getInventoryStore(ptr)
);
mPlayer->setAnimation(anim);
}
void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw)
{
eyepos = mPlayer->getPosition();
eyepos.z += mPlayer->getHeight();
mPlayer->getSightAngles(pitch, yaw);
}
} // namespace } // namespace

@ -56,7 +56,34 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine); RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine);
virtual ~RenderingManager(); virtual ~RenderingManager();
void togglePOV() {
mPlayer->toggleViewMode();
}
void togglePreviewMode(bool enable) {
mPlayer->togglePreviewMode(enable);
}
bool toggleVanityMode(bool enable, bool force) {
return mPlayer->toggleVanityMode(enable, force);
}
bool isVanityEnabled() {
return mPlayer->isVanityEnabled();
}
void allowVanityMode(bool allow) {
mPlayer->allowVanityMode(allow);
}
void togglePlayerLooking(bool enable) {
mPlayer->togglePlayerLooking(enable);
}
void getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw);
void attachCameraTo(const MWWorld::Ptr &ptr); void attachCameraTo(const MWWorld::Ptr &ptr);
void renderPlayer(const MWWorld::Ptr &ptr);
SkyManager* getSkyManager(); SkyManager* getSkyManager();
Compositors* getCompositors(); Compositors* getCompositors();

@ -280,7 +280,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
, mMoonRed(false) , mMoonRed(false)
{ {
mSceneMgr = pMwRoot->getCreator(); mSceneMgr = pMwRoot->getCreator();
mRootNode = mCamera->getParentSceneNode()->createChildSceneNode(); mRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates
mRootNode->setInheritOrientation(false); mRootNode->setInheritOrientation(false);
} }
@ -405,6 +405,9 @@ void SkyManager::update(float duration)
{ {
if (!mEnabled) return; if (!mEnabled) return;
mCamera->getParentSceneNode ()->needUpdate ();
mRootNode->setPosition(mCamera->getDerivedPosition());
// UV Scroll the clouds // UV Scroll the clouds
mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer", sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
@ -666,12 +669,13 @@ Ogre::SceneNode* SkyManager::getSunNode()
void SkyManager::setSkyPosition(const Ogre::Vector3& position) void SkyManager::setSkyPosition(const Ogre::Vector3& position)
{ {
mRootNode->_setDerivedPosition(position); mRootNode->setPosition(position);
} }
void SkyManager::resetSkyPosition() void SkyManager::resetSkyPosition()
{ {
mRootNode->setPosition(0,0,0); mCamera->getParentSceneNode ()->needUpdate ();
mRootNode->setPosition(mCamera->getDerivedPosition());
} }
void SkyManager::scaleSky(float scale) void SkyManager::scaleSky(float scale)

@ -32,7 +32,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mIsUnderwater(false), mVisibilityFlags(0), mIsUnderwater(false), mVisibilityFlags(0),
mReflectionTarget(0), mActive(1), mToggled(1), mReflectionTarget(0), mActive(1), mToggled(1),
mReflectionRenderActive(false), mRendering(rend), mReflectionRenderActive(false), mRendering(rend),
mOldFarClip(0), mOldFarClip2(0),
mWaterTimer(0.f) mWaterTimer(0.f)
{ {
mSky = rend->getSkyManager(); mSky = rend->getSkyManager();
@ -207,6 +206,7 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
{ {
if (evt.source == mReflectionTarget) if (evt.source == mReflectionTarget)
{ {
mCamera->getParentSceneNode ()->needUpdate ();
mReflectionCamera->setOrientation(mCamera->getDerivedOrientation()); mReflectionCamera->setOrientation(mCamera->getDerivedOrientation());
mReflectionCamera->setPosition(mCamera->getDerivedPosition()); mReflectionCamera->setPosition(mCamera->getDerivedPosition());
mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance()); mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance());
@ -215,11 +215,9 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
mReflectionCamera->setFOVy(mCamera->getFOVy()); mReflectionCamera->setFOVy(mCamera->getFOVy());
mReflectionRenderActive = true; mReflectionRenderActive = true;
/// \todo the reflection render (and probably all renderingmanager-updates) lag behind 1 camera frame for some reason
Vector3 pos = mCamera->getRealPosition(); Vector3 pos = mCamera->getRealPosition();
pos.y = mTop*2 - pos.y; pos.y = mTop*2 - pos.y;
mSky->setSkyPosition(pos); mSky->setSkyPosition(pos);
mSky->scaleSky(mCamera->getFarClipDistance() / 50.f);
mReflectionCamera->enableReflection(mWaterPlane); mReflectionCamera->enableReflection(mWaterPlane);
} }
} }
@ -229,7 +227,6 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt)
if (evt.source == mReflectionTarget) if (evt.source == mReflectionTarget)
{ {
mSky->resetSkyPosition(); mSky->resetSkyPosition();
mSky->scaleSky(1);
mReflectionCamera->disableReflection(); mReflectionCamera->disableReflection();
mReflectionCamera->disableCustomNearClipPlane(); mReflectionCamera->disableCustomNearClipPlane();
mReflectionRenderActive = false; mReflectionRenderActive = false;
@ -269,34 +266,19 @@ void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &in
// We don't want the sky to get clipped by custom near clip plane (the water plane) // We don't want the sky to get clipped by custom near clip plane (the water plane)
if (queueGroupId < 20 && mReflectionRenderActive) if (queueGroupId < 20 && mReflectionRenderActive)
{ {
mOldFarClip = mReflectionCamera->getFarClipDistance ();
mReflectionCamera->disableCustomNearClipPlane(); mReflectionCamera->disableCustomNearClipPlane();
mReflectionCamera->setFarClipDistance (1000000000);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
} }
else if (queueGroupId == RQG_UnderWater)
{/*
mOldFarClip2 = mCamera->getFarClipDistance ();
mCamera->setFarClipDistance (1000000000);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
*/}
} }
void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
{ {
if (queueGroupId < 20 && mReflectionRenderActive) if (queueGroupId < 20 && mReflectionRenderActive)
{ {
mReflectionCamera->setFarClipDistance (mOldFarClip);
if (!mIsUnderwater) if (!mIsUnderwater)
mReflectionCamera->enableCustomNearClipPlane(mErrorPlane); mReflectionCamera->enableCustomNearClipPlane(mErrorPlane);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
} }
if (queueGroupId == RQG_UnderWater)
{
/*
mCamera->setFarClipDistance (mOldFarClip2);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
*/}
} }
void Water::update(float dt) void Water::update(float dt)

@ -50,9 +50,6 @@ namespace MWRender {
bool mToggled; bool mToggled;
int mTop; int mTop;
int mOldFarClip;
int mOldFarClip2;
float mWaterTimer; float mWaterTimer;
bool mReflectionRenderActive; bool mReflectionRenderActive;

@ -181,4 +181,5 @@ op 0x2000170: user4, explicit reference (console only, requires --script-console
op 0x2000171: user4 (implicit reference, console only, requires --script-console switch) op 0x2000171: user4 (implicit reference, console only, requires --script-console switch)
op 0x2000172: GetStartingAngle op 0x2000172: GetStartingAngle
op 0x2000173: GetStartingAngle, explicit reference op 0x2000173: GetStartingAngle, explicit reference
opcodes 0x2000174-0x3ffffff unused op 0x2000174: ToggleVanityMode
opcodes 0x2000175-0x3ffffff unused

@ -207,6 +207,29 @@ namespace MWScript
} }
}; };
class OpToggleVanityMode : public Interpreter::Opcode0
{
public:
virtual void execute(Interpreter::Runtime &runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
MWBase::World *world =
MWBase::Environment::get().getWorld();
bool value = !world->isVanityEnabled();
if (world->toggleVanityMode(value, true)) {
context.report(
(value) ? "Vanity Mode -> On" : "Vanity Mode -> Off"
);
} else {
context.report("Vanity Mode -> No");
}
}
};
const int opcodeXBox = 0x200000c; const int opcodeXBox = 0x200000c;
const int opcodeOnActivate = 0x200000d; const int opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075; const int opcodeActivate = 0x2000075;
@ -222,6 +245,7 @@ namespace MWScript
const int opcodeToggleWater = 0x2000144; const int opcodeToggleWater = 0x2000144;
const int opcodeTogglePathgrid = 0x2000146; const int opcodeTogglePathgrid = 0x2000146;
const int opcodeDontSaveObject = 0x2000153; const int opcodeDontSaveObject = 0x2000153;
const int opcodeToggleVanityMode = 0x2000174;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -244,6 +268,8 @@ namespace MWScript
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid); extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid); extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject); extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -263,6 +289,7 @@ namespace MWScript
interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid); interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid);
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater); interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject); interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject);
interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode);
} }
} }
} }

@ -11,7 +11,7 @@
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
#include "../mwbase/world.hpp" // FIXME //#include "../mwbase/world.hpp" // FIXME
#include "ptr.hpp" #include "ptr.hpp"
#include "class.hpp" #include "class.hpp"
@ -42,32 +42,38 @@ namespace MWWorld
return mEngine; return mEngine;
} }
std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world) std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
{ {
std::string handle = ""; btVector3 dir(0, 1, 0);
dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch);
//get a ray pointing to the center of the viewport dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw);
Ray centerRay = mRender.getCamera()->getCameraToViewportRay( dir.setX(-dir.x());
mRender.getViewport()->getWidth()/2,
mRender.getViewport()->getHeight()/2); btVector3 origin(
//let's avoid the capsule shape of the player. mPlayerData.eyepos.x,
centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection()); mPlayerData.eyepos.y,
btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y); mPlayerData.eyepos.z);
btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y); origin += dir * 5;
return mEngine->rayTest(from,to); btVector3 dest = origin + dir * 500;
return mEngine->rayTest(origin, dest);
} }
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects () std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects ()
{ {
//get a ray pointing to the center of the viewport btVector3 dir(0, 1, 0);
Ray centerRay = mRender.getCamera()->getCameraToViewportRay( dir = dir.rotate(btVector3(1, 0, 0), mPlayerData.pitch);
mRender.getViewport()->getWidth()/2, dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw);
mRender.getViewport()->getHeight()/2); dir.setX(-dir.x());
btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y);
btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y); btVector3 origin(
mPlayerData.eyepos.x,
return mEngine->rayTest2(from,to); mPlayerData.eyepos.y,
mPlayerData.eyepos.z);
origin += dir * 5;
btVector3 dest = origin + dir * 500;
return mEngine->rayTest2(origin, dest);
} }
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects (float mouseX, float mouseY) std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects (float mouseX, float mouseY)
@ -172,7 +178,7 @@ namespace MWWorld
OEngine::Physic::PhysicActor* act = it->second; OEngine::Physic::PhysicActor* act = it->second;
act->setWalkDirection(btVector3(0,0,0)); act->setWalkDirection(btVector3(0,0,0));
} }
playerMove::playercmd& pm_ref = playerphysics->cmd; playerMove::playercmd& pm_ref = playerphysics->cmd;
pm_ref.rightmove = 0; pm_ref.rightmove = 0;
pm_ref.forwardmove = 0; pm_ref.forwardmove = 0;
@ -183,35 +189,18 @@ namespace MWWorld
iter!=actors.end(); ++iter) iter!=actors.end(); ++iter)
{ {
//dirty stuff to get the camera orientation. Must be changed! //dirty stuff to get the camera orientation. Must be changed!
if (iter->first == "player") {
playerphysics->ps.viewangles.x =
Ogre::Radian(mPlayerData.pitch).valueDegrees();
Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first); playerphysics->ps.viewangles.y =
Ogre::Vector3 dir; Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90;
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
Ogre::Quaternion yawQuat = yawNode->getOrientation();
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -iter->second.x;
pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = iter->second.z;
pm_ref.rightmove = -iter->second.x;
pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = iter->second.z;
}
} }
mEngine->stepSimulation(dt); mEngine->stepSimulation(dt);
} }
@ -402,4 +391,11 @@ namespace MWWorld
return true; return true;
} }
void PhysicsSystem::updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw)
{
mPlayerData.eyepos = eyepos;
mPlayerData.pitch = pitch;
mPlayerData.yaw = yaw;
}
} }

@ -70,7 +70,14 @@ namespace MWWorld
bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max); bool getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max);
void updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw);
private: private:
struct {
Ogre::Vector3 eyepos;
float pitch, yaw;
} mPlayerData;
OEngine::Render::OgreRenderer &mRender; OEngine::Render::OgreRenderer &mRender;
OEngine::Physic::PhysicEngine* mEngine; OEngine::Physic::PhysicEngine* mEngine;
bool mFreeFly; bool mFreeFly;
@ -80,7 +87,6 @@ namespace MWWorld
PhysicsSystem (const PhysicsSystem&); PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&);
}; };
} }
#endif #endif

@ -806,6 +806,11 @@ namespace MWWorld
/// \todo split this function up into subfunctions /// \todo split this function up into subfunctions
mWorldScene->update (duration); mWorldScene->update (duration);
float pitch, yaw;
Ogre::Vector3 eyepos;
mRendering->getPlayerData(eyepos, pitch, yaw);
mPhysics->updatePlayerData(eyepos, pitch, yaw);
mWeatherManager->update (duration); mWeatherManager->update (duration);
@ -1152,4 +1157,8 @@ namespace MWWorld
return pos.z < cell.water; return pos.z < cell.water;
} }
void World::renderPlayer()
{
mRendering->renderPlayer(mPlayer->getPlayer());
}
} }

@ -277,6 +277,31 @@ namespace MWWorld
virtual bool isSwimming(const MWWorld::Ptr &object); virtual bool isSwimming(const MWWorld::Ptr &object);
virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos); virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos);
virtual void togglePOV() {
mRendering->togglePOV();
}
virtual void togglePreviewMode(bool enable) {
mRendering->togglePreviewMode(enable);
}
virtual bool toggleVanityMode(bool enable, bool force) {
return mRendering->toggleVanityMode(enable, force);
}
virtual void allowVanityMode(bool allow) {
mRendering->allowVanityMode(allow);
}
virtual void togglePlayerLooking(bool enable) {
mRendering->togglePlayerLooking(enable);
}
virtual void renderPlayer();
virtual bool isVanityEnabled() {
return mRendering->isVanityEnabled();
}
}; };
} }

@ -6,7 +6,11 @@
namespace Files { namespace Files {
bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) { bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) {
// Append plugin suffix if debugging.
#if defined(DEBUG)
pluginName = pluginName + OGRE_PLUGIN_DEBUG_SUFFIX; pluginName = pluginName + OGRE_PLUGIN_DEBUG_SUFFIX;
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
std::ostringstream verStream; std::ostringstream verStream;
verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH; verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH;

@ -471,7 +471,7 @@ static Ogre::String getMaterial(const NiTriShape *shape, const Ogre::String &nam
float glossiness = 0.0f; float glossiness = 0.0f;
float alpha = 1.0f; float alpha = 1.0f;
int alphaFlags = -1; int alphaFlags = -1;
ubyte alphaTest = 0; // ubyte alphaTest = 0;
Ogre::String texName; Ogre::String texName;
bool vertexColour = (shape->data->colors.size() != 0); bool vertexColour = (shape->data->colors.size() != 0);
@ -523,7 +523,7 @@ static Ogre::String getMaterial(const NiTriShape *shape, const Ogre::String &nam
if (a) if (a)
{ {
alphaFlags = a->flags; alphaFlags = a->flags;
alphaTest = a->data.threshold; // alphaTest = a->data.threshold;
} }
// Material // Material

@ -35,7 +35,7 @@ Sylvain T. (Garvek)
Packagers: Packagers:
Alexander Olofsson (Ace) - Windows Alexander Olofsson (Ace) - Windows
BrotherBrick - Ubuntu Linux BrotherBrick - Ubuntu Linux
edmundo - Gentoo Linux Edmondo Tommasina - Gentoo Linux
Kenny Armstrong (artorius) - Fedora Linux Kenny Armstrong (artorius) - Fedora Linux
Nikolay Kasyanov (corristo) - Mac OS X Nikolay Kasyanov (corristo) - Mac OS X
Sandy Carter (bwrsandman) - Arch Linux Sandy Carter (bwrsandman) - Arch Linux

@ -97,8 +97,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
const btVector3 btstart(start.x, start.y, start.z); const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.z);
const btVector3 btend(end.x, end.y, end.z); const btVector3 btend(end.x, end.y, end.z + BBHalfExtents.z);
const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));

@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind
OpenMW is an attempt at recreating the engine for the popular role-playing game OpenMW is an attempt at recreating the engine for the popular role-playing game
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
Version: 0.16.0 Version: 0.17.0
License: GPL (see GPL3.txt for more information) License: GPL (see GPL3.txt for more information)
Website: http://www.openmw.org Website: http://www.openmw.org
@ -97,6 +97,37 @@ Allowed options:
CHANGELOG CHANGELOG
0.17.0
Bug #225: Valgrind reports about 40MB of leaked memory
Bug #241: Some physics meshes still don't match
Bug #248: Some textures are too dark
Bug #300: Dependency on proprietary CG toolkit
Bug #302: Some objects don't collide although they should
Bug #308: Freeze in Balmora, Meldor: Armorer
Bug #313: openmw without a ~/.config/openmw folder segfault.
Bug #317: adding non-existing spell via console locks game
Bug #318: Wrong character normals
Bug #341: Building with Ogre Debug libraries does not use debug version of plugins
Bug #347: Crash when running openmw with --start="XYZ"
Bug #353: FindMyGUI.cmake breaks path on Windows
Bug #359: WindowManager throws exception at destruction
Feature #33: Allow objects to cross cell-borders
Feature #59: Dropping Items (replaced stopgap implementation with a proper one)
Feature #93: Main Menu
Feature #96/329/330/331/332/333: Player Control
Feature #180: Object rotation and scaling.
Feature #272: Incorrect NIF material sharing
Feature #314: Potion usage
Feature #324: Skill Gain
Feature #342: Drain/fortify dynamic stats/attributes magic effects
Feature #350: Allow console only script instructions
Feature #352: Run scripts in console on startup
Task #107: Refactor mw*-subsystems
Task #325: Make CreatureStats into a class
Task #345: Use Ogre's animation system
Task #351: Rewrite Action class to support automatic sound playing
0.16.0 0.16.0
Bug #250: OpenMW launcher erratic behaviour Bug #250: OpenMW launcher erratic behaviour

Loading…
Cancel
Save