mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-04 07:13:29 +00:00
Restore getHitContact
This commit is contained in:
parent
627fee07bc
commit
85345e663a
@ -262,7 +262,7 @@ namespace MWBase
|
|||||||
/// Returns a pointer to the object the provided object would hit (if within the
|
/// Returns a pointer to the object the provided object would hit (if within the
|
||||||
/// specified distance), and the point where the hit occurs. This will attempt to
|
/// specified distance), and the point where the hit occurs. This will attempt to
|
||||||
/// use the "Head" node, or alternatively the "Bip01 Head" node as a basis.
|
/// use the "Head" node, or alternatively the "Bip01 Head" node as a basis.
|
||||||
virtual std::pair<MWWorld::Ptr,Ogre::Vector3> getHitContact(const MWWorld::Ptr &ptr, float distance) = 0;
|
virtual std::pair<MWWorld::Ptr,osg::Vec3f> getHitContact(const MWWorld::Ptr &ptr, float distance) = 0;
|
||||||
|
|
||||||
virtual void adjustPosition (const MWWorld::Ptr& ptr, bool force) = 0;
|
virtual void adjustPosition (const MWWorld::Ptr& ptr, bool force) = 0;
|
||||||
///< Adjust position after load to be on ground. Must be called after model load.
|
///< Adjust position after load to be on ground. Must be called after model load.
|
||||||
|
@ -238,7 +238,7 @@ namespace MWClass
|
|||||||
const float fCombatDistance = gmst.find("fCombatDistance")->getFloat();
|
const float fCombatDistance = gmst.find("fCombatDistance")->getFloat();
|
||||||
dist = fCombatDistance * weapon.get<ESM::Weapon>()->mBase->mData.mReach;
|
dist = fCombatDistance * weapon.get<ESM::Weapon>()->mBase->mData.mReach;
|
||||||
}
|
}
|
||||||
std::pair<MWWorld::Ptr, Ogre::Vector3> result = MWBase::Environment::get().getWorld()->getHitContact(ptr, dist);
|
std::pair<MWWorld::Ptr, osg::Vec3f> result = MWBase::Environment::get().getWorld()->getHitContact(ptr, dist);
|
||||||
if (result.first.isEmpty())
|
if (result.first.isEmpty())
|
||||||
return; // Didn't hit anything
|
return; // Didn't hit anything
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ namespace MWClass
|
|||||||
if (!victim.getClass().isActor())
|
if (!victim.getClass().isActor())
|
||||||
return; // Can't hit non-actors
|
return; // Can't hit non-actors
|
||||||
|
|
||||||
Ogre::Vector3 hitPosition = result.second;
|
Ogre::Vector3 hitPosition (result.second.x(), result.second.y(), result.second.z());
|
||||||
|
|
||||||
float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat);
|
float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat);
|
||||||
|
|
||||||
|
@ -491,9 +491,9 @@ namespace MWClass
|
|||||||
store.find("fHandToHandReach")->getFloat());
|
store.find("fHandToHandReach")->getFloat());
|
||||||
|
|
||||||
// TODO: Use second to work out the hit angle
|
// TODO: Use second to work out the hit angle
|
||||||
std::pair<MWWorld::Ptr, Ogre::Vector3> result = world->getHitContact(ptr, dist);
|
std::pair<MWWorld::Ptr, osg::Vec3f> result = world->getHitContact(ptr, dist);
|
||||||
MWWorld::Ptr victim = result.first;
|
MWWorld::Ptr victim = result.first;
|
||||||
Ogre::Vector3 hitPosition = result.second;
|
Ogre::Vector3 hitPosition (result.second.x(), result.second.y(), result.second.z());
|
||||||
if(victim.isEmpty()) // Didn't hit anything
|
if(victim.isEmpty()) // Didn't hit anything
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -31,6 +31,11 @@ namespace MWPhysics
|
|||||||
mPtr = updated;
|
mPtr = updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWWorld::Ptr getPtr() const
|
||||||
|
{
|
||||||
|
return mPtr;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MWWorld::Ptr mPtr;
|
MWWorld::Ptr mPtr;
|
||||||
};
|
};
|
||||||
|
@ -653,35 +653,78 @@ namespace MWPhysics
|
|||||||
return mDebugDrawEnabled;
|
return mDebugDrawEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string,Ogre::Vector3> PhysicsSystem::getHitContact(const std::string &name,
|
class DeepestNotMeContactTestResultCallback : public btCollisionWorld::ContactResultCallback
|
||||||
const Ogre::Vector3 &origin,
|
{
|
||||||
const Ogre::Quaternion &orient,
|
const btCollisionObject* mMe;
|
||||||
|
|
||||||
|
// Store the real origin, since the shape's origin is its center
|
||||||
|
btVector3 mOrigin;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const btCollisionObject *mObject;
|
||||||
|
btVector3 mContactPoint;
|
||||||
|
btScalar mLeastDistSqr;
|
||||||
|
|
||||||
|
DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const btVector3 &origin)
|
||||||
|
: mMe(me), mOrigin(origin), mObject(NULL), mContactPoint(0,0,0),
|
||||||
|
mLeastDistSqr(std::numeric_limits<float>::max())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual btScalar addSingleResult(btManifoldPoint& cp,
|
||||||
|
const btCollisionObjectWrapper* col0Wrap,int partId0,int index0,
|
||||||
|
const btCollisionObjectWrapper* col1Wrap,int partId1,int index1)
|
||||||
|
{
|
||||||
|
if (col1Wrap->m_collisionObject != mMe)
|
||||||
|
{
|
||||||
|
btScalar distsqr = mOrigin.distance2(cp.getPositionWorldOnA());
|
||||||
|
if(!mObject || distsqr < mLeastDistSqr)
|
||||||
|
{
|
||||||
|
mObject = col1Wrap->m_collisionObject;
|
||||||
|
mLeastDistSqr = distsqr;
|
||||||
|
mContactPoint = cp.getPositionWorldOnA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::pair<MWWorld::Ptr, osg::Vec3f> PhysicsSystem::getHitContact(const MWWorld::Ptr& actor,
|
||||||
|
const osg::Vec3f &origin,
|
||||||
|
const osg::Quat &orient,
|
||||||
float queryDistance)
|
float queryDistance)
|
||||||
{
|
{
|
||||||
return std::make_pair(std::string(), Ogre::Vector3());
|
|
||||||
/*
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
btConeShape shape(Ogre::Degree(store.find("fCombatAngleXY")->getFloat()/2.0f).valueRadians(),
|
btConeShape shape (osg::DegreesToRadians(store.find("fCombatAngleXY")->getFloat()/2.0f), queryDistance);
|
||||||
queryDistance);
|
shape.setLocalScaling(btVector3(1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->getFloat()/2.0f) /
|
||||||
shape.setLocalScaling(btVector3(1, 1, Ogre::Degree(store.find("fCombatAngleZ")->getFloat()/2.0f).valueRadians() /
|
|
||||||
shape.getRadius()));
|
shape.getRadius()));
|
||||||
|
|
||||||
// The shape origin is its center, so we have to move it forward by half the length. The
|
// The shape origin is its center, so we have to move it forward by half the length. The
|
||||||
// real origin will be provided to getFilteredContact to find the closest.
|
// real origin will be provided to getFilteredContact to find the closest.
|
||||||
Ogre::Vector3 center = origin + (orient * Ogre::Vector3(0.0f, queryDistance*0.5f, 0.0f));
|
osg::Vec3f center = origin + (orient * osg::Vec3f(0.0f, queryDistance*0.5f, 0.0f));
|
||||||
|
|
||||||
btCollisionObject object;
|
btCollisionObject object;
|
||||||
object.setCollisionShape(&shape);
|
object.setCollisionShape(&shape);
|
||||||
object.setWorldTransform(btTransform(btQuaternion(orient.x, orient.y, orient.z, orient.w),
|
object.setWorldTransform(btTransform(toBullet(orient), toBullet(center)));
|
||||||
btVector3(center.x, center.y, center.z)));
|
|
||||||
|
|
||||||
std::pair<const OEngine::Physic::RigidBody*,btVector3> result = mEngine->getFilteredContact(
|
const btCollisionObject* me = NULL;
|
||||||
name, btVector3(origin.x, origin.y, origin.z), &object);
|
Actor* physactor = getActor(actor);
|
||||||
if(!result.first)
|
if (physactor)
|
||||||
return std::make_pair(std::string(), Ogre::Vector3(&result.second[0]));
|
me = physactor->getCollisionObject();
|
||||||
return std::make_pair(result.first->mName, Ogre::Vector3(&result.second[0]));
|
|
||||||
*/
|
DeepestNotMeContactTestResultCallback resultCallback(me, toBullet(origin));
|
||||||
|
resultCallback.m_collisionFilterGroup = CollisionType_Actor;
|
||||||
|
resultCallback.m_collisionFilterMask = CollisionType_World | CollisionType_HeightMap | CollisionType_Actor;
|
||||||
|
mDynamicsWorld->contactTest(&object, resultCallback);
|
||||||
|
|
||||||
|
if (resultCallback.mObject)
|
||||||
|
{
|
||||||
|
const PtrHolder* holder = static_cast<const PtrHolder*>(resultCallback.mObject->getUserPointer());
|
||||||
|
if (holder)
|
||||||
|
return std::make_pair(holder->getPtr(), toOsg(resultCallback.mContactPoint));
|
||||||
|
}
|
||||||
|
return std::make_pair(MWWorld::Ptr(), osg::Vec3f());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
#include <osg/Quat>
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Group;
|
class Group;
|
||||||
@ -78,9 +80,9 @@ namespace MWPhysics
|
|||||||
std::vector<std::string> getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask); ///< get handles this object collides with
|
std::vector<std::string> getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask); ///< get handles this object collides with
|
||||||
osg::Vec3f traceDown(const MWWorld::Ptr &ptr, float maxHeight);
|
osg::Vec3f traceDown(const MWWorld::Ptr &ptr, float maxHeight);
|
||||||
|
|
||||||
std::pair<std::string,Ogre::Vector3> getHitContact(const std::string &name,
|
std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::Ptr& actor,
|
||||||
const Ogre::Vector3 &origin,
|
const osg::Vec3f &origin,
|
||||||
const Ogre::Quaternion &orientation,
|
const osg::Quat &orientation,
|
||||||
float queryDistance);
|
float queryDistance);
|
||||||
|
|
||||||
// cast ray, return true if it hit something.
|
// cast ray, return true if it hit something.
|
||||||
|
@ -315,6 +315,9 @@ namespace MWRender
|
|||||||
|
|
||||||
MWRender::Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr)
|
MWRender::Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr)
|
||||||
{
|
{
|
||||||
|
if (mPlayerAnimation.get() && ptr == mPlayerAnimation->getPtr())
|
||||||
|
return mPlayerAnimation.get();
|
||||||
|
|
||||||
return mObjects->getAnimation(ptr);
|
return mObjects->getAnimation(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#include "../mwmechanics/combat.hpp"
|
#include "../mwmechanics/combat.hpp"
|
||||||
#include "../mwmechanics/aiavoiddoor.hpp" //Used to tell actors to avoid doors
|
#include "../mwmechanics/aiavoiddoor.hpp" //Used to tell actors to avoid doors
|
||||||
|
|
||||||
//#include "../mwrender/animation.hpp"
|
#include "../mwrender/animation.hpp"
|
||||||
#include "../mwrender/renderingmanager.hpp"
|
#include "../mwrender/renderingmanager.hpp"
|
||||||
#include "../mwrender/camera.hpp"
|
#include "../mwrender/camera.hpp"
|
||||||
|
|
||||||
@ -1052,32 +1052,32 @@ namespace MWWorld
|
|||||||
//return getPtrViaHandle(facedHandle);
|
//return getPtrViaHandle(facedHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<MWWorld::Ptr,Ogre::Vector3> World::getHitContact(const MWWorld::Ptr &ptr, float distance)
|
std::pair<MWWorld::Ptr,osg::Vec3f> World::getHitContact(const MWWorld::Ptr &ptr, float distance)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
const ESM::Position &posdata = ptr.getRefData().getPosition();
|
const ESM::Position &posdata = ptr.getRefData().getPosition();
|
||||||
Ogre::Vector3 pos(posdata.pos);
|
|
||||||
Ogre::Quaternion rot = Ogre::Quaternion(Ogre::Radian(posdata.rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
|
||||||
Ogre::Quaternion(Ogre::Radian(posdata.rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X);
|
|
||||||
|
|
||||||
MWRender::Animation *anim = mRendering->getAnimation(ptr);
|
osg::Quat rot = osg::Quat(posdata.rot[0], osg::Vec3f(-1,0,0)) * osg::Quat(posdata.rot[2], osg::Vec3f(0,0,-1));
|
||||||
if(anim != NULL)
|
osg::Vec3f pos (posdata.asVec3());
|
||||||
|
|
||||||
|
MWRender::Animation* anim = mRendering->getAnimation(ptr);
|
||||||
|
if (anim != NULL)
|
||||||
{
|
{
|
||||||
Ogre::Node *node = anim->getNode("Head");
|
const osg::Node* node = anim->getNode("Head");
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
node = anim->getNode("Bip01 Head");
|
node = anim->getNode("Bip01 Head");
|
||||||
if(node != NULL)
|
if (node != NULL)
|
||||||
pos += node->_getDerivedPosition();
|
{
|
||||||
|
osg::MatrixList mats = node->getWorldMatrices();
|
||||||
|
if (mats.size())
|
||||||
|
pos = mats[0].getTrans();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string,Ogre::Vector3> result;// = mPhysics->getHitContact(ptr.getRefData().getHandle(),
|
std::pair<MWWorld::Ptr,osg::Vec3f> result = mPhysics->getHitContact(ptr, pos, rot, distance);
|
||||||
// pos, rot, distance);
|
if(result.first.isEmpty())
|
||||||
if(result.first.empty())
|
return std::make_pair(MWWorld::Ptr(), osg::Vec3f());
|
||||||
return std::make_pair(MWWorld::Ptr(), Ogre::Vector3(0.0f));
|
|
||||||
|
|
||||||
return std::make_pair(searchPtrViaHandle(result.first), result.second);
|
return std::make_pair(result.first, result.second);
|
||||||
*/
|
|
||||||
return std::make_pair(MWWorld::Ptr(), Ogre::Vector3(0.0f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::deleteObject (const Ptr& ptr)
|
void World::deleteObject (const Ptr& ptr)
|
||||||
|
@ -344,7 +344,7 @@ namespace MWWorld
|
|||||||
/// Returns a pointer to the object the provided object would hit (if within the
|
/// Returns a pointer to the object the provided object would hit (if within the
|
||||||
/// specified distance), and the point where the hit occurs. This will attempt to
|
/// specified distance), and the point where the hit occurs. This will attempt to
|
||||||
/// use the "Head" node as a basis.
|
/// use the "Head" node as a basis.
|
||||||
virtual std::pair<MWWorld::Ptr,Ogre::Vector3> getHitContact(const MWWorld::Ptr &ptr, float distance);
|
virtual std::pair<MWWorld::Ptr,osg::Vec3f> getHitContact(const MWWorld::Ptr &ptr, float distance);
|
||||||
|
|
||||||
virtual void deleteObject (const Ptr& ptr);
|
virtual void deleteObject (const Ptr& ptr);
|
||||||
virtual void undeleteObject (const Ptr& ptr);
|
virtual void undeleteObject (const Ptr& ptr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user