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;
     }
 }
Exemple #3
0
        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);
        }
Exemple #8
0
        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();
        }
Exemple #12
0
        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;
        }
Exemple #15
0
        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");
                }
            }
        }
Exemple #16
0
        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);
        }
Exemple #18
0
        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);
        }