/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Implements a visibility determination map for use with AI. #ifndef CRYINCLUDE_CRYAISYSTEM_VISIONMAP_H #define CRYINCLUDE_CRYAISYSTEM_VISIONMAP_H #pragma once #include #include #include #ifdef CRYAISYSTEM_DEBUG #define VISIONMAP_DEBUG 1 #endif class CVisionMap : public IVisionMap { public: CVisionMap(); virtual ~CVisionMap(); virtual void Reset(); virtual VisionID CreateVisionID(const char* name); virtual void RegisterObserver(const ObserverID& observerID, const ObserverParams& observerParams); virtual void UnregisterObserver(const ObserverID& observerID); virtual void RegisterObservable(const ObservableID& observableID, const ObservableParams& observerParams); virtual void UnregisterObservable(const ObservableID& observableID); virtual void ObserverChanged(const ObserverID& observerID, const ObserverParams& observerParams, uint32 hint); virtual void ObservableChanged(const ObservableID& observableID, const ObservableParams& newObservableParams, uint32 hint); virtual bool IsVisible(const ObserverID& observerID, const ObservableID& observableID) const; virtual const ObserverParams* GetObserverParams(const ObserverID& observerID) const; virtual const ObservableParams* GetObservableParams(const ObservableID& observableID) const; virtual void AddPriorityMapEntry(const PriorityMapEntry& priorityMapEntry); virtual void ClearPriorityMap(); virtual void Update(float frameTime); #if VISIONMAP_DEBUG void DebugDraw(); #endif private: struct ObservableInfo { ObservableInfo(const ObservableID& _observableID, const ObservableParams& _observableParams) : observableID(_observableID) , observableParams(_observableParams) {}; ObservableID observableID; ObservableParams observableParams; }; struct ObservablePosition { inline Vec3 operator()(const ObservableInfo* observableInfo) const { return observableInfo->observableParams.observablePositions[0]; } }; typedef hash_grid<256, ObservableInfo*, hash_grid_2d, ObservablePosition> ObservablesGrid; typedef AZStd::unordered_map Observables; struct PVSEntry { PVSEntry(const ObservableInfo& _observableInfo, RayCastRequest::Priority _priority) : pendingRayID(0) , observableInfo(_observableInfo) , visible(false) , currentTestPositionIndex(0) , priority(_priority) , needsUpdate(true) #if VISIONMAP_DEBUG , obstructionPosition(ZERO) , lastObserverPositionChecked(ZERO) , lastObservablePositionChecked(ZERO) , rayQueueTimestamp(0.0f) #endif {}; QueuedRayID pendingRayID; RayCastRequest::Priority priority; const ObservableInfo& observableInfo; bool visible; bool needsUpdate; int8 currentTestPositionIndex; int8 firstVisPos; #if VISIONMAP_DEBUG Vec3 obstructionPosition; Vec3 lastObserverPositionChecked; Vec3 lastObservablePositionChecked; float rayQueueTimestamp; #endif }; typedef std::map PVS; struct ObserverInfo { ObserverInfo(ObserverID _observerID) : observerID(_observerID) , needsPVSUpdate(false) , needsVisibilityUpdate(false) , queuedForPVSUpdate(false) , queuedForVisibilityUpdate(false) , updateAllVisibilityStatus(false) , nextPVSUpdateTime(0.0f) , nextVisibilityUpdateTime(0.0f) { } ObserverID observerID; ObserverParams observerParams; PVS pvs; bool needsPVSUpdate; bool needsVisibilityUpdate; bool queuedForPVSUpdate; bool queuedForVisibilityUpdate; bool updateAllVisibilityStatus; CTimeValue nextPVSUpdateTime; CTimeValue nextVisibilityUpdateTime; #if VISIONMAP_DEBUG CTimeValue queuedForPVSUpdateTime; CTimeValue queuedForVisibilityUpdateTime; #endif }; typedef std::unordered_map Observers; struct PendingRayInfo { PendingRayInfo(const ObserverInfo& _observerInfo, PVSEntry& _pvsEntry) : observerInfo(_observerInfo) , pvsEntry(_pvsEntry) #if VISIONMAP_DEBUG , observerPosition(ZERO) , observablePosition(ZERO) #endif { } const ObserverInfo& observerInfo; PVSEntry& pvsEntry; #if VISIONMAP_DEBUG Vec3 observerPosition; Vec3 observablePosition; #endif }; std::vector m_priorityMap; void AcquireSkipList(IPhysicalEntity** skipList, uint32 skipListSize); void ReleaseSkipList(IPhysicalEntity** skipList, uint32 skipListSize); #if VISIONMAP_DEBUG void UpdateDebugVisionMapObjects(); void DebugDrawObservers(); void DebugDrawObservables(); void DebugDrawVisionMapStats(); #endif void AddToObserverPVS(ObserverInfo& observerInfo, const ObservableInfo& observableInfo); void UpdateObservers(); void UpdatePVS(ObserverInfo& observerInfo); bool ShouldBeAddedToObserverPVS(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const; void UpdateVisibilityStatus(ObserverInfo& observerInfo); bool ShouldObserve(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const; bool IsInSightRange(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const; bool IsInFoV(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const; void QueueRay(const ObserverInfo& observerInfo, PVSEntry& pvsEntry); bool RayCastSubmit(const QueuedRayID& queuedRayID, RayCastRequest& request); void RayCastComplete(const QueuedRayID& queuedRayID, const RayCastResult& rayCastResult); RayCastRequest::Priority GetRayCastRequestPriority(const ObserverParams& observerParams, const ObservableParams& observable); void DeletePendingRay(PVSEntry& pvsEntry); void DeletePendingRays(PVS& pvs); void TriggerObserverCallback(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo, bool visible); void TriggerObservableCallback(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo, bool visible); Observers m_observers; Observables m_observables; ObservablesGrid m_observablesGrid; typedef std::deque ObserverQueue; ObserverQueue m_observerPVSUpdateQueue; ObserverQueue m_observerVisibilityUpdateQueue; typedef std::vector > QueryObservables; QueryObservables m_queryObservables; typedef std::map PendingRays; PendingRays m_pendingRays; #if VISIONMAP_DEBUG float m_debugTimer; uint32 m_numberOfPVSUpdatesThisFrame; uint32 m_numberOfVisibilityUpdatesThisFrame; uint32 m_numberOfRayCastsSubmittedThisFrame; VisionID m_debugObserverVisionID; VisionID m_debugObservableVisionID; CTimeValue m_pvsUpdateQueueLatency; CTimeValue m_visibilityUpdateQueueLatency; struct LatencyInfo { struct { float latency; float occurred; } buffer[512]; int bufferIndex; int usedBufferSize; }; LatencyInfo m_latencyInfo[RayCastRequest::TotalNumberOfPriorities]; int m_pendingRayCounts[RayCastRequest::TotalNumberOfPriorities]; #endif uint32 m_visionIdCounter; }; #endif // CRYINCLUDE_CRYAISYSTEM_VISIONMAP_H