mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-26 14:56:39 +00:00 
			
		
		
		
	Avoid double raycasts when using getFacedObject
This commit is contained in:
		
							parent
							
								
									574e40db5e
								
							
						
					
					
						commit
						64d53a2314
					
				
					 4 changed files with 42 additions and 6 deletions
				
			
		|  | @ -738,7 +738,9 @@ namespace MWRender | |||
| 
 | ||||
|         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) | ||||
|  |  | |||
|  | @ -120,6 +120,7 @@ namespace MWRender | |||
|             osg::Vec3f mHitNormalWorld; | ||||
|             osg::Vec3f mHitPointWorld; | ||||
|             MWWorld::Ptr mHitObject; | ||||
|             float mDistanceToFirstIntersection; | ||||
|         }; | ||||
| 
 | ||||
|         RayResult castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors=false); | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include "worldimp.hpp" | ||||
| #include <iostream> | ||||
| 
 | ||||
| #include <osg/Group> | ||||
| #include <osg/ComputeBoundsVisitor> | ||||
|  | @ -1023,15 +1024,16 @@ namespace MWWorld | |||
|             telekinesisRangeBonus = feetToGameUnits(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
 | ||||
|             // 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") | ||||
|                  return facedObject; | ||||
|             else | ||||
|                 facedObject = getFacedObject(getMaxActivationDistance()); | ||||
|             if (!facedObject.isEmpty() && (facedObject.getClass().isActor() | ||||
|                 || facedObject.getCellRef().getTeleport() || facedObject.getClass().getTypeName() == "struct ESM::Activator") | ||||
|                 && (distanceToObject > getMaxActivationDistance())) | ||||
|                 return 0; | ||||
|         } | ||||
| 
 | ||||
|         return facedObject; | ||||
|  | @ -1731,6 +1733,31 @@ namespace MWWorld | |||
|             return mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer).mHitObject; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     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 | ||||
|     { | ||||
|  |  | |||
|  | @ -127,7 +127,13 @@ namespace MWWorld | |||
|             void updateSoundListener(); | ||||
|             void updateWindowManager (); | ||||
|             void updatePlayer(bool paused); | ||||
| 
 | ||||
|             /// Return faced object
 | ||||
|             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
 | ||||
|             void removeContainerScripts(const Ptr& reference); | ||||
|     private: | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue