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
set (OPENMW_VERSION_MAJOR 0)
set (OPENMW_VERSION_MINOR 16)
set (OPENMW_VERSION_MINOR 17)
set (OPENMW_VERSION_RELEASE 0)
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)
endif (APPLE)
# Set up DEBUG define
set_directory_properties(PROPERTIES COMPILE_DEFINITIONS_DEBUG DEBUG=1)
# Set up Ogre plugin folder & debug suffix
# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt)
if (DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE)
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
else()
if (APPLE)
# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt)
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="")
else ()
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
endif()
add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}")

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

@ -356,6 +356,8 @@ void OMW::Engine::go()
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
pos.pos[2] = 0;
mEnvironment.getWorld()->renderPlayer();
if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName))
{
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 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 ();
size_t windowHnd;
resetIdleTime();
window->getCustomAttribute("WINDOW", &windowHnd);
std::ostringstream windowHndStr;
@ -141,6 +143,8 @@ namespace MWInput
if (mDragDrop)
return;
resetIdleTime ();
int action = channel->getNumber();
if (currentValue == 1)
{
@ -245,6 +249,46 @@ namespace MWInput
mPlayer.setUpDown (-1);
else
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;
}
void InputManager::resetIdleTime ()
{
if (mTimeIdle < 0) {
MWBase::Environment::get().getWorld()->toggleVanityMode(false, false);
}
mTimeIdle = 0.f;
}
void InputManager::adjustMouseRegion(int width, int height)
{
const OIS::MouseState &ms = mMouse->getMouseState();
@ -372,6 +424,8 @@ namespace MWInput
{
mInputCtrl->mouseMoved (arg);
resetIdleTime ();
if (mGuiCursorEnabled)
{
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
@ -539,6 +593,7 @@ namespace MWInput
defaultKeyBindings[A_Journal] = OIS::KC_J;
defaultKeyBindings[A_Rest] = OIS::KC_T;
defaultKeyBindings[A_GameMenu] = OIS::KC_ESCAPE;
defaultKeyBindings[A_TogglePOV] = OIS::KC_TAB;
std::map<int, int> defaultMouseButtonBindings;
defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right;
@ -588,6 +643,7 @@ namespace MWInput
descriptions[A_Journal] = "sJournal";
descriptions[A_Rest] = "sRestKey";
descriptions[A_Inventory] = "sInventory";
descriptions[A_TogglePOV] = "sTogglePOVCmd";
if (descriptions[action] == "")
return ""; // not configurable
@ -617,6 +673,7 @@ namespace MWInput
ret.push_back(A_MoveBackward);
ret.push_back(A_MoveLeft);
ret.push_back(A_MoveRight);
ret.push_back(A_TogglePOV);
ret.push_back(A_Crouch);
ret.push_back(A_Activate);
ret.push_back(A_ToggleWeapon);
@ -708,5 +765,4 @@ namespace MWInput
{
loadKeyDefaults(true);
}
}

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

@ -4,104 +4,359 @@
#include <OgreCamera.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/refdata.hpp"
#include "npcanimation.hpp"
namespace MWRender
{
Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node)
: mCamera (camera),
mNode (node),
: mCamera(camera),
mPlayerNode(node),
mCameraNode(mPlayerNode->createChildSceneNode()),
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;
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
if (mVanity.enabled) {
toggleVanityMode(false);
}
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
Ogre::Radian radx(rot.x);
if (radx.valueDegrees() > 89.5f) {
radx = Ogre::Degree(89.5f);
} else if (radx.valueDegrees() < -89.5f) {
radx = Ogre::Degree(-89.5f);
compensateYaw(diff);
}
trueRot.z = 0.f;
}
Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X);
// Rotate around Y axis
Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y);
if (mFreeLook || mVanity.enabled || mPreviewMode) {
rotateCamera(trueRot, adjust);
}
pitchNode->setOrientation(xr);
yawNode->setOrientation(yr);
/// \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();
return !mVanityModeEnabled;
}
std::string Player::getHandle() const
{
return mNode->getName();
return mPlayerNode->getName();
}
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();
Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode();
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;
}
float f = controlFlip(Ogre::Radian(rot.x).valueDegrees());
if (f != 0.0) {
pitchNode->pitch(Ogre::Degree(f));
bool Player::toggleVanityMode(bool enable, bool force)
{
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();
Ogre::Quaternion orient = pitchNode->getOrientation();
if (mPreviewMode == enable) {
return;
}
mPreviewMode = enable;
float offset = mCamera->getPosition().z;
if (mPreviewMode) {
mMainCam.offset = offset;
offset = mPreviewCam.offset;
float pitchAngle =
(2 * Ogre::Degree(Ogre::Math::ASin(orient.x)).valueDegrees());
mPlayerNode->setVisible(true, false);
setLowHeight(true);
} else {
mPreviewCam.offset = offset;
offset = mMainCam.offset;
if (pitchAngle + shift < 89.5f && pitchAngle + shift > -89.5f) {
return shift;
mPlayerNode->setVisible(!mFirstPersonView, false);
setLowHeight(!mFirstPersonView);
}
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;
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 0.f;
return mMainCam.yaw;
}
void Player::updateListener()
void Player::setYaw(float angle)
{
Ogre::Vector3 pos = mCamera->getRealPosition();
Ogre::Vector3 dir = mCamera->getRealDirection();
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;
}
}
Ogre::Real xch;
xch = pos.y, pos.y = -pos.z, pos.z = xch;
xch = dir.y, dir.y = -dir.z, dir.z = xch;
float Player::getPitch()
{
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>
namespace Ogre
{
{
class Vector3;
class Camera;
class SceneNode;
@ -18,20 +17,49 @@ namespace MWWorld
namespace MWRender
{
class NpcAnimation;
/// \brief Player character rendering and camera control
class Player
{
struct CamData {
float pitch, yaw, offset;
};
Ogre::Camera *mCamera;
Ogre::SceneNode* mNode;
Ogre::SceneNode *mPlayerNode;
Ogre::SceneNode *mCameraNode;
NpcAnimation *mAnimation;
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
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:
Player (Ogre::Camera *camera, Ogre::SceneNode* mNode);
@ -39,11 +67,7 @@ namespace MWRender
/// Set where the player is looking at. Uses Morrowind (euler) angles
/// \param rot Rotation angles in radians
/// \return true if player object needs to bo rotated physically
bool setRotation(const Ogre::Vector3 &rot);
/// \param rot Rotation angles in radians
/// \return true if player object needs to bo rotated physically
bool adjustRotation(const Ogre::Vector3 &rot);
bool rotate(const Ogre::Vector3 &rot, bool adjust);
std::string getHandle() const;
@ -52,12 +76,40 @@ namespace MWRender
/// several different objects
void attachTo(const MWWorld::Ptr &);
void toggleViewMode() {
mFirstPersonView = !mFirstPersonView;
}
void toggleViewMode();
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() {
mVanityModeEnabled = !mVanityModeEnabled;
bool isVanityEnabled() {
return mVanity.enabled;
}
};
}

@ -33,6 +33,7 @@
#include "localmap.hpp"
#include "water.hpp"
#include "compositors.hpp"
#include "npcanimation.hpp"
using namespace MWRender;
using namespace Ogre;
@ -40,7 +41,7 @@ using namespace Ogre;
namespace MWRender {
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
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();
mMwRoot = rt->createChildSceneNode();
mMwRoot->pitch(Degree(-90));
mObjects.setMwRoot(mMwRoot);
mActors.setMwRoot(mMwRoot);
Ogre::SceneNode *playerNode = mMwRoot->createChildSceneNode ("player");
playerNode->pitch(Degree(90));
Ogre::SceneNode *cameraYawNode = playerNode->createChildSceneNode();
Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode();
cameraPitchNode->attachObject(mRendering.getCamera());
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mShadows = new Shadows(&mRendering);
@ -147,7 +146,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode());
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mSun = 0;
mDebugging = new Debugging(mMwRoot, engine);
@ -259,11 +257,7 @@ RenderingManager::rotateObject(
bool force = true;
if (isPlayer) {
if (adjust) {
force = mPlayer->adjustRotation(rot);
} else {
force = mPlayer->setRotation(rot);
}
force = mPlayer->rotate(rot, adjust);
}
MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z);
@ -302,7 +296,22 @@ RenderingManager::moveObjectToCell(
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);
mObjects.update (duration);
@ -315,7 +324,23 @@ void RenderingManager::update (float 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) {
Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition();
@ -820,4 +845,22 @@ void RenderingManager::attachCameraTo(const MWWorld::Ptr &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

@ -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);
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 renderPlayer(const MWWorld::Ptr &ptr);
SkyManager* getSkyManager();
Compositors* getCompositors();

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

@ -32,7 +32,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
mIsUnderwater(false), mVisibilityFlags(0),
mReflectionTarget(0), mActive(1), mToggled(1),
mReflectionRenderActive(false), mRendering(rend),
mOldFarClip(0), mOldFarClip2(0),
mWaterTimer(0.f)
{
mSky = rend->getSkyManager();
@ -207,6 +206,7 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
{
if (evt.source == mReflectionTarget)
{
mCamera->getParentSceneNode ()->needUpdate ();
mReflectionCamera->setOrientation(mCamera->getDerivedOrientation());
mReflectionCamera->setPosition(mCamera->getDerivedPosition());
mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance());
@ -215,11 +215,9 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
mReflectionCamera->setFOVy(mCamera->getFOVy());
mReflectionRenderActive = true;
/// \todo the reflection render (and probably all renderingmanager-updates) lag behind 1 camera frame for some reason
Vector3 pos = mCamera->getRealPosition();
pos.y = mTop*2 - pos.y;
mSky->setSkyPosition(pos);
mSky->scaleSky(mCamera->getFarClipDistance() / 50.f);
mReflectionCamera->enableReflection(mWaterPlane);
}
}
@ -229,7 +227,6 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt)
if (evt.source == mReflectionTarget)
{
mSky->resetSkyPosition();
mSky->scaleSky(1);
mReflectionCamera->disableReflection();
mReflectionCamera->disableCustomNearClipPlane();
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)
if (queueGroupId < 20 && mReflectionRenderActive)
{
mOldFarClip = mReflectionCamera->getFarClipDistance ();
mReflectionCamera->disableCustomNearClipPlane();
mReflectionCamera->setFarClipDistance (1000000000);
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)
{
if (queueGroupId < 20 && mReflectionRenderActive)
{
mReflectionCamera->setFarClipDistance (mOldFarClip);
if (!mIsUnderwater)
mReflectionCamera->enableCustomNearClipPlane(mErrorPlane);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
}
if (queueGroupId == RQG_UnderWater)
{
/*
mCamera->setFarClipDistance (mOldFarClip2);
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
*/}
}
void Water::update(float dt)

@ -50,9 +50,6 @@ namespace MWRender {
bool mToggled;
int mTop;
int mOldFarClip;
int mOldFarClip2;
float mWaterTimer;
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 0x2000172: GetStartingAngle
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 opcodeOnActivate = 0x200000d;
const int opcodeActivate = 0x2000075;
@ -222,6 +245,7 @@ namespace MWScript
const int opcodeToggleWater = 0x2000144;
const int opcodeTogglePathgrid = 0x2000146;
const int opcodeDontSaveObject = 0x2000153;
const int opcodeToggleVanityMode = 0x2000174;
void registerExtensions (Compiler::Extensions& extensions)
{
@ -244,6 +268,8 @@ namespace MWScript
extensions.registerInstruction ("togglepathgrid", "", opcodeTogglePathgrid);
extensions.registerInstruction ("tpg", "", opcodeTogglePathgrid);
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
@ -263,6 +289,7 @@ namespace MWScript
interpreter.installSegment5 (opcodeTogglePathgrid, new OpTogglePathgrid);
interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater);
interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject);
interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode);
}
}
}

@ -11,7 +11,7 @@
#include <components/nifbullet/bullet_nif_loader.hpp>
#include "../mwbase/world.hpp" // FIXME
//#include "../mwbase/world.hpp" // FIXME
#include "ptr.hpp"
#include "class.hpp"
@ -42,32 +42,38 @@ namespace MWWorld
return mEngine;
}
std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
{
std::string handle = "";
//get a ray pointing to the center of the viewport
Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
mRender.getViewport()->getWidth()/2,
mRender.getViewport()->getHeight()/2);
//let's avoid the capsule shape of the player.
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);
std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
{
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());
btVector3 origin(
mPlayerData.eyepos.x,
mPlayerData.eyepos.y,
mPlayerData.eyepos.z);
origin += dir * 5;
btVector3 dest = origin + dir * 500;
return mEngine->rayTest(origin, dest);
}
std::vector < std::pair <float, std::string> > PhysicsSystem::getFacedObjects ()
{
//get a ray pointing to the center of the viewport
Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
mRender.getViewport()->getWidth()/2,
mRender.getViewport()->getHeight()/2);
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 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());
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)
@ -172,7 +178,7 @@ namespace MWWorld
OEngine::Physic::PhysicActor* act = it->second;
act->setWalkDirection(btVector3(0,0,0));
}
playerMove::playercmd& pm_ref = playerphysics->cmd;
playerMove::playercmd& pm_ref = playerphysics->cmd;
pm_ref.rightmove = 0;
pm_ref.forwardmove = 0;
@ -183,35 +189,18 @@ namespace MWWorld
iter!=actors.end(); ++iter)
{
//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);
Ogre::Vector3 dir;
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;
playerphysics->ps.viewangles.y =
Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90;
pm_ref.rightmove = -iter->second.x;
pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = iter->second.z;
}
}
mEngine->stepSimulation(dt);
}
@ -402,4 +391,11 @@ namespace MWWorld
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);
void updatePlayerData(Ogre::Vector3 &eyepos, float pitch, float yaw);
private:
struct {
Ogre::Vector3 eyepos;
float pitch, yaw;
} mPlayerData;
OEngine::Render::OgreRenderer &mRender;
OEngine::Physic::PhysicEngine* mEngine;
bool mFreeFly;
@ -80,7 +87,6 @@ namespace MWWorld
PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&);
};
}
#endif

@ -806,6 +806,11 @@ namespace MWWorld
/// \todo split this function up into subfunctions
mWorldScene->update (duration);
float pitch, yaw;
Ogre::Vector3 eyepos;
mRendering->getPlayerData(eyepos, pitch, yaw);
mPhysics->updatePlayerData(eyepos, pitch, yaw);
mWeatherManager->update (duration);
@ -1152,4 +1157,8 @@ namespace MWWorld
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 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 {
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;
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
std::ostringstream verStream;
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 alpha = 1.0f;
int alphaFlags = -1;
ubyte alphaTest = 0;
// ubyte alphaTest = 0;
Ogre::String texName;
bool vertexColour = (shape->data->colors.size() != 0);
@ -523,7 +523,7 @@ static Ogre::String getMaterial(const NiTriShape *shape, const Ogre::String &nam
if (a)
{
alphaFlags = a->flags;
alphaTest = a->data.threshold;
// alphaTest = a->data.threshold;
}
// Material

@ -35,7 +35,7 @@ Sylvain T. (Garvek)
Packagers:
Alexander Olofsson (Ace) - Windows
BrotherBrick - Ubuntu Linux
edmundo - Gentoo Linux
Edmondo Tommasina - Gentoo Linux
Kenny Armstrong (artorius) - Fedora Linux
Nikolay Kasyanov (corristo) - Mac OS X
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 btend(end.x, end.y, end.z);
const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.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 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
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)
Website: http://www.openmw.org
@ -97,6 +97,37 @@ Allowed options:
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
Bug #250: OpenMW launcher erratic behaviour

Loading…
Cancel
Save