forked from mirror/openmw-tes3mp
Fix being able to place items on top of actors (Fixes #1403)
This commit is contained in:
parent
3d103f3785
commit
c36decb855
3 changed files with 15 additions and 4 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, Ogre::Vector3* normal)
|
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY, Ogre::Vector3* normal, std::string* hit)
|
||||||
{
|
{
|
||||||
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay(
|
||||||
mouseX,
|
mouseX,
|
||||||
|
@ -510,6 +510,8 @@ namespace MWWorld
|
||||||
return std::make_pair(false, Ogre::Vector3());
|
return std::make_pair(false, Ogre::Vector3());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (hit != NULL)
|
||||||
|
*hit = result.first;
|
||||||
return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable
|
return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,9 +70,10 @@ 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, Ogre::Vector3* normal = NULL);
|
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY, Ogre::Vector3* normal = NULL, std::string* hit = NULL);
|
||||||
///< cast ray from the mouse, return true if it hit something and the first result
|
///< 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)
|
/// @param normal if non-NULL, the hit normal will be written there (if there is a hit)
|
||||||
|
/// @param hit if non-NULL, the string handle of the hit object will be written there (if there is a hit)
|
||||||
|
|
||||||
OEngine::Physic::PhysicEngine* getEngine();
|
OEngine::Physic::PhysicEngine* getEngine();
|
||||||
|
|
||||||
|
|
|
@ -1624,12 +1624,20 @@ namespace MWWorld
|
||||||
bool World::canPlaceObject(float cursorX, float cursorY)
|
bool World::canPlaceObject(float cursorX, float cursorY)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 normal(0,0,0);
|
Ogre::Vector3 normal(0,0,0);
|
||||||
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal);
|
std::string handle;
|
||||||
|
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY, &normal, &handle);
|
||||||
|
|
||||||
if (result.first)
|
if (result.first)
|
||||||
{
|
{
|
||||||
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall
|
// 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);
|
if (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() >= 30)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MWWorld::Ptr hitObject = searchPtrViaHandle(handle);
|
||||||
|
if (!hitObject.isEmpty() && hitObject.getClass().isActor())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue