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
This commit is contained in:
scrawl 2012-08-19 22:09:22 +02:00
commit 19ae30ee68
25 changed files with 712 additions and 180 deletions

View file

@ -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}")

View file

@ -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

View file

@ -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,

View file

@ -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;
}; };
} }

View file

@ -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);
} }
} }

View file

@ -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

View file

@ -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);

View file

@ -4,93 +4,102 @@
#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),
bool Player::setRotation(const Ogre::Vector3 &rot) mCameraDistance(300.f),
mDistanceAdjusted(false)
{ {
Ogre::SceneNode *sceneNode = mNode; mVanity.enabled = false;
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); mVanity.allowed = true;
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); mVanity.forced = false;
// we are only interested in X and Y rotation mCameraNode->attachObject(mCamera);
mCameraNode->setPosition(0.f, 0.f, mHeight);
// Rotate around X axis mPreviewCam.yaw = 0.f;
Ogre::Radian radx(rot.x); mPreviewCam.offset = 400.f;
if (radx.valueDegrees() > 89.5f) { }
radx = Ogre::Degree(89.5f);
} else if (radx.valueDegrees() < -89.5f) { bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
radx = Ogre::Degree(-89.5f); {
if (mVanity.enabled) {
toggleVanityMode(false);
} }
Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X);
// Rotate around Y axis Ogre::Vector3 trueRot = rot;
Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y);
pitchNode->setOrientation(xr); /// \note rotate player on forced vanity
yawNode->setOrientation(yr); if (mVanity.forced) {
if (mFreeLook) {
float diff = (adjust) ? rot.z : mMainCam.yaw - rot.z;
mVanity.enabled = false;
rotateCamera(rot, adjust);
mVanity.enabled = true;
compensateYaw(diff);
}
trueRot.z = 0.f;
}
if (mFreeLook || mVanity.enabled || mPreviewMode) {
rotateCamera(trueRot, adjust);
}
/// \note if vanity mode is forced by TVM then rotate player
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);
}
bool Player::adjustRotation(const Ogre::Vector3 &rot)
{
Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode();
Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode();
float f = controlFlip(Ogre::Radian(rot.x).valueDegrees());
if (f != 0.0) {
pitchNode->pitch(Ogre::Degree(f));
}
yawNode->yaw(Ogre::Radian(-rot.z));
updateListener();
return !mVanityModeEnabled;
}
float Player::controlFlip(float shift)
{
Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode();
Ogre::Quaternion orient = pitchNode->getOrientation();
float pitchAngle =
(2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees());
if (pitchAngle + shift < 89.5f && pitchAngle + shift > -89.5f) {
return shift;
}
if (pitchAngle > 0) {
float f = 89.5f - pitchAngle - shift;
return (f > 0.f) ? f : 0.f;
} else if (pitchAngle < 0) {
float f = -89.5 - pitchAngle - shift;
return (f < 0.f) ? f : 0.f;
}
return 0.f;
} }
void Player::updateListener() void Player::updateListener()
@ -104,4 +113,250 @@ namespace MWRender
MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir); 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);
}
}
void Player::toggleViewMode()
{
mFirstPersonView = !mFirstPersonView;
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;
}
bool Player::toggleVanityMode(bool enable, bool force)
{
if ((mVanity.forced && !force) ||
(!mVanity.allowed && (force || enable)))
{
return false;
} else if (mVanity.enabled == enable) {
return true;
}
mVanity.enabled = enable;
mVanity.forced = force && enable;
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;
mPlayerNode->setVisible(!mFirstPersonView, false);
setLowHeight(!mFirstPersonView);
}
rot.z = getYaw();
mCamera->setPosition(0.f, 0.f, offset);
rotateCamera(rot, false);
return true;
}
void Player::togglePreviewMode(bool enable)
{
if (mPreviewMode == enable) {
return;
}
mPreviewMode = enable;
float offset = mCamera->getPosition().z;
if (mPreviewMode) {
mMainCam.offset = offset;
offset = mPreviewCam.offset;
mPlayerNode->setVisible(true, false);
setLowHeight(true);
} else {
mPreviewCam.offset = offset;
offset = mMainCam.offset;
mPlayerNode->setVisible(!mFirstPersonView, false);
setLowHeight(!mFirstPersonView);
}
mCamera->setPosition(0.f, 0.f, offset);
rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
}
float Player::getYaw()
{
if (mVanity.enabled || mPreviewMode) {
return mPreviewCam.yaw;
}
return mMainCam.yaw;
}
void Player::setYaw(float angle)
{
if (angle > Ogre::Math::PI) {
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;
}
}
float Player::getPitch()
{
if (mVanity.enabled || mPreviewMode) {
return mPreviewCam.pitch;
}
return mMainCam.pitch;
}
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);
}
}
} }

View file

@ -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;
float controlFlip(float shift = 0.f); struct {
bool enabled, allowed, forced;
} mVanity;
float mHeight, mCameraDistance;
CamData mMainCam, mPreviewCam;
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;
}
void toggleVanityMode() { bool toggleVanityMode(bool enable, bool force = false);
mVanityModeEnabled = !mVanityModeEnabled; 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);
bool isVanityEnabled() {
return mVanity.enabled;
} }
}; };
} }

View file

@ -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

View file

@ -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();

View file

@ -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)

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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);
} }
} }
} }

View file

@ -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);
dir = dir.rotate(btVector3(0, 0, 1), mPlayerData.yaw);
dir.setX(-dir.x());
//get a ray pointing to the center of the viewport btVector3 origin(
Ray centerRay = mRender.getCamera()->getCameraToViewportRay( mPlayerData.eyepos.x,
mRender.getViewport()->getWidth()/2, mPlayerData.eyepos.y,
mRender.getViewport()->getHeight()/2); mPlayerData.eyepos.z);
//let's avoid the capsule shape of the player. origin += dir * 5;
centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection());
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);
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);
return mEngine->rayTest2(from,to); btVector3 origin(
mPlayerData.eyepos.x,
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;
}
} }

View file

@ -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

View file

@ -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());
}
} }

View file

@ -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();
}
}; };
} }

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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));

View file

@ -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