public PrimitiveGeometryCollector(NavMeshNativeInputBuilder inputBuilder, Unity.Physics.TerrainCollider *terrainCollider, RigidTransform transform, DtBoundingBox bounds) { InputBuilder = inputBuilder; TerrainCollider = terrainCollider; Transform = transform; Bounds = bounds; }
public ConvexHullGeometryCollector(NavMeshNativeInputBuilder inputBuilder, ConvexCollider *collider, RigidTransform transform, DtBoundingBox bounds) { InputBuilder = inputBuilder; Collider = collider; Transform = transform; Bounds = bounds; }
public MeshGeometryCollector(NavMeshNativeInputBuilder inputBuilder, MeshCollider *Collider, RigidTransform transform, DtBoundingBox bounds) { InputBuilder = inputBuilder; this.Collider = Collider; Transform = transform; Bounds = bounds; }
private void SetGlobalBounds(List <NavMeshBuildInput> inputs) { HeightBounds = inputs[0].TileBounds.Bounds; foreach (NavMeshBuildInput input in inputs) { HeightBounds = DtBoundingBox.Merge(HeightBounds, input.TileBounds.Bounds); } }
public static DtBoundingBox Merge(DtBoundingBox value1, float3 value2) { DtBoundingBox result; result.min = math.min(value1.min, value2); result.max = math.max(value1.max, value2); return(result); }
public static DtBoundingBox Merge(DtBoundingBox value1, DtBoundingBox value2) { DtBoundingBox box; box.min = math.min(value1.min, value2.min); box.max = math.max(value1.max, value2.max); return(box); }
public NavMeshInputBuilder(NavMeshTileBounds tileBounds) { Coord = tileBounds.Coord; BoundingBox = tileBounds.Bounds; Vertices = new AiNativeList <float3>(2); Indices = new AiNativeList <int>(2); Areas = new AiNativeList <byte>(2); }
public NavMeshNativeInputBuilder(NavMeshTileBounds tileBounds) { Coord = tileBounds.Coord; BoundingBox = tileBounds.Bounds; Vertices = new NativeList <float3>(Allocator.TempJob); Indices = new NativeList <int>(Allocator.TempJob); Areas = new NativeList <byte>(Allocator.TempJob); }
public void MarkDirty(DtBoundingBox bounds) { if (Building) { throw new InvalidOperationException("Building"); } Builder.MarkDirty(bounds); }
public void MarkDirty(DtBoundingBox boundingBox) { var tiles = NavMeshBuildUtils.GetOverlappingTiles(BuildSettings, boundingBox); foreach (var tileCoord in tiles) { TilesToBuild.Add(tileCoord); } }
public void GetDirtyTileBounds(List <NavMeshTileBounds> dirty) { foreach (var tileCoord in TilesToBuild) { DtBoundingBox bounds = NavMeshBuildUtils.CalculateTileBoundingBox(BuildSettings, tileCoord); NavMeshTileBounds tileBounds = new NavMeshTileBounds(tileCoord, bounds); dirty.Add(tileBounds); } }
public static bool ContainsPoint(ref DtBoundingBox box, ref float3 point) { if (box.min.x <= point.x && box.max.x >= point.x && box.min.y <= point.y && box.max.y >= point.y && box.min.z <= point.z && box.max.z >= point.z) { return(true); } return(false); }
private void HandleMesh(MeshCollider *collider, ref Translation translation, ref Rotation rotation) { RigidTransform colliderTransform = new RigidTransform(rotation.Value, translation.Value); Aabb aabb = collider->CalculateAabb(colliderTransform); DtBoundingBox colliderBox = new DtBoundingBox(aabb.Min, aabb.Max); if (DtBoundingBox.Intersects(ref TileBounds.Bounds, ref colliderBox)) { MeshGeometryCollector collector = new MeshGeometryCollector(InputBuilder, collider, colliderTransform, TileBounds.Bounds); collector.Collect(); } }
public void BuildSurface() { if (!EnsureSurfaceAdded()) { return; } Bounds bounds = new Bounds(Center, Size); DtBoundingBox box = DtBoundingBox.FromUnityBounds(bounds); var controller = Controller; controller.MarkDirty(box); Controller.OnBuildCompleted -= OnBuildCompleted; controller.OnBuildCompleted += OnBuildCompleted; }
/// <summary> /// Calculates X-Z span for a navigation mesh tile. The Y-axis will span from <see cref="float.MinValue"/> to <see cref="float.MaxValue"/> /// </summary> public static DtBoundingBox CalculateTileBoundingBox(NavMeshBuildSettings settings, int2 tileCoord) { float tcs = settings.TileSize * settings.CellSize; float2 tileMin = new float2(tileCoord.x * tcs, tileCoord.y * tcs); float2 tileMax = tileMin + new float2(tcs); DtBoundingBox boundingBox = default; boundingBox.min.x = tileMin.x; boundingBox.min.z = tileMin.y; boundingBox.max.x = tileMax.x; boundingBox.max.z = tileMax.y; boundingBox.min.y = float.MinValue; boundingBox.max.y = float.MaxValue; return(boundingBox); }
public void Append(NavMeshNativeInputBuilder other) { // Copy vertices int vbase = Vertices.Length; for (int i = 0; i < other.Vertices.Length; i++) { float3 point = other.Vertices[i]; Vertices.Add(point); BoundingBox = DtBoundingBox.Merge(BoundingBox, point); } // Copy indices with offset applied for (int i = 0; i < other.Indices.Length; i++) { Indices.Add(other.Indices[i] + vbase); } }
public static bool Intersects(ref DtBoundingBox box1, ref DtBoundingBox box2) { if (box1.min.x > box2.max.x || box2.min.x > box1.max.x) { return(false); } if (box1.min.y > box2.max.y || box2.min.y > box1.max.y) { return(false); } if (box1.min.z > box2.max.z || box2.min.z > box1.max.z) { return(false); } return(true); }
private bool SetActiveBoundsFilters(DtBoundingBox colliderBounds) { bool hasFilter = false; for (int i = 0; i < BoxFilters.Length; i++) { BoxFilter filter = BoxFilters[i]; if (DtBoundingBox.Intersects(ref filter.Bounds, ref colliderBounds)) { filter.Active = true; hasFilter = true; } else { filter.Active = false; } BoxFilters[i] = filter; } return(hasFilter); }
public void Append(float3[] vertices, int[] indices, byte[] areas) { // Copy vertices int vbase = Vertices.Length; for (int i = 0; i < vertices.Length; i++) { Vertices.Add(vertices[i]); BoundingBox = DtBoundingBox.Merge(BoundingBox, vertices[i]); } // Copy indices with offset applied for (int i = 0; i < indices.Length; i++) { Indices.Add(indices[i] + vbase); } for (int i = 0; i < areas.Length; i++) { Areas.Add(areas[i]); } }
public void Append(NativeArray <float3> vertices, NativeArray <int> indices, NativeArray <byte> areas) { // Copy vertices int vbase = Vertices.Length; for (int i = 0; i < vertices.Length; i++) { Vertices.Add(vertices[i]); BoundingBox = DtBoundingBox.Merge(BoundingBox, vertices[i]); } // Copy indices with offset applied for (int i = 0; i < indices.Length; i++) { Indices.Add(indices[i] + vbase); } for (int i = 0; i < areas.Length; i++) { Areas.Add(areas[i]); } }
/// <summary> /// Check which tiles overlap a given bounding box /// </summary> /// <param name="settings"></param> /// <param name="boundingBox"></param> /// <returns></returns> public static List <int2> GetOverlappingTiles(NavMeshBuildSettings settings, DtBoundingBox boundingBox) { List <int2> ret = new List <int2>(); float tcs = settings.TileSize * settings.CellSize; float2 start = boundingBox.min.xz / tcs; float2 end = boundingBox.max.xz / tcs; int2 startTile = new int2( (int)Math.Floor(start.x), (int)Math.Floor(start.y)); int2 endTile = new int2( (int)Math.Ceiling(end.x), (int)Math.Ceiling(end.y)); for (int y = startTile.y; y < endTile.y; y++) { for (int x = startTile.x; x < endTile.x; x++) { ret.Add(new int2(x, y)); } } return(ret); }
private void HandleTerrain(TerrainCollider *collider, ref Translation translation, ref Rotation rotation) { RigidTransform colliderTransform = new RigidTransform(rotation.Value, translation.Value); Aabb aabb = collider->CalculateAabb(colliderTransform); DtBoundingBox colliderBox = new DtBoundingBox(aabb.Min, aabb.Max); if (DtBoundingBox.Intersects(ref TileBounds.Bounds, ref colliderBox)) { TerrainGeometryCollector collector = new TerrainGeometryCollector { InputBuilder = InputBuilder, TerrainCollider = collider, Transform = colliderTransform, Bounds = TileBounds.Bounds, GeometryFilter = GeometryFilter }; if (SetActiveBoundsFilters(colliderBox)) { collector.SetBoundsFilters(BoxFilters); } collector.Collect(); } }
public void Append(NativeArray <float3> vertices, NativeArray <int> indices, byte area = DtArea.WALKABLE) { // Copy vertices int vbase = Vertices.Length; for (int i = 0; i < vertices.Length; i++) { Vertices.Add(vertices[i]); BoundingBox = DtBoundingBox.Merge(BoundingBox, vertices[i]); } // Copy indices with offset applied for (int i = 0; i < indices.Length; i++) { Indices.Add(indices[i] + vbase); } int triangleCount = indices.Length / 3; for (int i = 0; i < triangleCount; i++) { Areas.Add(area); } }
public bool Intersects(DtBoundingBox other) { return(Intersects(ref this, ref other)); }
private unsafe int BuildTile(int2 tileCoordinate, NavMeshBuildSettings buildSettings, NavAgentSettings agentSettings, NavMeshBuildInput buildInput, long buildTimeStamp, out NavMeshTile meshTile) { meshTile = null; if (buildInput.AreasLength != buildInput.IndicesLength / 3) { return(-1001); } if (buildInput.VerticesLength <= 0 || buildInput.IndicesLength <= 0) { return(-1000); } DtBoundingBox tileBoundingBox = NavMeshBuildUtils.CalculateTileBoundingBox(buildSettings, tileCoordinate); NavMeshBuildUtils.SnapBoundingBoxToCellHeight(buildSettings, ref tileBoundingBox); tileBoundingBox.min.y = HeightBounds.min.y; tileBoundingBox.max.y = HeightBounds.max.y; IntPtr builder = Navigation.NavMesh.CreateBuilder(); DtBuildSettings internalBuildSettings = new DtBuildSettings { // Tile settings BoundingBox = tileBoundingBox, TilePosition = tileCoordinate, TileSize = buildSettings.TileSize, // General build settings CellHeight = buildSettings.CellHeight, CellSize = buildSettings.CellSize, RegionMinArea = buildSettings.MinRegionArea, RegionMergeArea = buildSettings.RegionMergeArea, EdgeMaxLen = buildSettings.MaxEdgeLen, EdgeMaxError = buildSettings.MaxEdgeError, DetailSampleDist = buildSettings.DetailSamplingDistance, DetailSampleMaxError = buildSettings.MaxDetailSamplingError, // Agent settings AgentHeight = agentSettings.Height, AgentRadius = agentSettings.Radius, AgentMaxClimb = agentSettings.MaxClimb, AgentMaxSlope = agentSettings.MaxSlope }; Navigation.NavMesh.SetSettings(builder, new IntPtr(&internalBuildSettings)); IntPtr buildResultPtr = Navigation.NavMesh.Build2(builder, buildInput.Vertices, buildInput.VerticesLength, buildInput.Indices, buildInput.IndicesLength, buildInput.Areas); DtGeneratedData *generatedDataPtr = (DtGeneratedData *)buildResultPtr; if (generatedDataPtr->Success && generatedDataPtr->NavmeshDataLength > 0) { meshTile = new NavMeshTile(); // Copy the generated navigationMesh data meshTile.Data = new byte[generatedDataPtr->NavmeshDataLength + sizeof(long)]; Marshal.Copy(generatedDataPtr->NavmeshData, meshTile.Data, 0, generatedDataPtr->NavmeshDataLength); // Append time stamp byte[] timeStamp = BitConverter.GetBytes(buildTimeStamp); for (int i = 0; i < timeStamp.Length; i++) { meshTile.Data[meshTile.Data.Length - sizeof(long) + i] = timeStamp[i]; } } int error = generatedDataPtr->Error; Navigation.NavMesh.DestroyBuilder(builder); return(error); }
/// <summary> /// Snaps a <see cref="DtBoundingBox"/>'s height according to the given <see cref="NavMeshBuildSettings"/> /// </summary> /// <param name="settings">The build settings</param> /// <param name="boundingBox">Reference to the bounding box to snap</param> public static void SnapBoundingBoxToCellHeight(NavMeshBuildSettings settings, ref DtBoundingBox boundingBox) { // Snap Y to tile height to avoid height differences between tiles boundingBox.min.y = (float)Math.Floor(boundingBox.min.y / settings.CellHeight) * settings.CellHeight; boundingBox.max.y = (float)Math.Ceiling(boundingBox.max.y / settings.CellHeight) * settings.CellHeight; }
public NavMeshTileBounds(int2 coord, DtBoundingBox bounds) { Coord = coord; Bounds = bounds; }
public static bool Approximately(this DtBoundingBox self, DtBoundingBox other) { return(Approximately(self.min, other.min) && Approximately(self.max, other.max)); }