void UpdateLog() { int logMessageCount = RecastNavigationDllImports.GetGwNavLogMessageCount(); int msgSize = 0; string fullLog = ""; for (int msgIdx = 0; msgIdx < logMessageCount; ++msgIdx) { IntPtr logMsgPtr = RecastNavigationDllImports.GetGwNavLog(msgIdx, out msgSize); if (msgSize != 0) { string logMsg = Marshal.PtrToStringAnsi(logMsgPtr); if (logMsg != null && logMsg.Length != 0) { fullLog += logMsg; if (logMsg.EndsWith("\n")) { fullLog.Remove(fullLog.Length - 1); Debug.Log("[RecastNavigation] " + fullLog); fullLog = ""; } } } } // No need to flush if no message (save a call to the plugin) if (logMessageCount > 0) { RecastNavigationDllImports.FlushGwNavLog(); } }
void ConsumeMeshFilter(MeshFilter meshFilter, GameObject gameObject) { if (meshFilter.sharedMesh) { Vector3[] vertices = meshFilter.sharedMesh.vertices; int[] triangleVertexIndices = meshFilter.sharedMesh.triangles; Transform t = gameObject.transform; //GwNavTag navTag = BuildNavTag(gameObject); for (int triangleFirstVertexIdx = 0; triangleFirstVertexIdx < triangleVertexIndices.Length; triangleFirstVertexIdx += 3) { Vector3 posALocal = vertices[triangleVertexIndices[triangleFirstVertexIdx]]; Vector3 posBLocal = vertices[triangleVertexIndices[triangleFirstVertexIdx + 1]]; Vector3 posCLocal = vertices[triangleVertexIndices[triangleFirstVertexIdx + 2]]; Vector3 posA = t.TransformPoint(posALocal); Vector3 posB = t.TransformPoint(posBLocal); Vector3 posC = t.TransformPoint(posCLocal); if (HasNegativeScaleTransform(t)) { RecastNavigationDllImports.PushTriangleWithNavTag(posC, posB, posA); } else { RecastNavigationDllImports.PushTriangleWithNavTag(posA, posB, posC); } totalTriangleCount++; } } }
bool UpdateNavDataInDatabase() { UnityEngine.Object asset = Resources.Load(resourceFolder + "RecastNavmesh"); RecastNavigationAsset navDataAsset = asset as RecastNavigationAsset; if (navDataAsset == null) { if (m_navMeshRepresentation != null) { m_navMeshRepresentation.DoClear(); } return(false); } GCHandle handle = GCHandle.Alloc(navDataAsset.navMeshData, GCHandleType.Pinned); if (RecastNavigationDllImports.LoadNavDataImmediate(handle.AddrOfPinnedObject()) == false) { if (m_navMeshRepresentation != null) { m_navMeshRepresentation.DoClear(); } Debug.Log("Could not load data"); return(false); } return(true); }
protected void NavigationInit() { if (RecastNavigationDllImports.NavGeneration_Init() == false) { Debug.Log("Error initializing Recast Navigation plugin!"); } }
void DeInit() { // When the window is destroyed, remove the delegate // so that it will no longer do any drawing. SceneView.onSceneGUIDelegate -= this.OnSceneGUI; RecastNavigationDllImports.NavGeneration_DeInit(); // Get last messages and destroy log UpdateLog(); RecastNavigationDllImports.DestroyLog(); }
public void Move(Vector3 startPos, Vector3 movePos) { m_startPos = startPos; m_movePos = movePos; pathNum = 0; RecastNavigationDllImports.PathFind(m_startPos, m_movePos, ref pathNum, ref smoothPath); if (pathNum == 0) { pathNum = 1; smoothPath[0] = movePos; } }
private void LoadNavigationSuccessCallback(string NavAssetName, object NavAsset, float duration, object userData) { RecastNavigationAsset navDataAsset = NavAsset as RecastNavigationAsset; if (navDataAsset == null) { return; } handle = GCHandle.Alloc(navDataAsset.navMeshData, GCHandleType.Pinned); if (RecastNavigationDllImports.LoadNavDataImmediate(handle.AddrOfPinnedObject()) == false) { Debug.Log("Could not load data"); return; } }
void UpdateLog_AllMessagesInOneUnityLog() { int logMessageCount = RecastNavigationDllImports.GetGwNavLogMessageCount(); int msgSize = 0; if (logMessageCount == 0) { return; } string fullLog = ""; for (int msgIdx = 0; msgIdx < logMessageCount; ++msgIdx) { IntPtr logMsgPtr = RecastNavigationDllImports.GetGwNavLog(msgIdx, out msgSize); if (msgSize != 0) { string logMsg = Marshal.PtrToStringAnsi(logMsgPtr); // Hide the ======== if (logMsg.StartsWith("=")) { continue; } // Dont jump 2 lines, only one if (logMsg.StartsWith("\n\n")) { fullLog += '\n'; continue; } if (logMsg != null && logMsg.Length != 0) { fullLog += logMsg; } } } if (fullLog.Length != 0) { Debug.Log("[RecastNavigation] " + fullLog); } RecastNavigationDllImports.FlushGwNavLog(); }
void Init() { RecastNavigationDllImports.CreateLog(4096, 500); if (RecastNavigationDllImports.NavGeneration_Init() == false) { Debug.Log("Error initializing Recast Navigation plugin!"); } UpdateLog(); m_navMeshRepresentation = new RecastNavigationNavMeshRepresentation(); m_navMeshRepresentation.LoadShadersAndMaterials(); BuildProjectNameAndSceneName(); if (sceneName != null && sceneName.Length != 0) { BuildDatabaseMesh(); } SceneView.onSceneGUIDelegate += this.OnSceneGUI; }
void Bake() { if (IsEmptyScene()) { return; } //hasNavMeshVisualRep = false; m_generationConfig.m_radius = m_params.radius; m_generationConfig.m_height = m_params.height; m_generationConfig.m_maxSlope = m_params.maxSlope; m_generationConfig.m_stepHeight = m_params.stepHeight; m_generationConfig.m_minRegionArea = m_params.minRegionArea; m_generationConfig.m_dropHeight = m_params.DropHeight; m_generationConfig.m_jumpDistance = m_params.JumpDistance; m_generationConfig.m_widthInaccuracy = m_params.WidthInaccuracy; m_generationConfig.m_heightInaccuracy = m_params.HeightInaccuracy; m_generationConfig.m_heightMesh = m_params.HeightMesh; RecastNavigationDllImports.InitGenerator(); ConsumeSceneTriangles(); bool generationSucceeded = RecastNavigationDllImports.Generate(m_generationConfig, projectName + "-" + sceneName); UpdateLog_AllMessagesInOneUnityLog(); if (generationSucceeded) { GenerateAsset(); } else { UnityEngine.Debug.Log("Generation failed."); generationSucceeded = false; } if (generationSucceeded) { BuildDatabaseMesh(); } }
void UpdateMeshFromDatabaseTriangles() { RecastNavigationDllImports.BuildDatabaseGeometry(); // TODO: understand why sometimes m_navMeshRepresentation becomes null if (m_navMeshRepresentation == null) { Debug.LogWarning("NavMesh representation became null!"); m_navMeshRepresentation = new RecastNavigationNavMeshRepresentation(); m_navMeshRepresentation.LoadShadersAndMaterials(); } uint triangleCount = RecastNavigationDllImports.GetDatabaseTriangleCount(); m_navMeshRepresentation.Begin(triangleCount); RecastVisualTriangle triangle; for (uint i = 0; i < triangleCount; ++i) { RecastNavigationDllImports.GetDatabaseTriangle(i, out triangle); m_navMeshRepresentation.AddTriangle(triangle); } m_navMeshRepresentation.End(); int vertexCount = RecastNavigationDllImports.GetPolygonVertexCount(); m_navMeshRepresentation.ReSetLine(vertexCount); for (int i = 0; i < vertexCount; i++) { Vector3 vertex = new Vector3(); Color32 color = new Color32(); RecastNavigationDllImports.GetPolygonVertex((uint)i, out vertex, out color); m_navMeshRepresentation.AddLineVertex(i, vertex, color); } m_navMeshRepresentation.BuildLineMesh(); //hasNavMeshVisualRep = true; }
void GenerateAsset() { IntPtr unmanagedPtr = new IntPtr(); int size = 0; bool success = RecastNavigationDllImports.GetGeneratedData(ref unmanagedPtr, ref size); if (success) { RecastNavigationAsset navMeshAsset = CreateInstance <RecastNavigationAsset>(); navMeshAsset.AssignData(unmanagedPtr, size); //int generatedTriangleCount = RecastNavigationDllImports.GetNavMeshTriangleCount(); //if (generatedTriangleCount == 0) // Debug.LogError("No triangles generated: verify that you have some geometry tagged as NavigationStatic, that your seedpoint is not outside navigable geometry or that your world scale is correct (1 unity unit = 1 meter)"); //navMeshAsset.SetDataInfo(generatedTriangleCount); System.IO.Directory.CreateDirectory(resourceFolder); AssetDatabase.CreateAsset(navMeshAsset, resourceFolder + "RecastNavmesh.asset"); Debug.Log(AssetDatabase.GetAssetPath(navMeshAsset)); string binaryPath = resourceFolder + sceneName + ".bin"; System.IO.File.WriteAllBytes(binaryPath, navMeshAsset.navMeshData); } }
void BuildDatabaseMesh() { RecastNavigationDllImports.RemoveAllNavData(); UpdateNavDataInDatabase(); UpdateMeshFromDatabaseTriangles(); }
void ConsumeTerrainTriangles(TerrainData terrain, GameObject gameObject) { Vector3 terrainPos = gameObject.transform.position; //GwNavTag navTag = BuildNavTag(gameObject); int vertexCount_x = terrain.heightmapWidth; int vertexCount_z = terrain.heightmapHeight; float sampleWidthInMeter = terrain.size.x / (terrain.heightmapWidth - 1); float sampleHeightInMeter = terrain.size.z / (terrain.heightmapHeight - 1); for (int z = 0; z < vertexCount_z - 1; ++z) { for (int x = 0; x < vertexCount_x - 1; ++x) { Vector3 A = GetTerrainVertex(terrain, x, z, sampleWidthInMeter, sampleHeightInMeter) + terrainPos; Vector3 B = GetTerrainVertex(terrain, x + 1, z, sampleWidthInMeter, sampleHeightInMeter) + terrainPos; Vector3 C = GetTerrainVertex(terrain, x + 1, z + 1, sampleWidthInMeter, sampleHeightInMeter) + terrainPos; Vector3 D = GetTerrainVertex(terrain, x, z + 1, sampleWidthInMeter, sampleHeightInMeter) + terrainPos; // RecastNavigationDllImports.PushTriangleWithNavTag(A, B, C); // RecastNavigationDllImports.PushTriangleWithNavTag(A, C, D); RecastNavigationDllImports.PushTriangleWithNavTag(C, B, A); RecastNavigationDllImports.PushTriangleWithNavTag(D, C, A); totalTriangleCount += 2; } } float treeRadius = 0.3f; float treeHeight = 5.0f; //navTag.m_isExclusive = true; foreach (TreeInstance tree in terrain.treeInstances) { Vector3 center = Vector3.Scale(terrain.size, tree.position) + terrainPos; Vector3 baseA = new Vector3(center.x - treeRadius, center.y, center.z - treeRadius); Vector3 baseB = new Vector3(center.x + treeRadius, center.y, center.z - treeRadius); Vector3 baseC = new Vector3(center.x + treeRadius, center.y, center.z + treeRadius); Vector3 baseD = new Vector3(center.x - treeRadius, center.y, center.z + treeRadius); Vector3 topA = baseA + Vector3.up * treeHeight; Vector3 topB = baseB + Vector3.up * treeHeight; Vector3 topC = baseC + Vector3.up * treeHeight; Vector3 topD = baseD + Vector3.up * treeHeight; /* * // Push base has non walkable * RecastNavigationDllImports.PushTriangleWithNavTag(baseA, baseB, baseC, navTag); * RecastNavigationDllImports.PushTriangleWithNavTag(baseA, baseC, baseD, navTag); * totalTriangleCount +=2; */ // Push trunk as a vertical square based tube // Front RecastNavigationDllImports.PushTriangleWithNavTag(baseA, baseB, topB); RecastNavigationDllImports.PushTriangleWithNavTag(baseA, topB, topA); // Right RecastNavigationDllImports.PushTriangleWithNavTag(baseB, baseC, topC); RecastNavigationDllImports.PushTriangleWithNavTag(baseB, topC, topB); // Back RecastNavigationDllImports.PushTriangleWithNavTag(baseC, baseD, topD); RecastNavigationDllImports.PushTriangleWithNavTag(baseC, topD, topC); // Left RecastNavigationDllImports.PushTriangleWithNavTag(baseD, baseA, topA); RecastNavigationDllImports.PushTriangleWithNavTag(baseD, topA, topD); totalTriangleCount += 8; } }