1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-19 23:53:52 +00:00

Avoid double raycasts when using getFacedObject

This commit is contained in:
Allofich 2016-07-04 02:11:30 +09:00
parent 574e40db5e
commit 64d53a2314
4 changed files with 42 additions and 6 deletions

View file

@ -738,7 +738,9 @@ namespace MWRender
mViewer->getCamera()->accept(*createIntersectionVisitor(intersector, ignorePlayer, ignoreActors)); mViewer->getCamera()->accept(*createIntersectionVisitor(intersector, ignorePlayer, ignoreActors));
return getIntersectionResult(intersector); RayResult result = getIntersectionResult(intersector);
result.mDistanceToFirstIntersection = maxDistance * intersector->getFirstIntersection().ratio;
return result;
} }
void RenderingManager::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) void RenderingManager::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated)

View file

@ -120,6 +120,7 @@ namespace MWRender
osg::Vec3f mHitNormalWorld; osg::Vec3f mHitNormalWorld;
osg::Vec3f mHitPointWorld; osg::Vec3f mHitPointWorld;
MWWorld::Ptr mHitObject; MWWorld::Ptr mHitObject;
float mDistanceToFirstIntersection;
}; };
RayResult castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors=false); RayResult castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors=false);

View file

@ -1,4 +1,5 @@
#include "worldimp.hpp" #include "worldimp.hpp"
#include <iostream>
#include <osg/Group> #include <osg/Group>
#include <osg/ComputeBoundsVisitor> #include <osg/ComputeBoundsVisitor>
@ -1023,15 +1024,16 @@ namespace MWWorld
telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus); telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus);
float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus;
float distanceToObject;
facedObject = getFacedObject(activationDistance); facedObject = getFacedObject(activationDistance, distanceToObject, true);
// Not allowing telekinesis on actors, on doors that teleport to other cells, or on activators // Not allowing telekinesis on actors, on doors that teleport to other cells, or on activators
// Original engine doesn't allow telekinesis on books or lights, either // Original engine doesn't allow telekinesis on books or lights, either
if (!facedObject.isEmpty() && !facedObject.getClass().isActor() && !facedObject.getCellRef().getTeleport() && facedObject.getClass().getTypeName() != "struct ESM::Activator") if (!facedObject.isEmpty() && (facedObject.getClass().isActor()
return facedObject; || facedObject.getCellRef().getTeleport() || facedObject.getClass().getTypeName() == "struct ESM::Activator")
else && (distanceToObject > getMaxActivationDistance()))
facedObject = getFacedObject(getMaxActivationDistance()); return 0;
} }
return facedObject; return facedObject;
@ -1732,6 +1734,31 @@ namespace MWWorld
} }
} }
MWWorld::Ptr World::getFacedObject(float maxDistance, float& distance, bool ignorePlayer)
{
maxDistance += mRendering->getCameraDistance();
MWWorld::Ptr facedObject;
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
{
float x, y;
MWBase::Environment::get().getWindowManager()->getMousePosition(x, y);
MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(x, y, maxDistance, ignorePlayer);
facedObject = rayToObject.mHitObject;
if (!facedObject.isEmpty())
distance = rayToObject.mDistanceToFirstIntersection;
return facedObject;
}
else
{
MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer);
facedObject = rayToObject.mHitObject;
if (!facedObject.isEmpty())
distance = rayToObject.mDistanceToFirstIntersection;
return facedObject;
}
}
bool World::isCellExterior() const bool World::isCellExterior() const
{ {
const CellStore *currentCell = mWorldScene->getCurrentCell(); const CellStore *currentCell = mWorldScene->getCurrentCell();

View file

@ -127,7 +127,13 @@ namespace MWWorld
void updateSoundListener(); void updateSoundListener();
void updateWindowManager (); void updateWindowManager ();
void updatePlayer(bool paused); void updatePlayer(bool paused);
/// Return faced object
MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true); MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true);
/// Return faced object and distance from player to it
MWWorld::Ptr getFacedObject(float maxDistance, float& distanceToObject, bool ignorePlayer=true);
public: // FIXME public: // FIXME
void removeContainerScripts(const Ptr& reference); void removeContainerScripts(const Ptr& reference);
private: private: