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
|
||||
/// 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.
|
||||
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;
|
||||
///< 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();
|
||||
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())
|
||||
return; // Didn't hit anything
|
||||
|
||||
@ -247,7 +247,7 @@ namespace MWClass
|
||||
if (!victim.getClass().isActor())
|
||||
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);
|
||||
|
||||
|
@ -491,9 +491,9 @@ namespace MWClass
|
||||
store.find("fHandToHandReach")->getFloat());
|
||||
|
||||
// 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;
|
||||
Ogre::Vector3 hitPosition = result.second;
|
||||
Ogre::Vector3 hitPosition (result.second.x(), result.second.y(), result.second.z());
|
||||
if(victim.isEmpty()) // Didn't hit anything
|
||||
return;
|
||||
|
||||
|
@ -31,6 +31,11 @@ namespace MWPhysics
|
||||
mPtr = updated;
|
||||
}
|
||||
|
||||
MWWorld::Ptr getPtr() const
|
||||
{
|
||||
return mPtr;
|
||||
}
|
||||
|
||||
protected:
|
||||
MWWorld::Ptr mPtr;
|
||||
};
|
||||
|
@ -653,35 +653,78 @@ namespace MWPhysics
|
||||
return mDebugDrawEnabled;
|
||||
}
|
||||
|
||||
std::pair<std::string,Ogre::Vector3> PhysicsSystem::getHitContact(const std::string &name,
|
||||
const Ogre::Vector3 &origin,
|
||||
const Ogre::Quaternion &orient,
|
||||
class DeepestNotMeContactTestResultCallback : public btCollisionWorld::ContactResultCallback
|
||||
{
|
||||
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)
|
||||
{
|
||||
return std::make_pair(std::string(), Ogre::Vector3());
|
||||
/*
|
||||
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(),
|
||||
queryDistance);
|
||||
shape.setLocalScaling(btVector3(1, 1, Ogre::Degree(store.find("fCombatAngleZ")->getFloat()/2.0f).valueRadians() /
|
||||
btConeShape shape (osg::DegreesToRadians(store.find("fCombatAngleXY")->getFloat()/2.0f), queryDistance);
|
||||
shape.setLocalScaling(btVector3(1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->getFloat()/2.0f) /
|
||||
shape.getRadius()));
|
||||
|
||||
// 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.
|
||||
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;
|
||||
object.setCollisionShape(&shape);
|
||||
object.setWorldTransform(btTransform(btQuaternion(orient.x, orient.y, orient.z, orient.w),
|
||||
btVector3(center.x, center.y, center.z)));
|
||||
object.setWorldTransform(btTransform(toBullet(orient), toBullet(center)));
|
||||
|
||||
std::pair<const OEngine::Physic::RigidBody*,btVector3> result = mEngine->getFilteredContact(
|
||||
name, btVector3(origin.x, origin.y, origin.z), &object);
|
||||
if(!result.first)
|
||||
return std::make_pair(std::string(), Ogre::Vector3(&result.second[0]));
|
||||
return std::make_pair(result.first->mName, Ogre::Vector3(&result.second[0]));
|
||||
*/
|
||||
const btCollisionObject* me = NULL;
|
||||
Actor* physactor = getActor(actor);
|
||||
if (physactor)
|
||||
me = physactor->getCollisionObject();
|
||||
|
||||
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 <osg/Quat>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
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
|
||||
osg::Vec3f traceDown(const MWWorld::Ptr &ptr, float maxHeight);
|
||||
|
||||
std::pair<std::string,Ogre::Vector3> getHitContact(const std::string &name,
|
||||
const Ogre::Vector3 &origin,
|
||||
const Ogre::Quaternion &orientation,
|
||||
std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::Ptr& actor,
|
||||
const osg::Vec3f &origin,
|
||||
const osg::Quat &orientation,
|
||||
float queryDistance);
|
||||
|
||||
// cast ray, return true if it hit something.
|
||||
|
@ -315,6 +315,9 @@ namespace MWRender
|
||||
|
||||
MWRender::Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr)
|
||||
{
|
||||
if (mPlayerAnimation.get() && ptr == mPlayerAnimation->getPtr())
|
||||
return mPlayerAnimation.get();
|
||||
|
||||
return mObjects->getAnimation(ptr);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "../mwmechanics/combat.hpp"
|
||||
#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/camera.hpp"
|
||||
|
||||
@ -1052,32 +1052,32 @@ namespace MWWorld
|
||||
//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();
|
||||
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);
|
||||
if(anim != NULL)
|
||||
osg::Quat rot = osg::Quat(posdata.rot[0], osg::Vec3f(-1,0,0)) * osg::Quat(posdata.rot[2], osg::Vec3f(0,0,-1));
|
||||
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)
|
||||
node = anim->getNode("Bip01 Head");
|
||||
if(node != NULL)
|
||||
pos += node->_getDerivedPosition();
|
||||
if (node != NULL)
|
||||
{
|
||||
osg::MatrixList mats = node->getWorldMatrices();
|
||||
if (mats.size())
|
||||
pos = mats[0].getTrans();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<std::string,Ogre::Vector3> result;// = mPhysics->getHitContact(ptr.getRefData().getHandle(),
|
||||
// pos, rot, distance);
|
||||
if(result.first.empty())
|
||||
return std::make_pair(MWWorld::Ptr(), Ogre::Vector3(0.0f));
|
||||
std::pair<MWWorld::Ptr,osg::Vec3f> result = mPhysics->getHitContact(ptr, pos, rot, distance);
|
||||
if(result.first.isEmpty())
|
||||
return std::make_pair(MWWorld::Ptr(), osg::Vec3f());
|
||||
|
||||
return std::make_pair(searchPtrViaHandle(result.first), result.second);
|
||||
*/
|
||||
return std::make_pair(MWWorld::Ptr(), Ogre::Vector3(0.0f));
|
||||
return std::make_pair(result.first, result.second);
|
||||
}
|
||||
|
||||
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
|
||||
/// specified distance), and the point where the hit occurs. This will attempt to
|
||||
/// 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 undeleteObject (const Ptr& ptr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user