mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:53:53 +00:00
Consider hit normal for item drop test (Fixes #995)
This commit is contained in:
parent
f476aa4ade
commit
2fe86f2b85
5 changed files with 22 additions and 12 deletions
|
@ -492,7 +492,7 @@ namespace MWWorld
|
||||||
return std::make_pair(true, ray.getPoint(len * test.second));
|
return std::make_pair(true, ray.getPoint(len * test.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY)
|
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal)
|
||||||
{
|
{
|
||||||
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
||||||
mouseX,
|
mouseX,
|
||||||
|
@ -504,7 +504,7 @@ namespace MWWorld
|
||||||
_from = btVector3(from.x, from.y, from.z);
|
_from = btVector3(from.x, from.y, from.z);
|
||||||
_to = btVector3(to.x, to.y, to.z);
|
_to = btVector3(to.x, to.y, to.z);
|
||||||
|
|
||||||
std::pair<std::string, float> result = mEngine->rayTest(_from, _to);
|
std::pair<std::string, float> result = mEngine->rayTest(_from, _to, true, false, normal);
|
||||||
|
|
||||||
if (result.first == "")
|
if (result.first == "")
|
||||||
return std::make_pair(false, Ogre::Vector3());
|
return std::make_pair(false, Ogre::Vector3());
|
||||||
|
|
|
@ -70,8 +70,9 @@ namespace MWWorld
|
||||||
std::pair<bool, Ogre::Vector3>
|
std::pair<bool, Ogre::Vector3>
|
||||||
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
|
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);
|
||||||
|
|
||||||
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY);
|
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL);
|
||||||
///< cast ray from the mouse, return true if it hit something and the first result (in OGRE coordinates)
|
///< cast ray from the mouse, return true if it hit something and the first result
|
||||||
|
/// @param normal if non-NULL, the hit normal will be written there (if there is a hit)
|
||||||
|
|
||||||
OEngine::Physic::PhysicEngine* getEngine();
|
OEngine::Physic::PhysicEngine* getEngine();
|
||||||
|
|
||||||
|
|
|
@ -1620,13 +1620,16 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::canPlaceObject(float cursorX, float cursorY)
|
bool World::canPlaceObject(float cursorX, float cursorY)
|
||||||
{
|
{
|
||||||
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
|
Ogre::Vector3 normal(0,0,0);
|
||||||
|
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal);
|
||||||
|
|
||||||
/// \todo also check if the wanted position is on a flat surface, and not e.g. against a vertical wall!
|
if (result.first)
|
||||||
|
{
|
||||||
if (!result.first)
|
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall
|
||||||
|
return (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() < 30);
|
||||||
|
}
|
||||||
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -677,7 +677,7 @@ namespace Physic
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap)
|
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap, Ogre::Vector3* normal)
|
||||||
{
|
{
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
float d = -1;
|
float d = -1;
|
||||||
|
@ -694,7 +694,11 @@ namespace Physic
|
||||||
if (resultCallback1.hasHit())
|
if (resultCallback1.hasHit())
|
||||||
{
|
{
|
||||||
name = static_cast<const RigidBody&>(*resultCallback1.m_collisionObject).mName;
|
name = static_cast<const RigidBody&>(*resultCallback1.m_collisionObject).mName;
|
||||||
d = resultCallback1.m_closestHitFraction;;
|
d = resultCallback1.m_closestHitFraction;
|
||||||
|
if (normal)
|
||||||
|
*normal = Ogre::Vector3(resultCallback1.m_hitNormalWorld.x(),
|
||||||
|
resultCallback1.m_hitNormalWorld.y(),
|
||||||
|
resultCallback1.m_hitNormalWorld.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::pair<std::string,float>(name,d);
|
return std::pair<std::string,float>(name,d);
|
||||||
|
|
|
@ -308,8 +308,10 @@ namespace Physic
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
|
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
|
||||||
|
* If \a normal is non-NULL, the hit normal will be written there (if there is a hit)
|
||||||
*/
|
*/
|
||||||
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,bool ignoreHeightMap = false);
|
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,
|
||||||
|
bool ignoreHeightMap = false, Ogre::Vector3* normal = NULL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all objects hit by a ray.
|
* Return all objects hit by a ray.
|
||||||
|
|
Loading…
Reference in a new issue