mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
640d473866
13 changed files with 121 additions and 56 deletions
|
@ -15,7 +15,7 @@
|
||||||
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
||||||
|
|
||||||
#include <components/ogreinit/ogreinit.hpp>
|
#include <components/ogreinit/ogreinit.hpp>
|
||||||
|
#include <components/nifogre/ogrenifloader.hpp>
|
||||||
#include <components/bsa/resources.hpp>
|
#include <components/bsa/resources.hpp>
|
||||||
|
|
||||||
#include "model/doc/document.hpp"
|
#include "model/doc/document.hpp"
|
||||||
|
@ -35,6 +35,8 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||||
|
|
||||||
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
||||||
|
|
||||||
|
NifOgre::Loader::setShowMarkers(true);
|
||||||
|
|
||||||
mOverlaySystem.reset (new CSVRender::OverlaySystem);
|
mOverlaySystem.reset (new CSVRender::OverlaySystem);
|
||||||
|
|
||||||
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace CSVWorld
|
||||||
PhysicsSystem::PhysicsSystem()
|
PhysicsSystem::PhysicsSystem()
|
||||||
{
|
{
|
||||||
// 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(true);
|
||||||
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,12 @@
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool isConscious(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
return !stats.isDead() && !stats.getKnockedDown();
|
||||||
|
}
|
||||||
|
|
||||||
void adjustBoundItem (const std::string& item, bool bound, const MWWorld::Ptr& actor)
|
void adjustBoundItem (const std::string& item, bool bound, const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
if (bound)
|
if (bound)
|
||||||
|
@ -1101,12 +1107,12 @@ namespace MWMechanics
|
||||||
updateCrimePersuit(iter->first, duration);
|
updateCrimePersuit(iter->first, duration);
|
||||||
|
|
||||||
if (iter->first != player)
|
if (iter->first != player)
|
||||||
iter->first.getClass().getCreatureStats(iter->first).getAiSequence().execute(iter->first,iter->second->getAiState(), duration);
|
|
||||||
|
|
||||||
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
|
||||||
if(!stats.isDead())
|
|
||||||
{
|
{
|
||||||
if (stats.getAiSequence().isInCombat()) hostilesCount++;
|
CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first);
|
||||||
|
if (isConscious(iter->first))
|
||||||
|
stats.getAiSequence().execute(iter->first,iter->second->getAiState(), duration);
|
||||||
|
|
||||||
|
if (stats.getAiSequence().isInCombat() && !stats.isDead()) hostilesCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1515,7 +1521,9 @@ namespace MWMechanics
|
||||||
for (PtrActorMap::iterator it = map.begin(); it != map.end(); ++it)
|
for (PtrActorMap::iterator it = map.begin(); it != map.end(); ++it)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = it->first;
|
MWWorld::Ptr ptr = it->first;
|
||||||
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()
|
||||||
|
|| !isConscious(ptr)
|
||||||
|
|| ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Paralyze).getMagnitude() > 0)
|
||||||
continue;
|
continue;
|
||||||
MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
seq.fastForward(ptr, it->second->getAiState());
|
seq.fastForward(ptr, it->second->getAiState());
|
||||||
|
|
|
@ -152,8 +152,7 @@ bool AiSequence::isPackageDone() const
|
||||||
|
|
||||||
void AiSequence::execute (const MWWorld::Ptr& actor, AiState& state,float duration)
|
void AiSequence::execute (const MWWorld::Ptr& actor, AiState& state,float duration)
|
||||||
{
|
{
|
||||||
if(actor != MWBase::Environment::get().getWorld()->getPlayerPtr()
|
if(actor != MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||||
&& !actor.getClass().getCreatureStats(actor).getKnockedDown())
|
|
||||||
{
|
{
|
||||||
if (!mPackages.empty())
|
if (!mPackages.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -308,22 +308,26 @@ namespace MWMechanics
|
||||||
// Play idle voiced dialogue entries randomly
|
// Play idle voiced dialogue entries randomly
|
||||||
int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified();
|
int hello = cStats.getAiSetting(CreatureStats::AI_Hello).getModified();
|
||||||
if (hello > 0 && !MWBase::Environment::get().getWorld()->isSwimming(actor)
|
if (hello > 0 && !MWBase::Environment::get().getWorld()->isSwimming(actor)
|
||||||
&& actor.getRefData().getPosition().pos[2] < 3000 &&
|
&& MWBase::Environment::get().getSoundManager()->sayDone(actor))
|
||||||
MWBase::Environment::get().getSoundManager()->sayDone(actor))
|
|
||||||
{
|
{
|
||||||
float roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 10000; // [0, 9999]
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
|
|
||||||
// Don't bother if the player is out of hearing range
|
|
||||||
static float fVoiceIdleOdds = MWBase::Environment::get().getWorld()->getStore()
|
static float fVoiceIdleOdds = MWBase::Environment::get().getWorld()->getStore()
|
||||||
.get<ESM::GameSetting>().find("fVoiceIdleOdds")->getFloat();
|
.get<ESM::GameSetting>().find("fVoiceIdleOdds")->getFloat();
|
||||||
|
|
||||||
float x = fVoiceIdleOdds * MWBase::Environment::get().getFrameDuration();
|
float roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 10000;
|
||||||
|
|
||||||
|
// In vanilla MW the chance was FPS dependent, and did not allow proper changing of fVoiceIdleOdds
|
||||||
|
// due to the roll being an integer.
|
||||||
|
// Our implementation does not have these issues, so needs to be recalibrated. We chose to
|
||||||
|
// use the chance MW would have when run at 60 FPS with the default value of the GMST for calibration.
|
||||||
|
float x = fVoiceIdleOdds * 0.6 * (MWBase::Environment::get().getFrameDuration() / 0.1);
|
||||||
|
|
||||||
// Only say Idle voices when player is in LOS
|
// Only say Idle voices when player is in LOS
|
||||||
// A bit counterintuitive, likely vanilla did this to reduce the appearance of
|
// A bit counterintuitive, likely vanilla did this to reduce the appearance of
|
||||||
// voices going through walls?
|
// voices going through walls?
|
||||||
if (roll < x && Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(pos.pos)) < 1500*1500
|
if (roll < x && Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(pos.pos))
|
||||||
|
< 3000*3000 // maybe should be fAudioVoiceDefaultMaxDistance*fAudioMaxDistanceMult instead
|
||||||
&& MWBase::Environment::get().getWorld()->getLOS(player, actor))
|
&& MWBase::Environment::get().getWorld()->getLOS(player, actor))
|
||||||
MWBase::Environment::get().getDialogueManager()->say(actor, "idle");
|
MWBase::Environment::get().getDialogueManager()->say(actor, "idle");
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,13 +70,15 @@ void animateCollisionShapes (std::map<OEngine::Physic::RigidBody*, OEngine::Phys
|
||||||
if (bone == NULL)
|
if (bone == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
btCompoundShape* compound = dynamic_cast<btCompoundShape*>(instance.mCompound);
|
btCompoundShape* compound = static_cast<btCompoundShape*>(instance.mCompound);
|
||||||
|
|
||||||
btTransform trans;
|
btTransform trans;
|
||||||
trans.setOrigin(BtOgre::Convert::toBullet(bone->_getDerivedPosition()));
|
trans.setOrigin(BtOgre::Convert::toBullet(bone->_getDerivedPosition()) * compound->getLocalScaling());
|
||||||
trans.setRotation(BtOgre::Convert::toBullet(bone->_getDerivedOrientation()));
|
trans.setRotation(BtOgre::Convert::toBullet(bone->_getDerivedOrientation()));
|
||||||
|
|
||||||
compound->getChildShape(shapeIt->second)->setLocalScaling(BtOgre::Convert::toBullet(bone->_getDerivedScale()));
|
compound->getChildShape(shapeIt->second)->setLocalScaling(
|
||||||
|
compound->getLocalScaling() *
|
||||||
|
BtOgre::Convert::toBullet(bone->_getDerivedScale()));
|
||||||
compound->updateChildTransform(shapeIt->second, trans);
|
compound->updateChildTransform(shapeIt->second, trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,6 +350,8 @@ namespace MWWorld
|
||||||
velocity *= 1.f-(fStromWalkMult * (angle.valueDegrees()/180.f));
|
velocity *= 1.f-(fStromWalkMult * (angle.valueDegrees()/180.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 origVelocity = velocity;
|
||||||
|
|
||||||
Ogre::Vector3 newPosition = position;
|
Ogre::Vector3 newPosition = position;
|
||||||
/*
|
/*
|
||||||
* A loop to find newPosition using tracer, if successful different from the starting position.
|
* A loop to find newPosition using tracer, if successful different from the starting position.
|
||||||
|
@ -425,10 +429,18 @@ namespace MWWorld
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Can't move this way, try to find another spot along the plane
|
// Can't move this way, try to find another spot along the plane
|
||||||
Ogre::Real movelen = velocity.normalise();
|
Ogre::Vector3 direction = velocity;
|
||||||
|
Ogre::Real movelen = direction.normalise();
|
||||||
Ogre::Vector3 reflectdir = velocity.reflect(tracer.mPlaneNormal);
|
Ogre::Vector3 reflectdir = velocity.reflect(tracer.mPlaneNormal);
|
||||||
reflectdir.normalise();
|
reflectdir.normalise();
|
||||||
velocity = slide(reflectdir, tracer.mPlaneNormal)*movelen;
|
|
||||||
|
Ogre::Vector3 newVelocity = slide(reflectdir, tracer.mPlaneNormal)*movelen;
|
||||||
|
if ((newVelocity-velocity).squaredLength() < 0.01)
|
||||||
|
break;
|
||||||
|
if (velocity.dotProduct(origVelocity) <= 0.f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
velocity = newVelocity;
|
||||||
|
|
||||||
// Do not allow sliding upward if there is gravity. Stepping will have taken
|
// Do not allow sliding upward if there is gravity. Stepping will have taken
|
||||||
// care of that.
|
// care of that.
|
||||||
|
|
|
@ -21,6 +21,18 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void addObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics,
|
||||||
|
MWRender::RenderingManager& rendering)
|
||||||
|
{
|
||||||
|
std::string model = Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getModel(ptr));
|
||||||
|
std::string id = ptr.getClass().getId(ptr);
|
||||||
|
if (id == "prisonmarker" || id == "divinemarker" || id == "templemarker" || id == "northmarker")
|
||||||
|
model = ""; // marker objects that have a hardcoded function in the game logic, should be hidden from the player
|
||||||
|
rendering.addObject(ptr, model);
|
||||||
|
ptr.getClass().insertObject (ptr, model, physics);
|
||||||
|
}
|
||||||
|
|
||||||
void updateObjectLocalRotation (const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics,
|
void updateObjectLocalRotation (const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics,
|
||||||
MWRender::RenderingManager& rendering)
|
MWRender::RenderingManager& rendering)
|
||||||
{
|
{
|
||||||
|
@ -80,10 +92,7 @@ namespace
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const std::string& model = Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getModel(ptr));
|
addObject(ptr, mPhysics, mRendering);
|
||||||
mRendering.addObject(ptr, model);
|
|
||||||
ptr.getClass().insertObject (ptr, model, mPhysics);
|
|
||||||
|
|
||||||
updateObjectLocalRotation(ptr, mPhysics, mRendering);
|
updateObjectLocalRotation(ptr, mPhysics, mRendering);
|
||||||
if (ptr.getRefData().getBaseNode())
|
if (ptr.getRefData().getBaseNode())
|
||||||
{
|
{
|
||||||
|
@ -530,9 +539,7 @@ namespace MWWorld
|
||||||
|
|
||||||
void Scene::addObjectToScene (const Ptr& ptr)
|
void Scene::addObjectToScene (const Ptr& ptr)
|
||||||
{
|
{
|
||||||
const std::string& model = Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getModel(ptr));
|
addObject(ptr, *mPhysics, mRendering);
|
||||||
mRendering.addObject(ptr, model);
|
|
||||||
ptr.getClass().insertObject (ptr, model, *mPhysics);
|
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
|
||||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale());
|
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2107,6 +2107,9 @@ namespace MWWorld
|
||||||
Ogre::Vector3 playerPos(refdata.getPosition().pos);
|
Ogre::Vector3 playerPos(refdata.getPosition().pos);
|
||||||
|
|
||||||
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
||||||
|
if (!physactor)
|
||||||
|
throw std::runtime_error("can't find player");
|
||||||
|
|
||||||
if((!physactor->getOnGround()&&physactor->getCollisionMode()) || isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
if((!physactor->getOnGround()&&physactor->getCollisionMode()) || isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
||||||
return 2;
|
return 2;
|
||||||
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) ||
|
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) ||
|
||||||
|
@ -2326,9 +2329,15 @@ namespace MWWorld
|
||||||
if (!targetActor.getRefData().getBaseNode() || !targetActor.getRefData().getBaseNode())
|
if (!targetActor.getRefData().getBaseNode() || !targetActor.getRefData().getBaseNode())
|
||||||
return false; // not in active cell
|
return false; // not in active cell
|
||||||
|
|
||||||
Ogre::Vector3 halfExt1 = mPhysEngine->getCharacter(actor.getRefData().getHandle())->getHalfExtents();
|
OEngine::Physic::PhysicActor* actor1 = mPhysEngine->getCharacter(actor.getRefData().getHandle());
|
||||||
|
OEngine::Physic::PhysicActor* actor2 = mPhysEngine->getCharacter(targetActor.getRefData().getHandle());
|
||||||
|
|
||||||
|
if (!actor1 || !actor2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Ogre::Vector3 halfExt1 = actor1->getHalfExtents();
|
||||||
const float* pos1 = actor.getRefData().getPosition().pos;
|
const float* pos1 = actor.getRefData().getPosition().pos;
|
||||||
Ogre::Vector3 halfExt2 = mPhysEngine->getCharacter(targetActor.getRefData().getHandle())->getHalfExtents();
|
Ogre::Vector3 halfExt2 = actor2->getHalfExtents();
|
||||||
const float* pos2 = targetActor.getRefData().getPosition().pos;
|
const float* pos2 = targetActor.getRefData().getPosition().pos;
|
||||||
|
|
||||||
btVector3 from(pos1[0],pos1[1],pos1[2]+halfExt1.z*2*0.9); // eye level
|
btVector3 from(pos1[0],pos1[1],pos1[2]+halfExt1.z*2*0.9); // eye level
|
||||||
|
|
|
@ -158,7 +158,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
||||||
mShape->mAutogenerated = hasAutoGeneratedCollision(node);
|
mShape->mAutogenerated = hasAutoGeneratedCollision(node);
|
||||||
|
|
||||||
//do a first pass
|
//do a first pass
|
||||||
handleNode(node,0,false,false,false);
|
handleNode(node,0,false,false);
|
||||||
|
|
||||||
if(mBoundingBox != NULL)
|
if(mBoundingBox != NULL)
|
||||||
{
|
{
|
||||||
|
@ -232,7 +232,7 @@ bool ManualBulletShapeLoader::hasAutoGeneratedCollision(Nif::Node const * rootNo
|
||||||
|
|
||||||
void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
|
void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
|
||||||
bool isCollisionNode,
|
bool isCollisionNode,
|
||||||
bool raycasting, bool isMarker, bool isAnimated)
|
bool raycasting, bool isAnimated)
|
||||||
{
|
{
|
||||||
// Accumulate the flags from all the child nodes. This works for all
|
// Accumulate the flags from all the child nodes. This works for all
|
||||||
// the flags we currently use, at least.
|
// the flags we currently use, at least.
|
||||||
|
@ -254,13 +254,6 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
|
||||||
if(node->recType == Nif::RC_AvoidNode)
|
if(node->recType == Nif::RC_AvoidNode)
|
||||||
flags |= 0x800;
|
flags |= 0x800;
|
||||||
|
|
||||||
// Marker objects
|
|
||||||
/// \todo don't do this in the editor
|
|
||||||
std::string nodename = node->name;
|
|
||||||
Misc::StringUtils::toLower(nodename);
|
|
||||||
if (nodename.find("marker") != std::string::npos)
|
|
||||||
isMarker = true;
|
|
||||||
|
|
||||||
// Check for extra data
|
// Check for extra data
|
||||||
Nif::Extra const *e = node;
|
Nif::Extra const *e = node;
|
||||||
while (!e->extra.empty())
|
while (!e->extra.empty())
|
||||||
|
@ -281,16 +274,14 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
|
||||||
// No collision. Use an internal flag setting to mark this.
|
// No collision. Use an internal flag setting to mark this.
|
||||||
flags |= 0x800;
|
flags |= 0x800;
|
||||||
}
|
}
|
||||||
else if (sd->string == "MRK")
|
else if (sd->string == "MRK" && !mShowMarkers)
|
||||||
// Marker objects. These are only visible in the
|
// Marker objects. These are only visible in the
|
||||||
// editor. Until and unless we add an editor component to
|
// editor.
|
||||||
// the engine, just skip this entire node.
|
return;
|
||||||
isMarker = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (isCollisionNode || (mShape->mAutogenerated && !raycasting))
|
if (isCollisionNode || (mShape->mAutogenerated && !raycasting))
|
||||||
&& (!isMarker || (!mShape->mAutogenerated && !raycasting)))
|
|
||||||
{
|
{
|
||||||
// NOTE: a trishape with hasBounds=true, but no BBoxCollision flag should NOT go through handleNiTriShape!
|
// NOTE: a trishape with hasBounds=true, but no BBoxCollision flag should NOT go through handleNiTriShape!
|
||||||
// It must be ignored completely.
|
// It must be ignored completely.
|
||||||
|
@ -319,7 +310,7 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
|
||||||
for(size_t i = 0;i < list.length();i++)
|
for(size_t i = 0;i < list.length();i++)
|
||||||
{
|
{
|
||||||
if(!list[i].empty())
|
if(!list[i].empty())
|
||||||
handleNode(list[i].getPtr(), flags, isCollisionNode, raycasting, isMarker, isAnimated);
|
handleNode(list[i].getPtr(), flags, isCollisionNode, raycasting, isAnimated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,10 +365,17 @@ void ManualBulletShapeLoader::handleNiTriShape(const Nif::NiTriShape *shape, int
|
||||||
|
|
||||||
TriangleMeshShape* childShape = new TriangleMeshShape(childMesh,true);
|
TriangleMeshShape* childShape = new TriangleMeshShape(childMesh,true);
|
||||||
|
|
||||||
childShape->setLocalScaling(btVector3(transform[0][0], transform[1][1], transform[2][2]));
|
float scale = shape->trafo.scale;
|
||||||
|
const Nif::Node* parent = shape;
|
||||||
|
while (parent->parent)
|
||||||
|
{
|
||||||
|
parent = parent->parent;
|
||||||
|
scale *= parent->trafo.scale;
|
||||||
|
}
|
||||||
Ogre::Quaternion q = transform.extractQuaternion();
|
Ogre::Quaternion q = transform.extractQuaternion();
|
||||||
Ogre::Vector3 v = transform.getTrans();
|
Ogre::Vector3 v = transform.getTrans();
|
||||||
|
childShape->setLocalScaling(btVector3(scale, scale, scale));
|
||||||
|
|
||||||
btTransform trans(btQuaternion(q.x, q.y, q.z, q.w), btVector3(v.x, v.y, v.z));
|
btTransform trans(btQuaternion(q.x, q.y, q.z, q.w), btVector3(v.x, v.y, v.z));
|
||||||
|
|
||||||
if (raycasting)
|
if (raycasting)
|
||||||
|
|
|
@ -67,11 +67,12 @@ struct TriangleMeshShape : public btBvhTriangleMeshShape
|
||||||
class ManualBulletShapeLoader : public OEngine::Physic::BulletShapeLoader
|
class ManualBulletShapeLoader : public OEngine::Physic::BulletShapeLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ManualBulletShapeLoader()
|
ManualBulletShapeLoader(bool showMarkers=false)
|
||||||
: mShape(NULL)
|
: mShape(NULL)
|
||||||
, mStaticMesh(NULL)
|
, mStaticMesh(NULL)
|
||||||
, mCompoundShape(NULL)
|
, mCompoundShape(NULL)
|
||||||
, mBoundingBox(NULL)
|
, mBoundingBox(NULL)
|
||||||
|
, mShowMarkers(showMarkers)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ private:
|
||||||
*Parse a node.
|
*Parse a node.
|
||||||
*/
|
*/
|
||||||
void handleNode(Nif::Node const *node, int flags, bool isCollisionNode,
|
void handleNode(Nif::Node const *node, int flags, bool isCollisionNode,
|
||||||
bool raycasting, bool isMarker, bool isAnimated=false);
|
bool raycasting, bool isAnimated=false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Helper function
|
*Helper function
|
||||||
|
@ -130,6 +131,8 @@ private:
|
||||||
btBoxShape *mBoundingBox;
|
btBoxShape *mBoundingBox;
|
||||||
|
|
||||||
std::set<std::string> mControlledNodes;
|
std::set<std::string> mControlledNodes;
|
||||||
|
|
||||||
|
bool mShowMarkers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -689,6 +689,14 @@ public:
|
||||||
*/
|
*/
|
||||||
class NIFObjectLoader
|
class NIFObjectLoader
|
||||||
{
|
{
|
||||||
|
static bool sShowMarkers;
|
||||||
|
public:
|
||||||
|
static void setShowMarkers(bool show)
|
||||||
|
{
|
||||||
|
sShowMarkers = show;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
static void warn(const std::string &msg)
|
static void warn(const std::string &msg)
|
||||||
{
|
{
|
||||||
std::cerr << "NIFObjectLoader: Warn: " << msg << std::endl;
|
std::cerr << "NIFObjectLoader: Warn: " << msg << std::endl;
|
||||||
|
@ -1176,11 +1184,6 @@ class NIFObjectLoader
|
||||||
if(node->recType == Nif::RC_RootCollisionNode)
|
if(node->recType == Nif::RC_RootCollisionNode)
|
||||||
isRootCollisionNode = true;
|
isRootCollisionNode = true;
|
||||||
|
|
||||||
// Marker objects: just skip the entire node branch
|
|
||||||
/// \todo don't do this in the editor
|
|
||||||
if (node->name.find("marker") != std::string::npos)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(node->recType == Nif::RC_NiBSAnimationNode)
|
if(node->recType == Nif::RC_NiBSAnimationNode)
|
||||||
animflags |= node->flags;
|
animflags |= node->flags;
|
||||||
else if(node->recType == Nif::RC_NiBSParticleNode)
|
else if(node->recType == Nif::RC_NiBSParticleNode)
|
||||||
|
@ -1213,7 +1216,7 @@ class NIFObjectLoader
|
||||||
const Nif::NiStringExtraData *sd = static_cast<const Nif::NiStringExtraData*>(e.getPtr());
|
const Nif::NiStringExtraData *sd = static_cast<const Nif::NiStringExtraData*>(e.getPtr());
|
||||||
// String markers may contain important information
|
// String markers may contain important information
|
||||||
// affecting the entire subtree of this obj
|
// affecting the entire subtree of this obj
|
||||||
if(sd->string == "MRK")
|
if(sd->string == "MRK" && !sShowMarkers)
|
||||||
{
|
{
|
||||||
// Marker objects. These meshes are only visible in the
|
// Marker objects. These meshes are only visible in the
|
||||||
// editor.
|
// editor.
|
||||||
|
@ -1476,5 +1479,14 @@ void Loader::createKfControllers(Ogre::Entity *skelBase,
|
||||||
NIFObjectLoader::loadKf(skelBase->getSkeleton(), name, textKeys, ctrls);
|
NIFObjectLoader::loadKf(skelBase->getSkeleton(), name, textKeys, ctrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Loader::sShowMarkers = false;
|
||||||
|
bool NIFObjectLoader::sShowMarkers = false;
|
||||||
|
|
||||||
|
void Loader::setShowMarkers(bool show)
|
||||||
|
{
|
||||||
|
sShowMarkers = show;
|
||||||
|
NIFObjectLoader::setShowMarkers(show);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace NifOgre
|
} // namespace NifOgre
|
||||||
|
|
|
@ -110,10 +110,18 @@ public:
|
||||||
std::string name,
|
std::string name,
|
||||||
const std::string &group="General");
|
const std::string &group="General");
|
||||||
|
|
||||||
|
/// Set whether or not nodes marked as "MRK" should be shown.
|
||||||
|
/// These should be hidden ingame, but visible in the editior.
|
||||||
|
/// Default: false.
|
||||||
|
static void setShowMarkers(bool show);
|
||||||
|
|
||||||
static void createKfControllers(Ogre::Entity *skelBase,
|
static void createKfControllers(Ogre::Entity *skelBase,
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
TextKeyMap &textKeys,
|
TextKeyMap &textKeys,
|
||||||
std::vector<Ogre::Controller<Ogre::Real> > &ctrls);
|
std::vector<Ogre::Controller<Ogre::Real> > &ctrls);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool sShowMarkers;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Should be with other general Ogre extensions.
|
// FIXME: Should be with other general Ogre extensions.
|
||||||
|
|
3
extern/oics/ICSInputControlSystem.cpp
vendored
3
extern/oics/ICSInputControlSystem.cpp
vendored
|
@ -36,6 +36,9 @@ namespace ICS
|
||||||
, mDetectingBindingControl(NULL)
|
, mDetectingBindingControl(NULL)
|
||||||
, mLog(log)
|
, mLog(log)
|
||||||
, mXmouseAxisBinded(false), mYmouseAxisBinded(false)
|
, mXmouseAxisBinded(false), mYmouseAxisBinded(false)
|
||||||
|
, mClientHeight(1)
|
||||||
|
, mClientWidth(1)
|
||||||
|
, mDetectingBindingDirection(Control::STOP)
|
||||||
{
|
{
|
||||||
ICS_LOG(" - Creating InputControlSystem - ");
|
ICS_LOG(" - Creating InputControlSystem - ");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue