public HavokNavMeshGlobalSettings GetGlobalSettings(string settingsName) { if (m_settingsDictionary != null) { HavokNavMeshGlobalSettings settings = m_settingsDictionary.GetSettingsInstance(settingsName); System.Diagnostics.Debug.Assert(settings == null || settings.Name == settingsName); return(settings); } return(null); }
/// <summary> // Copy Global Settings private void CopySettingsButton_Click(object sender, EventArgs e) { if (GlobalSettings_ListView.SelectedItems.Count == 1) { string settingsName = GlobalSettings_ListView.SelectedItems[0].Tag as string; System.Diagnostics.Debug.Assert(settingsName != null); HavokNavMeshGlobalSettings settingsToBeCopied = GetGlobalSettings(settingsName); EditorManager.Clipboard.Data = CSharpFramework.Clipboard.EditorClipboard.CreateDataObject(settingsToBeCopied.Clone(), "Nav Mesh Global Settings"); PasteSettingsButton.Enabled = true; } }
private HavokNavMeshGlobalSettings GetGlobalSettings() { HavokNavMeshGlobalSettings settings = null; // get the AI panel HavokAiPanel aiPanel = HavokAiPanel.GetInstance(); System.Diagnostics.Debug.Assert(aiPanel != null); settings = aiPanel.GetGlobalSettings(m_navMeshGlobalSettingsName); return(settings); }
private void ConnectPhysicsCheckButton_Click(object sender, EventArgs e) { HavokNavMeshGlobalSettings settings = GetOrCreateDefaultGlobalSettings(); settings.ConnectToPhysics = tsb_ConnectPhysics.Checked; Modified = true; // Also apply to engine directly if running. if (EditorManager.InPlayingMode) { HavokAiManaged.ManagedModule.SetConnectToPhysicsWorld(settings.ConnectToPhysics); } this.GlobalSettings_PropertyGridEx1.Refresh(); }
/// <summary> /// Paste Global Settings /// </summary> private void PasteSettingsButton_Click(object sender, EventArgs e) { HavokNavMeshGlobalSettings newSettings = EditorManager.Clipboard.DataObject as HavokNavMeshGlobalSettings; if (newSettings == null) { return; } newSettings.Name = GenerateUniqueSettingsName(newSettings.Name + "_Copy"); AddGlobalSettings(newSettings.Name, newSettings, true); PasteSettingsButton.Enabled = false; }
public bool AddGlobalSettings(string settingsName, HavokNavMeshGlobalSettings settings, bool bUndoable) { if (m_settingsDictionary == null) { // create a collection if doesn't exist m_settingsDictionary = new HavokNavMeshGlobalSettingsDictionary(this); } if (bUndoable) { EditorManager.Actions.Add(new AddNavMeshGlobalSettingsAction(m_settingsDictionary, settingsName, settings)); return(m_settingsDictionary.GetSettingsInstance(settingsName) == settings); } else { return(m_settingsDictionary.AddSettingsInstance(settingsName, settings)); } }
public HavokNavMeshGlobalSettings GetOrCreateDefaultGlobalSettings() { HavokNavMeshGlobalSettings newDefault = null; if (m_settingsDictionary != null) { newDefault = m_settingsDictionary.GetDefaultSettingsInstance(); } if (newDefault == null) { // if null, settingsCollection is empty. System.Diagnostics.Debug.Assert(m_settingsDictionary == null); string newDefaultName = "GlobalSettings"; newDefault = CreateGlobalSettings(newDefaultName, true); } return(newDefault); }
public HavokNavMeshShape(string name) : base(name) { AddHint(HintFlags_e.NoRotation); AddHint(HintFlags_e.NoScale); AddHint(HintFlags_e.RetainPositionAtCreation); AddHint(HintFlags_e.HideGizmo); AddHint(HintFlags_e.NoUserTransform); // check to see if there's HavokNavMeshGlobalSettings and default to that shape // get the AI panel HavokAiPanel aiPanel = HavokAiPanel.GetInstance(); System.Diagnostics.Debug.Assert(aiPanel != null); HavokNavMeshGlobalSettings settings = aiPanel.GetOrCreateDefaultGlobalSettings(); m_navMeshGlobalSettingsName = settings.Name; }
public HavokNavMeshGlobalSettings CreateGlobalSettings(string settingsName, bool bUndoable) { if (m_settingsDictionary == null) { // create a collection if doesn't exist m_settingsDictionary = new HavokNavMeshGlobalSettingsDictionary(this); } if (bUndoable) { EditorManager.Actions.Add(new CreateNavMeshGlobalSettingsAction(m_settingsDictionary, settingsName)); } else { m_settingsDictionary.CreateAndAddSettingsInstance(settingsName); } HavokNavMeshGlobalSettings settings = m_settingsDictionary.GetSettingsInstance(settingsName); System.Diagnostics.Debug.Assert(settings == null || settings.Name == settingsName); return(settings); }
/// <summary> /// Import Global Settings /// </summary> private void ImportSettingsButton_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.InitialDirectory = EditorManager.Project.ProjectDir; dlg.FileName = null; dlg.Filter = "Nav Mesh Global Settings|*.*"; dlg.Title = "Load nav mesh global settings from file"; if (dlg.ShowDialog(this) != DialogResult.OK) { return; } string filename = dlg.FileName; dlg.Dispose(); HavokNavMeshGlobalSettings loadedSettings = null; try { BinaryFormatter fmt = SerializationHelper.BINARY_FORMATTER; FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read); loadedSettings = (HavokNavMeshGlobalSettings)fmt.Deserialize(fs); fs.Close(); } catch (Exception ex) { EditorManager.ShowMessageBox("Failed to load nav mesh global settings from file:\n\n" + ex.Message, "Error loading file", MessageBoxButtons.OK, MessageBoxIcon.Error); } if (loadedSettings != null) { string settingsName = Path.GetFileNameWithoutExtension(filename); loadedSettings.Name = GenerateUniqueSettingsName(settingsName); AddGlobalSettings(loadedSettings.Name, loadedSettings, true); } }
/// <summary> /// refresh property grid if different setting is selected /// </summary> private void GlobalSettingsListView_SelectedIndexChanged(object sender, EventArgs e) { if (GlobalSettings_ListView.SelectedItems.Count == 0) { GlobalSettings_PropertyGridEx1.SelectedObject = null; GlobalSettings_PropertyGridEx1.SelectedObjects = null; } else if (GlobalSettings_ListView.SelectedItems.Count == 1) { GlobalSettings_PropertyGridEx1.SelectedObjects = null; string settingsName = GlobalSettings_ListView.SelectedItems[0].Tag as string; HavokNavMeshGlobalSettings settings = GetGlobalSettings(settingsName); System.Diagnostics.Debug.Assert(settings != null); System.Diagnostics.Debug.Assert(settings.Name == settingsName); GlobalSettings_PropertyGridEx1.SelectedObject = settings; } else { ArrayList globalSettingsArray = new ArrayList(GlobalSettings_ListView.SelectedItems.Count); foreach (ListViewItem item in GlobalSettings_ListView.SelectedItems) { string settingsName = item.Tag as string; HavokNavMeshGlobalSettings settings = GetGlobalSettings(settingsName); System.Diagnostics.Debug.Assert(settings != null); System.Diagnostics.Debug.Assert(settings.Name == settingsName); globalSettingsArray.Add(settings); } GlobalSettings_PropertyGridEx1.SelectedObject = null; GlobalSettings_PropertyGridEx1.SelectedObjects = globalSettingsArray.ToArray(); } if (GlobalSettings_PropertyGridEx1.SelectedObject != null || GlobalSettings_PropertyGridEx1.SelectedObjects != null) { GlobalSettings_PropertyGridEx1.ExpandAllGridItems(); } UpdateSettingsToolStrip(); }
public override List <PropertyDescriptor> GetAdditionalRootProperties(ITypeDescriptorContext context) { List <PropertyDescriptor> list = base.GetAdditionalRootProperties(context); if (this.NavMeshGlobalSettingsKey != null) { // add the additional properties from the NavMeshGlobalSettings HavokNavMeshGlobalSettings globalSettings = GetGlobalSettings(); List <PropertyDescriptor> settingsList = globalSettings.GetCachedPropertiesList(); if (settingsList != null) { if (list == null) { list = settingsList; } else { list.AddRange(settingsList); } } } return(list); }
/// <summary> /// Export Global Settings /// </summary> private void ExportSelectedSettingsButton_Click(object sender, EventArgs e) { if (GlobalSettings_ListView.SelectedItems.Count == 1) { string settingsName = GlobalSettings_ListView.SelectedItems[0].Tag as string; System.Diagnostics.Debug.Assert(settingsName != null); HavokNavMeshGlobalSettings settingsToExported = GetGlobalSettings(settingsName); System.Diagnostics.Debug.Assert(settingsToExported != null); SaveFileDialog dlg = new SaveFileDialog(); dlg.InitialDirectory = EditorManager.Project.ProjectDir; dlg.FileName = null; dlg.Filter = "Nav Mesh Global Settings|*.*"; dlg.Title = "Save nav mesh global settings to editor format"; if (dlg.ShowDialog(this) != DialogResult.OK) { return; } string filename = dlg.FileName; dlg.Dispose(); try { BinaryFormatter fmt = SerializationHelper.BINARY_FORMATTER; FileStream fs = new FileStream(filename, FileMode.Create); fmt.Serialize(fs, settingsToExported); fs.Close(); } catch (Exception ex) { EditorManager.ShowMessageBox("Failed to save nav mesh global settings to file:\n\n" + ex.Message, "Error saving file", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
private void UpdateConnectPhysicsButton() { HavokNavMeshGlobalSettings settings = GetOrCreateDefaultGlobalSettings(); tsb_ConnectPhysics.Checked = settings.ConnectToPhysics; }
protected HavokNavMeshShape(SerializationInfo info, StreamingContext context) : base(info, context) { m_saveInputSnapshot = info.GetBoolean("SaveInputSnapshot"); m_snapshotFilename = info.GetString("SnapshotFilename"); if (SerializationHelper.HasElement(info, "NavmeshFilename")) { m_navMeshFilename = info.GetString("NavmeshFilename"); } if (SerializationHelper.HasElement(info, "DebugRenderOffset")) { m_debugRenderOffset = info.GetSingle("DebugRenderOffset"); } if (SerializationHelper.HasElement(info, "NavMeshSectionID")) { m_sectionID = info.GetUInt32("NavMeshSectionID"); } // check if it has a reference to a global settings shape already if (SerializationHelper.HasElement(info, "NavMeshGlobalSettingsName")) { m_navMeshGlobalSettingsName = info.GetString("NavMeshGlobalSettingsName"); } else { // get the AI panel HavokAiPanel aiPanel = HavokAiPanel.GetInstance(); System.Diagnostics.Debug.Assert(aiPanel != null); // if not, this is from an old version of the scene, so create a new settings struct and transfer all settings to this struct HavokNavMeshGlobalSettings globalSettings = aiPanel.CreateGlobalSettings(this.ToString() + "_GlobalSettings", false); m_navMeshGlobalSettingsName = globalSettings.Name; System.Diagnostics.Debug.Assert(globalSettings != null); // Nav Mesh Generation Settings globalSettings.CharacterHeight = info.GetSingle("CharacterHeight"); globalSettings.MaxWalkableSlope = info.GetSingle("MaxWalkableSlope"); globalSettings.MinRegionArea = info.GetSingle("MinRegionArea"); if (SerializationHelper.HasElement(info, "MinDistanceToSeedPoints")) { globalSettings.MinDistanceToSeedPoints = info.GetSingle("MinDistanceToSeedPoints"); } if (SerializationHelper.HasElement(info, "BorderPreservationTolerance")) { globalSettings.BorderPreservationTolerance = info.GetSingle("BorderPreservationTolerance"); } globalSettings.MinCharacterWidth = info.GetSingle("MinCharacterWidth"); globalSettings.CharacterWidthUsage = (eCharacterWidthUsage)info.GetValue("CharacterWidthUsage", typeof(eCharacterWidthUsage)); if (SerializationHelper.HasElement(info, "RestrictToZoneGeometry")) { globalSettings.RestrictToInputGeometryFromSameZone = info.GetBoolean("RestrictToZoneGeometry"); } // Nav Mesh Generation Settings (Advanced) globalSettings.QuantizationGridSize = info.GetSingle("QuantizationGridSize"); globalSettings.DegenerateAreaThreshold = info.GetSingle("DegenerateAreaThreshold"); globalSettings.DegenerateWidthThreshold = info.GetSingle("DegenerateWidthThreshold"); globalSettings.ConvexThreshold = info.GetSingle("ConvexThreshold"); globalSettings.MaxNumEdgesPerFace = info.GetInt32("MaxNumEdgesPerFace"); globalSettings.WeldInputVertices = info.GetBoolean("WeldInputVertices"); globalSettings.WeldThreshold = info.GetSingle("WeldThreshold"); // Nav Mesh Edge Matching Settings globalSettings.EdgeConnectionIterations = info.GetInt32("EdgeConnectionIterations"); globalSettings.EdgeMatchingMetric = (eEdgeMatchingMetric)info.GetValue("EdgeMatchingMetric", typeof(eEdgeMatchingMetric)); globalSettings.MaxStepHeight = info.GetSingle("MaxStepHeight"); globalSettings.MaxSeparation = info.GetSingle("MaxSeparation"); globalSettings.MaxOverhang = info.GetSingle("MaxOverhang"); globalSettings.PlanarAlignmentAngle = info.GetSingle("PlanarAlignmentAngle"); globalSettings.VerticalAlignmentAngle = info.GetSingle("VerticalAlignmentAngle"); globalSettings.MinEdgeOverlap = info.GetSingle("MinEdgeOverlap"); // Nav Mesh Simplification Settings globalSettings.EnableSimplification = info.GetBoolean("EnableSimplification"); globalSettings.MaxBorderSimplifyArea = info.GetSingle("MaxBorderSimplifyArea"); globalSettings.MaxConcaveBorderSimplifyArea = info.GetSingle("MaxConcaveBorderSimplifyArea"); globalSettings.UseHeightPartitioning = info.GetBoolean("UseHeightPartitioning"); globalSettings.MaxPartitionHeightError = info.GetSingle("MaxPartitionHeightError"); // Nav Mesh Simplification Settings (Advanced) globalSettings.MinCorridorWidth = info.GetSingle("MinCorridorWidth"); globalSettings.MaxCorridorWidth = info.GetSingle("MaxCorridorWidth"); globalSettings.HoleReplacementArea = info.GetSingle("HoleReplacementArea"); globalSettings.MaxLoopShrinkFraction = info.GetSingle("MaxLoopShrinkFraction"); globalSettings.MaxBorderHeightError = info.GetSingle("MaxBorderHeightError"); globalSettings.MaxBorderDistanceError = info.GetSingle("MaxBorderDistanceError"); globalSettings.MaxPartitionSize = info.GetInt32("MaxPartitionSize"); globalSettings.UseConservativeHeightPartitioning = info.GetBoolean("UseConservativeHeightPartitioning"); globalSettings.HertelMehlhornHeightError = info.GetSingle("HertelMehlhornHeightError"); globalSettings.PlanarityThreshold = info.GetSingle("PlanarityThreshold"); globalSettings.NonconvexityThreshold = info.GetSingle("NonconvexityThreshold"); globalSettings.BoundaryEdgeFilterThreshold = info.GetSingle("BoundaryEdgeFilterThreshold"); globalSettings.MaxSharedVertexHorizontalError = info.GetSingle("MaxSharedVertexHorizontalError"); globalSettings.MaxSharedVertexVerticalError = info.GetSingle("MaxSharedVertexVerticalError"); globalSettings.MaxBoundaryVertexHorizontalError = info.GetSingle("MaxBoundaryVertexHorizontalError"); globalSettings.MaxBoundaryVertexVerticalError = info.GetSingle("MaxBoundaryVertexVerticalError"); globalSettings.MergeLongestEdgesFirst = info.GetBoolean("MergeLongestEdgesFirst"); // Nav Mesh Split Generation Settings if (SerializationHelper.HasElement(info, "NumTilesX")) { globalSettings.NumTilesX = info.GetInt32("NumTilesX"); } if (SerializationHelper.HasElement(info, "NumTilesY")) { globalSettings.NumTilesY = info.GetInt32("NumTilesY"); } if (SerializationHelper.HasElement(info, "SplitGenerationMethod")) { globalSettings.SplitGenerationMethod = (eSplitGenerationMethod)info.GetValue("SplitGenerationMethod", typeof(eSplitGenerationMethod)); } if (SerializationHelper.HasElement(info, "ShelverType")) { globalSettings.ShelverType = (eShelverType)info.GetValue("ShelverType", typeof(eShelverType)); } // Nav Mesh Link Settings if (SerializationHelper.HasElement(info, "LinkEdgeMatchTolerance")) { globalSettings.LinkEdgeMatchTolerance = info.GetSingle("LinkEdgeMatchTolerance"); } if (SerializationHelper.HasElement(info, "LinkMaxStepHeight")) { globalSettings.LinkMaxStepHeight = info.GetSingle("LinkMaxStepHeight"); } if (SerializationHelper.HasElement(info, "LinkMaxSeparation")) { globalSettings.LinkMaxSeparation = info.GetSingle("LinkMaxSeparation"); } if (SerializationHelper.HasElement(info, "LinkMaxOverhang")) { globalSettings.LinkMaxOverhang = info.GetSingle("LinkMaxOverhang"); } if (SerializationHelper.HasElement(info, "LinkPlanarAlignmentAngle")) { globalSettings.LinkPlanarAlignmentAngle = info.GetSingle("LinkPlanarAlignmentAngle"); } if (SerializationHelper.HasElement(info, "LinkVerticalAlignmentAngle")) { globalSettings.LinkVerticalAlignmentAngle = info.GetSingle("LinkVerticalAlignmentAngle"); } if (SerializationHelper.HasElement(info, "LinkMinEdgeOverlap")) { globalSettings.LinkMinEdgeOverlap = info.GetSingle("LinkMinEdgeOverlap"); } } }
public override void SetEngineInstanceBaseProperties() { base.SetEngineInstanceBaseProperties(); if (!HasEngineInstance()) { return; } // Nav Mesh Generation Settings HavokNavMeshGlobalSettings globalSettings = GetGlobalSettings(); if (globalSettings == null) { return; } EngineNavMesh.m_characterHeight = globalSettings.CharacterHeight; EngineNavMesh.m_maxWalkableSlope = globalSettings.MaxWalkableSlope / 180.0f * 3.14159f; EngineNavMesh.m_minRegionArea = globalSettings.MinRegionArea; EngineNavMesh.m_minDistanceToSeedPoints = globalSettings.MinDistanceToSeedPoints; EngineNavMesh.m_borderPreservationTolerance = globalSettings.BorderPreservationTolerance; EngineNavMesh.m_minCharacterWidth = globalSettings.MinCharacterWidth; EngineNavMesh.m_characterWidthUsage = (int)globalSettings.CharacterWidthUsage; EngineNavMesh.m_terrainLOD = (int)globalSettings.TerrainLevelOfDetail; // Nav Mesh Generation Settings (Advanced) EngineNavMesh.m_quantizationGridSize = globalSettings.QuantizationGridSize; EngineNavMesh.m_degenerateAreaThreshold = globalSettings.DegenerateAreaThreshold; EngineNavMesh.m_degenerateWidthThreshold = globalSettings.DegenerateWidthThreshold; EngineNavMesh.m_convexThreshold = globalSettings.ConvexThreshold; EngineNavMesh.m_maxNumEdgesPerFace = globalSettings.MaxNumEdgesPerFace; EngineNavMesh.m_weldInputVertices = globalSettings.WeldInputVertices; EngineNavMesh.m_weldThreshold = globalSettings.WeldThreshold; EngineNavMesh.m_vertexSelectionMethod = (int)globalSettings.VertexSelectionMethod; EngineNavMesh.m_areaFraction = globalSettings.AreaFraction; EngineNavMesh.m_vertexFraction = globalSettings.VertexFraction; // Nav Mesh Edge Matching Settings EngineNavMesh.m_edgeConnectionIterations = globalSettings.EdgeConnectionIterations; EngineNavMesh.m_edgeMatchingMetric = (int)globalSettings.EdgeMatchingMetric; EngineNavMesh.m_maxStepHeight = globalSettings.MaxStepHeight; EngineNavMesh.m_maxSeparation = globalSettings.MaxSeparation; EngineNavMesh.m_maxOverhang = globalSettings.MaxOverhang; EngineNavMesh.m_cosPlanarAlignmentAngle = (float)Math.Cos(globalSettings.PlanarAlignmentAngle / 180.0f * 3.14159f); EngineNavMesh.m_cosVerticalAlignmentAngle = (float)Math.Cos(globalSettings.VerticalAlignmentAngle / 180.0f * 3.14159f); EngineNavMesh.m_minEdgeOverlap = globalSettings.MinEdgeOverlap; // Nav Mesh Simplification Settings EngineNavMesh.m_enableSimplification = globalSettings.EnableSimplification; EngineNavMesh.m_maxBorderSimplifyArea = globalSettings.MaxBorderSimplifyArea; EngineNavMesh.m_maxConcaveBorderSimplifyArea = globalSettings.MaxConcaveBorderSimplifyArea; EngineNavMesh.m_useHeightPartitioning = globalSettings.UseHeightPartitioning; EngineNavMesh.m_maxPartitionHeightError = globalSettings.MaxPartitionHeightError; // Nav Mesh Simplification Settings (Advanced) EngineNavMesh.m_minCorridorWidth = globalSettings.MinCorridorWidth; EngineNavMesh.m_maxCorridorWidth = globalSettings.MaxCorridorWidth; EngineNavMesh.m_holeReplacementArea = globalSettings.HoleReplacementArea; EngineNavMesh.m_maxLoopShrinkFraction = globalSettings.MaxLoopShrinkFraction; EngineNavMesh.m_maxBorderHeightError = globalSettings.MaxBorderHeightError; EngineNavMesh.m_maxBorderDistanceError = globalSettings.MaxBorderDistanceError; EngineNavMesh.m_maxPartitionSize = globalSettings.MaxPartitionSize; EngineNavMesh.m_useConservativeHeightPartitioning = globalSettings.UseConservativeHeightPartitioning; EngineNavMesh.m_hertelMehlhornHeightError = globalSettings.HertelMehlhornHeightError; EngineNavMesh.m_cosPlanarityThreshold = (float)Math.Cos(globalSettings.PlanarityThreshold / 180 * 3.14159f); EngineNavMesh.m_nonconvexityThreshold = globalSettings.NonconvexityThreshold; EngineNavMesh.m_boundaryEdgeFilterThreshold = globalSettings.BoundaryEdgeFilterThreshold; EngineNavMesh.m_maxSharedVertexHorizontalError = globalSettings.MaxSharedVertexHorizontalError; EngineNavMesh.m_maxSharedVertexVerticalError = globalSettings.MaxSharedVertexVerticalError; EngineNavMesh.m_maxBoundaryVertexHorizontalError = globalSettings.MaxBoundaryVertexHorizontalError; EngineNavMesh.m_maxBoundaryVertexVerticalError = globalSettings.MaxBoundaryVertexVerticalError; EngineNavMesh.m_mergeLongestEdgesFirst = globalSettings.MergeLongestEdgesFirst; // Nav Mesh Split Generation Settings EngineNavMesh.m_numTilesX = globalSettings.NumTilesX; EngineNavMesh.m_numTilesY = globalSettings.NumTilesY; EngineNavMesh.m_splitGenerationMethod = (int)globalSettings.SplitGenerationMethod; EngineNavMesh.m_shelverType = (int)globalSettings.ShelverType; }
/// <summary> /// Build nav mesh button /// </summary> private void BuildNavMesh_Click(object sender, EventArgs e) { CSharpFramework.Scene.ZoneCollection zones = EditorManager.Scene.Zones.ShallowClone(); GroupAction groupLoadAction = new GroupAction("Load all zones"); foreach (CSharpFramework.Scene.Zone zone in zones) { groupLoadAction.Add(new CSharpFramework.Actions.SetZoneLoadedStatusAction(zone, true)); } groupLoadAction.Do(); { // for printing out stats BuildStatisticsRichTextBox.ScrollBars = RichTextBoxScrollBars.ForcedVertical; Font oldFont = BuildStatisticsRichTextBox.SelectionFont; Font newFontPlain = new Font(oldFont, oldFont.Style & ~FontStyle.Bold); Font newFontBold = new Font(oldFont, oldFont.Style | FontStyle.Bold); ShapeCollection navMeshShapes = EditorManager.Scene.AllShapesOfType(typeof(HavokNavMeshShape)); // gather all geometry once (divide by zone later) ShapeCollection staticGeometries = new ShapeCollection(); { int numEntities = 0, numStaticMeshes = 0, numTerrains = 0; int numCarvers = 0, numSeedPoints = 0, numLocalSettings = 0; gatherGeometricShapes(ref staticGeometries, ref numEntities, ref numStaticMeshes, ref numTerrains, ref numCarvers, ref numSeedPoints, ref numLocalSettings); // // print out some debug info // BuildStatisticsRichTextBox.SelectionStart = BuildStatisticsRichTextBox.Text.Length; { String inputGeometryLabel = "Input Geometry"; BuildStatisticsRichTextBox.Text = inputGeometryLabel; } BuildStatisticsRichTextBox.SelectionLength = BuildStatisticsRichTextBox.Text.Length - BuildStatisticsRichTextBox.SelectionStart; BuildStatisticsRichTextBox.SelectionFont = newFontBold; { String inputGlobalGeometryInfo = "\n\nStatic meshes\t: " + numStaticMeshes + "\nTerrains\t\t: " + numTerrains + "\nEntities\t\t: " + numEntities + "\n\nCarvers\t\t: " + numCarvers + "\nSeed points\t: " + numSeedPoints + "\nLocal settings\t: " + numLocalSettings + "\n\n"; BuildStatisticsRichTextBox.Text += inputGlobalGeometryInfo; } BuildStatisticsRichTextBox.SelectionLength = BuildStatisticsRichTextBox.Text.Length - BuildStatisticsRichTextBox.SelectionStart; BuildStatisticsRichTextBox.SelectionFont = newFontPlain; // // debug info end // } // actually build the navmeshes here int numBuiltNavMeshShapes = 0; bool allCompleted = true; foreach (HavokNavMeshShape shape in navMeshShapes) { int numGeometryVertices = 0, numGeometryTriangles = 0; // note that the build function only uses static geometries that lie in the same zone! bool built = shape.Build(staticGeometries, ref numGeometryVertices, ref numGeometryTriangles); if (built) { numBuiltNavMeshShapes++; // // print out some debug info // BuildStatisticsRichTextBox.SelectionStart = BuildStatisticsRichTextBox.Text.Length; { String navMeshLabel = "\n\nNav Mesh #" + numBuiltNavMeshShapes; BuildStatisticsRichTextBox.Text += navMeshLabel; } BuildStatisticsRichTextBox.SelectionLength = BuildStatisticsRichTextBox.Text.Length - BuildStatisticsRichTextBox.SelectionStart; BuildStatisticsRichTextBox.SelectionFont = newFontBold; BuildStatisticsRichTextBox.SelectionStart = BuildStatisticsRichTextBox.Text.Length; { String inputPerNavMeshGeometryInfo = "\nTotal input triangles\t: " + numGeometryTriangles + "\nTotal input vertices\t: " + numGeometryVertices + "\n\n"; int facesSize = shape.GetNavMeshFaceSize() * shape.GetNumNavMeshFaces(); int edgesSize = shape.GetNavMeshEdgeSize() * shape.GetNumNavMeshEdges(); int verticesSize = shape.GetNavMeshVertexSize() * shape.GetNumNavMeshVertices(); int totalSize = shape.GetNavMeshStructSize() + facesSize + edgesSize + verticesSize; String navMeshInfo = "\nTotal size\t\t: " + totalSize + " bytes\nFaces ( " + shape.GetNumNavMeshFaces() + " )\t: " + facesSize + "\nEdges ( " + shape.GetNumNavMeshEdges() + " )\t: " + edgesSize + "\nVertices ( " + shape.GetNumNavMeshVertices() + " )\t: " + verticesSize; BuildStatisticsRichTextBox.Text += navMeshInfo; } BuildStatisticsRichTextBox.SelectionLength = BuildStatisticsRichTextBox.Text.Length - BuildStatisticsRichTextBox.SelectionStart; BuildStatisticsRichTextBox.SelectionFont = newFontPlain; // // debug info end // } else { allCompleted = false; break; } } if (allCompleted) { // stitch the navmeshes together using (HavokAiManaged.EngineInstanceHavokNavMeshLinker linker = new HavokAiManaged.EngineInstanceHavokNavMeshLinker()) { // collect all navmeshes at once foreach (HavokNavMeshShape shape in navMeshShapes) { if (shape.HasEngineInstance()) { linker.AddNavMeshShape(shape._engineInstance.GetNativeObject()); HavokNavMeshGlobalSettings globalSettings = GetGlobalSettings(shape.NavMeshGlobalSettingsKey); if (globalSettings != null) { linker.m_linkEdgeMatchTolerance = globalSettings.LinkEdgeMatchTolerance; linker.m_linkMaxStepHeight = globalSettings.LinkMaxStepHeight; linker.m_linkMaxSeparation = globalSettings.LinkMaxSeparation; linker.m_linkMaxOverhang = globalSettings.LinkMaxOverhang; linker.m_linkCosPlanarAlignmentAngle = (float)Math.Cos(globalSettings.LinkPlanarAlignmentAngle / 180.0f * 3.14159f); linker.m_linkCosVerticalAlignmentAngle = (float)Math.Cos(globalSettings.LinkVerticalAlignmentAngle / 180.0f * 3.14159f); linker.m_linkMinEdgeOverlap = globalSettings.LinkMinEdgeOverlap; } } } // link them together linker.LinkNavMeshes(); } // save it to disk (separate from next loop because we want to guarantee that we don't serialize out some runtime only data) foreach (HavokNavMeshShape shape in navMeshShapes) { shape.SaveNavMeshesToFile(); } // finally load it into the havok ai world foreach (HavokNavMeshShape shape in navMeshShapes) { shape.AddNavMeshToWorld(); } if (EditorManager.InPlayingMode && WantPhysicsConnection()) { HavokAiManaged.ManagedModule.SetConnectToPhysicsWorld(true); } } EnableBuildButtonAsterisk(false); //EnableStreamingDependentControls(shape.GetNumNavMeshes()>1); } groupLoadAction.Undo(); EditorManager.ActiveView.UpdateView(true); }
public bool Build(ShapeCollection staticGeometries, ref int numGeometryVertices, ref int numGeometryTriangles) { if (!HasEngineInstance()) { return(false); } EngineNavMesh.ClearNavMesh(); EngineNavMesh.ClearGeometry(); EngineNavMesh.ClearCarvers(); EngineNavMesh.ClearSeedPoints(); EngineNavMesh.ClearLocalSettings(); EngineNavMesh.ClearDecorationCapsules(); SetEngineInstanceBaseProperties(); HavokNavMeshGlobalSettings globalSettings = GetGlobalSettings(); if (globalSettings == null) { return(false); } BoundingBox parentZoneBbox = new BoundingBox(); if (globalSettings.RestrictToInputGeometryFromSameZone && ParentZone != null) { parentZoneBbox = ParentZone.CalculateBoundingBox(); } // check if there's a parent zone foreach (ShapeBase shape in staticGeometries) { // treat as cutter if flag is set and if in different zone bool potentiallyTreatAsCutter = globalSettings.RestrictToInputGeometryFromSameZone && (shape.ParentZone != ParentZone); if (shape is EntityShape) { EntityShape entity = shape as EntityShape; eNavMeshUsage usage = entity.GetNavMeshUsage(); // exclude entities that have a vHavokRigidBody component with "Motion Type" != "Fixed" ShapeComponentType compType = (ShapeComponentType)EditorManager.EngineManager.ComponentClassManager.GetCollectionType("vHavokRigidBody"); if (compType != null && entity.Components != null) { ShapeComponent comp = entity.Components.GetComponentByType(compType); if (comp != null) { string propValue = comp.GetPropertyValue("Motion Type") as string; if (string.Compare(propValue, "Fixed") != 0) { usage = eNavMeshUsage.ExcludeFromNavMesh; } } } // potentially override usage if (potentiallyTreatAsCutter && (usage == eNavMeshUsage.IncludeInNavMesh)) { usage = eNavMeshUsage.CutterOnly; } if (usage != eNavMeshUsage.ExcludeFromNavMesh) { EngineNavMesh.AddEntityGeometry(entity.EngineEntity.GetNativeObject(), (int)usage, parentZoneBbox); } } else if (shape is StaticMeshShape) { StaticMeshShape staticMesh = shape as StaticMeshShape; eNavMeshUsage usage = staticMesh.GetNavMeshUsage(); // potentially override usage if (potentiallyTreatAsCutter && (usage == eNavMeshUsage.IncludeInNavMesh)) { usage = eNavMeshUsage.CutterOnly; } if (usage != eNavMeshUsage.ExcludeFromNavMesh) { EngineNavMesh.AddStaticMeshGeometry(staticMesh.EngineMesh.GetNativeObject(), (int)usage, parentZoneBbox); } } else if (shape is TerrainShape) { TerrainShape terrain = shape as TerrainShape; eNavMeshUsage usage = terrain.GetNavMeshUsage(); // potentially override usage if (potentiallyTreatAsCutter && (usage == eNavMeshUsage.IncludeInNavMesh)) { usage = eNavMeshUsage.CutterOnly; } if (usage != eNavMeshUsage.ExcludeFromNavMesh) { EngineNavMesh.AddTerrainGeometry(terrain.EngineTerrain.GetNativeObject(), (int)usage, parentZoneBbox); } } #if !HK_ANARCHY else if (shape is DecorationGroupShape) { DecorationGroupShape decorationGroup = shape as DecorationGroupShape; // Please note that currently the native HavokAiEnginePlugin only supports decoration capsules as cutters. if (decorationGroup.GetNavMeshLimitedUsage() == DecorationGroupShape.eNavMeshLimitedUsage.CutterOnly) { EngineNavMesh.AddDecorationGroupCapsules(decorationGroup.EngineGroup.GetGroupsObject()); } } #endif #if USE_SPEEDTREE else if (shape is Speedtree6GroupShape) { Speedtree6GroupShape trees = shape as Speedtree6GroupShape; if (trees.EnableCollisions) { EngineNavMesh.AddSpeedTree6Capsules(trees.EngineGroup.GetGroupsObject()); } } #endif } numGeometryVertices = EngineNavMesh.GetNumGeometryVertices(); numGeometryTriangles = EngineNavMesh.GetNumGeometryTriangles(); // Add carvers ShapeCollection carvers = EditorManager.Scene.AllShapesOfType(typeof(HavokNavMeshCarverShape)); foreach (ShapeBase shape in carvers) { HavokNavMeshCarverShape carver = shape as HavokNavMeshCarverShape; BoundingBox localBbox = null; carver.GetLocalBoundingBox(ref localBbox); localBbox.vMin.X *= carver.ScaleX; localBbox.vMin.Y *= carver.ScaleY; localBbox.vMin.Z *= carver.ScaleZ; localBbox.vMax.X *= carver.ScaleX; localBbox.vMax.Y *= carver.ScaleY; localBbox.vMax.Z *= carver.ScaleZ; EngineNavMesh.AddBoxCarver(localBbox.vMin, localBbox.vMax, carver.Position, carver.RotationMatrix, carver.IsInverted()); } // Add seed points ShapeCollection seedPoints = EditorManager.Scene.AllShapesOfType(typeof(HavokNavMeshSeedPointShape)); foreach (ShapeBase shape in seedPoints) { HavokNavMeshSeedPointShape seedPoint = shape as HavokNavMeshSeedPointShape; EngineNavMesh.AddSeedPoint(seedPoint.Position); } // Add local settings ShapeCollection localSettings = EditorManager.Scene.AllShapesOfType(typeof(HavokNavMeshLocalSettingsShape)); foreach (ShapeBase shape in localSettings) { HavokNavMeshLocalSettingsShape ls = shape as HavokNavMeshLocalSettingsShape; BoundingBox bbox = null; ls.GetLocalBoundingBox(ref bbox); bbox.vMin.X *= ls.ScaleX; bbox.vMin.Y *= ls.ScaleY; bbox.vMin.Z *= ls.ScaleZ; bbox.vMax.X *= ls.ScaleX; bbox.vMax.Y *= ls.ScaleY; bbox.vMax.Z *= ls.ScaleZ; // Nav Mesh Generation Settings EngineNavMesh.m_maxWalkableSlope = ls.MaxWalkableSlope / 180.0f * 3.14159f; // Nav Mesh Edge Matching Settings EngineNavMesh.m_maxStepHeight = ls.MaxStepHeight; EngineNavMesh.m_maxSeparation = ls.MaxSeparation; EngineNavMesh.m_maxOverhang = ls.MaxOverhang; EngineNavMesh.m_cosPlanarAlignmentAngle = (float)Math.Cos(ls.PlanarAlignmentAngle / 180.0f * 3.14159f); EngineNavMesh.m_cosVerticalAlignmentAngle = (float)Math.Cos(ls.VerticalAlignmentAngle / 180.0f * 3.14159f); EngineNavMesh.m_minEdgeOverlap = ls.MinEdgeOverlap; // Nav Mesh Simplification Settings EngineNavMesh.m_maxBorderSimplifyArea = ls.MaxBorderSimplifyArea; EngineNavMesh.m_maxConcaveBorderSimplifyArea = ls.MaxConcaveBorderSimplifyArea; EngineNavMesh.m_useHeightPartitioning = ls.UseHeightPartitioning; EngineNavMesh.m_maxPartitionHeightError = ls.MaxPartitionHeightError; // Nav Mesh Simplification Settings (Advanced) EngineNavMesh.m_minCorridorWidth = ls.MinCorridorWidth; EngineNavMesh.m_maxCorridorWidth = ls.MaxCorridorWidth; EngineNavMesh.m_holeReplacementArea = ls.HoleReplacementArea; EngineNavMesh.m_maxLoopShrinkFraction = ls.MaxLoopShrinkFraction; EngineNavMesh.m_maxBorderHeightError = ls.MaxBorderHeightError; EngineNavMesh.m_maxBorderDistanceError = ls.MaxBorderDistanceError; EngineNavMesh.m_maxPartitionSize = ls.MaxPartitionSize; EngineNavMesh.m_useConservativeHeightPartitioning = ls.UseConservativeHeightPartitioning; EngineNavMesh.m_hertelMehlhornHeightError = ls.HertelMehlhornHeightError; EngineNavMesh.m_cosPlanarityThreshold = (float)Math.Cos(ls.PlanarityThreshold / 180 * 3.14159f); EngineNavMesh.m_nonconvexityThreshold = ls.NonconvexityThreshold; EngineNavMesh.m_boundaryEdgeFilterThreshold = ls.BoundaryEdgeFilterThreshold; EngineNavMesh.m_maxSharedVertexHorizontalError = ls.MaxSharedVertexHorizontalError; EngineNavMesh.m_maxSharedVertexVerticalError = ls.MaxSharedVertexVerticalError; EngineNavMesh.m_maxBoundaryVertexHorizontalError = ls.MaxBoundaryVertexHorizontalError; EngineNavMesh.m_maxBoundaryVertexVerticalError = ls.MaxBoundaryVertexVerticalError; EngineNavMesh.m_mergeLongestEdgesFirst = ls.MergeLongestEdgesFirst; EngineNavMesh.AddLocalSettings(bbox.vMin, bbox.vMax, ls.Position, ls.RotationMatrix); } // todo: figure out how to pass class instances between here and EngineNavMesh. // basically the settings members of EngineNavMesh are reused for transferring the local settings to // EngineNavMesh. this should be harmless due to the following call which will revert any changes. SetEngineInstanceBaseProperties(); string fullSnapshotPath = Path.Combine(CSharpFramework.EditorManager.Scene.Project.ProjectDir, m_snapshotFilename); bool ret = EngineNavMesh.BuildNavMeshFromGeometry(m_saveInputSnapshot, fullSnapshotPath); EngineNavMesh.ClearGeometry(); EngineNavMesh.ClearCarvers(); EngineNavMesh.ClearSeedPoints(); EngineNavMesh.ClearLocalSettings(); EngineNavMesh.ClearDecorationCapsules(); return(ret); }
public AddNavMeshGlobalSettingsAction(HavokNavMeshGlobalSettingsDictionary collection, string settingsName, HavokNavMeshGlobalSettings settings) { m_collection = collection; m_settings = settings; m_settingsName = settingsName; }
public bool WantPhysicsConnection() { HavokNavMeshGlobalSettings settings = GetOrCreateDefaultGlobalSettings(); return(settings.ConnectToPhysics); }