Merge branch 'master' of https://github.com/zinnschlag/openmw into gui

actorid
scrawl 13 years ago
commit ad5753ba91

@ -122,6 +122,10 @@ set(OENGINE_BULLET
${LIBDIR}/openengine/bullet/physic.hpp
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
${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)
, mUseSound (true)
, mCompileAll (false)
, mFocusTDiff (0)
, mScriptContext (0)
, mFSStrict (false)
, mCfgMgr(configurationManager)
@ -263,7 +262,6 @@ void OMW::Engine::setNewGame(bool newGame)
void OMW::Engine::go()
{
mFocusTDiff = 0;
assert (!mCellName.empty());
assert (!mMaster.empty());
assert (!mOgre);

@ -74,7 +74,6 @@ namespace OMW
bool mNewGame;
bool mUseSound;
bool mCompileAll;
float mFocusTDiff;
std::string mFocusName;
std::map<std::string,std::string> mFallbackMap;

@ -287,11 +287,12 @@ namespace MWClass
{
Ogre::Vector3 vector (0, 0, 0);
vector.x = - getMovementSettings (ptr).mLeftRight * 200;
vector.y = getMovementSettings (ptr).mForwardBackward * 200;
vector.x = - getMovementSettings (ptr).mLeftRight * 127;
vector.y = getMovementSettings (ptr).mForwardBackward * 127;
vector.z = getMovementSettings(ptr).mUpDown * 127;
if (getStance (ptr, Run, false))
vector *= 2;
//if (getStance (ptr, Run, false))
// vector *= 2;
return vector;
}

@ -161,6 +161,8 @@ namespace MWDialogue
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());
iter != info.selects.end(); ++iter)
{
@ -195,6 +197,9 @@ namespace MWDialogue
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 NPCstats = MWWorld::Class::get(actor).getNpcStats(actor);
int sameFaction = 0;
@ -283,6 +288,8 @@ namespace MWDialogue
bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
const ESM::DialInfo::SelectStruct& select) const
{
bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
char type = select.selectRule[1];
if (type!='0')
@ -380,6 +387,9 @@ namespace MWDialogue
return true;
case '8':// not faction
if (isCreature)
return false;
if(select.type==ESM::VT_Int)
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@ -394,6 +404,9 @@ namespace MWDialogue
return true;
case '9':// not class
if (isCreature)
return false;
if(select.type==ESM::VT_Int)
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData>* npc = actor.get<ESM::NPC>();
@ -408,6 +421,9 @@ namespace MWDialogue
return true;
case 'A'://not Race
if (isCreature)
return false;
if(select.type==ESM::VT_Int)
{
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 isCreature = (actor.getTypeName() != typeid(ESM::NPC).name());
// actor id
if (!info.actor.empty())
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
@ -472,6 +490,9 @@ namespace MWDialogue
//NPC race
if (!info.race.empty())
{
if (isCreature)
return false;
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
@ -484,6 +505,9 @@ namespace MWDialogue
//NPC class
if (!info.clas.empty())
{
if (isCreature)
return false;
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
@ -496,6 +520,9 @@ namespace MWDialogue
//NPC faction
if (!info.npcFaction.empty())
{
if (isCreature)
return false;
//MWWorld::Class npcClass = MWWorld::Class::get(actor);
MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor);
std::map<std::string,int>::iterator it = stats.mFactionRank.find(info.npcFaction);
@ -529,17 +556,19 @@ namespace MWDialogue
}
//check gender
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 (!isCreature)
{
if(static_cast<int> (info.data.gender)==1) 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;
}
}
// check cell
if (!info.cell.empty())
if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell->name != info.cell)
@ -839,6 +868,9 @@ namespace MWDialogue
std::string DialogueManager::getFaction()
{
if (mActor.getTypeName() != typeid(ESM::NPC).name())
return "";
std::string factionID("");
MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor);
if(stats.mFactionRank.empty())

@ -9,6 +9,7 @@
#include "mode.hpp"
#include "../mwbase/environment.hpp"
#include "../mwsound/soundmanager.hpp"
namespace
{
@ -16,6 +17,7 @@ namespace
{
const char* mText;
const char* mButtons[3];
const char* mSound;
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.",
"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."},
"vo\\misc\\chargen qa1.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 2
@ -32,6 +35,7 @@ namespace
{"Work in the forge with him casting iron for a new plow.",
"Gather herbs for your mother who is preparing dinner.",
"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}
},
// 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.",
"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."},
"vo\\misc\\chargen qa3.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// 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.",
"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."},
"vo\\misc\\chargen qa4.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 5
@ -53,6 +59,7 @@ namespace
{"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?",
"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}
},
// 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.",
"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."},
"vo\\misc\\chargen qa6.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// 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.",
"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."},
"vo\\misc\\chargen qa7.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 8
@ -74,6 +83,7 @@ namespace
{"Position yourself between the pipe and your mother.",
"Grab the hot pipe and try to push it away.",
"Push your mother out of the way."},
"vo\\misc\\chargen qa8.wav",
{ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth}
},
// Question 9
@ -81,6 +91,7 @@ namespace
{"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.",
"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}
},
// Question 10
@ -88,6 +99,7 @@ namespace
{"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.",
"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}
}
} };
@ -480,6 +492,8 @@ void CharacterCreation::onCreateClassDialogBack()
void CharacterCreation::onClassQuestionChosen(int _index)
{
MWBase::Environment::get().getSoundManager()->stopSay();
if (mGenerateClassQuestionDialog)
mWM->removeDialog(mGenerateClassQuestionDialog);
if (_index < 0 || _index >= 3)
@ -585,6 +599,8 @@ void CharacterCreation::showClassQuestionDialog()
mGenerateClassQuestionDialog->setButtons(buttons);
mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen);
mGenerateClassQuestionDialog->open();
MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps[mGenerateClassStep].mSound);
}
void CharacterCreation::onGenerateClassBack()

@ -60,6 +60,7 @@ namespace MWInput
A_CycleWeaponRight,
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
A_ToggleWalk, //Toggle Walking/Running
A_Crouch,
A_QuickSave,
A_QuickLoad,
@ -313,6 +314,9 @@ namespace MWInput
poller.bind(A_MoveRight, KC_D);
poller.bind(A_MoveForward, KC_W);
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
@ -359,6 +363,13 @@ namespace MWInput
}
else
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

@ -8,8 +8,9 @@ namespace MWMechanics
{
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 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();
const float *f = ptr.getRefData().getPosition().pos;
insert->setPosition(f[0], f[1], f[2]);
insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale);
// Convert MW rotation to a quaternion:
f = ptr.getCellRef().pos.rot;

@ -189,7 +189,7 @@ void MpgSnd_Decoder::readAll(std::vector<char> &output)
{
size_t pos = output.size();
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;
}
// 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++)
{
size_t got;
got = mDecoder->read(data.data(), data.size());
alBufferData(mBuffers[i], mFormat, data.data(), got, mSampleRate);
got = mDecoder->read(&data[0], data.size());
alBufferData(mBuffers[i], mFormat, &data[0], got, mSampleRate);
}
throwALerror();
@ -299,11 +299,11 @@ bool OpenAL_SoundStream::process()
if(finished)
continue;
got = mDecoder->read(data.data(), data.size());
got = mDecoder->read(&data[0], data.size());
finished = (got < data.size());
if(got > 0)
{
alBufferData(bufid, mFormat, data.data(), got, mSampleRate);
alBufferData(bufid, mFormat, &data[0], got, mSampleRate);
alSourceQueueBuffers(mSource, 1, &bufid);
}
} while(processed > 0);
@ -595,7 +595,7 @@ ALuint OpenAL_Output::getBuffer(const std::string &fname)
alGenBuffers(1, &buf);
throwALerror();
alBufferData(buf, format, data.data(), data.size(), srate);
alBufferData(buf, format, &data[0], data.size(), srate);
mBufferCache[fname] = buf;
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
{
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)
{

@ -97,11 +97,18 @@ namespace MWSound
void say(MWWorld::Ptr reference, const std::string& filename);
///< 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?
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);
///< Play a sound, independently of 3D-position

@ -21,23 +21,24 @@ namespace MWWorld
PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) :
mRender(_rend), mEngine(0), mFreeFly (true)
{
playerphysics = new playerMove;
// Create physics. shapeLoader is deleted by the physic engine
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
playerphysics->mEngine = mEngine;
}
PhysicsSystem::~PhysicsSystem()
{
delete mEngine;
}
OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine()
{
return mEngine;
}
std::pair<std::string, float> PhysicsSystem::getFacedHandle (MWWorld::World& world)
{
std::string handle = "";
@ -65,6 +66,13 @@ namespace MWWorld
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)
{
@ -75,35 +83,35 @@ namespace MWWorld
btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y);
return result;
}
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to)
{
btVector3 _from, _to;
_from = btVector3(from.x, from.y, from.z);
_to = btVector3(to.x, to.y, to.z);
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
return !(result.first == "");
}
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
void PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
{
//set the DebugRenderingMode. To disable it,set it to 0
//eng->setDebugRenderingMode(1);
//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++)
{
OEngine::Physic::PhysicActor* act = it->second;
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;
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
iter!=actors.end(); ++iter)
@ -118,21 +126,24 @@ namespace MWWorld
Ogre::Node* yawNode = sceneNode->getChildIterator().getNext();
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
Ogre::Quaternion yawQuat = yawNode->getOrientation();
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
Ogre::Quaternion both = yawQuat * pitchQuat;
//playerphysics->ps.viewangles.z = both.getPitch().valueDegrees();
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
// unused
//Ogre::Quaternion both = yawQuat * pitchQuat;
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
playerphysics->ps.viewangles.z = 0;
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
if(mFreeFly)
{
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";
//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
@ -140,31 +151,65 @@ namespace MWWorld
}
else
{
Ogre::Quaternion quat = yawNode->getOrientation();
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);
}
//set the walk direction
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;
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());
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));
}
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,
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
// 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()
{
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++)
{
if (it->first=="player")
@ -258,7 +315,12 @@ namespace MWWorld
}
void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
// unused
//Ogre::Vector3 objPos = node->getPosition();
addObject (node->getName(), model, node->getOrientation(),
node->getScale().x, node->getPosition());
}

@ -5,6 +5,7 @@
#include <openengine/ogre/renderer.hpp>
#include <openengine/bullet/physic.hpp>
#include "ptr.hpp"
#include <openengine/bullet/pmove.h>
namespace MWWorld
{
@ -15,8 +16,11 @@ namespace MWWorld
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
~PhysicsSystem ();
std::vector< std::pair<std::string, Ogre::Vector3> > doPhysics (float duration,
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
void doPhysics(float duration, 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,
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,
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 moveObject (const std::string& handle, const Ogre::Vector3& position);
@ -49,11 +59,13 @@ namespace MWWorld
OEngine::Physic::PhysicEngine* getEngine();
void setCurrentWater(bool hasWater, int waterHeight);
private:
OEngine::Render::OgreRenderer &mRender;
OEngine::Physic::PhysicEngine* mEngine;
bool mFreeFly;
playerMove* playerphysics;
PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&);

@ -85,6 +85,14 @@ namespace MWWorld
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()
{
@ -100,4 +108,5 @@ namespace MWWorld
MWWorld::Ptr ptr = getPlayer();
return MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState;
}
}

@ -116,6 +116,7 @@ namespace MWWorld
void setLeftRight (int value);
void setForwardBackward (int value);
void setUpDown(int value);
void toggleRunning();
};

@ -75,11 +75,14 @@ namespace MWWorld
// silence annoying g++ warning
for (std::vector<Ogre::SceneNode*>::const_iterator iter (functor.mHandles.begin());
iter!=functor.mHandles.end(); ++iter){
Ogre::SceneNode* node = *iter;
for (std::vector<Ogre::SceneNode*>::const_iterator iter2 (functor.mHandles.begin());
iter2!=functor.mHandles.end(); ++iter2){
Ogre::SceneNode* node = *iter2;
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);
@ -103,20 +106,36 @@ namespace MWWorld
std::pair<CellStoreCollection::iterator, bool> result =
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,
bool adjustPlayerPos)
{
bool hasWater = cell->cell->data.flags & cell->cell->HasWater;
mPhysics->setCurrentWater(hasWater, cell->cell->water);
if (adjustPlayerPos)
mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]);

@ -215,6 +215,7 @@ namespace MWWorld
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[1] = y;
ptr.getRefData().getPosition().pos[2] = z;
@ -582,6 +584,7 @@ namespace MWWorld
if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
{
mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
ret = true;
}
}
@ -591,6 +594,8 @@ namespace MWWorld
/// \todo cell change for non-player ref
mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
return ret;
}
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,
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();
it!= vectors.end(); ++it)
// Game clock part of the loop, contains everything that has to be executed in a fixed timestep
long long dt = mTimer.getMilliseconds() - lastTick;
if (dt >= 100)
{
// 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)
{
if (it->first=="player")
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);
moveObjectImp (ptr, it->second.x, it->second.y, it->second.z);
if (moveObjectImp (getPtrViaHandle (player->first),
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()
@ -789,7 +815,8 @@ namespace MWWorld
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
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);
}

@ -22,6 +22,8 @@
#include <openengine/bullet/physic.hpp>
#include <openengine/ogre/fader.hpp>
#include <OgreTimer.h>
namespace Ogre
{
class Vector3;
@ -100,9 +102,13 @@ namespace MWWorld
int mNumFacing;
std::map<std::string,std::string> mFallback;
unsigned long lastTick;
Ogre::Timer mTimer;
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:

@ -1,6 +1,7 @@
#include "physic.hpp"
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include <components/nifbullet/bullet_nif_loader.hpp>
//#include <apps\openmw\mwworld\world.hpp>
#include "CMotionState.h"
@ -10,6 +11,8 @@
#include "BtOgreGP.h"
#include "BtOgreExtras.h"
#include <boost/lexical_cast.hpp>
#define BIT(x) (1<<(x))
namespace OEngine {
@ -161,10 +164,12 @@ namespace Physic
// The actual physics solver
solver = new btSequentialImpulseConstraintSolver;
//btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache();
pairCache = new btSortedOverlappingPairCache();
//pairCache->setInternalGhostPairCallback( new btGhostPairCallback() );
broadphase = new btDbvtBroadphase(pairCache);
broadphase = new btDbvtBroadphase();
// The world.
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
@ -253,6 +258,60 @@ namespace Physic
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)
{
//get the shape from the .nif
@ -334,7 +393,7 @@ namespace Physic
void PhysicEngine::stepSimulation(double deltaT)
{
dynamicsWorld->stepSimulation(deltaT,1,1/50.);
dynamicsWorld->stepSimulation(deltaT,10, 1/60.0);
if(isDebugCreated)
{
mDebugDrawer->step();

@ -140,6 +140,18 @@ namespace Physic
*/
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
*/

File diff suppressed because it is too large Load Diff

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

@ -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
};
enum collaborativePhysicsType : unsigned
enum collaborativePhysicsType
{
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)
@ -53,10 +53,10 @@ struct traceResults
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);
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<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);
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…
Cancel
Save