mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 18:35:20 +00:00
Merge branch 'master' into tooltips
This commit is contained in:
commit
4ddd24fdfc
@ -122,6 +122,10 @@ set(OENGINE_BULLET
|
|||||||
${LIBDIR}/openengine/bullet/physic.hpp
|
${LIBDIR}/openengine/bullet/physic.hpp
|
||||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
|
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
|
||||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
|
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
|
||||||
|
${LIBDIR}/openengine/bullet/pmove.cpp
|
||||||
|
${LIBDIR}/openengine/bullet/pmove.h
|
||||||
|
${LIBDIR}/openengine/bullet/trace.cpp
|
||||||
|
${LIBDIR}/openengine/bullet/trace.h
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -148,7 +148,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
|||||||
, mNewGame (false)
|
, mNewGame (false)
|
||||||
, mUseSound (true)
|
, mUseSound (true)
|
||||||
, mCompileAll (false)
|
, mCompileAll (false)
|
||||||
, mFocusTDiff (0)
|
|
||||||
, mScriptContext (0)
|
, mScriptContext (0)
|
||||||
, mFSStrict (false)
|
, mFSStrict (false)
|
||||||
, mCfgMgr(configurationManager)
|
, mCfgMgr(configurationManager)
|
||||||
@ -263,7 +262,6 @@ void OMW::Engine::setNewGame(bool newGame)
|
|||||||
|
|
||||||
void OMW::Engine::go()
|
void OMW::Engine::go()
|
||||||
{
|
{
|
||||||
mFocusTDiff = 0;
|
|
||||||
assert (!mCellName.empty());
|
assert (!mCellName.empty());
|
||||||
assert (!mMaster.empty());
|
assert (!mMaster.empty());
|
||||||
assert (!mOgre);
|
assert (!mOgre);
|
||||||
|
@ -74,7 +74,6 @@ namespace OMW
|
|||||||
bool mNewGame;
|
bool mNewGame;
|
||||||
bool mUseSound;
|
bool mUseSound;
|
||||||
bool mCompileAll;
|
bool mCompileAll;
|
||||||
float mFocusTDiff;
|
|
||||||
std::string mFocusName;
|
std::string mFocusName;
|
||||||
std::map<std::string,std::string> mFallbackMap;
|
std::map<std::string,std::string> mFallbackMap;
|
||||||
|
|
||||||
|
@ -287,11 +287,12 @@ namespace MWClass
|
|||||||
{
|
{
|
||||||
Ogre::Vector3 vector (0, 0, 0);
|
Ogre::Vector3 vector (0, 0, 0);
|
||||||
|
|
||||||
vector.x = - getMovementSettings (ptr).mLeftRight * 200;
|
vector.x = - getMovementSettings (ptr).mLeftRight * 127;
|
||||||
vector.y = getMovementSettings (ptr).mForwardBackward * 200;
|
vector.y = getMovementSettings (ptr).mForwardBackward * 127;
|
||||||
|
vector.z = getMovementSettings(ptr).mUpDown * 127;
|
||||||
|
|
||||||
if (getStance (ptr, Run, false))
|
//if (getStance (ptr, Run, false))
|
||||||
vector *= 2;
|
// vector *= 2;
|
||||||
|
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,8 @@ namespace MWDialogue
|
|||||||
|
|
||||||
bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
|
bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice)
|
||||||
{
|
{
|
||||||
|
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
|
||||||
|
|
||||||
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
|
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
|
||||||
iter != info.selects.end(); ++iter)
|
iter != info.selects.end(); ++iter)
|
||||||
{
|
{
|
||||||
@ -195,6 +197,9 @@ namespace MWDialogue
|
|||||||
|
|
||||||
case 46://Same faction
|
case 46://Same faction
|
||||||
{
|
{
|
||||||
|
if (isCreature)
|
||||||
|
return false;
|
||||||
|
|
||||||
MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
|
||||||
MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor);
|
MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor);
|
||||||
int sameFaction = 0;
|
int sameFaction = 0;
|
||||||
@ -283,6 +288,8 @@ namespace MWDialogue
|
|||||||
bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
|
bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
|
||||||
const ESM::DialInfo::SelectStruct& select) const
|
const ESM::DialInfo::SelectStruct& select) const
|
||||||
{
|
{
|
||||||
|
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
|
||||||
|
|
||||||
char type = select.selectRule[1];
|
char type = select.selectRule[1];
|
||||||
|
|
||||||
if (type!='0')
|
if (type!='0')
|
||||||
@ -380,6 +387,9 @@ namespace MWDialogue
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case '8':// not faction
|
case '8':// not faction
|
||||||
|
if (isCreature)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(select.type==ESM::VT_Int)
|
if(select.type==ESM::VT_Int)
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||||
@ -394,6 +404,9 @@ namespace MWDialogue
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case '9':// not class
|
case '9':// not class
|
||||||
|
if (isCreature)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(select.type==ESM::VT_Int)
|
if(select.type==ESM::VT_Int)
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||||
@ -408,6 +421,9 @@ namespace MWDialogue
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 'A'://not Race
|
case 'A'://not Race
|
||||||
|
if (isCreature)
|
||||||
|
return false;
|
||||||
|
|
||||||
if(select.type==ESM::VT_Int)
|
if(select.type==ESM::VT_Int)
|
||||||
{
|
{
|
||||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||||
@ -464,6 +480,8 @@ namespace MWDialogue
|
|||||||
|
|
||||||
bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
|
bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
|
||||||
{
|
{
|
||||||
|
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
|
||||||
|
|
||||||
// actor id
|
// actor id
|
||||||
if (!info.actor.empty())
|
if (!info.actor.empty())
|
||||||
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
|
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
|
||||||
@ -472,6 +490,9 @@ namespace MWDialogue
|
|||||||
//NPC race
|
//NPC race
|
||||||
if (!info.race.empty())
|
if (!info.race.empty())
|
||||||
{
|
{
|
||||||
|
if (isCreature)
|
||||||
|
return false;
|
||||||
|
|
||||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
||||||
|
|
||||||
if (!cellRef)
|
if (!cellRef)
|
||||||
@ -484,6 +505,9 @@ namespace MWDialogue
|
|||||||
//NPC class
|
//NPC class
|
||||||
if (!info.clas.empty())
|
if (!info.clas.empty())
|
||||||
{
|
{
|
||||||
|
if (isCreature)
|
||||||
|
return false;
|
||||||
|
|
||||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
|
||||||
|
|
||||||
if (!cellRef)
|
if (!cellRef)
|
||||||
@ -496,6 +520,9 @@ namespace MWDialogue
|
|||||||
//NPC faction
|
//NPC faction
|
||||||
if (!info.npcFaction.empty())
|
if (!info.npcFaction.empty())
|
||||||
{
|
{
|
||||||
|
if (isCreature)
|
||||||
|
return false;
|
||||||
|
|
||||||
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
|
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
|
||||||
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
||||||
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
|
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
|
||||||
@ -529,16 +556,18 @@ namespace MWDialogue
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check gender
|
//check gender
|
||||||
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
if (!isCreature)
|
||||||
if(npc->base->flags&npc->base->Female)
|
|
||||||
{
|
{
|
||||||
if(static_cast<int> (info.data.gender)==0) return false;
|
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
|
||||||
|
if(npc->base->flags&npc->base->Female)
|
||||||
|
{
|
||||||
|
if(static_cast<int> (info.data.gender)==0) return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(static_cast<int> (info.data.gender)==1) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if(static_cast<int> (info.data.gender)==1) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// check cell
|
// check cell
|
||||||
if (!info.cell.empty())
|
if (!info.cell.empty())
|
||||||
@ -839,6 +868,9 @@ namespace MWDialogue
|
|||||||
|
|
||||||
std::string DialogueManager::getFaction()
|
std::string DialogueManager::getFaction()
|
||||||
{
|
{
|
||||||
|
if (mActor.getTypeName() != typeid(ESM::NPC).name())
|
||||||
|
return "";
|
||||||
|
|
||||||
std::string factionID("");
|
std::string factionID("");
|
||||||
MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
|
MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
|
||||||
if(stats.mFactionRank.empty())
|
if(stats.mFactionRank.empty())
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "mode.hpp"
|
#include "mode.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwsound/soundmanager.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -16,6 +17,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const char* mText;
|
const char* mText;
|
||||||
const char* mButtons[3];
|
const char* mButtons[3];
|
||||||
|
const char* mSound;
|
||||||
ESM::Class::Specialization mSpecializations[3]; // The specialization for each answer
|
ESM::Class::Specialization mSpecializations[3]; // The specialization for each answer
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ namespace
|
|||||||
{"Draw your dagger, mercifully endings its life with a single thrust.",
|
{"Draw your dagger, mercifully endings its life with a single thrust.",
|
||||||
"Use herbs from your pack to put it to sleep.",
|
"Use herbs from your pack to put it to sleep.",
|
||||||
"Do not interfere in the natural evolution of events, but rather take the opportunity to learn more about a strange animal that you have never seen before."},
|
"Do not interfere in the natural evolution of events, but rather take the opportunity to learn more about a strange animal that you have never seen before."},
|
||||||
|
"vo\\misc\\chargen qa1.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 2
|
// Question 2
|
||||||
@ -32,6 +35,7 @@ namespace
|
|||||||
{"Work in the forge with him casting iron for a new plow.",
|
{"Work in the forge with him casting iron for a new plow.",
|
||||||
"Gather herbs for your mother who is preparing dinner.",
|
"Gather herbs for your mother who is preparing dinner.",
|
||||||
"Go catch fish at the stream using a net and line."},
|
"Go catch fish at the stream using a net and line."},
|
||||||
|
"vo\\misc\\chargen qa2.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 3
|
// Question 3
|
||||||
@ -39,6 +43,7 @@ namespace
|
|||||||
{"Beat up your cousin, then tell him that if he ever calls you that nickname again, you will bloody him worse than this time.",
|
{"Beat up your cousin, then tell him that if he ever calls you that nickname again, you will bloody him worse than this time.",
|
||||||
"Make up a story that makes your nickname a badge of honor instead of something humiliating.",
|
"Make up a story that makes your nickname a badge of honor instead of something humiliating.",
|
||||||
"Make up an even more embarrassing nickname for him and use it constantly until he learns his lesson."},
|
"Make up an even more embarrassing nickname for him and use it constantly until he learns his lesson."},
|
||||||
|
"vo\\misc\\chargen qa3.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 4
|
// Question 4
|
||||||
@ -46,6 +51,7 @@ namespace
|
|||||||
{"This is a terrible practice. A person's thoughts are his own and no one, not even a king, has the right to make such an invasion into another human's mind.",
|
{"This is a terrible practice. A person's thoughts are his own and no one, not even a king, has the right to make such an invasion into another human's mind.",
|
||||||
"Loyal followers to the king have nothing to fear from a Telepath. It is important to have a method of finding assassins and spies before it is too late.",
|
"Loyal followers to the king have nothing to fear from a Telepath. It is important to have a method of finding assassins and spies before it is too late.",
|
||||||
"In these times, it is a necessary evil. Although you do not necessarily like the idea, a Telepath could have certain advantages during a time of war or in finding someone innocent of a crime."},
|
"In these times, it is a necessary evil. Although you do not necessarily like the idea, a Telepath could have certain advantages during a time of war or in finding someone innocent of a crime."},
|
||||||
|
"vo\\misc\\chargen qa4.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 5
|
// Question 5
|
||||||
@ -53,6 +59,7 @@ namespace
|
|||||||
{"Return to the store and give the shopkeeper his hard-earned money, explaining to him the mistake?",
|
{"Return to the store and give the shopkeeper his hard-earned money, explaining to him the mistake?",
|
||||||
"Decide to put the extra money to good use and purchase items that would help your family?",
|
"Decide to put the extra money to good use and purchase items that would help your family?",
|
||||||
"Pocket the extra money, knowing that shopkeepers in general tend to overcharge customers anyway?"},
|
"Pocket the extra money, knowing that shopkeepers in general tend to overcharge customers anyway?"},
|
||||||
|
"vo\\misc\\chargen qa5.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 6
|
// Question 6
|
||||||
@ -60,6 +67,7 @@ namespace
|
|||||||
{"Pick up the bag and signal to the guard, knowing that the only honorable thing to do is return the money to its rightful owner.",
|
{"Pick up the bag and signal to the guard, knowing that the only honorable thing to do is return the money to its rightful owner.",
|
||||||
"Leave the bag there, knowing that it is better not to get involved.",
|
"Leave the bag there, knowing that it is better not to get involved.",
|
||||||
"Pick up the bag and pocket it, knowing that the extra windfall will help your family in times of trouble."},
|
"Pick up the bag and pocket it, knowing that the extra windfall will help your family in times of trouble."},
|
||||||
|
"vo\\misc\\chargen qa6.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 7
|
// Question 7
|
||||||
@ -67,6 +75,7 @@ namespace
|
|||||||
{"Decline his offer, knowing that your father expects you to do the work, and it is better not to be in debt.",
|
{"Decline his offer, knowing that your father expects you to do the work, and it is better not to be in debt.",
|
||||||
"Ask him to help you, knowing that two people can do the job faster than one, and agree to help him with one task of his choosing in the future.",
|
"Ask him to help you, knowing that two people can do the job faster than one, and agree to help him with one task of his choosing in the future.",
|
||||||
"Accept his offer, reasoning that as long as the stables are cleaned, it matters not who does the cleaning."},
|
"Accept his offer, reasoning that as long as the stables are cleaned, it matters not who does the cleaning."},
|
||||||
|
"vo\\misc\\chargen qa7.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 8
|
// Question 8
|
||||||
@ -74,6 +83,7 @@ namespace
|
|||||||
{"Position yourself between the pipe and your mother.",
|
{"Position yourself between the pipe and your mother.",
|
||||||
"Grab the hot pipe and try to push it away.",
|
"Grab the hot pipe and try to push it away.",
|
||||||
"Push your mother out of the way."},
|
"Push your mother out of the way."},
|
||||||
|
"vo\\misc\\chargen qa8.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 9
|
// Question 9
|
||||||
@ -81,6 +91,7 @@ namespace
|
|||||||
{"Drop the sweetroll and step on it, then get ready for the fight.",
|
{"Drop the sweetroll and step on it, then get ready for the fight.",
|
||||||
"Give him the sweetroll now without argument, knowing that later this afternoon you will have all your friends with you and can come and take whatever he owes you.",
|
"Give him the sweetroll now without argument, knowing that later this afternoon you will have all your friends with you and can come and take whatever he owes you.",
|
||||||
"Act like you're going to give him the sweetroll, but at the last minute throw it in the air, hoping that they'll pay attention to it long enough for you to get a shot in on the leader."},
|
"Act like you're going to give him the sweetroll, but at the last minute throw it in the air, hoping that they'll pay attention to it long enough for you to get a shot in on the leader."},
|
||||||
|
"vo\\misc\\chargen qa9.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
},
|
},
|
||||||
// Question 10
|
// Question 10
|
||||||
@ -88,6 +99,7 @@ namespace
|
|||||||
{"Rush to the town's aid immediately, despite your lack of knowledge of the circumstances.",
|
{"Rush to the town's aid immediately, despite your lack of knowledge of the circumstances.",
|
||||||
"Stand aside and allow the man and the mob to pass, realizing it is probably best not to get involved.",
|
"Stand aside and allow the man and the mob to pass, realizing it is probably best not to get involved.",
|
||||||
"Rush to the man's aid immediately, despite your lack of knowledge of the circumstances."},
|
"Rush to the man's aid immediately, despite your lack of knowledge of the circumstances."},
|
||||||
|
"vo\\misc\\chargen qa10.wav",
|
||||||
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
|
||||||
}
|
}
|
||||||
} };
|
} };
|
||||||
@ -479,6 +491,8 @@ void CharacterCreation::onCreateClassDialogBack()
|
|||||||
|
|
||||||
void CharacterCreation::onClassQuestionChosen(int _index)
|
void CharacterCreation::onClassQuestionChosen(int _index)
|
||||||
{
|
{
|
||||||
|
MWBase::Environment::get().getSoundManager()->stopSay();
|
||||||
|
|
||||||
if (mGenerateClassQuestionDialog)
|
if (mGenerateClassQuestionDialog)
|
||||||
mWM->removeDialog(mGenerateClassQuestionDialog);
|
mWM->removeDialog(mGenerateClassQuestionDialog);
|
||||||
if (_index < 0 || _index >= 3)
|
if (_index < 0 || _index >= 3)
|
||||||
@ -584,6 +598,8 @@ void CharacterCreation::showClassQuestionDialog()
|
|||||||
mGenerateClassQuestionDialog->setButtons(buttons);
|
mGenerateClassQuestionDialog->setButtons(buttons);
|
||||||
mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen);
|
mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen);
|
||||||
mGenerateClassQuestionDialog->open();
|
mGenerateClassQuestionDialog->open();
|
||||||
|
|
||||||
|
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps[mGenerateClassStep].mSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::onGenerateClassBack()
|
void CharacterCreation::onGenerateClassBack()
|
||||||
|
@ -60,6 +60,7 @@ namespace MWInput
|
|||||||
A_CycleWeaponRight,
|
A_CycleWeaponRight,
|
||||||
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
|
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
|
||||||
A_ToggleWalk, //Toggle Walking/Running
|
A_ToggleWalk, //Toggle Walking/Running
|
||||||
|
A_Crouch,
|
||||||
|
|
||||||
A_QuickSave,
|
A_QuickSave,
|
||||||
A_QuickLoad,
|
A_QuickLoad,
|
||||||
@ -310,6 +311,9 @@ namespace MWInput
|
|||||||
poller.bind(A_MoveRight, KC_D);
|
poller.bind(A_MoveRight, KC_D);
|
||||||
poller.bind(A_MoveForward, KC_W);
|
poller.bind(A_MoveForward, KC_W);
|
||||||
poller.bind(A_MoveBackward, KC_S);
|
poller.bind(A_MoveBackward, KC_S);
|
||||||
|
|
||||||
|
poller.bind(A_Jump, KC_E);
|
||||||
|
poller.bind(A_Crouch, KC_LCONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: Used to check for movement keys
|
//NOTE: Used to check for movement keys
|
||||||
@ -356,6 +360,13 @@ namespace MWInput
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
player.setForwardBackward (0);
|
player.setForwardBackward (0);
|
||||||
|
|
||||||
|
if (poller.isDown(A_Jump))
|
||||||
|
player.setUpDown (1);
|
||||||
|
else if (poller.isDown(A_Crouch))
|
||||||
|
player.setUpDown (-1);
|
||||||
|
else
|
||||||
|
player.setUpDown (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch between gui modes. Besides controlling the Gui windows
|
// Switch between gui modes. Besides controlling the Gui windows
|
||||||
|
@ -8,8 +8,9 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
signed char mLeftRight; // 1: wants to move left, -1: wants to move right
|
signed char mLeftRight; // 1: wants to move left, -1: wants to move right
|
||||||
signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward
|
signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward
|
||||||
|
signed char mUpDown;
|
||||||
|
|
||||||
Movement() : mLeftRight (0), mForwardBackward (0) {}
|
Movement() : mLeftRight (0), mForwardBackward (0), mUpDown(0) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,10 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
|
|||||||
|
|
||||||
Ogre::SceneNode* insert = cellnode->createChildSceneNode();
|
Ogre::SceneNode* insert = cellnode->createChildSceneNode();
|
||||||
const float *f = ptr.getRefData().getPosition().pos;
|
const float *f = ptr.getRefData().getPosition().pos;
|
||||||
|
|
||||||
insert->setPosition(f[0], f[1], f[2]);
|
insert->setPosition(f[0], f[1], f[2]);
|
||||||
insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale);
|
insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale);
|
||||||
|
|
||||||
|
|
||||||
// Convert MW rotation to a quaternion:
|
// Convert MW rotation to a quaternion:
|
||||||
f = ptr.getCellRef().pos.rot;
|
f = ptr.getCellRef().pos.rot;
|
||||||
|
@ -189,7 +189,7 @@ void MpgSnd_Decoder::readAll(std::vector<char> &output)
|
|||||||
{
|
{
|
||||||
size_t pos = output.size();
|
size_t pos = output.size();
|
||||||
output.resize(pos + mSndInfo.frames*mSndInfo.channels*2);
|
output.resize(pos + mSndInfo.frames*mSndInfo.channels*2);
|
||||||
sf_readf_short(mSndFile, (short*)(output.data()+pos), mSndInfo.frames);
|
sf_readf_short(mSndFile, (short*)(&output[0]+pos), mSndInfo.frames);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Fallback in case we don't know the total already
|
// Fallback in case we don't know the total already
|
||||||
|
@ -222,8 +222,8 @@ void OpenAL_SoundStream::play()
|
|||||||
for(ALuint i = 0;i < sNumBuffers;i++)
|
for(ALuint i = 0;i < sNumBuffers;i++)
|
||||||
{
|
{
|
||||||
size_t got;
|
size_t got;
|
||||||
got = mDecoder->read(data.data(), data.size());
|
got = mDecoder->read(&data[0], data.size());
|
||||||
alBufferData(mBuffers[i], mFormat, data.data(), got, mSampleRate);
|
alBufferData(mBuffers[i], mFormat, &data[0], got, mSampleRate);
|
||||||
}
|
}
|
||||||
throwALerror();
|
throwALerror();
|
||||||
|
|
||||||
@ -299,11 +299,11 @@ bool OpenAL_SoundStream::process()
|
|||||||
if(finished)
|
if(finished)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
got = mDecoder->read(data.data(), data.size());
|
got = mDecoder->read(&data[0], data.size());
|
||||||
finished = (got < data.size());
|
finished = (got < data.size());
|
||||||
if(got > 0)
|
if(got > 0)
|
||||||
{
|
{
|
||||||
alBufferData(bufid, mFormat, data.data(), got, mSampleRate);
|
alBufferData(bufid, mFormat, &data[0], got, mSampleRate);
|
||||||
alSourceQueueBuffers(mSource, 1, &bufid);
|
alSourceQueueBuffers(mSource, 1, &bufid);
|
||||||
}
|
}
|
||||||
} while(processed > 0);
|
} while(processed > 0);
|
||||||
@ -595,7 +595,7 @@ ALuint OpenAL_Output::getBuffer(const std::string &fname)
|
|||||||
alGenBuffers(1, &buf);
|
alGenBuffers(1, &buf);
|
||||||
throwALerror();
|
throwALerror();
|
||||||
|
|
||||||
alBufferData(buf, format, data.data(), data.size(), srate);
|
alBufferData(buf, format, &data[0], data.size(), srate);
|
||||||
mBufferCache[fname] = buf;
|
mBufferCache[fname] = buf;
|
||||||
mBufferRefs[buf] = 1;
|
mBufferRefs[buf] = 1;
|
||||||
|
|
||||||
|
@ -228,11 +228,47 @@ namespace MWSound
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::say(const std::string& filename)
|
||||||
|
{
|
||||||
|
if(!mOutput->isInitialized())
|
||||||
|
return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
float basevol = mMasterVolume * mSFXVolume;
|
||||||
|
std::string filePath = "Sound/"+filename;
|
||||||
|
|
||||||
|
SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal);
|
||||||
|
sound->mBaseVolume = basevol;
|
||||||
|
|
||||||
|
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), std::string("_say_sound"));
|
||||||
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
std::cout <<"Sound Error: "<<e.what()<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SoundManager::sayDone(MWWorld::Ptr ptr) const
|
bool SoundManager::sayDone(MWWorld::Ptr ptr) const
|
||||||
{
|
{
|
||||||
return !isPlaying(ptr, "_say_sound");
|
return !isPlaying(ptr, "_say_sound");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::stopSay(MWWorld::Ptr ptr)
|
||||||
|
{
|
||||||
|
SoundMap::iterator snditer = mActiveSounds.begin();
|
||||||
|
while(snditer != mActiveSounds.end())
|
||||||
|
{
|
||||||
|
if(snditer->second.first == ptr && snditer->second.second == "_say_sound")
|
||||||
|
{
|
||||||
|
snditer->first->stop();
|
||||||
|
mActiveSounds.erase(snditer++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snditer++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode)
|
SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode)
|
||||||
{
|
{
|
||||||
|
@ -97,11 +97,18 @@ namespace MWSound
|
|||||||
|
|
||||||
void say(MWWorld::Ptr reference, const std::string& filename);
|
void say(MWWorld::Ptr reference, const std::string& filename);
|
||||||
///< Make an actor say some text.
|
///< Make an actor say some text.
|
||||||
/// \param filename name of a sound file in "Sound/Vo/" in the data directory.
|
/// \param filename name of a sound file in "Sound/" in the data directory.
|
||||||
|
|
||||||
bool sayDone(MWWorld::Ptr reference) const;
|
void say(const std::string& filename);
|
||||||
|
///< Say some text, without an actor ref
|
||||||
|
/// \param filename name of a sound file in "Sound/" in the data directory.
|
||||||
|
|
||||||
|
bool sayDone(MWWorld::Ptr reference=MWWorld::Ptr()) const;
|
||||||
///< Is actor not speaking?
|
///< Is actor not speaking?
|
||||||
|
|
||||||
|
void stopSay(MWWorld::Ptr reference=MWWorld::Ptr());
|
||||||
|
///< Stop an actor speaking
|
||||||
|
|
||||||
SoundPtr playSound(const std::string& soundId, float volume, float pitch, int mode=Play_Normal);
|
SoundPtr playSound(const std::string& soundId, float volume, float pitch, int mode=Play_Normal);
|
||||||
///< Play a sound, independently of 3D-position
|
///< Play a sound, independently of 3D-position
|
||||||
|
|
||||||
|
@ -21,23 +21,24 @@ namespace MWWorld
|
|||||||
PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
|
PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
|
||||||
mRender(_rend), mEngine(0), mFreeFly (true)
|
mRender(_rend), mEngine(0), mFreeFly (true)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
playerphysics = new playerMove;
|
||||||
// Create physics. shapeLoader is deleted by the physic engine
|
// Create physics. shapeLoader is deleted by the physic engine
|
||||||
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
|
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
|
||||||
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
||||||
|
playerphysics->mEngine = mEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicsSystem::~PhysicsSystem()
|
PhysicsSystem::~PhysicsSystem()
|
||||||
{
|
{
|
||||||
delete mEngine;
|
delete mEngine;
|
||||||
|
|
||||||
}
|
}
|
||||||
OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
|
OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
|
||||||
{
|
{
|
||||||
return mEngine;
|
return mEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
|
std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
|
||||||
{
|
{
|
||||||
std::string handle = "";
|
std::string handle = "";
|
||||||
@ -65,6 +66,13 @@ namespace MWWorld
|
|||||||
|
|
||||||
return mEngine->rayTest2(from,to);
|
return mEngine->rayTest2(from,to);
|
||||||
}
|
}
|
||||||
|
void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight){
|
||||||
|
playerphysics->hasWater = hasWater;
|
||||||
|
if(hasWater){
|
||||||
|
playerphysics->waterHeight = waterHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
btVector3 PhysicsSystem::getRayPoint(float extent)
|
btVector3 PhysicsSystem::getRayPoint(float extent)
|
||||||
{
|
{
|
||||||
@ -75,35 +83,35 @@ namespace MWWorld
|
|||||||
btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y);
|
btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
|
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
|
||||||
{
|
{
|
||||||
btVector3 _from, _to;
|
btVector3 _from, _to;
|
||||||
_from = btVector3(from.x, from.y, from.z);
|
_from = btVector3(from.x, from.y, from.z);
|
||||||
_to = btVector3(to.x, to.y, to.z);
|
_to = btVector3(to.x, to.y, to.z);
|
||||||
|
|
||||||
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
|
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
|
||||||
|
|
||||||
return !(result.first == "");
|
return !(result.first == "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
|
|
||||||
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
|
||||||
{
|
{
|
||||||
//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 walkdirection 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->setWalkDirection(btVector3(0,0,0));
|
||||||
}
|
}
|
||||||
|
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
||||||
|
|
||||||
|
pm_ref.rightmove = 0;
|
||||||
|
pm_ref.forwardmove = 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());
|
||||||
iter!=actors.end(); ++iter)
|
iter!=actors.end(); ++iter)
|
||||||
@ -118,21 +126,24 @@ namespace MWWorld
|
|||||||
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
|
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
|
||||||
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
|
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
|
||||||
Ogre::Quaternion yawQuat = yawNode->getOrientation();
|
Ogre::Quaternion yawQuat = yawNode->getOrientation();
|
||||||
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
|
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
|
||||||
Ogre::Quaternion both = yawQuat * pitchQuat;
|
|
||||||
|
// unused
|
||||||
|
//Ogre::Quaternion both = yawQuat * pitchQuat;
|
||||||
//playerphysics->ps.viewangles.z = both.getPitch().valueDegrees();
|
|
||||||
|
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
|
||||||
|
playerphysics->ps.viewangles.z = 0;
|
||||||
|
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
|
||||||
|
|
||||||
if(mFreeFly)
|
if(mFreeFly)
|
||||||
{
|
{
|
||||||
|
|
||||||
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
||||||
|
|
||||||
|
pm_ref.rightmove = -dir1.x;
|
||||||
|
pm_ref.forwardmove = dir1.z;
|
||||||
|
pm_ref.upmove = dir1.y;
|
||||||
|
|
||||||
|
|
||||||
//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
|
//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
|
||||||
//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
|
//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
|
||||||
//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
|
//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
|
||||||
@ -140,31 +151,65 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
Ogre::Quaternion quat = yawNode->getOrientation();
|
Ogre::Quaternion quat = yawNode->getOrientation();
|
||||||
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
||||||
|
|
||||||
|
pm_ref.rightmove = -dir1.x;
|
||||||
|
pm_ref.forwardmove = dir1.z;
|
||||||
|
pm_ref.upmove = dir1.y;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dir = 0.025*(quat*dir1);
|
dir = 0.025*(quat*dir1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//set the walk direction
|
//set the walk direction
|
||||||
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
|
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
|
||||||
}
|
}
|
||||||
mEngine->stepSimulation(duration);
|
mEngine->stepSimulation(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysicsFixed (
|
||||||
|
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
||||||
|
{
|
||||||
|
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();
|
btVector3 newPos = it->second->getPosition();
|
||||||
|
|
||||||
Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
|
Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
|
||||||
|
if(it->first == "player"){
|
||||||
|
|
||||||
|
coord = playerphysics->ps.origin;
|
||||||
|
//std::cout << "ZCoord: " << coord.z << "\n";
|
||||||
|
//std::cout << "Coord" << coord << "\n";
|
||||||
|
//coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
|
response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::addHeightField (float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts)
|
||||||
|
{
|
||||||
|
mEngine->addHeightField(heights, x, y, yoffset, triSize, sqrtVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::removeHeightField (int x, int y)
|
||||||
|
{
|
||||||
|
mEngine->removeHeightField(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
|
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
||||||
{
|
{
|
||||||
@ -207,7 +252,14 @@ namespace MWWorld
|
|||||||
{
|
{
|
||||||
// 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
|
||||||
act->setPosition(btVector3(position.x,position.y,position.z));
|
if (handle == "player")
|
||||||
|
{
|
||||||
|
playerphysics->ps.origin = position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
act->setPosition(btVector3(position.x,position.y,position.z));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +280,11 @@ namespace MWWorld
|
|||||||
|
|
||||||
bool PhysicsSystem::toggleCollisionMode()
|
bool PhysicsSystem::toggleCollisionMode()
|
||||||
{
|
{
|
||||||
|
if(playerphysics->ps.move_type==PM_NOCLIP)
|
||||||
|
playerphysics->ps.move_type=PM_NORMAL;
|
||||||
|
|
||||||
|
else
|
||||||
|
playerphysics->ps.move_type=PM_NOCLIP;
|
||||||
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++)
|
||||||
{
|
{
|
||||||
if (it->first=="player")
|
if (it->first=="player")
|
||||||
@ -258,7 +315,12 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
|
void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
|
||||||
|
|
||||||
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
||||||
|
|
||||||
|
// unused
|
||||||
|
//Ogre::Vector3 objPos = node->getPosition();
|
||||||
|
|
||||||
addObject (node->getName(), model, node->getOrientation(),
|
addObject (node->getName(), model, node->getOrientation(),
|
||||||
node->getScale().x, node->getPosition());
|
node->getScale().x, node->getPosition());
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <openengine/ogre/renderer.hpp>
|
#include <openengine/ogre/renderer.hpp>
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
#include "ptr.hpp"
|
#include "ptr.hpp"
|
||||||
|
#include <openengine/bullet/pmove.h>
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
@ -15,8 +16,11 @@ namespace MWWorld
|
|||||||
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
|
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
|
||||||
~PhysicsSystem ();
|
~PhysicsSystem ();
|
||||||
|
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > doPhysics (float duration,
|
void doPhysics(float duration, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
|
||||||
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
|
///< do physics with dt - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
|
||||||
|
|
||||||
|
std::vector< std::pair<std::string, Ogre::Vector3> > doPhysicsFixed (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
|
||||||
|
///< do physics with fixed timestep - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
|
||||||
|
|
||||||
void addObject (const std::string& handle, const std::string& mesh,
|
void addObject (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
|
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
|
||||||
@ -24,6 +28,12 @@ namespace MWWorld
|
|||||||
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);
|
||||||
|
|
||||||
|
void addHeightField (float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts);
|
||||||
|
|
||||||
|
void removeHeightField (int x, int y);
|
||||||
|
|
||||||
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, const Ogre::Vector3& position);
|
||||||
@ -49,11 +59,13 @@ namespace MWWorld
|
|||||||
|
|
||||||
OEngine::Physic::PhysicEngine* getEngine();
|
OEngine::Physic::PhysicEngine* getEngine();
|
||||||
|
|
||||||
|
void setCurrentWater(bool hasWater, int waterHeight);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEngine::Render::OgreRenderer &mRender;
|
OEngine::Render::OgreRenderer &mRender;
|
||||||
OEngine::Physic::PhysicEngine* mEngine;
|
OEngine::Physic::PhysicEngine* mEngine;
|
||||||
bool mFreeFly;
|
bool mFreeFly;
|
||||||
|
playerMove* playerphysics;
|
||||||
|
|
||||||
PhysicsSystem (const PhysicsSystem&);
|
PhysicsSystem (const PhysicsSystem&);
|
||||||
PhysicsSystem& operator= (const PhysicsSystem&);
|
PhysicsSystem& operator= (const PhysicsSystem&);
|
||||||
|
@ -85,6 +85,14 @@ namespace MWWorld
|
|||||||
|
|
||||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
||||||
}
|
}
|
||||||
|
void Player::setUpDown(int value)
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::toggleRunning()
|
void Player::toggleRunning()
|
||||||
{
|
{
|
||||||
@ -100,4 +108,5 @@ namespace MWWorld
|
|||||||
MWWorld::Ptr ptr = getPlayer();
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
return MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState;
|
return MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@ namespace MWWorld
|
|||||||
void setLeftRight (int value);
|
void setLeftRight (int value);
|
||||||
|
|
||||||
void setForwardBackward (int value);
|
void setForwardBackward (int value);
|
||||||
|
void setUpDown(int value);
|
||||||
|
|
||||||
void toggleRunning();
|
void toggleRunning();
|
||||||
};
|
};
|
||||||
|
@ -75,11 +75,14 @@ namespace MWWorld
|
|||||||
|
|
||||||
|
|
||||||
// silence annoying g++ warning
|
// silence annoying g++ warning
|
||||||
for (std::vector<Ogre::SceneNode*>::const_iterator iter (functor.mHandles.begin());
|
for (std::vector<Ogre::SceneNode*>::const_iterator iter2 (functor.mHandles.begin());
|
||||||
iter!=functor.mHandles.end(); ++iter){
|
iter2!=functor.mHandles.end(); ++iter2){
|
||||||
Ogre::SceneNode* node = *iter;
|
Ogre::SceneNode* node = *iter2;
|
||||||
mPhysics->removeObject (node->getName());
|
mPhysics->removeObject (node->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!((*iter)->cell->data.flags & ESM::Cell::Interior))
|
||||||
|
mPhysics->removeHeightField( (*iter)->cell->data.gridX, (*iter)->cell->data.gridY );
|
||||||
}
|
}
|
||||||
|
|
||||||
mRendering.removeCell(*iter);
|
mRendering.removeCell(*iter);
|
||||||
@ -103,20 +106,36 @@ namespace MWWorld
|
|||||||
|
|
||||||
std::pair<CellStoreCollection::iterator, bool> result =
|
std::pair<CellStoreCollection::iterator, bool> result =
|
||||||
mActiveCells.insert(cell);
|
mActiveCells.insert(cell);
|
||||||
if(result.second){
|
|
||||||
insertCell(*cell);
|
|
||||||
mRendering.cellAdded(cell);
|
|
||||||
mRendering.configureAmbient(*cell);
|
|
||||||
mRendering.requestMap(cell);
|
|
||||||
mRendering.configureAmbient(*cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(result.second)
|
||||||
|
{
|
||||||
|
insertCell(*cell);
|
||||||
|
mRendering.cellAdded (cell);
|
||||||
|
|
||||||
|
float verts = ESM::Land::LAND_SIZE;
|
||||||
|
float worldsize = ESM::Land::REAL_SIZE;
|
||||||
|
|
||||||
|
if (!(cell->cell->data.flags & ESM::Cell::Interior))
|
||||||
|
{
|
||||||
|
ESM::Land* land = mWorld->getStore().lands.search(cell->cell->data.gridX,cell->cell->data.gridY);
|
||||||
|
mPhysics->addHeightField (land->landData->heights,
|
||||||
|
cell->cell->data.gridX, cell->cell->data.gridY,
|
||||||
|
0, ( worldsize/(verts-1) ), verts);
|
||||||
|
}
|
||||||
|
|
||||||
|
mRendering.configureAmbient(*cell);
|
||||||
|
mRendering.requestMap(cell);
|
||||||
|
mRendering.configureAmbient(*cell);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||||
bool adjustPlayerPos)
|
bool adjustPlayerPos)
|
||||||
{
|
{
|
||||||
|
bool hasWater = cell->cell->data.flags & cell->cell->HasWater;
|
||||||
|
mPhysics->setCurrentWater(hasWater, cell->cell->water);
|
||||||
if (adjustPlayerPos)
|
if (adjustPlayerPos)
|
||||||
mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]);
|
mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]);
|
||||||
|
|
||||||
|
@ -215,6 +215,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
setFallbackValues(fallbackMap);
|
setFallbackValues(fallbackMap);
|
||||||
|
|
||||||
|
lastTick = mTimer.getMilliseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -559,8 +560,9 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::moveObjectImp (Ptr ptr, float x, float y, float z)
|
bool World::moveObjectImp (Ptr ptr, float x, float y, float z)
|
||||||
{
|
{
|
||||||
|
bool ret = false;
|
||||||
ptr.getRefData().getPosition().pos[0] = x;
|
ptr.getRefData().getPosition().pos[0] = x;
|
||||||
ptr.getRefData().getPosition().pos[1] = y;
|
ptr.getRefData().getPosition().pos[1] = y;
|
||||||
ptr.getRefData().getPosition().pos[2] = z;
|
ptr.getRefData().getPosition().pos[2] = z;
|
||||||
@ -582,6 +584,7 @@ namespace MWWorld
|
|||||||
if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
|
if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
|
||||||
{
|
{
|
||||||
mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
|
mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -591,6 +594,8 @@ namespace MWWorld
|
|||||||
/// \todo cell change for non-player ref
|
/// \todo cell change for non-player ref
|
||||||
|
|
||||||
mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
|
mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::moveObject (Ptr ptr, float x, float y, float z)
|
void World::moveObject (Ptr ptr, float x, float y, float z)
|
||||||
@ -632,29 +637,50 @@ namespace MWWorld
|
|||||||
void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
||||||
float duration)
|
float duration)
|
||||||
{
|
{
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysics (duration, actors);
|
mPhysics->doPhysics(duration, actors);
|
||||||
|
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
|
const int tick = 16; // 16 ms ^= 60 Hz
|
||||||
|
|
||||||
for (std::vector< std::pair<std::string, Ogre::Vector3> >::iterator it = vectors.begin();
|
// Game clock part of the loop, contains everything that has to be executed in a fixed timestep
|
||||||
it!= vectors.end(); ++it)
|
long long dt = mTimer.getMilliseconds() - lastTick;
|
||||||
|
if (dt >= 100)
|
||||||
{
|
{
|
||||||
if (it->first=="player")
|
// throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps
|
||||||
|
lastTick += (dt - 100);
|
||||||
|
dt = 100;
|
||||||
|
}
|
||||||
|
while (dt >= tick)
|
||||||
|
{
|
||||||
|
dt -= tick;
|
||||||
|
lastTick += tick;
|
||||||
|
|
||||||
|
std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysicsFixed (actors);
|
||||||
|
|
||||||
|
std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
|
||||||
|
|
||||||
|
for (std::vector< std::pair<std::string, Ogre::Vector3> >::iterator it = vectors.begin();
|
||||||
|
it!= vectors.end(); ++it)
|
||||||
{
|
{
|
||||||
player = it;
|
if (it->first=="player")
|
||||||
|
{
|
||||||
|
player = it;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MWWorld::Ptr ptr = getPtrViaHandle (it->first);
|
||||||
|
moveObjectImp (ptr, it->second.x, it->second.y, it->second.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Make sure player is moved last (otherwise the cell might change in the middle of an update
|
||||||
|
// loop)
|
||||||
|
if (player!=vectors.end())
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = getPtrViaHandle (it->first);
|
if (moveObjectImp (getPtrViaHandle (player->first),
|
||||||
moveObjectImp (ptr, it->second.x, it->second.y, it->second.z);
|
player->second.x, player->second.y, player->second.z) == true)
|
||||||
|
return; // abort the current loop if the cell has changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure player is moved last (otherwise the cell might change in the middle of an update
|
|
||||||
// loop)
|
|
||||||
if (player!=vectors.end())
|
|
||||||
moveObjectImp (getPtrViaHandle (player->first),
|
|
||||||
player->second.x, player->second.y, player->second.z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::toggleCollisionMode()
|
bool World::toggleCollisionMode()
|
||||||
@ -789,7 +815,8 @@ namespace MWWorld
|
|||||||
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
||||||
while (it != results.end())
|
while (it != results.end())
|
||||||
{
|
{
|
||||||
if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() )
|
if ( (*it).second.find("HeightField") != std::string::npos // not interested in terrain
|
||||||
|
|| getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) // not interested in player (unless you want to talk to yourself)
|
||||||
{
|
{
|
||||||
it = results.erase(it);
|
it = results.erase(it);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
#include <openengine/ogre/fader.hpp>
|
#include <openengine/ogre/fader.hpp>
|
||||||
|
|
||||||
|
#include <OgreTimer.h>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Vector3;
|
class Vector3;
|
||||||
@ -100,9 +102,13 @@ namespace MWWorld
|
|||||||
int mNumFacing;
|
int mNumFacing;
|
||||||
std::map<std::string,std::string> mFallback;
|
std::map<std::string,std::string> mFallback;
|
||||||
|
|
||||||
|
unsigned long lastTick;
|
||||||
|
Ogre::Timer mTimer;
|
||||||
|
|
||||||
int getDaysPerMonth (int month) const;
|
int getDaysPerMonth (int month) const;
|
||||||
|
|
||||||
void moveObjectImp (Ptr ptr, float x, float y, float z);
|
bool moveObjectImp (Ptr ptr, float x, float y, float z);
|
||||||
|
///< @return true if the active cell (cell player is in) changed
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "physic.hpp"
|
#include "physic.hpp"
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <btBulletCollisionCommon.h>
|
#include <btBulletCollisionCommon.h>
|
||||||
|
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||||
//#include <apps\openmw\mwworld\world.hpp>
|
//#include <apps\openmw\mwworld\world.hpp>
|
||||||
#include "CMotionState.h"
|
#include "CMotionState.h"
|
||||||
@ -10,6 +11,8 @@
|
|||||||
#include "BtOgreGP.h"
|
#include "BtOgreGP.h"
|
||||||
#include "BtOgreExtras.h"
|
#include "BtOgreExtras.h"
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#define BIT(x) (1<<(x))
|
#define BIT(x) (1<<(x))
|
||||||
|
|
||||||
namespace OEngine {
|
namespace OEngine {
|
||||||
@ -161,10 +164,12 @@ namespace Physic
|
|||||||
// The actual physics solver
|
// The actual physics solver
|
||||||
solver = new btSequentialImpulseConstraintSolver;
|
solver = new btSequentialImpulseConstraintSolver;
|
||||||
|
|
||||||
|
//btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache();
|
||||||
pairCache = new btSortedOverlappingPairCache();
|
pairCache = new btSortedOverlappingPairCache();
|
||||||
|
|
||||||
//pairCache->setInternalGhostPairCallback( new btGhostPairCallback() );
|
//pairCache->setInternalGhostPairCallback( new btGhostPairCallback() );
|
||||||
|
|
||||||
broadphase = new btDbvtBroadphase(pairCache);
|
broadphase = new btDbvtBroadphase();
|
||||||
|
|
||||||
// The world.
|
// The world.
|
||||||
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
|
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
|
||||||
@ -253,6 +258,60 @@ namespace Physic
|
|||||||
delete mShapeLoader;
|
delete mShapeLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicEngine::addHeightField(float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts)
|
||||||
|
{
|
||||||
|
const std::string name = "HeightField_"
|
||||||
|
+ boost::lexical_cast<std::string>(x) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(y);
|
||||||
|
|
||||||
|
// find the minimum and maximum heights (needed for bullet)
|
||||||
|
float minh;
|
||||||
|
float maxh;
|
||||||
|
for (int i=0; i<sqrtVerts*sqrtVerts; ++i)
|
||||||
|
{
|
||||||
|
float h = heights[i];
|
||||||
|
if (i==0)
|
||||||
|
{
|
||||||
|
minh = h;
|
||||||
|
maxh = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h>maxh) maxh = h;
|
||||||
|
if (h<minh) minh = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
btHeightfieldTerrainShape* hfShape = new btHeightfieldTerrainShape(
|
||||||
|
sqrtVerts, sqrtVerts, heights, 1,
|
||||||
|
minh, maxh, 2,
|
||||||
|
PHY_FLOAT,true);
|
||||||
|
|
||||||
|
hfShape->setUseDiamondSubdivision(true);
|
||||||
|
|
||||||
|
btVector3 scl(triSize, triSize, 1);
|
||||||
|
hfShape->setLocalScaling(scl);
|
||||||
|
|
||||||
|
CMotionState* newMotionState = new CMotionState(this,name);
|
||||||
|
|
||||||
|
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,hfShape);
|
||||||
|
RigidBody* body = new RigidBody(CI,name);
|
||||||
|
body->collide = true;
|
||||||
|
body->getWorldTransform().setOrigin(btVector3( (x+0.5)*triSize*(sqrtVerts-1), (y+0.5)*triSize*(sqrtVerts-1), (maxh+minh)/2.f));
|
||||||
|
|
||||||
|
addRigidBody(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicEngine::removeHeightField(int x, int y)
|
||||||
|
{
|
||||||
|
const std::string name = "HeightField_"
|
||||||
|
+ boost::lexical_cast<std::string>(x) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(y);
|
||||||
|
|
||||||
|
removeRigidBody(name);
|
||||||
|
deleteRigidBody(name);
|
||||||
|
}
|
||||||
|
|
||||||
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
|
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
|
||||||
{
|
{
|
||||||
//get the shape from the .nif
|
//get the shape from the .nif
|
||||||
@ -334,7 +393,7 @@ namespace Physic
|
|||||||
|
|
||||||
void PhysicEngine::stepSimulation(double deltaT)
|
void PhysicEngine::stepSimulation(double deltaT)
|
||||||
{
|
{
|
||||||
dynamicsWorld->stepSimulation(deltaT,1,1/50.);
|
dynamicsWorld->stepSimulation(deltaT,10, 1/60.0);
|
||||||
if(isDebugCreated)
|
if(isDebugCreated)
|
||||||
{
|
{
|
||||||
mDebugDrawer->step();
|
mDebugDrawer->step();
|
||||||
|
@ -140,6 +140,18 @@ namespace Physic
|
|||||||
*/
|
*/
|
||||||
RigidBody* createRigidBody(std::string mesh,std::string name,float scale);
|
RigidBody* createRigidBody(std::string mesh,std::string name,float scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a HeightField to the simulation
|
||||||
|
*/
|
||||||
|
void addHeightField(float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a HeightField from the simulation
|
||||||
|
*/
|
||||||
|
void removeHeightField(int x, int y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a RigidBody to the simulation
|
* Add a RigidBody to the simulation
|
||||||
*/
|
*/
|
||||||
|
2095
libs/openengine/bullet/pmove.cpp
Normal file
2095
libs/openengine/bullet/pmove.cpp
Normal file
File diff suppressed because it is too large
Load Diff
200
libs/openengine/bullet/pmove.h
Normal file
200
libs/openengine/bullet/pmove.h
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
#ifndef OENGINE_BULLET_PMOVE_H
|
||||||
|
#define OENGINE_BULLET_PMOVE_H
|
||||||
|
/*
|
||||||
|
This source file is a *modified* version of various header files from the Quake 3 Arena source code,
|
||||||
|
which was released under the GNU GPL (v2) in 2005.
|
||||||
|
Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Ogre.h>
|
||||||
|
#include <OgreMath.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include "trace.h"
|
||||||
|
#include "physic.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
//#include "GameMath.h"
|
||||||
|
//#include "GameTime.h"
|
||||||
|
|
||||||
|
// Forwards-declare it!
|
||||||
|
|
||||||
|
/*#ifndef COMPILING_PMOVE
|
||||||
|
#include "Scene.h"
|
||||||
|
extern SceneInstance* global_lastscene;
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
||||||
|
|
||||||
|
#define MAX_CLIP_PLANES 5
|
||||||
|
#define OVERCLIP 1.001f
|
||||||
|
//#define STEPSIZE 18 // 18 is way too much
|
||||||
|
#define STEPSIZE (18 / 2)
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846f
|
||||||
|
#endif
|
||||||
|
#define YAW 0
|
||||||
|
#define PITCH /*1*/2
|
||||||
|
#define ROLL /*2*/1
|
||||||
|
#define SHORT2ANGLE(x) ( (x) * (360.0f / 65536.0f) )
|
||||||
|
#define ANGLE2SHORT(x) ( (const short)( (x) / (360.0f / 65536.0f) ) )
|
||||||
|
#define GENTITYNUM_BITS 10 // don't need to send any more
|
||||||
|
#define MAX_GENTITIES (1 << GENTITYNUM_BITS)
|
||||||
|
#define ENTITYNUM_NONE (MAX_GENTITIES - 1)
|
||||||
|
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
|
||||||
|
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
|
||||||
|
#define JUMP_VELOCITY (270)
|
||||||
|
#define PS_PMOVEFRAMECOUNTBITS 6
|
||||||
|
#define MINS_Z -24
|
||||||
|
#define DEFAULT_VIEWHEIGHT 26
|
||||||
|
#define CROUCH_VIEWHEIGHT 12
|
||||||
|
#define DEAD_VIEWHEIGHT (-16)
|
||||||
|
#define CONTENTS_SOLID 1 // an eye is never valid in a solid
|
||||||
|
#define CONTENTS_LAVA 8
|
||||||
|
#define CONTENTS_SLIME 16
|
||||||
|
#define CONTENTS_WATER 32
|
||||||
|
#define CONTENTS_FOG 64
|
||||||
|
static const float pm_accelerate = 10.0f;
|
||||||
|
static const float pm_stopspeed = 100.0f;
|
||||||
|
static const float pm_friction = 12.0f;
|
||||||
|
static const float pm_flightfriction = 3.0f;
|
||||||
|
static const float pm_waterfriction = 1.0f;
|
||||||
|
static const float pm_airaccelerate = 1.0f;
|
||||||
|
static const float pm_swimScale = 0.50f;
|
||||||
|
static const float pm_duckScale = 0.25f;
|
||||||
|
static const float pm_flyaccelerate = 8.0f;
|
||||||
|
static const float pm_wateraccelerate = 4.0f;
|
||||||
|
|
||||||
|
enum pmtype_t
|
||||||
|
{
|
||||||
|
PM_NORMAL, // can accelerate and turn
|
||||||
|
PM_NOCLIP, // noclip movement
|
||||||
|
PM_SPECTATOR, // still run into walls
|
||||||
|
PM_DEAD, // no acceleration or turning, but free falling
|
||||||
|
PM_FREEZE, // stuck in place with no control
|
||||||
|
PM_INTERMISSION, // no movement or status bar
|
||||||
|
PM_SPINTERMISSION // no movement or status bar
|
||||||
|
};
|
||||||
|
|
||||||
|
enum waterlevel_t
|
||||||
|
{
|
||||||
|
WL_DRYLAND = 0,
|
||||||
|
WL_ANKLE,
|
||||||
|
WL_WAIST,
|
||||||
|
WL_UNDERWATER
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//#include "bprintf.h"
|
||||||
|
|
||||||
|
struct playerMove
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
origin = Ogre::Vector3(733.164f,900.0f, 839.432f);
|
||||||
|
velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
delta_angles[0] = delta_angles[1] = delta_angles[2] = 0;
|
||||||
|
|
||||||
|
lastframe_origin.x = lastframe_origin.y = lastframe_origin.z = 0;
|
||||||
|
lerp_multiplier.x = lerp_multiplier.y = lerp_multiplier.z = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SpeedUp(void)
|
||||||
|
{
|
||||||
|
//printf("speed up to: %f\n", speed);
|
||||||
|
speed *= 1.25f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SpeedDown(void)
|
||||||
|
{
|
||||||
|
//printf("speed down to %f\n", speed);
|
||||||
|
speed /= 1.25f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 velocity;
|
||||||
|
Ogre::Vector3 origin;
|
||||||
|
bool bSnap;
|
||||||
|
bool snappingImplemented;
|
||||||
|
int counter;
|
||||||
|
float gravity; // default = 800
|
||||||
|
float speed; // default = 320
|
||||||
|
|
||||||
|
int commandTime; // the time at which this command was issued (in milliseconds)
|
||||||
|
|
||||||
|
int pm_time;
|
||||||
|
|
||||||
|
Ogre::Vector3 viewangles;
|
||||||
|
|
||||||
|
int groundEntityNum;
|
||||||
|
|
||||||
|
int pmove_framecount;
|
||||||
|
|
||||||
|
int watertype;
|
||||||
|
waterlevel_t waterlevel;
|
||||||
|
|
||||||
|
signed short delta_angles[3];
|
||||||
|
|
||||||
|
pmtype_t move_type;
|
||||||
|
|
||||||
|
float last_compute_time;
|
||||||
|
Ogre::Vector3 lastframe_origin;
|
||||||
|
Ogre::Vector3 lerp_multiplier;
|
||||||
|
} ps;
|
||||||
|
|
||||||
|
struct playercmd
|
||||||
|
{
|
||||||
|
enum CMDstateChange
|
||||||
|
{
|
||||||
|
NO_CHANGE,
|
||||||
|
KEYDOWN,
|
||||||
|
KEYUP
|
||||||
|
};
|
||||||
|
|
||||||
|
playercmd() : forwardmove(0), rightmove(0), upmove(0), serverTime(50), ducking(false),
|
||||||
|
activating(false), lastActivatingState(false), procActivating(NO_CHANGE),
|
||||||
|
dropping(false), lastDroppingState(false), procDropping(NO_CHANGE)
|
||||||
|
{
|
||||||
|
angles[0] = angles[1] = angles[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int serverTime;
|
||||||
|
|
||||||
|
short angles[3];
|
||||||
|
|
||||||
|
signed char forwardmove;
|
||||||
|
signed char rightmove;
|
||||||
|
signed char upmove;
|
||||||
|
|
||||||
|
bool ducking;
|
||||||
|
bool activating; // if the user is holding down the activate button
|
||||||
|
bool dropping; // if the user is dropping an item
|
||||||
|
|
||||||
|
bool lastActivatingState;
|
||||||
|
bool lastDroppingState;
|
||||||
|
|
||||||
|
CMDstateChange procActivating;
|
||||||
|
CMDstateChange procDropping;
|
||||||
|
} cmd;
|
||||||
|
|
||||||
|
playerMove() : msec(50), pmove_fixed(false), pmove_msec(50), waterHeight(0), isInterior(true), hasWater(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int msec;
|
||||||
|
int pmove_msec;
|
||||||
|
bool pmove_fixed;
|
||||||
|
int waterHeight;
|
||||||
|
bool hasWater;
|
||||||
|
bool isInterior;
|
||||||
|
//Object* traceObj;
|
||||||
|
OEngine::Physic::PhysicEngine* mEngine;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Pmove (playerMove* const pmove);
|
||||||
|
void Ext_UpdateViewAngles(playerMove* const pm);
|
||||||
|
void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Ogre::Vector3* const right, Ogre::Vector3* const up) ;
|
||||||
|
#endif
|
190
libs/openengine/bullet/trace.cpp
Normal file
190
libs/openengine/bullet/trace.cpp
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
|
||||||
|
//if (!traceobj)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
//if (!traceobj->incellptr)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
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;
|
||||||
|
//std::cout << "Starting trace\n";
|
||||||
|
//Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45);
|
||||||
|
//Ogre::Vector3 endReplace = startReplace;
|
||||||
|
//endReplace.z -= .25;
|
||||||
|
|
||||||
|
const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0, rotation), isInterior, enginePass);
|
||||||
|
|
||||||
|
if (out.fraction < 0.001f)
|
||||||
|
results->startsolid = true;
|
||||||
|
else
|
||||||
|
results->startsolid = false;
|
||||||
|
|
||||||
|
|
||||||
|
//results->allsolid = out.startSolid;
|
||||||
|
|
||||||
|
// If outside and underground, we're solid
|
||||||
|
/*if (isInterior)
|
||||||
|
{
|
||||||
|
const Ogre::Vector3 height = GetGroundPosition(start, CellCoords(traceCell->data->gridX, traceCell->data->gridY) );
|
||||||
|
if (start.yPos - height.yPos < (-2.0f * BBHalfExtents.yPos) )
|
||||||
|
{
|
||||||
|
results->allsolid = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
results->allsolid = false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// If inside and out of the tree, we're solid
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
results->allsolid = out.startSolid;
|
||||||
|
//std::cout << "allsolid" << results->allsolid << "\n";
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (!hasHit)
|
||||||
|
{
|
||||||
|
results->endpos = end;
|
||||||
|
results->planenormal = Ogre::Vector3(0.0f, 0.0f, 1.0f);
|
||||||
|
results->entityNum = ENTITYNUM_NONE;
|
||||||
|
results->fraction = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
results->fraction = out.fraction;
|
||||||
|
results->planenormal = out.hitNormal;
|
||||||
|
results->endpos = rayDir * results->fraction + start;
|
||||||
|
results->entityNum = ENTITYNUM_WORLD;
|
||||||
|
/*bprintf("Start: (%f, %f, %f) End: (%f, %f, %f) TraceDir: (%f, %f, %f) HitNormal: (%f, %f, %f) Fraction: %f Hitpos: (%f, %f, %f) CompensatedHitpos: (%f, %f, %f)\n",
|
||||||
|
start.xPos, start.yPos, start.zPos,
|
||||||
|
end.xPos, end.yPos, end.zPos,
|
||||||
|
rayDir.xPos, rayDir.yPos, rayDir.zPos,
|
||||||
|
results->planenormal.xPos, results->planenormal.yPos, results->planenormal.zPos, results->fraction,
|
||||||
|
out.endPos.xPos, out.endPos.yPos, out.endPos.zPos,
|
||||||
|
results->endpos.xPos, results->endpos.yPos, results->endpos.zPos);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <const traceWorldType traceType>
|
||||||
|
const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end,
|
||||||
|
const Ogre::Vector3& BBHalfExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass)
|
||||||
|
{
|
||||||
|
//if (!traceobj->incellptr)
|
||||||
|
// return false;
|
||||||
|
//if(enginePass->dynamicsWorld->getCollisionObjectArray().at(60)->getCollisionShape()->isConvex())
|
||||||
|
// std::cout << "It's convex\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const btVector3 btstart(start.x, start.y, start.z);
|
||||||
|
const btVector3 btend(end.x, end.y, end.z);
|
||||||
|
const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z
|
||||||
|
|
||||||
|
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
||||||
|
const btTransform from(btrot, btstart);
|
||||||
|
const btTransform to(btrot, btend);
|
||||||
|
|
||||||
|
// warning: unused variable ...
|
||||||
|
/*
|
||||||
|
float x = from.getOrigin().getX();
|
||||||
|
float y = from.getOrigin().getY();
|
||||||
|
float z = from.getOrigin().getZ();
|
||||||
|
float x2 = to.getOrigin().getX();
|
||||||
|
float y2 = to.getOrigin().getY();
|
||||||
|
float z2 = to.getOrigin().getZ();
|
||||||
|
*/
|
||||||
|
|
||||||
|
//std::cout << "BtFrom: " << x << "," << y << "," << z << "\n";
|
||||||
|
//std::cout << "BtTo: " << x2 << "," << y2 << "," << z2 << "\n";
|
||||||
|
//std::cout << "BtTo: " << to.getOrigin().getX() << "," << to.getOrigin().getY() << "," << to.getOrigin().getZ() << "\n";
|
||||||
|
|
||||||
|
|
||||||
|
btCollisionWorld::ClosestConvexResultCallback
|
||||||
|
newTraceCallback(btstart, btend);
|
||||||
|
|
||||||
|
newTraceCallback.m_collisionFilterMask = (traceType == collisionWorldTrace) ? Only_Collision : Only_Pickup;
|
||||||
|
|
||||||
|
|
||||||
|
enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback);
|
||||||
|
//newTraceCallback.
|
||||||
|
|
||||||
|
|
||||||
|
//std::cout << "NUM: " << enginePass->dynamicsWorld->getNumCollisionObjects() << "\n";
|
||||||
|
|
||||||
|
// Copy the hit data over to our trace results struct:
|
||||||
|
out->fraction = newTraceCallback.m_closestHitFraction;
|
||||||
|
|
||||||
|
Ogre::Vector3& outhitnormal = out->hitNormal;
|
||||||
|
const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
|
||||||
|
|
||||||
|
outhitnormal.x = tracehitnormal.x();
|
||||||
|
outhitnormal.y = tracehitnormal.y();
|
||||||
|
outhitnormal.z = tracehitnormal.z();
|
||||||
|
|
||||||
|
Ogre::Vector3& outhitpos = out->endPos;
|
||||||
|
const btVector3& tracehitpos = newTraceCallback.m_hitPointWorld;
|
||||||
|
|
||||||
|
outhitpos.x = tracehitpos.x();
|
||||||
|
outhitpos.y = tracehitpos.y();
|
||||||
|
outhitpos.z= tracehitpos.z();
|
||||||
|
|
||||||
|
// StartSolid test:
|
||||||
|
{
|
||||||
|
out->startSolid = false;
|
||||||
|
//btCollisionObject collision;
|
||||||
|
//collision.setCollisionShape(const_cast<btBoxShape* const>(&newshape) );
|
||||||
|
|
||||||
|
//CustomContactCallback crb;
|
||||||
|
|
||||||
|
//world.world->contactTest(&collision, crb);
|
||||||
|
//out->startSolid = crb.hit;
|
||||||
|
|
||||||
|
// If outside and underground, we're solid
|
||||||
|
if (!isInterior) //Check if we are interior
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// If inside and out of the tree, we're solid
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btVector3 aabbMin, aabbMax;
|
||||||
|
enginePass->broadphase->getBroadphaseAabb(aabbMin, aabbMax);
|
||||||
|
//std::cout << "AABBMIN" << aabbMin.getX() <<"," <<aabbMin.getY() << "," << aabbMin.getZ() << "\n";
|
||||||
|
//std::cout << "AABBMAX" << aabbMax.getX() <<"," <<aabbMax.getY() << "," << aabbMax.getZ() << "\n";
|
||||||
|
//std::cout << "AABBMAX" << aabbMax << "\n";
|
||||||
|
if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
|
||||||
|
{
|
||||||
|
//We're solid
|
||||||
|
out->startSolid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool hasHit = newTraceCallback.hasHit();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return hasHit;
|
||||||
|
}
|
@ -18,7 +18,7 @@ enum traceWorldType
|
|||||||
bothWorldTrace = collisionWorldTrace | pickWorldTrace
|
bothWorldTrace = collisionWorldTrace | pickWorldTrace
|
||||||
};
|
};
|
||||||
|
|
||||||
enum collaborativePhysicsType : unsigned
|
enum collaborativePhysicsType
|
||||||
{
|
{
|
||||||
No_Physics = 0, // Both are empty (example: statics you can walk through, like tall grass)
|
No_Physics = 0, // Both are empty (example: statics you can walk through, like tall grass)
|
||||||
Only_Collision = 1, // This object only has collision physics but no pickup physics (example: statics)
|
Only_Collision = 1, // This object only has collision physics but no pickup physics (example: statics)
|
||||||
@ -53,10 +53,10 @@ struct traceResults
|
|||||||
|
|
||||||
template <const traceWorldType traceType>
|
template <const traceWorldType traceType>
|
||||||
const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
||||||
template const bool NewPhysicsTrace<collisionWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
//template const bool NewPhysicsTrace<collisionWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
||||||
template const bool NewPhysicsTrace<pickWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
//template const bool NewPhysicsTrace<pickWorldTrace>(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
||||||
|
|
||||||
void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user