/// <summary> /// Find the distance from a point to a triangle. /// </summary> /// <param name="tile">Current mesh tile</param> /// <param name="indexPoly">Current polygon's index</param> /// <param name="pos">Current position</param> /// <param name="h">Resulting height</param> /// <returns>True, if a height is found. False, if otherwise.</returns> public static bool ClosestHeight(MeshTile tile, int indexPoly, Vector3 pos, out float h) { Poly poly = tile.Polys[indexPoly]; PolyMeshDetail.MeshData pd = tile.DetailMeshes[indexPoly]; //find height at the location for (int j = 0; j < tile.DetailMeshes[indexPoly].TriangleCount; j++) { PolyMeshDetail.TriangleData t = tile.DetailTris[pd.TriangleIndex + j]; Vector3[] v = new Vector3[3]; for (int k = 0; k < 3; k++) { if (t[k] < poly.VertCount) { v[k] = tile.Verts[poly.Verts[t[k]]]; } else { v[k] = tile.DetailVerts[pd.VertexIndex + (t[k] - poly.VertCount)]; } } if (Distance.PointToTriangle(pos, v[0], v[1], v[2], out h)) { return(true); } } h = float.MaxValue; return(false); }
/// <summary> /// Find and add a tile if it is found /// </summary> /// <param name="x">The x-coordinate</param> /// <param name="y">The y-coordinate</param> /// <param name="tiles">Tile array</param> /// <returns>Number of tiles satisfying condition</returns> public int GetTilesAt(int x, int y, MeshTile[] tiles) { int n = 0; //Find tile based on hash int h = ComputeTileHash(x, y, tileLookupTableMask); MeshTile tile = posLookup[h]; while (tile != null) { //Tile found. //Add to tile array if (tile.Header != null && tile.Header.X == x && tile.Header.Y == y) { if (n < tiles.Length) { tiles[n++] = tile; } } //Keep searching tile = tile.Next; } return(n); }
/// <summary> /// Find the closest polygon possible in the tile under certain constraints. /// </summary> /// <param name="tile">Current tile</param> /// <param name="center">Center starting point</param> /// <param name="extents">Range of search</param> /// <param name="nearestPt">Resulting nearest point</param> /// <returns>Polygon Reference which contains nearest point</returns> public PolyId FindNearestPolyInTile(MeshTile tile, Vector3 center, Vector3 extents, ref Vector3 nearestPt) { BBox3 bounds; bounds.Min = center - extents; bounds.Max = center + extents; //Get nearby polygons from proximity grid List <PolyId> polys = new List <PolyId>(128); int polyCount = QueryPolygonsInTile(tile, bounds, polys); //Find nearest polygon amongst the nearby polygons PolyId nearest = PolyId.Null; float nearestDistanceSqr = float.MaxValue; //Iterate throuh all the polygons for (int i = 0; i < polyCount; i++) { PolyId reference = polys[i]; Vector3 closestPtPoly = new Vector3(); tile.ClosestPointOnPoly(reference.DecodePolyIndex(polyBits), center, ref closestPtPoly); float d = (center - closestPtPoly).LengthSquared(); if (d < nearestDistanceSqr) { nearestPt = closestPtPoly; nearestDistanceSqr = d; nearest = reference; } } return(nearest); }
public void AddTileAt(MeshTile tile, PolyId id) { //TODO more error checking, what if tile already exists? Vector2i loc = tile.Location; List <MeshTile> locList; if (!tileSet.TryGetValue(loc, out locList)) { locList = new List <MeshTile>(); locList.Add(tile); tileSet.Add(loc, locList); } else { locList.Add(tile); } tileRefs.Add(tile, id); int index = idManager.DecodeTileIndex(ref id); //HACK this is pretty bad but only way to insert at index //TODO tileIndex should have a level of indirection from the list? while (index >= tileList.Count) { tileList.Add(null); } tileList[index] = tile; }
private void CreateNavMeshOverlay() { var vertices = new List <Point3D>(); var indices = new List <int>(); NavMesh navMesh = ExilePather.PolyPathfinder.NavMesh; int tcount = navMesh.GetMaxTiles(); for (int i = 0; i < tcount; i++) { MeshTile tile = navMesh.GetTile(i); if (tile.Header == null) { continue; } AddMeshTile(tile, vertices, indices); } var b = new MeshBuilder(); for (int i = 0; i < indices.Count - 3; i += 3) { b.AddTriangle(vertices[indices[i + 2]], vertices[indices[i + 1]], vertices[indices[i]]); } _initialSeed = _curData.Seed; LokiPoe.BeginDispatchIfNecessary(View.Dispatcher, () => (Visual as MeshVisual3D).Content = new GeometryModel3D(b.ToMesh(true), MaterialHelper.CreateMaterial(Colors.DeepSkyBlue, 0.35))); }
void CreateSquare(int x, int y) { MeshTile tile = World.instance.GetTile(x, y); if ((int)tile.t == tileType) { tile = new MeshTile(tileType, x, y, 0); } else if ((int)tile.t == tileType + 1 && (int)tile.t != 0) { tile = new MeshTile(tileType, x, y, 0); } else { tile = new MeshTile(5, x, y, 0); } vertices.Add(new Vector3(x + 0, y + 0)); vertices.Add(new Vector3(x + blendFactor, y + 0)); vertices.Add(new Vector3(x + 0, y + blendFactor)); vertices.Add(new Vector3(x + blendFactor, y + blendFactor)); vertices.Add(new Vector3(x + blendFactor / 2f, y + blendFactor / 2f)); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 5); triangles.Add(vertices.Count - 4); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 2); triangles.Add(vertices.Count - 3); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 2); triangles.Add(vertices.Count - 4); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 5); triangles.Add(vertices.Count - 3); /* * vertices.Add (new Vector3(x + 0, y + 0)); * vertices.Add (new Vector3(x + 1.5f, y + 0)); * vertices.Add (new Vector3(x + 0, y + 1.5f)); * vertices.Add (new Vector3(x + 1.5f, y + 1.5f)); * * triangles.Add (vertices.Count - 1); * triangles.Add (vertices.Count - 3); * triangles.Add (vertices.Count - 4); * * triangles.Add (vertices.Count - 2); * triangles.Add (vertices.Count - 1); * triangles.Add (vertices.Count - 4); */ UVs.AddRange(SpriteLoader.instance.GetTileUVs(tile)); }
private JObject SerializeMeshTile(MeshTile tile) { var result = new JObject(); result.Add("location", JToken.FromObject(tile.Location, serializer)); result.Add("layer", JToken.FromObject(tile.Layer, serializer)); result.Add("salt", JToken.FromObject(tile.Salt, serializer)); result.Add("bounds", JToken.FromObject(tile.Bounds, serializer)); result.Add("polys", JToken.FromObject(tile.Polys, serializer)); result.Add("verts", JToken.FromObject(tile.Verts, serializer)); result.Add("detailMeshes", JToken.FromObject(tile.DetailMeshes, serializer)); result.Add("detailVerts", JToken.FromObject(tile.DetailVerts, serializer)); result.Add("detailTris", JToken.FromObject(tile.DetailTris, serializer)); result.Add("offMeshConnections", JToken.FromObject(tile.OffMeshConnections, serializer)); var treeNodes = (BVTree.Node[])GetPrivateField(tile.BVTree, "nodes"); JObject treeObject = new JObject(); treeObject.Add("nodes", JToken.FromObject(treeNodes, serializer)); result.Add("bvTree", treeObject); result.Add("bvQuantFactor", JToken.FromObject(tile.BvQuantFactor, serializer)); result.Add("bvNodeCount", JToken.FromObject(tile.BvNodeCount, serializer)); result.Add("walkableClimb", JToken.FromObject(tile.WalkableClimb, serializer)); return(result); }
private MeshTile DeserializeMeshTile(JToken token, PolyIdManager manager, PolyId refId) { Vector2i location = token["location"].ToObject <Vector2i>(serializer); int layer = token["layer"].ToObject <int>(serializer); MeshTile result = new MeshTile(location, layer, manager, refId); result.Salt = token["salt"].ToObject <int>(serializer); result.Bounds = token["bounds"].ToObject <BBox3>(serializer); result.Polys = token["polys"].ToObject <Poly[]>(serializer); result.PolyCount = result.Polys.Length; result.Verts = token["verts"].ToObject <Vector3[]>(serializer); result.DetailMeshes = token["detailMeshes"].ToObject <PolyMeshDetail.MeshData[]>(serializer); result.DetailVerts = token["detailVerts"].ToObject <Vector3[]>(serializer); result.DetailTris = token["detailTris"].ToObject <PolyMeshDetail.TriangleData[]>(serializer); result.OffMeshConnections = token["offMeshConnections"].ToObject <OffMeshConnection[]>(serializer); result.OffMeshConnectionCount = result.OffMeshConnections.Length; result.BvNodeCount = token["bvNodeCount"].ToObject <int>(serializer); result.BvQuantFactor = token["bvQuantFactor"].ToObject <float>(serializer); result.WalkableClimb = token["walkableClimb"].ToObject <float>(serializer); var tree = (BVTree)FormatterServices.GetUninitializedObject(typeof(BVTree)); var treeObject = (JObject)token["bvTree"]; var nodes = treeObject.GetValue("nodes").ToObject <BVTree.Node[]>(); SetPrivateField(tree, "nodes", nodes); result.BVTree = tree; return(result); }
public override TiledNavMesh Deserialize(string path) { JObject root = JObject.Parse(File.ReadAllText(path)); if (root["meta"]["version"]["snj"].ToObject <int>() != FormatVersion) { throw new ArgumentException("The version of the file does not match the version of the parser. Consider using an older version of SharpNav or re-generating your .snj meshes."); } Vector3 origin = root["origin"].ToObject <Vector3>(serializer); float tileWidth = root["tileWidth"].ToObject <float>(serializer); float tileHeight = root["tileHeight"].ToObject <float>(serializer); int maxTiles = root["maxTiles"].ToObject <int>(serializer); int maxPolys = root["maxPolys"].ToObject <int>(serializer); var mesh = new TiledNavMesh(origin, tileWidth, tileHeight, maxTiles, maxPolys); JArray tilesToken = (JArray)root["tiles"]; List <MeshTile> tiles = new List <MeshTile>(); foreach (JToken tileToken in tilesToken) { PolyId tileRef; MeshTile tile = DeserializeMeshTile(tileToken, mesh.IdManager, out tileRef); mesh.AddTileAt(tile, tileRef); } return(mesh); }
private MeshTile DeserializeMeshTile(JToken token) { JObject jObject = (JObject)token; MeshTile result = new MeshTile(); result.Salt = jObject.GetValue("Salt").Value <int>(); result.LinksFreeList = jObject.GetValue("LinksFreeList").Value <int>(); result.Header = jObject.GetValue("Header").ToObject <PathfindingCommon.NavMeshInfo>(); result.Polys = jObject.GetValue("Polys").ToObject <Poly[]>(); result.Verts = jObject.GetValue("Verts").ToObject <Vector3[]>(); result.Links = jObject.GetValue("Links").ToObject <Link[]>(); result.DetailMeshes = jObject.GetValue("DetailMeshes").ToObject <PolyMeshDetail.MeshData[]>(); result.DetailVerts = jObject.GetValue("DetailVerts").ToObject <Vector3[]>(); result.DetailTris = jObject.GetValue("DetailTris").ToObject <PolyMeshDetail.TriangleData[]>(); result.OffMeshConnections = jObject.GetValue("OffMeshConnections").ToObject <OffMeshConnection[]>(); var tree = (BVTree)FormatterServices.GetUninitializedObject(typeof(BVTree)); var treeObject = (JObject)jObject.GetValue("BVTree"); var nodes = treeObject.GetValue("nodes").ToObject <BVTree.Node[]>(); SetPrivateField(tree, "nodes", nodes); result.BVTree = tree; return(result); }
/// <summary> /// Only use this function if it is known that the provided polygon reference is valid. /// </summary> /// <param name="reference">Polygon reference</param> /// <param name="tile">Resulting tile</param> /// <param name="poly">Resulting poly</param> public void TryGetTileAndPolyByRefUnsafe(PolyId reference, out MeshTile tile, out Poly poly) { int salt, polyIndex, tileIndex; reference.Decode(polyBits, tileBits, saltBits, out polyIndex, out tileIndex, out salt); tile = tiles[tileIndex]; poly = tiles[tileIndex].Polys[polyIndex]; }
/// <summary> /// Only use this function if it is known that the provided polygon reference is valid. /// </summary> /// <param name="reference">Polygon reference</param> /// <param name="tile">Resulting tile</param> /// <param name="poly">Resulting poly</param> public void TryGetTileAndPolyByRefUnsafe(PolyId reference, out MeshTile tile, out Poly poly) { int salt, polyIndex, tileIndex; idManager.Decode(ref reference, out polyIndex, out tileIndex, out salt); tile = tileList[tileIndex]; poly = tileList[tileIndex].Polys[polyIndex]; }
private void Awake() { Application.targetFrameRate = 120; _device = Device.Open(0); _device.StartCameras(new DeviceConfiguration { ColorFormat = ImageFormat.ColorBGRA32, // Note: other formats would be hardware-native, faster ColorResolution = ColorResolution.R720p, DepthMode = DepthMode.NFOV_Unbinned, // Note: makes a large difference in latency! SynchronizedImagesOnly = true, CameraFPS = FPS.FPS30, }); var calibration = _device.GetCalibration(); _colorDims = new int2( calibration.ColorCameraCalibration.ResolutionWidth, calibration.ColorCameraCalibration.ResolutionHeight ); // _depthDims = new int2( // calibration.DepthCameraCalibration.ResolutionWidth, // calibration.DepthCameraCalibration.ResolutionHeight // ); _depth = new NativeArray <float>(_colorDims.x * _colorDims.y, Allocator.Persistent); _depthTex = new Texture2D(_colorDims.x, _colorDims.y, TextureFormat.RFloat, false, true); _segmentTex = new Texture2D(_colorDims.x, _colorDims.y, TextureFormat.RGBA32, false, true); _colorTex = new Texture2D(_colorDims.x, _colorDims.y, TextureFormat.RGBA32, false, true); _transformedDepth = new Image( ImageFormat.Depth16, _colorDims.x, _colorDims.y, _colorDims.x * sizeof(System.UInt16)); _transformedSegment = new Image( ImageFormat.Custom8, _colorDims.x, _colorDims.y, _colorDims.x * sizeof(System.Byte)); _depthTransformer = calibration.CreateTransformation(); // _tracker = Tracker.Create(calibration, new TrackerConfiguration { // SensorOrientation = SensorOrientation.Default, // ProcessingMode = TrackerProcessingMode.Gpu, // GpuDeviceId = 0, // }); _mesh = new GameObject("Mesh").AddComponent <MeshTile>(); _mesh.Create(_colorDims); _mesh.MeshRenderer.material = _material; _mesh.MeshRenderer.material.SetTexture("_ColorTex", _colorTex); _mesh.MeshRenderer.material.SetTexture("_DepthTex", _depthTex); _exporter = gameObject.GetComponent <AlembicExporter>(); }
/// <summary> /// Find the closest point on an offmesh connection, which is in between the two points. /// </summary> /// <param name="tile">Current mesh tile.</param> /// <param name="poly">Current polygon</param> /// <param name="pos">Current position</param> /// <param name="closest">Resulting point that is closest.</param> public static void ClosestPointOnPolyOffMeshConnection(MeshTile tile, Poly poly, Vector3 pos, out Vector3 closest) { Vector3 v0 = tile.Verts[poly.Verts[0]]; Vector3 v1 = tile.Verts[poly.Verts[1]]; float d0 = (pos - v0).Length(); float d1 = (pos - v1).Length(); float u = d0 / (d0 + d1); closest = Vector3.Lerp(v0, v1, u); }
private static void DisableConnection(MeshTile tile, int index) { var poly = tile.GetPolygon((ushort)(index + tile.Header.OffMeshBase)); if (poly == null) { return; } poly.Disable(); }
/// <summary> /// Retrieve the endpoints of the offmesh connection at the specified polygon /// </summary> /// <param name="prevRef">The previous polygon reference</param> /// <param name="polyRef">The current polygon reference</param> /// <param name="startPos">The starting position</param> /// <param name="endPos">The ending position</param> /// <returns>True if endpoints found, false if not</returns> public bool GetOffMeshConnectionPolyEndPoints(PolyId prevRef, PolyId polyRef, ref Vector3 startPos, ref Vector3 endPos) { int salt = 0, indexTile = 0, indexPoly = 0; if (polyRef == PolyId.Null) { return(false); } //get current polygon idManager.Decode(ref polyRef, out indexPoly, out indexTile, out salt); if (indexTile >= maxTiles) { return(false); } if (tileList[indexTile].Salt != salt) { return(false); } MeshTile tile = tileList[indexTile]; if (indexPoly >= tile.PolyCount) { return(false); } Poly poly = tile.Polys[indexPoly]; if (poly.PolyType != PolygonType.OffMeshConnection) { return(false); } int idx0 = 0, idx1 = 1; //find the link that points to the first vertex foreach (Link link in poly.Links) { if (link.Edge == 0) { if (link.Reference != prevRef) { idx0 = 1; idx1 = 0; } break; } } startPos = tile.Verts[poly.Verts[idx0]]; endPos = tile.Verts[poly.Verts[idx1]]; return(true); }
/// <summary> /// Retrieve the endpoints of the offmesh connection at the specified polygon /// </summary> /// <param name="prevRef">The previous polygon reference</param> /// <param name="polyRef">The current polygon reference</param> /// <param name="startPos">The starting position</param> /// <param name="endPos">The ending position</param> /// <returns>True if endpoints found, false if not</returns> public bool GetOffMeshConnectionPolyEndPoints(PolyId prevRef, PolyId polyRef, ref Vector3 startPos, ref Vector3 endPos) { int salt = 0, indexTile = 0, indexPoly = 0; if (polyRef == PolyId.Null) { return(false); } //get current polygon polyRef.Decode(polyBits, tileBits, saltBits, out indexPoly, out indexTile, out salt); if (indexTile >= maxTiles) { return(false); } if (tiles[indexTile].Salt != salt || tiles[indexTile].Header == null) { return(false); } MeshTile tile = tiles[indexTile]; if (indexPoly >= tile.Header.PolyCount) { return(false); } Poly poly = tile.Polys[indexPoly]; if (poly.PolyType != PolygonType.OffMeshConnection) { return(false); } int idx0 = 0, idx1 = 1; //find the link that points to the first vertex for (int i = poly.FirstLink; i != Link.Null; i = tile.Links[i].Next) { if (tile.Links[i].Edge == 0) { if (tile.Links[i].Reference != prevRef) { idx0 = 1; idx1 = 0; } break; } } startPos = tile.Verts[poly.Verts[idx0]]; endPos = tile.Verts[poly.Verts[idx1]]; return(true); }
/// <summary> /// Allocate a new link if possible. /// </summary> /// <param name="tile">Current tile</param> /// <returns>New link number</returns> public int AllocLink(MeshTile tile) { if (!IsLinkAllocated(tile.LinksFreeList)) { return(Link.Null); } int link = tile.LinksFreeList; tile.LinksFreeList = tile.Links[link].Next; return(link); }
/// <summary> /// Allocate links for each of the tile's polygons' vertices /// </summary> /// <param name="tile">A tile contains a set of polygons, which are linked to each other</param> public void ConnectIntLinks(ref MeshTile tile) { if (tile == null) { return; } PolyId polyBase = GetPolyRefBase(tile); //Iterate through all the polygons for (int i = 0; i < tile.Header.PolyCount; i++) { //The polygon links will end in a null link tile.Polys[i].FirstLink = Link.Null; //Avoid Off-Mesh Connection polygons if (tile.Polys[i].PolyType == PolygonType.OffMeshConnection) { continue; } //Build edge links for (int j = tile.Polys[i].VertCount - 1; j >= 0; j--) { //Skip hard and non-internal edges if (tile.Polys[i].Neis[j] == 0 || IsExternalLink(tile.Polys[i].Neis[j])) { continue; } //Allocate a new link if possible int idx = AllocLink(tile); //Allocation of link should be successful if (IsLinkAllocated(idx)) { //Initialize a new link PolyId id; PolyId.SetPolyIndex(ref polyBase, tile.Polys[i].Neis[j] - 1, out id); tile.Links[idx].Reference = id; tile.Links[idx].Edge = j; tile.Links[idx].Side = BoundarySide.Internal; tile.Links[idx].BMin = tile.Links[idx].BMax = 0; //Add to polygon's links list tile.Links[idx].Next = tile.Polys[i].FirstLink; tile.Polys[i].FirstLink = idx; } } } }
/// <summary> /// Builds a Single polygon out of the NavMesh, called by BuildNavMeshGeometry /// </summary> /// <param name="refId"></param> /// <param name="color"></param> /// <param name="verts"></param> /// <param name="colors"></param> /// <param name="uvs"></param> /// <param name="tris"></param> private void BuildNavMeshPoly(long refId, Color color, List <Vector3> verts, List <Color> colors, List <Vector2> uvs, List <int> tris) { MeshTile tile = null; Poly poly = null; if ((NavMesh.GetTileAndPolyByRef(refId, ref tile, ref poly) & Status.Failure) != 0) { return; } long ip = 0; for (int i = 0; i < tile.Polys.Length; i++) { if (poly == tile.Polys[i]) { ip = i; } } if (poly.Type == LunaNav.NavMeshBuilder.PolyTypeOffMeshConnection) { } else { PolyDetail pd = tile.DetailMeshes[ip]; for (int i = 0; i < pd.TriCount; i++) { int t = ((int)pd.TriBase + i) * 4; for (int j = 0; j < 3; j++) { if (tile.DetailTris[t + j] < poly.VertCount) { verts.Add(new Vector3(tile.Verts[poly.Verts[tile.DetailTris[t + j]] * 3 + 0], tile.Verts[poly.Verts[tile.DetailTris[t + j]] * 3 + 1], tile.Verts[poly.Verts[tile.DetailTris[t + j]] * 3 + 2])); } else { verts.Add( new Vector3(tile.DetailVerts[(pd.VertBase + tile.DetailTris[t + j] - poly.VertCount) * 3 + 0], tile.DetailVerts[(pd.VertBase + tile.DetailTris[t + j] - poly.VertCount) * 3 + 1], tile.DetailVerts[(pd.VertBase + tile.DetailTris[t + j] - poly.VertCount) * 3 + 2])); } uvs.Add(new Vector2()); colors.Add(color);//duIntToCol((int)ip, 192)); tris.Add(tris.Count); } } } }
void CreateQuadrant(MeshTile tile, MeshTile[] neighbors, float x, float y, int quadrant) { vertices.Add(new Vector3(x + 0, y + 0)); vertices.Add(new Vector3(x + 0.5f, y + 0)); vertices.Add(new Vector3(x + 0, y + 0.5f)); vertices.Add(new Vector3(x + 0.5f, y + 0.5f)); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 3); triangles.Add(vertices.Count - 4); triangles.Add(vertices.Count - 2); triangles.Add(vertices.Count - 1); triangles.Add(vertices.Count - 4); }
public const int OFFMESH_CON_BIDIR = 1; //bidirectional /// <summary> /// Given a point, find the closest point on that poly. /// </summary> /// <param name="tile">The current tile.</param> /// <param name="poly">The current polygon.</param> /// <param name="pos">The current position</param> /// <param name="closest">Reference to the closest point</param> public static void ClosestPointOnPolyInTile(MeshTile tile, Poly poly, Vector3 pos, ref Vector3 closest) { int indexPoly = 0; for (int i = 0; i < tile.Polys.Length; i++) { if (tile.Polys[i] == poly) { indexPoly = i; break; } } ClosestPointOnPolyInTile(tile, indexPoly, pos, ref closest); }
public Vector2[] GetTileUVs(MeshTile tile) { //string key = GetKeyForSprite(tile); string key = tile.t.ToString(); if (tileUVMap.ContainsKey(key) == true) { return(tileUVMap[key]); } else { Debug.LogError("There is no UV map for tile type: " + key); return(tileUVMap["Void"]); } }
private static void AddMeshTile(MeshTile tile, List <Point3D> vertices, List <int> indices) { byte[] detailTris = tile.GetAllDetailIndices(); var verts = tile.GetAllVertices(); var detailVerts = tile.GetAllDetailVertices(); var vertMap = new Dictionary <uint, int>(); for (int i = 0; i < tile.Header.PolyCount; i++) { Poly p = tile.GetPoly(i); if (p.Type == 1) // DT_POLYTYPE_OFFMESH_CONNECTION { continue; } PolyDetail pd = tile.GetPolyDetail(i); for (int j = 0; j < pd.TriCount; j++) { for (int k = 0; k < 3; k++) { int index = detailTris[(pd.TriBase + j) * 4 + k]; uint vertIndex; if (index < p.VertCount) { vertIndex = p.GetVert(index); } else { var val = verts.Length + pd.VertBase + index - p.VertCount; Debug.Assert(val <= uint.MaxValue); vertIndex = (uint)val; } if (!vertMap.ContainsKey(vertIndex)) { var pos = vertIndex >= verts.Length ? detailVerts[vertIndex - verts.Length] : verts[vertIndex]; pos.Y += 0.03f; vertices.Add(new Point3D(pos.X, pos.Z, pos.Y + 0.5)); vertMap[vertIndex] = vertices.Count - 1; } indices.Add(vertMap[vertIndex]); } } } }
/// <summary> /// Get the tile reference /// </summary> /// <param name="tile">Tile to look for</param> /// <returns>Tile reference</returns> public PolyId GetTileRef(MeshTile tile) { if (tile == null) { return(PolyId.Null); } PolyId id; if (!tileRefs.TryGetValue(tile, out id)) { id = PolyId.Null; } return(id); }
public void SpawnTrees() { for (int x = 0; x < 100; x++) { for (int y = 0; y < 100; y++) { Random.Range(1, 100); MeshTile mt = World.instance.GetTile(x, y); if (mt.t == MeshTile.Type.Grass && Random.Range(1, 100) < 10) { GameObject tree = Instantiate(treePrefab[Random.Range(0, 2)], new Vector3(x + .5f, y + .8f, 0), Quaternion.identity); } } } }
private void HandleConnections(MeshTile tile) { if (tile.Header.OffMeshConCount <= 0) { return; } var count = tile.Header.OffMeshConCount; for (int i = 0; i < count; i++) { var con = tile.GetOffMeshConnection(i); if (con == null) { continue; } var path = TaxiHelper.GetPath((int)con.UserID); if (path == null) { DisableConnection(tile, i); continue; } var from = TaxiHelper.GetNode(path.From); var to = TaxiHelper.GetNode(path.To); if (from == null || to == null) { DisableConnection(tile, i); continue; } var data = new ConnectionData { Alliance = from.IsAlliance || to.IsAlliance, Horde = from.IsHorde || to.IsHorde, Cost = path.Cost, From = from.Name, To = to.Name, Id = (int)con.UserID }; if (!ConnectionHandler(data)) { DisableConnection(tile, i); } } }
public MeshTile[] GetNeighbors(int tileX, int tileY, int chunkSize) { MeshTile[] neighbors = new MeshTile[4]; // if ((tileY - y) > (chunkSize - 1)) // { // neighbors[0] = TileRenderer.instance.chunkArray[]; // } // else { neighbors[0] = GetTile(tileX + 0, tileY + 1, chunkSize); // } neighbors[1] = GetTile(tileX + 1, tileY + 0, chunkSize); neighbors[2] = GetTile(tileX + 0, tileY - 1, chunkSize); neighbors[3] = GetTile(tileX - 1, tileY + 0, chunkSize); return(neighbors); }
/// <summary> /// Initialize the Tiled Navigation Mesh variables and arrays. /// </summary> /// <param name="parameters">Tiled Navigation Mesh attributes</param> /// <returns>True if initialization is successful</returns> public bool InitTileNavMesh() { //init tiles tileLookupTableSize = MathHelper.NextPowerOfTwo(maxTiles / 4); if (tileLookupTableSize == 0) { tileLookupTableSize = 1; } tileLookupTableMask = tileLookupTableSize - 1; tiles = new MeshTile[maxTiles]; posLookup = new MeshTile[tileLookupTableSize]; for (int i = 0; i < tiles.Length; i++) { tiles[i] = new MeshTile(); } for (int i = 0; i < posLookup.Length; i++) { posLookup[i] = null; } //create a linked list of tiles nextFree = null; for (int i = maxTiles - 1; i >= 0; i--) { tiles[i].Salt = 1; tiles[i].Next = nextFree; nextFree = tiles[i]; } //init ID generator values tileBits = MathHelper.Log2(MathHelper.NextPowerOfTwo(maxTiles)); polyBits = MathHelper.Log2(MathHelper.NextPowerOfTwo(maxPolys)); //only allow 31 salt bits, since salt mask is calculated using 32-bit int and it will overflow saltBits = Math.Min(31, 32 - tileBits - polyBits); if (saltBits < 10) { return(false); } return(true); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET: //ORIGINAL LINE: public void write(java.io.OutputStream stream, org.recast4j.detour.NavMesh mesh, java.nio.ByteOrder order, boolean cCompatibility) throws java.io.IOException public virtual void write(System.IO.Stream stream, NavMesh mesh, ByteOrder order, bool cCompatibility) { // Write header. write(stream, NavMeshSetHeader.NAVMESHSET_MAGIC, order); write(stream, cCompatibility ? NavMeshSetHeader.NAVMESHSET_VERSION : NavMeshSetHeader.NAVMESHSET_VERSION_RECAST4J, order); int numTiles = 0; for (int i = 0; i < mesh.MaxTiles; ++i) { MeshTile tile = mesh.getTile(i); if (tile == null || tile.data == null || tile.data.header == null) { continue; } numTiles++; } write(stream, numTiles, order); paramWriter.write(stream, mesh.Params, order); // Store tiles. for (int i = 0; i < mesh.MaxTiles; ++i) { MeshTile tile = mesh.getTile(i); if (tile == null || tile.data == null || tile.data.header == null) { continue; } NavMeshTileHeader tileHeader = new NavMeshTileHeader(); tileHeader.tileRef = mesh.getTileRef(tile); ByteArrayOutputStream baos = new ByteArrayOutputStream(); writer.write(baos, tile.data, order, cCompatibility); sbyte[] ba = baos.toByteArray(); tileHeader.dataSize = ba.Length; write(stream, tileHeader.tileRef, order); write(stream, tileHeader.dataSize, order); if (cCompatibility) { write(stream, 0, order); // C struct padding } stream.Write(ba, 0, ba.Length); } }
private static void DisableConnection(MeshTile tile, int index) { var poly = tile.GetPolygon((ushort)(index + tile.Header.OffMeshBase)); if (poly == null) return; poly.Disable(); }
public bool LoadTile(int x, int y, byte[] data, out MeshTile tile) { // Tile already loaded? if ((tile = DetourMesh.GetTileAt(x, y)) != null) return true; bool ret = DetourMesh.AddTileAt(x, y, data); AddMemoryPressure(data.Length); tile = DetourMesh.GetTileAt(x, y); return ret && tile != null; }
private void HandleConnections(MeshTile tile) { if (tile.Header.OffMeshConCount <= 0) return; var count = tile.Header.OffMeshConCount; for (int i = 0; i < count; i++) { var con = tile.GetOffMeshConnection(i); if (con == null) continue; var path = TaxiHelper.GetPath((int)con.UserID); if (path == null) { DisableConnection(tile, i); continue; } var from = TaxiHelper.GetNode(path.From); var to = TaxiHelper.GetNode(path.To); if (from == null || to == null) { DisableConnection(tile, i); continue; } var data = new ConnectionData { Alliance = from.IsAlliance || to.IsAlliance, Horde = from.IsHorde || to.IsHorde, Cost = path.Cost, From = from.Name, To = to.Name, Id = (int)con.UserID }; if (!ConnectionHandler(data)) DisableConnection(tile, i); } }