mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-04 03:40:14 +00:00
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:
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,93 +4,102 @@
|
||||
#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)
|
||||
{}
|
||||
|
||||
bool Player::setRotation(const Ogre::Vector3 &rot)
|
||||
mPreviewMode(false),
|
||||
mFreeLook(true),
|
||||
mHeight(128.f),
|
||||
mCameraDistance(300.f),
|
||||
mDistanceAdjusted(false)
|
||||
{
|
||||
Ogre::SceneNode *sceneNode = mNode;
|
||||
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
|
||||
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
|
||||
mVanity.enabled = false;
|
||||
mVanity.allowed = true;
|
||||
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
|
||||
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);
|
||||
mPreviewCam.yaw = 0.f;
|
||||
mPreviewCam.offset = 400.f;
|
||||
}
|
||||
|
||||
bool Player::rotate(const Ogre::Vector3 &rot, bool adjust)
|
||||
{
|
||||
if (mVanity.enabled) {
|
||||
toggleVanityMode(false);
|
||||
}
|
||||
Ogre::Quaternion xr(radx, Ogre::Vector3::UNIT_X);
|
||||
|
||||
// Rotate around Y axis
|
||||
Ogre::Quaternion yr(Ogre::Radian(-rot.z), Ogre::Vector3::UNIT_Y);
|
||||
Ogre::Vector3 trueRot = rot;
|
||||
|
||||
pitchNode->setOrientation(xr);
|
||||
yawNode->setOrientation(yr);
|
||||
/// \note rotate player on forced vanity
|
||||
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();
|
||||
|
||||
return !mVanityModeEnabled;
|
||||
}
|
||||
|
||||
std::string Player::getHandle() const
|
||||
{
|
||||
return mNode->getName();
|
||||
return mPlayerNode->getName();
|
||||
}
|
||||
|
||||
void Player::attachTo(const MWWorld::Ptr &ptr)
|
||||
{
|
||||
ptr.getRefData().setBaseNode(mNode);
|
||||
}
|
||||
|
||||
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;
|
||||
ptr.getRefData().setBaseNode(mPlayerNode);
|
||||
}
|
||||
|
||||
void Player::updateListener()
|
||||
@ -104,4 +113,250 @@ namespace MWRender
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Vector3;
|
||||
@ -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;
|
||||
|
||||
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
|
||||
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();
|
||||
|
||||
void toggleVanityMode() {
|
||||
mVanityModeEnabled = !mVanityModeEnabled;
|
||||
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);
|
||||
|
||||
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 = "";
|
||||
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());
|
||||
|
||||
//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);
|
||||
btVector3 origin(
|
||||
mPlayerData.eyepos.x,
|
||||
mPlayerData.eyepos.y,
|
||||
mPlayerData.eyepos.z);
|
||||
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 ()
|
||||
{
|
||||
//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);
|
||||
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());
|
||||
|
||||
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)
|
||||
@ -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
|
||||
|
@ -807,6 +807,11 @@ namespace MWWorld
|
||||
|
||||
mWorldScene->update (duration);
|
||||
|
||||
float pitch, yaw;
|
||||
Ogre::Vector3 eyepos;
|
||||
mRendering->getPlayerData(eyepos, pitch, yaw);
|
||||
mPhysics->updatePlayerData(eyepos, pitch, yaw);
|
||||
|
||||
mWeatherManager->update (duration);
|
||||
|
||||
// inform the GUI about focused object
|
||||
@ -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));
|
||||
|
33
readme.txt
33
readme.txt
@ -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…
x
Reference in New Issue
Block a user