public static bool TryFindTerrainOverlayNode(this TerrainOverlayNetwork terrainOverlayNetwork, Vector3 p, out TerrainOverlayNetworkNode result, out Vector3 pLocal) { foreach (var bvhNode in terrainOverlayNetwork.NodeBvh.FindIntersectingLeaves(p.ToOpenMobaVector())) { for (var i = bvhNode.StartIndexInclusive; i < bvhNode.EndIndexExclusive; i++) { var node = bvhNode.Values[i]; pLocal = Vector3.Transform(p, node.SectorNodeDescription.WorldTransformInv); var pLocalXy = new IntVector2((int)pLocal.X, (int)pLocal.Y); // todo: correctness issues if (!node.LandPolyNode.PointInLandPolygonNonrecursive(pLocalXy)) { continue; } if (Math.Abs(pLocal.Z) > 1E-3f) { continue; } result = node; return(true); } } result = null; pLocal = default(Vector3); return(false); }
public static bool TryFindTerrainOverlayNode(this TerrainOverlayNetwork terrainOverlayNetwork, DoubleVector3 p, out TerrainOverlayNetworkNode result, out DoubleVector3 pLocal) { var res = TryFindTerrainOverlayNode(terrainOverlayNetwork, p.ToDotNetVector(), out result, out var pLocalV3); pLocal = pLocalV3.ToOpenMobaVector(); return(res); }
public TerrainOverlayNetwork CompileTerrainOverlayNetwork(double agentRadius) { if (terrainOverlayNetworkCache.TryGetValue(agentRadius, out var existingTerrainOverlayNetwork)) { return(existingTerrainOverlayNetwork); } // Console.WriteLine($"Compiling Terrain Overlay Network for Agent Radius {agentRadius}."); //---------------------------------------------------------------------------------------- // Sector Node Description => Default Local Geometry View //---------------------------------------------------------------------------------------- var renderedLocalGeometryViewBySectorNodeDescription = localGeometryViewManagerBySectorNodeDescription.Map( (k, v) => v.GetErodedView(agentRadius * k.WorldToLocalScalingFactor)); var defaultLocalGeometryViewBySectorNodeDescription = renderedLocalGeometryViewBySectorNodeDescription.Map( (k, v) => true || v.IsPunchedLandEvaluated ? v : v.Preview); var landPolyNodesByDefaultLocalGeometryView = defaultLocalGeometryViewBySectorNodeDescription.Values.Distinct().ToDictionary( lgv => lgv, lgv => lgv.PunchedLand.GetLandNodes()); var terrainNodesBySectorNodeDescription = defaultLocalGeometryViewBySectorNodeDescription.Map( (k, v) => landPolyNodesByDefaultLocalGeometryView[v].Map(pn => new TerrainOverlayNetworkNode(k, v, pn))); var terrainNodesBySectorNodeDescriptionAndPolyNode = terrainNodesBySectorNodeDescription.Values.SelectMany(tns => tns).ToDictionary( tn => (tn.SectorNodeDescription, tn.LandPolyNode)); //---------------------------------------------------------------------------------------- // Edge Lookups //---------------------------------------------------------------------------------------- var edgesBySource = edgeDescriptions.ToLookup(ed => ed.Source); var edgesByDestination = edgeDescriptions.ToLookup(ed => ed.Destination); var edgesByEndpoints = MultiValueDictionary <SectorNodeDescription, SectorEdgeDescription> .Create(() => new HashSet <SectorEdgeDescription>()); foreach (var(k, edges) in edgesBySource) { foreach (var edge in edges) { edgesByEndpoints.Add(k, edge); } } foreach (var(k, edges) in edgesByDestination) { foreach (var edge in edges) { edgesByEndpoints.Add(k, edge); } } //---------------------------------------------------------------------------------------- // Build and Initialize Terrain Overlay Network //---------------------------------------------------------------------------------------- var terrainOverlayNetwork = new TerrainOverlayNetwork( agentRadius, defaultLocalGeometryViewBySectorNodeDescription, terrainNodesBySectorNodeDescription, landPolyNodesByDefaultLocalGeometryView, terrainNodesBySectorNodeDescriptionAndPolyNode, edgeDescriptions, edgesBySource, edgesByDestination, edgesByEndpoints); terrainOverlayNetwork.Initialize(); return(terrainOverlayNetworkCache[agentRadius] = terrainOverlayNetwork); }
public static bool TryFindTerrainOverlayNode(this TerrainOverlayNetwork terrainOverlayNetwork, DoubleVector3 p, out TerrainOverlayNetworkNode result) { return(TryFindTerrainOverlayNode(terrainOverlayNetwork, p, out result, out _)); }