private static VisiblePortionResult CalculateVisiblePortion(Projectile heuristic, Vector3 observerVantage, Vector3 targetVantage) { var data = new Tuple <Projectile, Vector3, Vector3>( heuristic, observerVantage, targetVantage ); if (instance.calculateVisiblePortionCache.ContainsKey(data)) { return(instance.calculateVisiblePortionCache[data]); } float targetHeightAboveGround = targetVantage.y - FindHeightAt(targetVantage.x, targetVantage.z); float heightAdjustment = targetHeightAboveGround / 2; Vector3 rayTarget = targetVantage - new Vector3(0, heightAdjustment, 0); bool canPassThrough = false; for (int i = 0; i < TERRAINDISPARITYCONFIDENCEINTERVAL; i++) { heightAdjustment /= 2; heuristic.ResetStrength(); canPassThrough = ProjectileCanPassThrough(heuristic, observerVantage, rayTarget); if (canPassThrough) { rayTarget.y -= heightAdjustment; } else { rayTarget.y += heightAdjustment; } } //Debug.DrawLine(observerVantage, rayTarget); VisiblePortionResult result = new VisiblePortionResult(); result.visible = targetVantage.y - rayTarget.y; result.heightOfTarget = targetHeightAboveGround; instance.calculateVisiblePortionCache[data] = result; if (instance.calculateVisiblePortionCache.Count > CALCULATE_VISIBLE_PORTION_CACHE_MAX_SiZE) { instance.calculateVisiblePortionCache.PopFirst(); } return(result); }
public static TerrainDisparity CalculateTerrainDisparityBetween( Projectile heuristicOfObserver, Projectile heuristicOfTarget, Vector3 observerVantage, Vector3 targetVantage ) { Tuple <Projectile, Projectile, Vector3, Vector3> data = new Tuple <Projectile, Projectile, Vector3, Vector3>( heuristicOfObserver, heuristicOfTarget, observerVantage, targetVantage ); if (instance.calculateTerrainDisparityBetweenCache.ContainsKey(data)) { return(instance.calculateTerrainDisparityBetweenCache[data]); } TerrainDisparity result = new TerrainDisparity(); VisiblePortionResult observerResult = CalculateVisiblePortion(heuristicOfObserver, observerVantage, targetVantage); VisiblePortionResult targetResult = CalculateVisiblePortion(heuristicOfTarget, targetVantage, observerVantage); result.visibleToObserver = observerResult.visible; result.targetHeight = observerResult.heightOfTarget; result.visibleToTarget = targetResult.visible; result.observerHeight = targetResult.heightOfTarget; instance.calculateTerrainDisparityBetweenCache[data] = result; if (instance.calculateTerrainDisparityBetweenCache.Count > CALCULATE_TERRAIN_DISPARITY_BETWEEN_CACHE_MAX_SIZE) { instance.calculateTerrainDisparityBetweenCache.PopFirst(); } return(result); }