Merge branch 'next' of https://github.com/zinnschlag/openmw into globalmap

This commit is contained in:
scrawl 2012-09-20 17:41:14 +02:00
commit 8214966d44
55 changed files with 1173 additions and 346 deletions

View file

@ -29,7 +29,7 @@ add_openmw_dir (mwgui
map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list
formatting inventorywindow container hud countdialog tradewindow settingswindow formatting inventorywindow container hud countdialog tradewindow settingswindow
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue

View file

@ -222,6 +222,8 @@ namespace MWBase
virtual void enableRest() = 0; virtual void enableRest() = 0;
virtual bool getRestEnabled() = 0; virtual bool getRestEnabled() = 0;
virtual bool getPlayerSleeping() = 0;
}; };
} }

View file

@ -160,6 +160,9 @@ namespace MWBase
virtual void setDay (int day) = 0; virtual void setDay (int day) = 0;
///< Set in-game time day. ///< Set in-game time day.
virtual int getDay() = 0;
virtual int getMonth() = 0;
virtual MWWorld::TimeStamp getTimeStamp() const = 0; virtual MWWorld::TimeStamp getTimeStamp() const = 0;
///< Return current in-game time stamp. ///< Return current in-game time stamp.
@ -282,6 +285,13 @@ namespace MWBase
virtual void renderGlobalMap() = 0; virtual void renderGlobalMap() = 0;
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
virtual int canRest() = 0;
///< check if the player is allowed to rest \n
/// 0 - yes \n
/// 1 - only waiting \n
/// 2 - player is underwater \n
/// 3 - enemies are nearby (not implemented)
}; };
} }

View file

@ -141,6 +141,7 @@ namespace MWClass
assert(ref->base != NULL); assert(ref->base != NULL);
std::string headID = ref->base->head; std::string headID = ref->base->head;
int end = headID.find_last_of("head_") - 4; int end = headID.find_last_of("head_") - 4;
std::string bodyRaceID = headID.substr(0, end); std::string bodyRaceID = headID.substr(0, end);
@ -153,6 +154,7 @@ namespace MWClass
model = "meshes\\base_animkna.nif"; model = "meshes\\base_animkna.nif";
} }
return model; return model;
} }
std::string Npc::getName (const MWWorld::Ptr& ptr) const std::string Npc::getName (const MWWorld::Ptr& ptr) const
@ -297,7 +299,7 @@ namespace MWClass
{ {
Ogre::Vector3 vector (0, 0, 0); Ogre::Vector3 vector (0, 0, 0);
vector.x = - getMovementSettings (ptr).mLeftRight * 127; vector.x = getMovementSettings (ptr).mLeftRight * 127;
vector.y = getMovementSettings (ptr).mForwardBackward * 127; vector.y = getMovementSettings (ptr).mForwardBackward * 127;
vector.z = getMovementSettings(ptr).mUpDown * 127; vector.z = getMovementSettings(ptr).mUpDown * 127;

View file

@ -173,7 +173,7 @@ namespace MWGui
creatureStats.setLevel (creatureStats.getLevel()+1); creatureStats.setLevel (creatureStats.getLevel()+1);
pcStats.levelUp (); pcStats.levelUp ();
mWindowManager.removeGuiMode (GM_Rest); mWindowManager.removeGuiMode (GM_Levelup);
} }
} }

View file

@ -20,6 +20,7 @@ namespace MWGui
GM_Dialogue, // NPC interaction GM_Dialogue, // NPC interaction
GM_Barter, GM_Barter,
GM_Rest, GM_Rest,
GM_RestBed,
GM_SpellBuying, GM_SpellBuying,
GM_Levelup, GM_Levelup,

View file

@ -40,7 +40,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
getWidget(mHeadRotate, "HeadRotate"); getWidget(mHeadRotate, "HeadRotate");
mHeadRotate->setScrollRange(50); mHeadRotate->setScrollRange(50);
mHeadRotate->setScrollPosition(20); mHeadRotate->setScrollPosition(25);
mHeadRotate->setScrollViewPage(10); mHeadRotate->setScrollViewPage(10);
mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate);

View file

@ -122,6 +122,7 @@ namespace MWGui
getWidget(mInvertYButton, "InvertYButton"); getWidget(mInvertYButton, "InvertYButton");
getWidget(mUISensitivitySlider, "UISensitivitySlider"); getWidget(mUISensitivitySlider, "UISensitivitySlider");
getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider");
getWidget(mGammaSlider, "GammaSlider");
mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
@ -143,6 +144,7 @@ namespace MWGui
mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected); mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mGammaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
@ -200,6 +202,14 @@ namespace MWGui
getWidget(fovText, "FovText"); getWidget(fovText, "FovText");
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")"); fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")");
float gammaVal = (Settings::Manager::getFloat("gamma", "Video")-0.1f)/(3.f-0.1f);
mGammaSlider->setScrollPosition(gammaVal * (mGammaSlider->getScrollRange()-1));
MyGUI::TextBox* gammaText;
getWidget(gammaText, "GammaText");
std::stringstream gamma;
gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video");
gammaText->setCaption("Gamma (" + gamma.str() + ")");
float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0; float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0;
mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1)); mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1));
std::string tf = Settings::Manager::getString("texture filtering", "General"); std::string tf = Settings::Manager::getString("texture filtering", "General");
@ -511,6 +521,15 @@ namespace MWGui
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")"); fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")");
Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax); Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax);
} }
else if (scroller == mGammaSlider)
{
Settings::Manager::setFloat("gamma", "Video", (1-val) * 0.1f + val * 3.f);
MyGUI::TextBox* gammaText;
getWidget(gammaText, "GammaText");
std::stringstream gamma;
gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video");
gammaText->setCaption("Gamma (" + gamma.str() + ")");
}
else if (scroller == mAnisotropySlider) else if (scroller == mAnisotropySlider)
{ {
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")"); mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")");

View file

@ -40,6 +40,7 @@ namespace MWGui
MyGUI::Button* mFPSButton; MyGUI::Button* mFPSButton;
MyGUI::ScrollBar* mViewDistanceSlider; MyGUI::ScrollBar* mViewDistanceSlider;
MyGUI::ScrollBar* mFOVSlider; MyGUI::ScrollBar* mFOVSlider;
MyGUI::ScrollBar* mGammaSlider;
MyGUI::ScrollBar* mAnisotropySlider; MyGUI::ScrollBar* mAnisotropySlider;
MyGUI::Button* mTextureFilteringButton; MyGUI::Button* mTextureFilteringButton;
MyGUI::TextBox* mAnisotropyLabel; MyGUI::TextBox* mAnisotropyLabel;

View file

@ -0,0 +1,213 @@
#include "waitdialog.hpp"
#include <boost/lexical_cast.hpp>
#include <libs/openengine/ogre/fader.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/timestamp.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/ptr.hpp"
#include "../mwworld/class.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "widgets.hpp"
namespace MWGui
{
WaitDialogProgressBar::WaitDialogProgressBar(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_wait_dialog_progressbar.layout", parWindowManager)
{
getWidget(mProgressBar, "ProgressBar");
getWidget(mProgressText, "ProgressText");
}
void WaitDialogProgressBar::open()
{
center();
}
void WaitDialogProgressBar::setProgress (int cur, int total)
{
mProgressBar->setProgressRange (total);
mProgressBar->setProgressPosition (cur);
mProgressText->setCaption(boost::lexical_cast<std::string>(cur) + "/" + boost::lexical_cast<std::string>(total));
}
// ---------------------------------------------------------------------------------------------------------
WaitDialog::WaitDialog(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_wait_dialog.layout", parWindowManager)
, mProgressBar(parWindowManager)
, mWaiting(false)
, mSleeping(false)
, mHours(1)
, mRemainingTime(0.05)
{
getWidget(mDateTimeText, "DateTimeText");
getWidget(mRestText, "RestText");
getWidget(mHourText, "HourText");
getWidget(mHourSlider, "HourSlider");
getWidget(mUntilHealedButton, "UntilHealedButton");
getWidget(mWaitButton, "WaitButton");
getWidget(mCancelButton, "CancelButton");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onCancelButtonClicked);
mUntilHealedButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onUntilHealedButtonClicked);
mWaitButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onWaitButtonClicked);
mHourSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &WaitDialog::onHourSliderChangedPosition);
mProgressBar.setVisible (false);
}
void WaitDialog::open()
{
if (!MWBase::Environment::get().getWindowManager ()->getRestEnabled ())
{
mWindowManager.popGuiMode ();
}
int canRest = MWBase::Environment::get().getWorld ()->canRest ();
if (canRest == 2)
{
// resting underwater or mid-air not allowed
mWindowManager.messageBox ("#{sNotifyMessage1}", std::vector<std::string>());
mWindowManager.popGuiMode ();
}
setCanRest(canRest == 0);
onHourSliderChangedPosition(mHourSlider, 0);
mHourSlider->setScrollPosition (0);
// http://www.uesp.net/wiki/Lore:Calendar
std::string month;
int m = MWBase::Environment::get().getWorld ()->getMonth ();
if (m == 0)
month = "#{sMonthMorningstar}";
else if (m == 1)
month = "#{sMonthSunsdawn}";
else if (m == 2)
month = "#{sMonthFirstseed}";
else if (m == 3)
month = "#{sMonthRainshand}";
else if (m == 4)
month = "#{sMonthSecondseed}";
else if (m == 5)
month = "#{sMonthMidyear}";
else if (m == 6)
month = "#{sMonthSunsheight}";
else if (m == 7)
month = "#{sMonthLastseed}";
else if (m == 8)
month = "#{sMonthHeartfire}";
else if (m == 9)
month = "#{sMonthFrostfall}";
else if (m == 10)
month = "#{sMonthSunsdusk}";
else if (m == 11)
month = "#{sMonthEveningstar}";
int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour ();
bool pm = hour >= 12;
if (hour >= 13) hour -= 12;
std::string dateTimeText =
boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getDay ()+1) + " "
+ month + " (#{sDay} " + boost::lexical_cast<std::string>(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay ()+1)
+ ") " + boost::lexical_cast<std::string>(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}");
mDateTimeText->setCaptionWithReplacing (dateTimeText);
}
void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender)
{
startWaiting();
}
void WaitDialog::onWaitButtonClicked(MyGUI::Widget* sender)
{
startWaiting();
}
void WaitDialog::startWaiting ()
{
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.2);
setVisible(false);
mProgressBar.setVisible (true);
mWaiting = true;
mCurHour = 0;
mRemainingTime = 0.05;
mProgressBar.setProgress (0, mHours);
}
void WaitDialog::onCancelButtonClicked(MyGUI::Widget* sender)
{
mWindowManager.popGuiMode ();
}
void WaitDialog::onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position)
{
mHourText->setCaptionWithReplacing (boost::lexical_cast<std::string>(position+1) + " #{sRestMenu2}");
mHours = position+1;
}
void WaitDialog::setCanRest (bool canRest)
{
mUntilHealedButton->setVisible(canRest);
mWaitButton->setCaptionWithReplacing (canRest ? "#{sRest}" : "#{sWait}");
mRestText->setCaptionWithReplacing (canRest ? "#{sRestMenu3}" : "#{sRestIllegal}");
mSleeping = canRest;
dynamic_cast<Widgets::Box*>(mMainWidget)->notifyChildrenSizeChanged();
center();
}
void WaitDialog::onFrame(float dt)
{
if (!mWaiting)
return;
mRemainingTime -= dt;
if (mRemainingTime < 0)
{
mRemainingTime = 0.05;
++mCurHour;
mProgressBar.setProgress (mCurHour, mHours);
if (mCurHour <= mHours)
MWBase::Environment::get().getWorld ()->advanceTime (1);
}
if (mCurHour > mHours)
stopWaiting();
}
void WaitDialog::stopWaiting ()
{
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.2);
mProgressBar.setVisible (false);
mWindowManager.popGuiMode ();
mWaiting = false;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::NpcStats pcstats = MWWorld::Class::get(player).getNpcStats(player);
// trigger levelup if possible
if (mSleeping && pcstats.getLevelProgress () >= 10)
{
mWindowManager.pushGuiMode (GM_Levelup);
}
}
}

View file

@ -0,0 +1,66 @@
#ifndef MWGUI_WAIT_DIALOG_H
#define MWGUI_WAIT_DIALOG_H
#include "window_base.hpp"
namespace MWGui
{
class WaitDialogProgressBar : public WindowBase
{
public:
WaitDialogProgressBar(MWBase::WindowManager& parWindowManager);
virtual void open();
void setProgress(int cur, int total);
protected:
MyGUI::ProgressBar* mProgressBar;
MyGUI::TextBox* mProgressText;
};
class WaitDialog : public WindowBase
{
public:
WaitDialog(MWBase::WindowManager& parWindowManager);
virtual void open();
void onFrame(float dt);
void bedActivated() { setCanRest(true); }
bool getSleeping() { return mWaiting && mSleeping; }
protected:
MyGUI::TextBox* mDateTimeText;
MyGUI::TextBox* mRestText;
MyGUI::TextBox* mHourText;
MyGUI::ScrollBar* mHourSlider;
MyGUI::Button* mUntilHealedButton;
MyGUI::Button* mWaitButton;
MyGUI::Button* mCancelButton;
bool mWaiting;
bool mSleeping;
int mCurHour;
int mHours;
float mRemainingTime;
WaitDialogProgressBar mProgressBar;
void onUntilHealedButtonClicked(MyGUI::Widget* sender);
void onWaitButtonClicked(MyGUI::Widget* sender);
void onCancelButtonClicked(MyGUI::Widget* sender);
void onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position);
void setCanRest(bool canRest);
void startWaiting();
void stopWaiting();
};
}
#endif

View file

@ -795,7 +795,6 @@ void MWDynamicStat::initialiseOverride()
// --------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------------
void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w) void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w)
{ {
if (w->getParent () != 0) if (w->getParent () != 0)
@ -869,29 +868,33 @@ void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::st
Box::Box() Box::Box()
: mSpacing(4) : mSpacing(4)
, mPadding(0)
, mAutoResize(false)
{ {
} }
void Box::setPropertyOverride(const std::string& _key, const std::string& _value)
{
if (_key == "Spacing")
{
mSpacing = MyGUI::utility::parseValue<int>(_value);
}
}
void Box::notifyChildrenSizeChanged () void Box::notifyChildrenSizeChanged ()
{ {
align(); align();
} }
void Box::_setPropertyImpl(const std::string& _key, const std::string& _value)
{
if (_key == "Spacing")
mSpacing = MyGUI::utility::parseValue<int>(_value);
else if (_key == "Padding")
mPadding = MyGUI::utility::parseValue<int>(_value);
else if (_key == "AutoResize")
mAutoResize = MyGUI::utility::parseValue<bool>(_value);
}
void HBox::align () void HBox::align ()
{ {
unsigned int count = getChildCount (); unsigned int count = getChildCount ();
size_t h_stretched_count = 0; size_t h_stretched_count = 0;
int total_width = 0; int total_width = 0;
int total_height = 0;
std::vector< std::pair<MyGUI::IntSize, bool> > sizes; std::vector< std::pair<MyGUI::IntSize, bool> > sizes;
for (unsigned int i = 0; i < count; ++i) for (unsigned int i = 0; i < count; ++i)
@ -904,28 +907,43 @@ void HBox::align ()
{ {
sizes.push_back(std::make_pair(aw->getRequestedSize (), hstretch)); sizes.push_back(std::make_pair(aw->getRequestedSize (), hstretch));
total_width += aw->getRequestedSize ().width; total_width += aw->getRequestedSize ().width;
total_height = std::max(total_height, aw->getRequestedSize ().height);
} }
else else
{ {
if (!hstretch) h_stretched_count ++; sizes.push_back (std::make_pair(w->getSize(), hstretch));
sizes.push_back (std::make_pair(MyGUI::IntSize(0,0), true)); total_width += w->getSize().width;
} }
if (i != count-1) if (i != count-1)
total_width += mSpacing; total_width += mSpacing;
} }
if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height))
{
setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2));
return;
}
int curX = 0; int curX = 0;
for (unsigned int i = 0; i < count; ++i) for (unsigned int i = 0; i < count; ++i)
{ {
if (i == 0)
curX += mPadding;
MyGUI::Widget* w = getChildAt(i); MyGUI::Widget* w = getChildAt(i);
bool vstretch = w->getUserString ("VStretch") == "true";
int height = vstretch ? total_height : sizes[i].first.height;
MyGUI::IntCoord widgetCoord; MyGUI::IntCoord widgetCoord;
widgetCoord.left = curX; widgetCoord.left = curX;
widgetCoord.top = (getSize().height - sizes[i].first.height) / 2; widgetCoord.top = mPadding + (getSize().height-mPadding*2 - height) / 2;
int width = sizes[i].second ? sizes[i].first.width + (getSize().width - total_width)/h_stretched_count int width = sizes[i].second ? sizes[i].first.width + (getSize().width-mPadding*2 - total_width)/h_stretched_count
: sizes[i].first.width; : sizes[i].first.width;
widgetCoord.width = width; widgetCoord.width = width;
widgetCoord.height = sizes[i].first.height; widgetCoord.height = height;
w->setCoord(widgetCoord); w->setCoord(widgetCoord);
curX += width; curX += width;
@ -934,12 +952,33 @@ void HBox::align ()
} }
} }
void HBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
Box::_setPropertyImpl (_key, _value);
}
void HBox::setSize (const MyGUI::IntSize& _value) void HBox::setSize (const MyGUI::IntSize& _value)
{ {
MyGUI::Widget::setSize (_value); MyGUI::Widget::setSize (_value);
align(); align();
} }
void HBox::setCoord (const MyGUI::IntCoord& _value)
{
MyGUI::Widget::setCoord (_value);
align();
}
void HBox::onWidgetCreated(MyGUI::Widget* _widget)
{
align();
}
void HBox::onWidgetDestroy(MyGUI::Widget* _widget)
{
align();
}
MyGUI::IntSize HBox::getRequestedSize () MyGUI::IntSize HBox::getRequestedSize ()
{ {
MyGUI::IntSize size(0,0); MyGUI::IntSize size(0,0);
@ -954,6 +993,19 @@ MyGUI::IntSize HBox::getRequestedSize ()
if (i != getChildCount()-1) if (i != getChildCount()-1)
size.width += mSpacing; size.width += mSpacing;
} }
else
{
MyGUI::IntSize requested = getChildAt(i)->getSize ();
size.height = std::max(size.height, requested.height);
if (getChildAt(i)->getUserString("HStretch") != "true")
size.width = size.width + requested.width;
if (i != getChildCount()-1)
size.width += mSpacing;
}
size.height += mPadding*2;
size.width += mPadding*2;
} }
return size; return size;
} }
@ -963,7 +1015,69 @@ MyGUI::IntSize HBox::getRequestedSize ()
void VBox::align () void VBox::align ()
{ {
// not yet implemented unsigned int count = getChildCount ();
size_t v_stretched_count = 0;
int total_height = 0;
int total_width = 0;
std::vector< std::pair<MyGUI::IntSize, bool> > sizes;
for (unsigned int i = 0; i < count; ++i)
{
MyGUI::Widget* w = getChildAt(i);
bool vstretch = w->getUserString ("VStretch") == "true";
v_stretched_count += vstretch;
AutoSizedWidget* aw = dynamic_cast<AutoSizedWidget*>(w);
if (aw)
{
sizes.push_back(std::make_pair(aw->getRequestedSize (), vstretch));
total_height += aw->getRequestedSize ().height;
total_width = std::max(total_width, aw->getRequestedSize ().width);
}
else
{
sizes.push_back (std::make_pair(w->getSize(), vstretch));
total_height += w->getSize().height;
}
if (i != count-1)
total_height += mSpacing;
}
if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height))
{
setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2));
return;
}
int curY = 0;
for (unsigned int i = 0; i < count; ++i)
{
if (i==0)
curY += mPadding;
MyGUI::Widget* w = getChildAt(i);
bool hstretch = w->getUserString ("HStretch") == "true";
int width = hstretch ? total_width : sizes[i].first.width;
MyGUI::IntCoord widgetCoord;
widgetCoord.top = curY;
widgetCoord.left = mPadding + (getSize().width-mPadding*2 - width) / 2;
int height = sizes[i].second ? sizes[i].first.height + (getSize().height-mPadding*2 - total_height)/v_stretched_count
: sizes[i].first.height;
widgetCoord.height = height;
widgetCoord.width = width;
w->setCoord(widgetCoord);
curY += height;
if (i != count-1)
curY += mSpacing;
}
}
void VBox::setPropertyOverride(const std::string& _key, const std::string& _value)
{
Box::_setPropertyImpl (_key, _value);
} }
void VBox::setSize (const MyGUI::IntSize& _value) void VBox::setSize (const MyGUI::IntSize& _value)
@ -972,6 +1086,12 @@ void VBox::setSize (const MyGUI::IntSize& _value)
align(); align();
} }
void VBox::setCoord (const MyGUI::IntCoord& _value)
{
MyGUI::Widget::setCoord (_value);
align();
}
MyGUI::IntSize VBox::getRequestedSize () MyGUI::IntSize VBox::getRequestedSize ()
{ {
MyGUI::IntSize size(0,0); MyGUI::IntSize size(0,0);
@ -986,6 +1106,29 @@ MyGUI::IntSize VBox::getRequestedSize ()
if (i != getChildCount()-1) if (i != getChildCount()-1)
size.height += mSpacing; size.height += mSpacing;
} }
else
{
MyGUI::IntSize requested = getChildAt(i)->getSize ();
size.width = std::max(size.width, requested.width);
if (getChildAt(i)->getUserString("VStretch") != "true")
size.height = size.height + requested.height;
if (i != getChildCount()-1)
size.height += mSpacing;
}
size.height += mPadding*2;
size.width += mPadding*2;
} }
return size; return size;
} }
void VBox::onWidgetCreated(MyGUI::Widget* _widget)
{
align();
}
void VBox::onWidgetDestroy(MyGUI::Widget* _widget)
{
align();
}

View file

@ -357,10 +357,13 @@ namespace MWGui
protected: protected:
virtual void align() = 0; virtual void align() = 0;
virtual void setPropertyOverride(const std::string& _key, const std::string& _value); virtual void _setPropertyImpl(const std::string& _key, const std::string& _value);
int mSpacing; // how much space to put between elements int mSpacing; // how much space to put between elements
int mPadding; // outer padding
bool mAutoResize; // auto resize the box so that it exactly fits all elements
}; };
class HBox : public Box, public MyGUI::Widget class HBox : public Box, public MyGUI::Widget
@ -369,10 +372,16 @@ namespace MWGui
public: public:
virtual void setSize (const MyGUI::IntSize &_value); virtual void setSize (const MyGUI::IntSize &_value);
virtual void setCoord (const MyGUI::IntCoord &_value);
protected: protected:
virtual void align(); virtual void align();
virtual MyGUI::IntSize getRequestedSize(); virtual MyGUI::IntSize getRequestedSize();
virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
virtual void onWidgetCreated(MyGUI::Widget* _widget);
virtual void onWidgetDestroy(MyGUI::Widget* _widget);
}; };
class VBox : public Box, public MyGUI::Widget class VBox : public Box, public MyGUI::Widget
@ -381,10 +390,16 @@ namespace MWGui
public: public:
virtual void setSize (const MyGUI::IntSize &_value); virtual void setSize (const MyGUI::IntSize &_value);
virtual void setCoord (const MyGUI::IntCoord &_value);
protected: protected:
virtual void align(); virtual void align();
virtual MyGUI::IntSize getRequestedSize(); virtual MyGUI::IntSize getRequestedSize();
virtual void setPropertyOverride(const std::string& _key, const std::string& _value);
virtual void onWidgetCreated(MyGUI::Widget* _widget);
virtual void onWidgetDestroy(MyGUI::Widget* _widget);
}; };
} }
} }

View file

@ -45,6 +45,7 @@
#include "quickkeysmenu.hpp" #include "quickkeysmenu.hpp"
#include "loadingscreen.hpp" #include "loadingscreen.hpp"
#include "levelupdialog.hpp" #include "levelupdialog.hpp"
#include "waitdialog.hpp"
using namespace MWGui; using namespace MWGui;
@ -71,6 +72,8 @@ WindowManager::WindowManager(
, mSpellWindow(NULL) , mSpellWindow(NULL)
, mLoadingScreen(NULL) , mLoadingScreen(NULL)
, mCharGen(NULL) , mCharGen(NULL)
, mLevelupDialog(NULL)
, mWaitDialog(NULL)
, mPlayerClass() , mPlayerClass()
, mPlayerName() , mPlayerName()
, mPlayerRaceId() , mPlayerRaceId()
@ -150,6 +153,7 @@ WindowManager::WindowManager(
mSpellWindow = new SpellWindow(*this); mSpellWindow = new SpellWindow(*this);
mQuickKeysMenu = new QuickKeysMenu(*this); mQuickKeysMenu = new QuickKeysMenu(*this);
mLevelupDialog = new LevelupDialog(*this); mLevelupDialog = new LevelupDialog(*this);
mWaitDialog = new WaitDialog(*this);
mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this);
mLoadingScreen->onResChange (w,h); mLoadingScreen->onResChange (w,h);
@ -204,6 +208,7 @@ WindowManager::~WindowManager()
delete mSpellWindow; delete mSpellWindow;
delete mLoadingScreen; delete mLoadingScreen;
delete mLevelupDialog; delete mLevelupDialog;
delete mWaitDialog;
cleanupGarbage(); cleanupGarbage();
@ -252,6 +257,7 @@ void WindowManager::updateVisible()
mSpellWindow->setVisible(false); mSpellWindow->setVisible(false);
mQuickKeysMenu->setVisible(false); mQuickKeysMenu->setVisible(false);
mLevelupDialog->setVisible(false); mLevelupDialog->setVisible(false);
mWaitDialog->setVisible(false);
mHud->setVisible(true); mHud->setVisible(true);
@ -304,6 +310,13 @@ void WindowManager::updateVisible()
mAlchemyWindow->setVisible(true); mAlchemyWindow->setVisible(true);
break; break;
case GM_Rest: case GM_Rest:
mWaitDialog->setVisible(true);
break;
case GM_RestBed:
mWaitDialog->setVisible(true);
mWaitDialog->bedActivated();
break;
case GM_Levelup:
mLevelupDialog->setVisible(true); mLevelupDialog->setVisible(true);
break; break;
case GM_Name: case GM_Name:
@ -540,6 +553,8 @@ void WindowManager::onFrame (float frameDuration)
mStatsWindow->onFrame(); mStatsWindow->onFrame();
mWaitDialog->onFrame(frameDuration);
mHud->onFrame(frameDuration); mHud->onFrame(frameDuration);
mDialogueWindow->checkReferenceAvailable(); mDialogueWindow->checkReferenceAvailable();
@ -934,3 +949,8 @@ void WindowManager::loadingDone ()
{ {
mLoadingScreen->loadingDone (); mLoadingScreen->loadingDone ();
} }
bool WindowManager::getPlayerSleeping ()
{
return mWaitDialog->getSleeping();
}

View file

@ -63,6 +63,7 @@ namespace MWGui
class QuickKeysMenu; class QuickKeysMenu;
class LoadingScreen; class LoadingScreen;
class LevelupDialog; class LevelupDialog;
class WaitDialog;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
{ {
@ -203,6 +204,8 @@ namespace MWGui
virtual void enableRest() { mRestAllowed = true; } virtual void enableRest() { mRestAllowed = true; }
virtual bool getRestEnabled() { return mRestAllowed; } virtual bool getRestEnabled() { return mRestAllowed; }
virtual bool getPlayerSleeping();
private: private:
OEngine::GUI::MyGUIManager *mGuiManager; OEngine::GUI::MyGUIManager *mGuiManager;
HUD *mHud; HUD *mHud;
@ -229,6 +232,7 @@ namespace MWGui
QuickKeysMenu* mQuickKeysMenu; QuickKeysMenu* mQuickKeysMenu;
LoadingScreen* mLoadingScreen; LoadingScreen* mLoadingScreen;
LevelupDialog* mLevelupDialog; LevelupDialog* mLevelupDialog;
WaitDialog* mWaitDialog;
CharacterCreation* mCharGen; CharacterCreation* mCharGen;

View file

@ -77,12 +77,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
bodyRaceID = "b_n_"+ref->base->race; bodyRaceID = "b_n_"+ref->base->race;
std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower); std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower);
/*std::cout << "Race: " << ref->base->race ;
if(female)
std::cout << " Sex: Female" << " Height: " << race->data.height.female << "\n";
else
std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n";
*/
mInsert = node; mInsert = node;
assert(mInsert); assert(mInsert);
@ -129,6 +123,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
} }
} }
if(isFemale) if(isFemale)
mInsert->scale(race->data.height.female, race->data.height.female, race->data.height.female); mInsert->scale(race->data.height.female, race->data.height.female, race->data.height.female);
else else

View file

@ -131,6 +131,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2)));
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6)));
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(
Settings::Manager::getFloat ("gamma", "Video"))));
applyCompositors(); applyCompositors();
@ -280,13 +282,15 @@ RenderingManager::rotateObject(
float *f = ptr.getRefData().getPosition().rot; float *f = ptr.getRefData().getPosition().rot;
rot.x += f[0], rot.y += f[1], rot.z += f[2]; rot.x += f[0], rot.y += f[1], rot.z += f[2];
} }
if (!isPlayer && isActive) { if (!isPlayer && isActive) {
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X); Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y); Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y);
Ogre::Quaternion zr(Ogre::Radian(rot.z), Ogre::Vector3::UNIT_Z); Ogre::Quaternion zr(Ogre::Radian(rot.z), Ogre::Vector3::UNIT_Z);
ptr.getRefData().getBaseNode()->setOrientation(xr * yr * zr); ptr.getRefData().getBaseNode()->setOrientation(xr * yr * zr);
} }
return force; return force;
} }
@ -752,6 +756,11 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
mObjects.rebuildStaticGeometry (); mObjects.rebuildStaticGeometry ();
} }
else if (it->second == "gamma" && it->first == "Video")
{
sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(
Settings::Manager::getFloat ("gamma", "Video"))));
}
else if (it->second == "shader mode" && it->first == "General") else if (it->second == "shader mode" && it->first == "General")
{ {
sh::Language lang; sh::Language lang;

View file

@ -202,5 +202,6 @@ op 0x200019b: PlaceItem
op 0x200019c: PlaceAtPc op 0x200019c: PlaceAtPc
op 0x200019d: PlaceAtMe op 0x200019d: PlaceAtMe
op 0x200019e: PlaceAtMe Explicit op 0x200019e: PlaceAtMe Explicit
opcodes 0x200019f-0x3ffffff unused op 0x200019f: GetPcSleep
opcodes 0x20001a0-0x3ffffff unused

View file

@ -160,7 +160,7 @@ opcodeEnableStatsReviewMenu);
new OpEnableRest ()); new OpEnableRest ());
interpreter.installSegment5 (opcodeShowRestMenu, interpreter.installSegment5 (opcodeShowRestMenu,
new OpShowDialogue (MWGui::GM_Rest)); new OpShowDialogue (MWGui::GM_RestBed));
interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed); interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed);

View file

@ -10,6 +10,7 @@
#include <components/interpreter/opcodes.hpp> #include <components/interpreter/opcodes.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -20,6 +21,16 @@ namespace MWScript
{ {
namespace Misc namespace Misc
{ {
class OpGetPcSleep : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.push (MWBase::Environment::get().getWindowManager ()->getPlayerSleeping());
}
};
class OpXBox : public Interpreter::Opcode0 class OpXBox : public Interpreter::Opcode0
{ {
public: public:
@ -249,6 +260,7 @@ namespace MWScript
const int opcodeTogglePathgrid = 0x2000146; const int opcodeTogglePathgrid = 0x2000146;
const int opcodeDontSaveObject = 0x2000153; const int opcodeDontSaveObject = 0x2000153;
const int opcodeToggleVanityMode = 0x2000174; const int opcodeToggleVanityMode = 0x2000174;
const int opcodeGetPcSleep = 0x200019f;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -273,6 +285,7 @@ namespace MWScript
extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject); extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject);
extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode); extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode);
extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode); extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode);
extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep);
} }
void installOpcodes (Interpreter::Interpreter& interpreter) void installOpcodes (Interpreter::Interpreter& interpreter)
@ -293,6 +306,7 @@ namespace MWScript
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); interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode);
interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep);
} }
} }
} }

View file

@ -96,6 +96,10 @@ namespace MWWorld
if(hasWater){ if(hasWater){
playerphysics->waterHeight = waterHeight; playerphysics->waterHeight = waterHeight;
} }
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
{
it->second->setCurrentWater(hasWater, waterHeight);
}
} }
@ -172,17 +176,20 @@ namespace MWWorld
//set the DebugRenderingMode. To disable it,set it to 0 //set the DebugRenderingMode. To disable it,set it to 0
//eng->setDebugRenderingMode(1); //eng->setDebugRenderingMode(1);
//set the walkdirection to 0 (no movement) for every actor) //set the movement keys to 0 (no movement) for every actor)
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
{ {
OEngine::Physic::PhysicActor* act = it->second; OEngine::Physic::PhysicActor* act = it->second;
act->setWalkDirection(btVector3(0,0,0)); act->setMovement(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;
pm_ref.upmove = 0; pm_ref.upmove = 0;
//playerphysics->ps.move_type = PM_NOCLIP; //playerphysics->ps.move_type = PM_NOCLIP;
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin()); for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
@ -193,10 +200,12 @@ namespace MWWorld
playerphysics->ps.viewangles.x = playerphysics->ps.viewangles.x =
Ogre::Radian(mPlayerData.pitch).valueDegrees(); Ogre::Radian(mPlayerData.pitch).valueDegrees();
playerphysics->ps.viewangles.y = playerphysics->ps.viewangles.y =
Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90; Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90;
pm_ref.rightmove = -iter->second.x; pm_ref.rightmove = iter->second.x;
pm_ref.forwardmove = -iter->second.y; pm_ref.forwardmove = -iter->second.y;
pm_ref.upmove = iter->second.z; pm_ref.upmove = iter->second.z;
} }
@ -208,16 +217,17 @@ namespace MWWorld
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors) const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
{ {
Pmove(playerphysics); Pmove(playerphysics);
std::vector< std::pair<std::string, Ogre::Vector3> > response; std::vector< std::pair<std::string, Ogre::Vector3> > response;
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
{ {
btVector3 newPos = it->second->getPosition();
Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z()); Ogre::Vector3 coord = it->second->getPosition();
if(it->first == "player"){ if(it->first == "player"){
coord = playerphysics->ps.origin; coord = playerphysics->ps.origin ;
} }
@ -243,21 +253,15 @@ namespace MWWorld
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position) const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
{ {
handleToMesh[handle] = mesh; handleToMesh[handle] = mesh;
OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale); OEngine::Physic::RigidBody* body = mEngine->createAndAdjustRigidBody(mesh,handle,scale, position, rotation);
mEngine->addRigidBody(body); mEngine->addRigidBody(body);
btTransform tr;
tr.setOrigin(btVector3(position.x,position.y,position.z));
tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w));
body->setWorldTransform(tr);
} }
void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh, void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh,
const Ogre::Vector3& position) const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation)
{ {
//TODO:optimize this. Searching the std::map isn't very efficient i think. //TODO:optimize this. Searching the std::map isn't very efficient i think.
mEngine->addCharacter(handle); mEngine->addCharacter(handle, mesh, position, scale, rotation);
OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle);
act->setPosition(btVector3(position.x,position.y,position.z));
} }
void PhysicsSystem::removeObject (const std::string& handle) void PhysicsSystem::removeObject (const std::string& handle)
@ -268,15 +272,25 @@ namespace MWWorld
mEngine->deleteRigidBody(handle); mEngine->deleteRigidBody(handle);
} }
void PhysicsSystem::moveObject (const std::string& handle, const Ogre::Vector3& position) void PhysicsSystem::moveObject (const std::string& handle, Ogre::SceneNode* node)
{ {
Ogre::Vector3 position = node->getPosition();
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
{ {
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
// start positions others than 0, 0, 0 // start positions others than 0, 0, 0
btTransform tr = body->getWorldTransform();
tr.setOrigin(btVector3(position.x,position.y,position.z));
body->setWorldTransform(tr); if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL){
btTransform tr = body->getWorldTransform();
tr.setOrigin(btVector3(position.x,position.y,position.z));
body->setWorldTransform(tr);
}
else{
//For objects that contain a box shape.
//Do any such objects exist? Perhaps animated objects?
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, position, node->getOrientation());
}
} }
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
{ {
@ -288,34 +302,45 @@ namespace MWWorld
} }
else else
{ {
act->setPosition(btVector3(position.x,position.y,position.z)); act->setPosition(position);
} }
} }
} }
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) void PhysicsSystem::rotateObject (const std::string& handle, Ogre::SceneNode* node)
{ {
Ogre::Quaternion rotation = node->getOrientation();
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
{ {
act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); //Needs to be changed
act->setRotation(rotation);
} }
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
{ {
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL)
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
else
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation);
} }
} }
void PhysicsSystem::scaleObject (const std::string& handle, float scale) void PhysicsSystem::scaleObject (const std::string& handle, Ogre::SceneNode* node)
{ {
if(handleToMesh.find(handle) != handleToMesh.end()) if(handleToMesh.find(handle) != handleToMesh.end())
{ {
btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform();
removeObject(handle); removeObject(handle);
Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ()); float scale = node->getScale().x;
Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ()); Ogre::Quaternion quat = node->getOrientation();
Ogre::Vector3 vec = node->getPosition();
addObject(handle, handleToMesh[handle], quat, scale, vec); addObject(handle, handleToMesh[handle], quat, scale, vec);
} }
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
{
float scale = node->getScale().x;
act->setScale(scale);
}
} }
bool PhysicsSystem::toggleCollisionMode() bool PhysicsSystem::toggleCollisionMode()
@ -335,8 +360,6 @@ namespace MWWorld
if(cmode) if(cmode)
{ {
act->enableCollisions(false); act->enableCollisions(false);
act->setGravity(0.);
act->setVerticalVelocity(0);
mFreeFly = true; mFreeFly = true;
return false; return false;
} }
@ -344,8 +367,6 @@ namespace MWWorld
{ {
mFreeFly = false; mFreeFly = false;
act->enableCollisions(true); act->enableCollisions(true);
act->setGravity(4.);
act->setVerticalVelocity(0);
return true; return true;
} }
} }
@ -368,7 +389,7 @@ namespace MWWorld
void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){ void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){
Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
addActor (node->getName(), model, node->getPosition()); addActor (node->getName(), model, node->getPosition(), node->getScale().x, node->getOrientation());
} }
bool PhysicsSystem::getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max) bool PhysicsSystem::getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max)

View file

@ -24,7 +24,7 @@ namespace MWWorld
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position); const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
void addActor (const std::string& handle, const std::string& mesh, void addActor (const std::string& handle, const std::string& mesh,
const Ogre::Vector3& position); const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation);
void addHeightField (float* heights, void addHeightField (float* heights,
int x, int y, float yoffset, int x, int y, float yoffset,
@ -34,11 +34,11 @@ namespace MWWorld
void removeObject (const std::string& handle); void removeObject (const std::string& handle);
void moveObject (const std::string& handle, const Ogre::Vector3& position); void moveObject (const std::string& handle, Ogre::SceneNode* node);
void rotateObject (const std::string& handle, const Ogre::Quaternion& rotation); void rotateObject (const std::string& handle, Ogre::SceneNode* node);
void scaleObject (const std::string& handle, float scale); void scaleObject (const std::string& handle, Ogre::SceneNode* node);
bool toggleCollisionMode(); bool toggleCollisionMode();

View file

@ -189,7 +189,9 @@ namespace MWWorld
mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this); mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this);
mRendering->attachCameraTo(mPlayer->getPlayer()); mRendering->attachCameraTo(mPlayer->getPlayer());
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0)); std::string playerCollisionFile = "meshes\\base_anim.nif"; //This is used to make a collision shape for our player
//We will need to support the 1st person file too in the future
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), playerCollisionFile, Ogre::Vector3 (0, 0, 0), 1, Ogre::Quaternion::ZERO);
// global variables // global variables
mGlobalVariables = new Globals (mStore); mGlobalVariables = new Globals (mStore);
@ -450,6 +452,16 @@ namespace MWWorld
mRendering->skySetDate (mGlobalVariables->getInt ("day"), month); mRendering->skySetDate (mGlobalVariables->getInt ("day"), month);
} }
int World::getDay()
{
return mGlobalVariables->getInt("day");
}
int World::getMonth()
{
return mGlobalVariables->getInt("month");
}
TimeStamp World::getTimeStamp() const TimeStamp World::getTimeStamp() const
{ {
return TimeStamp (mGlobalVariables->getFloat ("gamehour"), return TimeStamp (mGlobalVariables->getFloat ("gamehour"),
@ -603,7 +615,7 @@ namespace MWWorld
} }
if (haveToMove) { if (haveToMove) {
mRendering->moveObject(ptr, vec); mRendering->moveObject(ptr, vec);
mPhysics->moveObject(ptr.getRefData().getHandle(), vec); mPhysics->moveObject (ptr.getRefData().getHandle(), ptr.getRefData().getBaseNode());
} }
} }
@ -624,6 +636,8 @@ namespace MWWorld
void World::moveObject (const Ptr& ptr, float x, float y, float z) void World::moveObject (const Ptr& ptr, float x, float y, float z)
{ {
moveObjectImp(ptr, x, y, z); moveObjectImp(ptr, x, y, z);
} }
void World::scaleObject (const Ptr& ptr, float scale) void World::scaleObject (const Ptr& ptr, float scale)
@ -633,7 +647,7 @@ namespace MWWorld
ptr.getCellRef().scale = scale; ptr.getCellRef().scale = scale;
//scale = scale/ptr.getRefData().getBaseNode()->getScale().x; //scale = scale/ptr.getRefData().getBaseNode()->getScale().x;
ptr.getRefData().getBaseNode()->setScale(scale,scale,scale); ptr.getRefData().getBaseNode()->setScale(scale,scale,scale);
mPhysics->scaleObject( ptr.getRefData().getHandle(), scale ); mPhysics->scaleObject( ptr.getRefData().getHandle(), ptr.getRefData().getBaseNode());
} }
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust) void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
@ -642,18 +656,20 @@ namespace MWWorld
rot.x = Ogre::Degree(x).valueRadians(); rot.x = Ogre::Degree(x).valueRadians();
rot.y = Ogre::Degree(y).valueRadians(); rot.y = Ogre::Degree(y).valueRadians();
rot.z = Ogre::Degree(z).valueRadians(); rot.z = Ogre::Degree(z).valueRadians();
if (mRendering->rotateObject(ptr, rot, adjust)) { if (mRendering->rotateObject(ptr, rot, adjust)) {
float *objRot = ptr.getRefData().getPosition().rot; float *objRot = ptr.getRefData().getPosition().rot;
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z; objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
if (ptr.getRefData().getBaseNode() != 0) { if (ptr.getRefData().getBaseNode() != 0) {
mPhysics->rotateObject( mPhysics->rotateObject(
ptr.getRefData().getHandle(), ptr.getRefData().getHandle(),
ptr.getRefData().getBaseNode()->getOrientation() ptr.getRefData().getBaseNode()
); );
} }
} }
} }
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos) void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
@ -1246,4 +1262,28 @@ namespace MWWorld
{ {
mRendering->setupExternalRendering (rendering); mRendering->setupExternalRendering (rendering);
} }
int World::canRest ()
{
Ptr::CellStore *currentCell = mWorldScene->getCurrentCell();
Ogre::Vector3 playerPos;
float* pos = mPlayer->getPlayer ().getRefData ().getPosition ().pos;
playerPos.x = pos[0];
playerPos.y = pos[1];
playerPos.z = pos[2];
std::pair<bool, Ogre::Vector3> hit =
mPhysics->castRay(playerPos, Ogre::Vector3(0,0,-1), 50);
bool isOnGround = (hit.first ? (hit.second.distance (playerPos) < 25) : false);
if (!isOnGround || isUnderwater (*currentCell->cell, playerPos))
return 2;
if (currentCell->cell->data.flags & ESM::Cell::NoSleep)
return 1;
return 0;
}
} }

View file

@ -179,6 +179,9 @@ namespace MWWorld
virtual void setDay (int day); virtual void setDay (int day);
///< Set in-game time day. ///< Set in-game time day.
virtual int getDay();
virtual int getMonth();
virtual TimeStamp getTimeStamp() const; virtual TimeStamp getTimeStamp() const;
///< Return current in-game time stamp. ///< Return current in-game time stamp.
@ -313,6 +316,13 @@ namespace MWWorld
virtual void renderGlobalMap(); virtual void renderGlobalMap();
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); virtual void setupExternalRendering (MWRender::ExternalRendering& rendering);
virtual int canRest();
///< check if the player is allowed to rest \n
/// 0 - yes \n
/// 1 - only waiting \n
/// 2 - player is underwater \n
/// 3 - enemies are nearby (not implemented)
}; };
} }

View file

@ -72,6 +72,9 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
cShape = static_cast<BulletShape *>(resource); cShape = static_cast<BulletShape *>(resource);
resourceName = cShape->getName(); resourceName = cShape->getName();
cShape->collide = false; cShape->collide = false;
mBoundingBox = NULL;
cShape->boxTranslation = Ogre::Vector3(0,0,0);
cShape->boxRotation = Ogre::Quaternion::IDENTITY;
mTriMesh = new btTriangleMesh(); mTriMesh = new btTriangleMesh();
@ -125,9 +128,14 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
delete m_meshInterface; delete m_meshInterface;
} }
}; };
if(mBoundingBox != NULL)
cShape->Shape = mBoundingBox;
currentShape = new TriangleMeshShape(mTriMesh,true); else
cShape->Shape = currentShape; {
currentShape = new TriangleMeshShape(mTriMesh,true);
cShape->Shape = currentShape;
}
} }
bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
@ -218,6 +226,17 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
} }
if(node->hasBounds)
{
btVector3 boxsize = getbtVector((node->boundXYZ));
cShape->boxTranslation = node->boundPos;
cShape->boxRotation = node->boundRot;
mBoundingBox = new btBoxShape(boxsize);
}
// For NiNodes, loop through children // For NiNodes, loop through children
if (node->recType == Nif::RC_NiNode) if (node->recType == Nif::RC_NiNode)

View file

@ -102,8 +102,11 @@ private:
std::string resourceName; std::string resourceName;
std::string resourceGroup; std::string resourceGroup;
BulletShape* cShape;//current shape BulletShape* cShape;//current shape
btTriangleMesh *mTriMesh; btTriangleMesh *mTriMesh;
btBoxShape *mBoundingBox;
btBvhTriangleMeshShape* currentShape;//the shape curently under construction btBvhTriangleMeshShape* currentShape;//the shape curently under construction
}; };

View file

@ -1,3 +1,7 @@
#define gammaCorrectRead(v) pow(v, float3(gammaCorrection,gammaCorrection,gammaCorrection))
#define gammaCorrectOutput(v) pow(v, float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection))
#if SH_HLSL == 1 || SH_CG == 1 #if SH_HLSL == 1 || SH_CG == 1
#define shTexture2D sampler2D #define shTexture2D sampler2D

View file

@ -112,6 +112,8 @@
shUniform(float, far) @shAutoConstant(far, far_clip_distance) shUniform(float, far) @shAutoConstant(far, far_clip_distance)
#endif #endif
shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection)
#if LIGHTING #if LIGHTING
shInput(float3, normalPassthrough) shInput(float3, normalPassthrough)
shInput(float3, objSpacePositionPassthrough) shInput(float3, objSpacePositionPassthrough)
@ -173,7 +175,8 @@
SH_START_PROGRAM SH_START_PROGRAM
{ {
shOutputColour(0) = shSample(diffuseMap, UV); shOutputColour(0) = shSample(diffuseMap, UV);
shOutputColour(0).xyz = gammaCorrectRead(shOutputColour(0).xyz);
#if LIGHTING #if LIGHTING
float3 normal = normalize(normalPassthrough); float3 normal = normalize(normalPassthrough);
float3 lightDir; float3 lightDir;
@ -259,7 +262,7 @@
// regular fog only if fragment is above water // regular fog only if fragment is above water
if (worldPos.y > waterLevel) if (worldPos.y > waterLevel)
#endif #endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
#endif #endif
// prevent negative colour output (for example with negative lights) // prevent negative colour output (for example with negative lights)
@ -274,12 +277,11 @@
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85)) *waterSunGradient * 0.5;
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; float3 watercolour = ( gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0;
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
@ -292,6 +294,8 @@
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled);
#endif #endif
shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz);
#if MRT #if MRT
shOutputColour(1) = float4(depthPassthrough / far,1,1,1); shOutputColour(1) = float4(depthPassthrough / far,1,1,1);
#endif #endif

View file

@ -137,6 +137,8 @@
shSampler2D(normalMap) // global normal map shSampler2D(normalMap) // global normal map
shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection)
@shForeach(@shPropertyString(num_blendmaps)) @shForeach(@shPropertyString(num_blendmaps))
shSampler2D(blendMap@shIterator) shSampler2D(blendMap@shIterator)
@ -247,9 +249,9 @@
#if IS_FIRST_PASS == 1 && @shIterator == 0 #if IS_FIRST_PASS == 1 && @shIterator == 0
// first layer of first pass doesn't need a blend map // first layer of first pass doesn't need a blend map
albedo = shSample(diffuseMap0, UV * 10).rgb; albedo = gammaCorrectRead(shSample(diffuseMap0, UV * 10).rgb);
#else #else
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); albedo = shLerp(albedo, gammaCorrectRead(shSample(diffuseMap@shIterator, UV * 10).rgb), blendValues@shPropertyString(blendmap_component_@shIterator));
#endif #endif
@shEndForeach @shEndForeach
@ -336,7 +338,7 @@
// regular fog only if fragment is above water // regular fog only if fragment is above water
if (worldPos.y > waterLevel) if (worldPos.y > waterLevel)
#endif #endif
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue);
#endif #endif
// prevent negative colour output (for example with negative lights) // prevent negative colour output (for example with negative lights)
@ -351,12 +353,12 @@
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5;
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0;
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
@ -369,6 +371,8 @@
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
#endif #endif
shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz);
#if MRT #if MRT
shOutputColour(1) = float4(depth / far,1,1,1); shOutputColour(1) = float4(depth / far,1,1,1);

View file

@ -73,6 +73,8 @@ set(MYGUI_FILES
openmw_spell_buying_window.layout openmw_spell_buying_window.layout
openmw_loading_screen.layout openmw_loading_screen.layout
openmw_levelup_dialog.layout openmw_levelup_dialog.layout
openmw_wait_dialog.layout
openmw_wait_dialog_progressbar.layout
smallbars.png smallbars.png
VeraMono.ttf VeraMono.ttf
markers.png markers.png

View file

@ -77,8 +77,9 @@
<!-- Buttons --> <!-- Buttons -->
<Widget type="HBox" skin="" position="160 370 380 24"> <Widget type="HBox" skin="" position="160 370 380 24">
<Widget type="Widget"/> <!-- spacer --> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CreateButton"> <Widget type="AutoSizedButton" skin="MW_Button" name="CreateButton">
<Property key="Caption" value="#{sCreate}"/> <Property key="Caption" value="#{sCreate}"/>
</Widget> </Widget>

View file

@ -15,7 +15,9 @@
<!-- Dialog buttons --> <!-- Dialog buttons -->
<Widget type="HBox" position="0 340 473 24"> <Widget type="HBox" position="0 340 473 24">
<Widget type="Widget"/> <!-- spacer --> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton"> <Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
<Property key="Caption" value="#{sBack}"/> <Property key="Caption" value="#{sBack}"/>
</Widget> </Widget>

View file

@ -61,7 +61,9 @@
<!-- Dialog buttons --> <!-- Dialog buttons -->
<Widget type="HBox" position="0 265 476 24"> <Widget type="HBox" position="0 265 476 24">
<Widget type="Widget"/> <!-- spacer --> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton"> <Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
<Property key="Caption" value="#{sBack}"/> <Property key="Caption" value="#{sBack}"/>
</Widget> </Widget>

View file

@ -59,7 +59,9 @@
<!-- Dialog buttons --> <!-- Dialog buttons -->
<Widget type="HBox" position="0 158 459 24"> <Widget type="HBox" position="0 158 459 24">
<Widget type="Widget"/> <!-- spacer --> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="DescriptionButton"> <Widget type="AutoSizedButton" skin="MW_Button" name="DescriptionButton">
<Property key="Caption" value="#{sCreateClassMenu1}"/> <Property key="Caption" value="#{sCreateClassMenu1}"/>
</Widget> </Widget>

View file

@ -21,7 +21,9 @@
<!-- Dialog buttons --> <!-- Dialog buttons -->
<Widget type="HBox" position="0 219 319 24"> <Widget type="HBox" position="0 219 319 24">
<Widget type="Widget"/> <!-- spacer --> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton"> <Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
<Property key="Caption" value="#{sBack}"/> <Property key="Caption" value="#{sBack}"/>
</Widget> </Widget>

View file

@ -57,7 +57,10 @@
<!-- Dialog buttons --> <!-- Dialog buttons -->
<Widget type="HBox" position="0 397 574 24"> <Widget type="HBox" position="0 397 574 24">
<Widget type="Widget"/> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="471 397 53 23" name="BackButton"> <Widget type="AutoSizedButton" skin="MW_Button" position="471 397 53 23" name="BackButton">
<Property key="Caption" value="#{sBack}"/> <Property key="Caption" value="#{sBack}"/>
</Widget> </Widget>

View file

@ -112,7 +112,9 @@
<!-- Dialog buttons --> <!-- Dialog buttons -->
<Widget type="HBox" position="0 372 502 24"> <Widget type="HBox" position="0 372 502 24">
<Widget type="Widget"/> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BackButton"> <Widget type="AutoSizedButton" skin="MW_Button" name="BackButton">
<Property key="Caption" value="#{sBack}"/> <Property key="Caption" value="#{sBack}"/>
</Widget> </Widget>

View file

@ -14,7 +14,9 @@
</Widget> </Widget>
<Widget type="HBox" position="0 84 272 24" align="Right Bottom"> <Widget type="HBox" position="0 84 272 24" align="Right Bottom">
<Widget type="Widget"/> <!-- spacer --> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton" align="Right Bottom"> <Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton" align="Right Bottom">
<Property key="Caption" value="#{sCancel}"/> <Property key="Caption" value="#{sCancel}"/>
</Widget> </Widget>

View file

@ -12,7 +12,9 @@
</Widget> </Widget>
<Widget type="HBox" position="0 235 580 24" align="Right Bottom"> <Widget type="HBox" position="0 235 580 24" align="Right Bottom">
<Widget type="Widget"/> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="TakeButton" align="Right Bottom"> <Widget type="AutoSizedButton" skin="MW_Button" name="TakeButton" align="Right Bottom">
<Property key="Caption" value="#{sTakeAll}"/> <Property key="Caption" value="#{sTakeAll}"/>
</Widget> </Widget>

View file

@ -22,7 +22,9 @@
<Widget type="HBox" position="0 90 572 24" align="Right Bottom"> <Widget type="HBox" position="0 90 572 24" align="Right Bottom">
<Widget type="Widget"/> <!-- spacer --> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="417 90 60 24" name="CancelButton" align="Right Top"> <Widget type="AutoSizedButton" skin="MW_Button" position="417 90 60 24" name="CancelButton" align="Right Top">
<Property key="Caption" value="#{sCancel}"/> <Property key="Caption" value="#{sCancel}"/>
</Widget> </Widget>

View file

@ -157,7 +157,7 @@
<Widget type="TabItem" skin="" position="4 28 344 272"> <Widget type="TabItem" skin="" position="4 28 344 272">
<Property key="Caption" value=" Video "/> <Property key="Caption" value=" Video "/>
<Widget type="ListBox" skin="MW_List" position="4 4 200 150" align="Left Top" name="ResolutionList"/> <Widget type="ListBox" skin="MW_List" position="4 4 200 120" align="Left Top" name="ResolutionList"/>
<Widget type="HBox" position="212 4 300 24"> <Widget type="HBox" position="212 4 300 24">
@ -174,20 +174,37 @@
</Widget> </Widget>
</Widget> </Widget>
<Widget type="HBox" position="212 104 300 24"> <Widget type="HBox" position="212 64 300 24">
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="ShadersButton"/> <Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="ShadersButton"/>
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top"> <Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
<Property key="Caption" value="Shaders"/> <Property key="Caption" value="Shaders"/>
</Widget> </Widget>
</Widget> </Widget>
<Widget type="HBox" position="4 163 300 24"> <Widget type="HBox" position="212 94 300 24">
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="FPSButton"/> <Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="FPSButton"/>
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top"> <Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
<Property key="Caption" value="Show frames per second"/> <Property key="Caption" value="FPS"/>
</Widget> </Widget>
</Widget> </Widget>
<Widget type="TextBox" skin="NormalText" position="4 128 329 18" align="Left Top" name="GammaText">
<Property key="Caption" value="Gamma"/>
</Widget>
<Widget type="ScrollBar" skin="MW_HSlider" position="4 152 329 18" align="Left Top" name="GammaSlider">
<Property key="Range" value="1000000"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="4 176 329 18" align="Left Top">
<Property key="Caption" value="#{sDark_Gamma}"/>
<Property key="TextAlign" value="Left"/>
</Widget>
<Widget type="TextBox" skin="SandText" position="4 176 329 18" align="Left Top">
<Property key="Caption" value="#{sLight_Gamma}"/>
<Property key="TextAlign" value="Right"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="4 198 329 18" align="Left Top" name="FovText"> <Widget type="TextBox" skin="NormalText" position="4 198 329 18" align="Left Top" name="FovText">
<Property key="Caption" value="Field of View"/> <Property key="Caption" value="Field of View"/>
</Widget> </Widget>

View file

@ -56,7 +56,9 @@
</Widget> </Widget>
<Widget type="HBox" position="0 60 566 24" align="Right Bottom"> <Widget type="HBox" position="0 60 566 24" align="Right Bottom">
<Widget type="Widget"/> <Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="OfferButton" align="Right Top"> <Widget type="AutoSizedButton" skin="MW_Button" name="OfferButton" align="Right Top">
<Property key="Caption" value="#{sBarterDialog8}"/> <Property key="Caption" value="#{sBarterDialog8}"/>
</Widget> </Widget>

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="VBox" skin="MW_Dialog" layer="Windows" position="0 0 600 200" name="_Main">
<Property key="Padding" value="12"/>
<Property key="Spacing" value="8"/>
<Property key="AutoResize" value="true"/>
<Widget type="AutoSizedTextBox" skin="SandText" name="DateTimeText">
<Property key="Caption" value="24 Herzfeuer (Tag 24) 2 a.m."/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="RestText">
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" name="HourText">
</Widget>
<Widget type="ScrollBar" skin="MW_HScroll" name="HourSlider" position="0 0 0 18">
<Property key="MoveToClick" value="true"/>
<Property key="Range" value="24"/>
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="HBox">
<UserString key="HStretch" value="true"/>
<Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="UntilHealedButton">
<Property key="Caption" value="#{sUntilHealed}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="WaitButton">
<Property key="Caption" value="#{sRest}"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 219 40" name="_Main">
<Widget type="ProgressBar" skin="MW_Progress_Blue" position="5 6 199 20" name="ProgressBar">
<Widget type="TextBox" skin="SandText" position="0 0 199 20" name="ProgressText">
<Property key="TextAlign" value="Center"/>
</Widget>
</Widget>
</Widget>
</MyGUI>

View file

@ -28,6 +28,8 @@ vsync = false
# PBuffer, FBO, Copy # PBuffer, FBO, Copy
opengl rtt mode = FBO opengl rtt mode = FBO
gamma = 2.2
[GUI] [GUI]
# 1 is fully opaque # 1 is fully opaque
menu transparency = 0.84 menu transparency = 0.84

View file

@ -4,7 +4,7 @@
#include <OgreResource.h> #include <OgreResource.h>
#include <OgreResourceManager.h> #include <OgreResourceManager.h>
#include <btBulletCollisionCommon.h> #include <btBulletCollisionCommon.h>
#include <OgreVector3.h>
//For some reason, Ogre Singleton cannot be used in another namespace, that's why there is no namespace here. //For some reason, Ogre Singleton cannot be used in another namespace, that's why there is no namespace here.
//But the risk of name collision seems pretty low here. //But the risk of name collision seems pretty low here.
@ -31,6 +31,8 @@ public:
virtual ~BulletShape(); virtual ~BulletShape();
btCollisionShape* Shape; btCollisionShape* Shape;
Ogre::Vector3 boxTranslation;
Ogre::Quaternion boxRotation;
//this flag indicate if the shape is used for collision or if it's for raycasting only. //this flag indicate if the shape is used for collision or if it's for raycasting only.
bool collide; bool collide;
}; };

View file

@ -2,6 +2,7 @@
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h> #include <btBulletCollisionCommon.h>
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h> #include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include "pmove.h"
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
#include "CMotionState.h" #include "CMotionState.h"
#include "OgreRoot.h" #include "OgreRoot.h"
@ -26,111 +27,139 @@ namespace Physic
COL_RAYCASTING = BIT(3) COL_RAYCASTING = BIT(3)
}; };
PhysicActor::PhysicActor(std::string name) PhysicActor::PhysicActor(std::string name, std::string mesh, PhysicEngine* engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale):
mName(name), mEngine(engine), mMesh(mesh), mBoxScaledTranslation(0,0,0), mBoxRotationInverse(0,0,0,0), mBody(0), collisionMode(false), mBoxRotation(0,0,0,0)
{ {
mName = name; mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation);
Ogre::Quaternion inverse = mBoxRotation.Inverse();
// The capsule is at the origin mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w);
btTransform transform; mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
transform.setIdentity(); pmove = new playerMove;
pmove->mEngine = mEngine;
// External capsule btBoxShape* box = static_cast<btBoxShape*> (mBody->getCollisionShape());
externalGhostObject = new PairCachingGhostObject(name); if(box != NULL){
externalGhostObject->setWorldTransform( transform ); btVector3 size = box->getHalfExtentsWithMargin();
Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ());
btScalar externalCapsuleHeight = 120; pmove->ps.halfExtents = halfExtents;
btScalar externalCapsuleWidth = 19; }
externalCollisionShape = new btCapsuleShapeZ( externalCapsuleWidth, externalCapsuleHeight );
externalCollisionShape->setMargin( 0.1 );
externalGhostObject->setCollisionShape( externalCollisionShape );
externalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
// Internal capsule
internalGhostObject = new PairCachingGhostObject(name);
internalGhostObject->setWorldTransform( transform );
//internalGhostObject->getBroadphaseHandle()->s
btScalar internalCapsuleHeight = 110;
btScalar internalCapsuleWidth = 17;
internalCollisionShape = new btCapsuleShapeZ( internalCapsuleWidth, internalCapsuleHeight );
internalCollisionShape->setMargin( 0.1 );
internalGhostObject->setCollisionShape( internalCollisionShape );
internalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
mCharacter = new btKinematicCharacterController( externalGhostObject,internalGhostObject,btScalar( 40 ),1,4,20,9.8,0.2 );
mCharacter->setUpAxis(btKinematicCharacterController::Z_AXIS);
mCharacter->setUseGhostSweepTest(false);
mCharacter->mCollision = false;
setGravity(0);
mTranslation = btVector3(0,0,70);
} }
PhysicActor::~PhysicActor() PhysicActor::~PhysicActor()
{ {
delete mCharacter; if(mBody){
delete internalGhostObject; mEngine->dynamicsWorld->removeRigidBody(mBody);
delete internalCollisionShape; delete mBody;
delete externalGhostObject; }
delete externalCollisionShape; delete pmove;
}
void PhysicActor::setCurrentWater(bool hasWater, int waterHeight){
pmove->hasWater = hasWater;
if(hasWater){
pmove->waterHeight = waterHeight;
}
} }
void PhysicActor::setGravity(float gravity) void PhysicActor::setGravity(float gravity)
{ {
mCharacter->setGravity(gravity); pmove->ps.gravity = gravity;
//mCharacter-> }
void PhysicActor::setSpeed(float speed)
{
pmove->ps.speed = speed;
} }
void PhysicActor::enableCollisions(bool collision) void PhysicActor::enableCollisions(bool collision)
{ {
mCharacter->mCollision = collision; collisionMode = collision;
if(collisionMode)
pmove->ps.move_type=PM_NORMAL;
else
pmove->ps.move_type=PM_NOCLIP;
} }
void PhysicActor::setVerticalVelocity(float z) void PhysicActor::setJumpVelocity(float velocity)
{ {
mCharacter->setVerticalVelocity(z); pmove->ps.jump_velocity = velocity;
} }
bool PhysicActor::getCollisionMode() bool PhysicActor::getCollisionMode()
{ {
return mCharacter->mCollision; return collisionMode;
} }
void PhysicActor::setWalkDirection(const btVector3& mvt) void PhysicActor::setMovement(signed char rightmove, signed char forwardmove, signed char upmove)
{ {
mCharacter->setWalkDirection( mvt ); playerMove::playercmd& pm_ref = pmove->cmd;
pm_ref.rightmove = rightmove;
pm_ref.forwardmove = forwardmove;
pm_ref.upmove = upmove;
} }
void PhysicActor::Rotate(const btQuaternion& quat) void PhysicActor::setPmoveViewAngles(float pitch, float yaw, float roll){
{ pmove->ps.viewangles.x = pitch;
externalGhostObject->getWorldTransform().setRotation( externalGhostObject->getWorldTransform().getRotation() * quat ); pmove->ps.viewangles.y = yaw;
internalGhostObject->getWorldTransform().setRotation( internalGhostObject->getWorldTransform().getRotation() * quat ); pmove->ps.viewangles.z = roll;
} }
void PhysicActor::setRotation(const btQuaternion& quat)
void PhysicActor::setRotation(const Ogre::Quaternion quat)
{ {
externalGhostObject->getWorldTransform().setRotation( quat ); if(!quat.equals(getRotation(), Ogre::Radian(0))){
internalGhostObject->getWorldTransform().setRotation( quat ); mEngine->adjustRigidBody(mBody, getPosition(), quat, mBoxScaledTranslation, mBoxRotation);
}
} }
btVector3 PhysicActor::getPosition(void) Ogre::Vector3 PhysicActor::getPosition()
{ {
return internalGhostObject->getWorldTransform().getOrigin() -mTranslation; btVector3 vec = mBody->getWorldTransform().getOrigin();
Ogre::Quaternion rotation = Ogre::Quaternion(mBody->getWorldTransform().getRotation().getW(), mBody->getWorldTransform().getRotation().getX(),
mBody->getWorldTransform().getRotation().getY(), mBody->getWorldTransform().getRotation().getZ());
Ogre::Vector3 transrot = rotation * mBoxScaledTranslation;
Ogre::Vector3 visualPosition = Ogre::Vector3(vec.getX(), vec.getY(), vec.getZ()) - transrot;
return visualPosition;
} }
btQuaternion PhysicActor::getRotation(void) Ogre::Quaternion PhysicActor::getRotation()
{ {
return internalGhostObject->getWorldTransform().getRotation(); btQuaternion quat = mBody->getWorldTransform().getRotation() * mBoxRotationInverse;
return Ogre::Quaternion(quat.getW(), quat.getX(), quat.getY(), quat.getZ());
} }
void PhysicActor::setPosition(const btVector3& pos) void PhysicActor::setPosition(const Ogre::Vector3 pos)
{ {
internalGhostObject->getWorldTransform().setOrigin(pos+mTranslation); mEngine->adjustRigidBody(mBody, pos, getRotation(), mBoxScaledTranslation, mBoxRotation);
externalGhostObject->getWorldTransform().setOrigin(pos+mTranslation); btVector3 vec = mBody->getWorldTransform().getOrigin();
pmove->ps.origin = Ogre::Vector3(vec.getX(), vec.getY(), vec.getZ());
}
void PhysicActor::setScale(float scale){
Ogre::Vector3 position = getPosition();
Ogre::Quaternion rotation = getRotation();
//We only need to change the scaled box translation, box rotations remain the same.
mBoxScaledTranslation = mBoxScaledTranslation / mBody->getCollisionShape()->getLocalScaling().getX();
mBoxScaledTranslation *= scale;
if(mBody){
mEngine->dynamicsWorld->removeRigidBody(mBody);
delete mBody;
}
//Create the newly scaled rigid body
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation);
mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
btBoxShape* box = static_cast<btBoxShape*> (mBody->getCollisionShape());
if(box != NULL){
btVector3 size = box->getHalfExtentsWithMargin();
Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ());
pmove->ps.halfExtents = halfExtents;
}
}
void PhysicActor::runPmove(){
Pmove(pmove);
Ogre::Vector3 newpos = pmove->ps.origin;
mBody->getWorldTransform().setOrigin(btVector3(newpos.x, newpos.y, newpos.z));
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -230,8 +259,8 @@ namespace Physic
delete hf_it->second.mBody; delete hf_it->second.mBody;
} }
RigidBodyContainer::iterator rb_it = RigidBodyMap.begin(); RigidBodyContainer::iterator rb_it = ObjectMap.begin();
for (; rb_it != RigidBodyMap.end(); ++rb_it) for (; rb_it != ObjectMap.end(); ++rb_it)
{ {
if (rb_it->second != NULL) if (rb_it->second != NULL)
{ {
@ -247,9 +276,7 @@ namespace Physic
{ {
if (pa_it->second != NULL) if (pa_it->second != NULL)
{ {
dynamicsWorld->removeCollisionObject(pa_it->second->externalGhostObject);
dynamicsWorld->removeCollisionObject(pa_it->second->internalGhostObject);
dynamicsWorld->removeAction(pa_it->second->mCharacter);
delete pa_it->second; delete pa_it->second;
pa_it->second = NULL; pa_it->second = NULL;
@ -332,18 +359,42 @@ namespace Physic
mHeightFieldMap.erase(name); mHeightFieldMap.erase(name);
} }
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale) void PhysicEngine::adjustRigidBody(RigidBody* body, Ogre::Vector3 position, Ogre::Quaternion rotation,
{ Ogre::Vector3 scaledBoxTranslation, Ogre::Quaternion boxRotation){
btTransform tr;
rotation = rotation * boxRotation;
Ogre::Vector3 transrot = rotation * scaledBoxTranslation;
Ogre::Vector3 newPosition = transrot + position;
tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z));
tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w));
body->setWorldTransform(tr);
}
void PhysicEngine::boxAdjustExternal(std::string mesh, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation){
std::string sid = (boost::format("%07.3f") % scale).str(); std::string sid = (boost::format("%07.3f") % scale).str();
std::string outputstring = mesh + sid; std::string outputstring = mesh + sid;
//std::cout << "The string" << outputstring << "\n"; //std::cout << "The string" << outputstring << "\n";
//get the shape from the .nif
mShapeLoader->load(outputstring,"General");
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation);
}
RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation,
Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation)
{
std::string sid = (boost::format("%07.3f") % scale).str();
std::string outputstring = mesh + sid;
//get the shape from the .nif //get the shape from the .nif
mShapeLoader->load(outputstring,"General"); mShapeLoader->load(outputstring,"General");
BulletShapeManager::getSingletonPtr()->load(outputstring,"General"); BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
shape->Shape->setLocalScaling( btVector3(scale,scale,scale)); shape->Shape->setLocalScaling( btVector3(scale,scale,scale));
//btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(dynamic_cast<btBvhTriangleMeshShape*> (shape->Shape), btVector3(scale,scale,scale));
//create the motionState //create the motionState
CMotionState* newMotionState = new CMotionState(this,name); CMotionState* newMotionState = new CMotionState(this,name);
@ -352,11 +403,19 @@ namespace Physic
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape); btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape);
RigidBody* body = new RigidBody(CI,name); RigidBody* body = new RigidBody(CI,name);
body->collide = shape->collide; body->collide = shape->collide;
if(scaledBoxTranslation != 0)
*scaledBoxTranslation = shape->boxTranslation * scale;
if(boxRotation != 0)
*boxRotation = shape->boxRotation;
adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation);
return body; return body;
} }
void PhysicEngine::addRigidBody(RigidBody* body) void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap)
{ {
if(body) if(body)
{ {
@ -369,21 +428,23 @@ namespace Physic
dynamicsWorld->addRigidBody(body,COL_RAYCASTING,COL_RAYCASTING|COL_WORLD); dynamicsWorld->addRigidBody(body,COL_RAYCASTING,COL_RAYCASTING|COL_WORLD);
} }
body->setActivationState(DISABLE_DEACTIVATION); body->setActivationState(DISABLE_DEACTIVATION);
RigidBody* oldBody = RigidBodyMap[body->mName]; if(addToMap){
if (oldBody != NULL) RigidBody* oldBody = ObjectMap[body->mName];
{ if (oldBody != NULL)
dynamicsWorld->removeRigidBody(oldBody); {
delete oldBody; dynamicsWorld->removeRigidBody(oldBody);
} delete oldBody;
}
RigidBodyMap[body->mName] = body; ObjectMap[body->mName] = body;
}
} }
} }
void PhysicEngine::removeRigidBody(std::string name) void PhysicEngine::removeRigidBody(std::string name)
{ {
RigidBodyContainer::iterator it = RigidBodyMap.find(name); RigidBodyContainer::iterator it = ObjectMap.find(name);
if (it != RigidBodyMap.end() ) if (it != ObjectMap.end() )
{ {
RigidBody* body = it->second; RigidBody* body = it->second;
if(body != NULL) if(body != NULL)
@ -402,8 +463,8 @@ namespace Physic
void PhysicEngine::deleteRigidBody(std::string name) void PhysicEngine::deleteRigidBody(std::string name)
{ {
RigidBodyContainer::iterator it = RigidBodyMap.find(name); RigidBodyContainer::iterator it = ObjectMap.find(name);
if (it != RigidBodyMap.end() ) if (it != ObjectMap.end() )
{ {
RigidBody* body = it->second; RigidBody* body = it->second;
//btScaledBvhTriangleMeshShape* scaled = dynamic_cast<btScaledBvhTriangleMeshShape*> (body->getCollisionShape()); //btScaledBvhTriangleMeshShape* scaled = dynamic_cast<btScaledBvhTriangleMeshShape*> (body->getCollisionShape());
@ -416,16 +477,16 @@ namespace Physic
{ {
delete scaled; delete scaled;
}*/ }*/
RigidBodyMap.erase(it); ObjectMap.erase(it);
} }
} }
RigidBody* PhysicEngine::getRigidBody(std::string name) RigidBody* PhysicEngine::getRigidBody(std::string name)
{ {
RigidBodyContainer::iterator it = RigidBodyMap.find(name); RigidBodyContainer::iterator it = ObjectMap.find(name);
if (it != RigidBodyMap.end() ) if (it != ObjectMap.end() )
{ {
RigidBody* body = RigidBodyMap[name]; RigidBody* body = ObjectMap[name];
return body; return body;
} }
else else
@ -443,16 +504,17 @@ namespace Physic
} }
} }
void PhysicEngine::addCharacter(std::string name) void PhysicEngine::addCharacter(std::string name, std::string mesh,
Ogre::Vector3 position, float scale, Ogre::Quaternion rotation)
{ {
// Remove character with given name, so we don't make memory // Remove character with given name, so we don't make memory
// leak when character would be added twice // leak when character would be added twice
removeCharacter(name); removeCharacter(name);
PhysicActor* newActor = new PhysicActor(name); PhysicActor* newActor = new PhysicActor(name, mesh, this, position, rotation, scale);
dynamicsWorld->addCollisionObject( newActor->externalGhostObject, COL_ACTOR_EXTERNAL, COL_WORLD |COL_ACTOR_EXTERNAL );
dynamicsWorld->addCollisionObject( newActor->internalGhostObject, COL_ACTOR_INTERNAL, COL_WORLD |COL_ACTOR_INTERNAL );
dynamicsWorld->addAction( newActor->mCharacter ); //dynamicsWorld->addAction( newActor->mCharacter );
PhysicActorMap[name] = newActor; PhysicActorMap[name] = newActor;
} }
@ -465,25 +527,11 @@ namespace Physic
PhysicActor* act = it->second; PhysicActor* act = it->second;
if(act != NULL) if(act != NULL)
{ {
/*broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
PhysicActorContainer::iterator it2 = PhysicActorMap.begin();
for(;it2!=PhysicActorMap.end();it++)
{
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
}*/
//act->externalGhostObject->
dynamicsWorld->removeCollisionObject(act->externalGhostObject);
dynamicsWorld->removeCollisionObject(act->internalGhostObject);
dynamicsWorld->removeAction(act->mCharacter);
delete act; delete act;
} }
PhysicActorMap.erase(it); PhysicActorMap.erase(it);
} }
//std::cout << "ok";
} }
PhysicActor* PhysicEngine::getCharacter(std::string name) PhysicActor* PhysicEngine::getCharacter(std::string name)

View file

@ -9,14 +9,16 @@
#include "BulletShapeLoader.h" #include "BulletShapeLoader.h"
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
class btRigidBody; class btRigidBody;
class btBroadphaseInterface; class btBroadphaseInterface;
class btDefaultCollisionConfiguration; class btDefaultCollisionConfiguration;
class btSequentialImpulseConstraintSolver; class btSequentialImpulseConstraintSolver;
class btCollisionDispatcher; class btCollisionDispatcher;
class btDiscreteDynamicsWorld; class btDiscreteDynamicsWorld;
class btKinematicCharacterController;
class btHeightfieldTerrainShape; class btHeightfieldTerrainShape;
struct playerMove;
namespace BtOgre namespace BtOgre
{ {
@ -28,11 +30,14 @@ namespace MWWorld
class World; class World;
} }
namespace OEngine { namespace OEngine {
namespace Physic namespace Physic
{ {
class CMotionState; class CMotionState;
struct PhysicEvent; struct PhysicEvent;
class PhysicEngine;
class RigidBody;
/** /**
*This is just used to be able to name objects. *This is just used to be able to name objects.
@ -50,55 +55,88 @@ namespace Physic
}; };
/** /**
* A physic Actor use a modifed KinematicCharacterController taken in the bullet forum. * A physic actor uses a rigid body based on box shapes.
* Pmove is used to move the physic actor around the dynamic world.
*/ */
class PhysicActor class PhysicActor
{ {
public: public:
PhysicActor(std::string name); PhysicActor(std::string name, std::string mesh, PhysicEngine *engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale);
~PhysicActor(); ~PhysicActor();
void setCurrentWater(bool hasWater, int waterHeight);
/** /**
* This function set the walkDirection. This is not relative to the actor orientation. * This function sets the movement keys for pmove
* I think it's also needed to take time into account. A typical call should look like this:
* setWalkDirection( mvt * orientation * dt)
*/ */
void setWalkDirection(const btVector3& mvt); void setMovement(signed char rightmove, signed char forwardmove, signed char upmove);
void Rotate(const btQuaternion& quat); /**
* This adjusts the rotation of a PhysicActor
void setRotation(const btQuaternion& quat); * If we have any problems with this (getting stuck in pmove) we should change it
* from setting the visual orientation to setting the orientation of the rigid body directly.
*/
void setRotation(const Ogre::Quaternion quat);
void setGravity(float gravity); void setGravity(float gravity);
void setVerticalVelocity(float z); void setSpeed(float speed);
void setJumpVelocity(float velocity);
void enableCollisions(bool collision); void enableCollisions(bool collision);
bool getCollisionMode(); bool getCollisionMode();
btVector3 getPosition(void); /**
* This returns the visual position of the PhysicActor (used to position a scenenode).
btQuaternion getRotation(void); * Note - this is different from the position of the contained mBody.
*/
void setPosition(const btVector3& pos); Ogre::Vector3 getPosition();
btKinematicCharacterController* mCharacter;
PairCachingGhostObject* internalGhostObject;
btCollisionShape* internalCollisionShape;
PairCachingGhostObject* externalGhostObject;
btCollisionShape* externalCollisionShape;
std::string mName;
/** /**
*NPC scenenode is located on there feet, and you can't simply translate a btShape, so this vector is used * Returns the visual orientation of the PhysicActor
*each time get/setposition is called. */
*/ Ogre::Quaternion getRotation();
btVector3 mTranslation;
/**
* Sets the position of mBody from a visual position input.
* For most cases this should not be used. We should instead let pmove move the PhysicActor around for us
*/
void setPosition(const Ogre::Vector3 pos);
/**
* Sets the view angles for pmove directly.
* Remember, add 90 for yaw. Set roll to 0.
*/
void setPmoveViewAngles(float pitch, float yaw, float roll);
/**
* Sets the scale of the PhysicActor
*/
void setScale(float scale);
/**
* Runs pmove for this PhysicActor
*/
void runPmove();
private:
OEngine::Physic::RigidBody* mBody;
Ogre::Vector3 mBoxScaledTranslation;
btQuaternion mBoxRotationInverse;
Ogre::Quaternion mBoxRotation;
bool collisionMode;
std::string mMesh;
PhysicEngine* mEngine;
std::string mName;
playerMove* pmove;
}; };
/** /**
@ -143,11 +181,22 @@ namespace Physic
~PhysicEngine(); ~PhysicEngine();
/** /**
* Create a RigidBody.It does not add it to the simulation, but it does add it to the rigidBody Map, * Creates a RigidBody. It does not add it to the simulation.
* so you can get it with the getRigidBody function. * After created, the body is set to the correct rotation, position, and scale
*/ */
RigidBody* createRigidBody(std::string mesh,std::string name,float scale); RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation,
Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0);
/**
* Adjusts a rigid body to the right position and rotation
*/
void adjustRigidBody(RigidBody* body, Ogre::Vector3 position, Ogre::Quaternion rotation,
Ogre::Vector3 scaledBoxTranslation = Ogre::Vector3::ZERO, Ogre::Quaternion boxRotation = Ogre::Quaternion::IDENTITY);
/**
Mainly used to (but not limited to) adjust rigid bodies based on box shapes to the right position and rotation.
*/
void boxAdjustExternal(std::string mesh, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation);
/** /**
* Add a HeightField to the simulation * Add a HeightField to the simulation
*/ */
@ -163,7 +212,7 @@ namespace Physic
/** /**
* Add a RigidBody to the simulation * Add a RigidBody to the simulation
*/ */
void addRigidBody(RigidBody* body); void addRigidBody(RigidBody* body, bool addToMap = true);
/** /**
* Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap. * Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
@ -184,7 +233,8 @@ namespace Physic
/** /**
* Create and add a character to the scene, and add it to the ActorMap. * Create and add a character to the scene, and add it to the ActorMap.
*/ */
void addCharacter(std::string name); void addCharacter(std::string name, std::string mesh,
Ogre::Vector3 position, float scale, Ogre::Quaternion rotation);
/** /**
* Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done? * Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done?
@ -254,7 +304,7 @@ namespace Physic
HeightFieldContainer mHeightFieldMap; HeightFieldContainer mHeightFieldMap;
typedef std::map<std::string,RigidBody*> RigidBodyContainer; typedef std::map<std::string,RigidBody*> RigidBodyContainer;
RigidBodyContainer RigidBodyMap; RigidBodyContainer ObjectMap;
typedef std::map<std::string, PhysicActor*> PhysicActorContainer; typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
PhysicActorContainer PhysicActorMap; PhysicActorContainer PhysicActorMap;
@ -263,6 +313,7 @@ namespace Physic
BtOgre::DebugDrawer* mDebugDrawer; BtOgre::DebugDrawer* mDebugDrawer;
bool isDebugCreated; bool isDebugCreated;
bool mDebugActive; bool mDebugActive;
}; };

View file

@ -231,7 +231,7 @@ bool PM_SlideMove( bool gravity )
// see if we can make it there // see if we can make it there
//pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemaskg); //pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemaskg);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj); //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj);
newtrace(&trace, pm->ps.origin, end, halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(&trace, pm->ps.origin, end, pm->ps.halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
if (trace.allsolid) if (trace.allsolid)
{ {
@ -301,7 +301,7 @@ bool PM_SlideMove( bool gravity )
if(planes[i].x >= .70) if(planes[i].x >= .70)
{ {
pm->ps.velocity = Ogre::Vector3(0,0,0); pm->ps.velocity.z = 0;
return true; return true;
} }
// see how hard we are hitting things // see how hard we are hitting things
@ -449,7 +449,7 @@ int PM_StepSlideMove( bool gravity )
//pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask); //pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
//tracefunc(&trace, start_o, down, , 0, pml.scene); //tracefunc(&trace, start_o, down, , 0, pml.scene);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj); //tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
newtrace(&trace, start_o, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(&trace, down, start_o, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
// up = vec3(0, 0, 1) // up = vec3(0, 0, 1)
//VectorSet(up, 0, 0, 1); //VectorSet(up, 0, 0, 1);
@ -479,7 +479,7 @@ int PM_StepSlideMove( bool gravity )
// test the player position if they were a stepheight higher // test the player position if they were a stepheight higher
//pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask); //pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&up, D3DXVECTOR3(0.0f, STEPSIZE, 0.0f), 0, pml.traceObj); //tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&up, D3DXVECTOR3(0.0f, STEPSIZE, 0.0f), 0, pml.traceObj);
newtrace(&trace, start_o, up, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(&trace, start_o, up, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
if ( trace.allsolid ) if ( trace.allsolid )
{ {
//if ( pm->debugLevel ) //if ( pm->debugLevel )
@ -510,7 +510,7 @@ int PM_StepSlideMove( bool gravity )
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask); //pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj); //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
newtrace(&trace, pm->ps.origin, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(&trace, pm->ps.origin, down, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
if ( !trace.allsolid ) if ( !trace.allsolid )
//VectorCopy (trace.endpos, pm->ps->origin); //VectorCopy (trace.endpos, pm->ps->origin);
pm->ps.origin = trace.endpos; pm->ps.origin = trace.endpos;
@ -527,7 +527,7 @@ int PM_StepSlideMove( bool gravity )
delta = pm->ps.origin.z - start_o.z; delta = pm->ps.origin.z - start_o.z;
if ( delta > 2 ) if ( delta > 2 )
{ {
pm->ps.counter = 5; pm->ps.counter = 10;
/* /*
if (gravity) if (gravity)
@ -657,10 +657,11 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
// int i; // int i;
float addspeed, accelspeed, currentspeed; float addspeed, accelspeed, currentspeed;
// currentspeed = pm->ps->velocity dot wishdir // currentspeed = pm->ps->velocity dot wishdir
//currentspeed = DotProduct (pm->ps->velocity, wishdir); //currentspeed = DotProduct (pm->ps->velocity, wishdir);
currentspeed = pm->ps.velocity.dotProduct(wishdir); currentspeed = pm->ps.velocity.dotProduct(wishdir);
addspeed = wishspeed - currentspeed; addspeed = wishspeed - currentspeed;
if (addspeed <= 0) if (addspeed <= 0)
return; return;
@ -675,6 +676,8 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
//for (i=0 ; i<3 ; i++) //for (i=0 ; i<3 ; i++)
//pm->ps->velocity[i] += accelspeed * wishdir[i]; //pm->ps->velocity[i] += accelspeed * wishdir[i];
pm->ps.velocity += (wishdir * accelspeed); pm->ps.velocity += (wishdir * accelspeed);
//pm->ps.velocity = wishdir * wishspeed; //New, for instant acceleration
} }
static bool PM_CheckJump(void) static bool PM_CheckJump(void)
@ -701,7 +704,7 @@ static bool PM_CheckJump(void)
//pm->ps->pm_flags |= PMF_JUMP_HELD; //pm->ps->pm_flags |= PMF_JUMP_HELD;
pm->ps.groundEntityNum = ENTITYNUM_NONE; pm->ps.groundEntityNum = ENTITYNUM_NONE;
pm->ps.velocity.z = JUMP_VELOCITY; pm->ps.velocity.z = pm->ps.jump_velocity;
pm->ps.bSnap = false; pm->ps.bSnap = false;
//PM_AddEvent( EV_JUMP ); //PM_AddEvent( EV_JUMP );
@ -899,7 +902,7 @@ static void PM_WalkMove( playerMove* const pmove )
if (pmove->hasWater ) if (pmove->hasWater )
{ {
const float waterHeight = pmove->waterHeight; const float waterHeight = pmove->waterHeight;
const float waterSoundStepHeight = waterHeight + halfExtents.y; const float waterSoundStepHeight = waterHeight + pm->ps.halfExtents.y;
if (pmove->ps.origin.y < waterSoundStepHeight) if (pmove->ps.origin.y < waterSoundStepHeight)
step_underwater = true; step_underwater = true;
} }
@ -1179,7 +1182,7 @@ void PM_GroundTraceMissed()
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); //pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -64.0f, 0.0f), 0, pml.traceObj); //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -64.0f, 0.0f), 0, pml.traceObj);
newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(&trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
//It hit the ground below //It hit the ground below
if ( trace.fraction < 1.0 && pm->ps.origin.z > trace.endpos.z) if ( trace.fraction < 1.0 && pm->ps.origin.z > trace.endpos.z)
{ {
@ -1225,7 +1228,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
//pm->trace (trace, point, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); //pm->trace (trace, point, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
//tracefunc(trace, *(const D3DXVECTOR3* const)&point, *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, 0.0f, 0.0f), 0, pml.traceObj); //tracefunc(trace, *(const D3DXVECTOR3* const)&point, *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, 0.0f, 0.0f), 0, pml.traceObj);
newtrace(trace, point, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(trace, point, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
if ( !trace->allsolid ) if ( !trace->allsolid )
{ {
@ -1237,7 +1240,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
//pm->trace (trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); //pm->trace (trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
//tracefunc(trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj); //tracefunc(trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
newtrace(trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
pml.groundTrace = *trace; pml.groundTrace = *trace;
return true; return true;
} }
@ -1338,7 +1341,7 @@ static void PM_CrashLand( void )
{ {
const float waterHeight = pm->waterHeight; const float waterHeight = pm->waterHeight;
const float waterHeightSplash = waterHeight + halfExtents.y; const float waterHeightSplash = waterHeight + pm->ps.halfExtents.y;
if (pm->ps.origin.z < waterHeightSplash) if (pm->ps.origin.z < waterHeightSplash)
{ {
splashSound = true; splashSound = true;
@ -1413,7 +1416,7 @@ static void PM_GroundTrace( void )
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); //pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj); //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); newtrace(&trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
pml.groundTrace = trace; pml.groundTrace = trace;
// do something corrective if the trace starts in a solid... // do something corrective if the trace starts in a solid...

View file

@ -23,7 +23,7 @@ Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc.
extern SceneInstance* global_lastscene; extern SceneInstance* global_lastscene;
#endif*/ #endif*/
static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); static const Ogre::Vector3 halfExtentsDefault(14.64f * 2, 14.24f * 2, 33.25f * 2);
#define MAX_CLIP_PLANES 5 #define MAX_CLIP_PLANES 5
#define OVERCLIP 1.001f #define OVERCLIP 1.001f
@ -42,7 +42,6 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
#define ENTITYNUM_NONE (MAX_GENTITIES - 1) #define ENTITYNUM_NONE (MAX_GENTITIES - 1)
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2) #define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
#define MIN_WALK_NORMAL .7f // can't walk on very steep slopes #define MIN_WALK_NORMAL .7f // can't walk on very steep slopes
#define JUMP_VELOCITY (270)
#define PS_PMOVEFRAMECOUNTBITS 6 #define PS_PMOVEFRAMECOUNTBITS 6
#define MINS_Z -24 #define MINS_Z -24
#define DEFAULT_VIEWHEIGHT 26 #define DEFAULT_VIEWHEIGHT 26
@ -90,9 +89,9 @@ struct playerMove
{ {
struct playerStruct struct playerStruct
{ {
playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) playerStruct() : gravity(800.0f), speed(480.0f), jump_velocity(270), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1), halfExtents(halfExtentsDefault)
{ {
origin = Ogre::Vector3(733.164f,900.0f, 839.432f); origin = Ogre::Vector3(0.0f, 0.0f, 0.0f);
velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f); viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f);
@ -117,11 +116,13 @@ struct playerMove
Ogre::Vector3 velocity; Ogre::Vector3 velocity;
Ogre::Vector3 origin; Ogre::Vector3 origin;
Ogre::Vector3 halfExtents;
bool bSnap; bool bSnap;
bool snappingImplemented; bool snappingImplemented;
int counter; int counter;
float gravity; // default = 800 float gravity; // default = 800
float speed; // default = 320 float speed; // default = 320
float jump_velocity; //default = 270
int commandTime; // the time at which this command was issued (in milliseconds) int commandTime; // the time at which this command was issued (in milliseconds)

View file

@ -13,18 +13,22 @@
void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object
{ {
static float lastyaw = 0.0f;
static float lastpitch = 0.0f;
//if (!traceobj) //if (!traceobj)
// return; // return;
//if (!traceobj->incellptr) //if (!traceobj->incellptr)
// return; // return;
const Ogre::Vector3 rayDir = end - start; const Ogre::Vector3 rayDir = end - start;
// Nudge starting point backwards
//const Position3D nudgestart = start + (rayDir * -0.1f); // by 10% (isn't that too much?)
//const Position3D nudgestart = start;
NewPhysTraceResults out; NewPhysTraceResults out;
//std::cout << "Starting trace\n"; //std::cout << "Starting trace\n";
@ -32,7 +36,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr
//Ogre::Vector3 endReplace = startReplace; //Ogre::Vector3 endReplace = startReplace;
//endReplace.z -= .25; //endReplace.z -= .25;
const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0, rotation), isInterior, enginePass); const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f, 0.0f), isInterior, enginePass);
if (out.fraction < 0.001f) if (out.fraction < 0.001f)
results->startsolid = true; results->startsolid = true;
@ -95,13 +99,14 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
//if(enginePass->dynamicsWorld->getCollisionObjectArray().at(60)->getCollisionShape()->isConvex()) //if(enginePass->dynamicsWorld->getCollisionObjectArray().at(60)->getCollisionShape()->isConvex())
// std::cout << "It's convex\n"; // std::cout << "It's convex\n";
const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.z); const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.z);
const btVector3 btend(end.x, end.y, end.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 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));
//const btCapsuleShapeZ newshape(BBHalfExtents.x, BBHalfExtents.z * 2 - BBHalfExtents.x * 2);
const btTransform from(btrot, btstart); const btTransform from(btrot, btstart);
const btTransform to(btrot, btend); const btTransform to(btrot, btend);
@ -176,7 +181,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) ) if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
{ {
//We're solid //We're solid
out->startSolid = true; //THIS NEEDS TO BE TURNED OFF IF WE WANT FALLING IN EXTERIORS TO WORK CORRECTLY!!!!!!!
//out->startSolid = true;
} }
} }
} }

View file

@ -5,9 +5,8 @@
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h> #include <btBulletCollisionCommon.h>
#include <components/nifbullet/bullet_nif_loader.hpp> #include <components/nifbullet/bullet_nif_loader.hpp>
#include <openengine/bullet/pmove.h>
#include <openengine/bullet/physic.hpp> #include <openengine/bullet/physic.hpp>
#include "pmove.h"
enum traceWorldType enum traceWorldType

View file

@ -1,52 +1,50 @@
#include "fader.hpp" #include "fader.hpp"
#include <OgreOverlayManager.h>
#include <OgreOverlayContainer.h>
#include <OgreOverlay.h>
#include <OgreMaterial.h> #include <OgreMaterial.h>
#include <OgreTechnique.h> #include <OgreTechnique.h>
#include <OgreMaterialManager.h> #include <OgreMaterialManager.h>
#include <OgreResourceGroupManager.h> #include <OgreResourceGroupManager.h>
#include <OgreRectangle2D.h>
#include <OgreSceneManager.h>
#define FADE_OVERLAY_NAME "FadeInOutOverlay"
#define FADE_OVERLAY_PANEL_NAME "FadeInOutOverlayPanel"
#define FADE_MATERIAL_NAME "FadeInOutMaterial"
using namespace Ogre; using namespace Ogre;
using namespace OEngine::Render; using namespace OEngine::Render;
Fader::Fader() : Fader::Fader(Ogre::SceneManager* sceneMgr)
mMode(FadingMode_In), : mSceneMgr(sceneMgr)
mRemainingTime(0.f), , mMode(FadingMode_In)
mTargetTime(0.f), , mRemainingTime(0.f)
mTargetAlpha(0.f), , mTargetTime(0.f)
mCurrentAlpha(0.f), , mTargetAlpha(0.f)
mStartAlpha(0.f) , mCurrentAlpha(0.f)
, mStartAlpha(0.f)
{ {
// Create the fading material // Create the fading material
MaterialPtr material = MaterialManager::getSingleton().create( FADE_MATERIAL_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); MaterialPtr material = MaterialManager::getSingleton().create("FadeInOutMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
Pass* pass = material->getTechnique(0)->getPass(0); Pass* pass = material->getTechnique(0)->getPass(0);
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mFadeTextureUnit = pass->createTextureUnitState(); mFadeTextureUnit = pass->createTextureUnitState();
mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour
// Create the overlay mRectangle = new Ogre::Rectangle2D(true);
OverlayManager& ovm = OverlayManager::getSingleton(); mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0);
mRectangle->setMaterial("FadeInOutMaterial");
mRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY-1);
// Use infinite AAB to always stay visible
Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite();
mRectangle->setBoundingBox(aabInf);
// Attach background to the scene
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(mRectangle);
mRectangle->setVisible(false);
mRectangle->setVisibilityFlags (0x01);
}
mOverlay = ovm.create( FADE_OVERLAY_NAME ); Fader::~Fader()
{
OverlayContainer* overlay_panel; delete mRectangle;
overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", FADE_OVERLAY_PANEL_NAME);
// position it over the whole screen
overlay_panel->_setPosition(0, 0);
overlay_panel->_setDimensions(1, 1);
overlay_panel->setMaterialName( FADE_MATERIAL_NAME );
overlay_panel->show();
mOverlay->add2D(overlay_panel);
mOverlay->hide();
} }
void Fader::update(float dt) void Fader::update(float dt)
@ -69,12 +67,12 @@ void Fader::update(float dt)
mRemainingTime -= dt; mRemainingTime -= dt;
} }
if (mCurrentAlpha == 0.f) mOverlay->hide(); if (mCurrentAlpha == 0.f) mRectangle->setVisible(false);
} }
void Fader::applyAlpha() void Fader::applyAlpha()
{ {
mOverlay->show(); mRectangle->setVisible(true);
mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, mCurrentAlpha); mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, mCurrentAlpha);
} }

View file

@ -4,52 +4,52 @@
/* /*
A class that handles fading in the screen from black or fading it out to black. A class that handles fading in the screen from black or fading it out to black.
To achieve this, it uses a full-screen Ogre::Overlay To achieve this, it uses a full-screen Rectangle2d
inspired by http://www.ogre3d.org/tikiwiki/FadeEffectOverlay (heavily adjusted)
*/ */
namespace Ogre namespace Ogre
{ {
class TextureUnitState; class TextureUnitState;
class Overlay; class Rectangle2D;
class SceneManager;
} }
namespace OEngine { namespace OEngine {
namespace Render namespace Render
{ {
class Fader class Fader
{
public:
Fader();
void update(float dt);
void fadeIn(const float time);
void fadeOut(const float time);
void fadeTo(const int percent, const float time);
private:
enum FadingMode
{ {
FadingMode_In, public:
FadingMode_Out Fader(Ogre::SceneManager* sceneMgr);
~Fader();
void update(float dt);
void fadeIn(const float time);
void fadeOut(const float time);
void fadeTo(const int percent, const float time);
private:
enum FadingMode
{
FadingMode_In,
FadingMode_Out
};
void applyAlpha();
Ogre::TextureUnitState* mFadeTextureUnit;
Ogre::Rectangle2D* mRectangle;
FadingMode mMode;
float mRemainingTime;
float mTargetTime;
float mTargetAlpha;
float mCurrentAlpha;
float mStartAlpha;
Ogre::SceneManager* mSceneMgr;
}; };
}}
void applyAlpha();
Ogre::TextureUnitState* mFadeTextureUnit;
Ogre::Overlay* mOverlay;
FadingMode mMode;
float mRemainingTime;
float mTargetTime;
float mTargetAlpha;
float mCurrentAlpha;
float mStartAlpha;
protected:
};
}}
#endif #endif

View file

@ -247,7 +247,7 @@ void OgreRenderer::createScene(const std::string& camName, float fov, float near
// Alter the camera aspect ratio to match the viewport // Alter the camera aspect ratio to match the viewport
mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight())); mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight()));
mFader = new Fader(); mFader = new Fader(mScene);
} }
void OgreRenderer::adjustViewport() void OgreRenderer::adjustViewport()