Exemplo n.º 1
0
        void MigrateCharacterControllerProperties(ShapeComponent physX, ShapeComponent havok)
        {
            havok.SetPropertyValue("Max_Slope", physX.GetPropertyValue("m_fSlopeLimit", false));
            float fRadius = (float)physX.GetPropertyValue("m_fRadius", false);
            float fHeight = (float)physX.GetPropertyValue("m_fHeight", false);

            if (fRadius > 0.0f && fHeight > 0.0f)
            {
                havok.SetPropertyValue("Capsule_Radius", fRadius);
                Vector3F top = new Vector3F(0.0f, 0.0f, fHeight + fRadius);
                havok.SetPropertyValue("Character_Top", top);
                Vector3F bottom = new Vector3F(0.0f, 0.0f, fRadius);
                havok.SetPropertyValue("Character_Bottom", bottom);
            }
            havok.SetPropertyValue("Debug", physX.GetPropertyValue("DebugRendering", false));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Map properties from the START_VAR_TABLE(vPhysXRigidBody,... to the counterparts in START_VAR_TABLE(vHavokRigidBody...
        /// </summary>
        /// <param name="physX">Input physX rigid body property</param>
        /// <param name="havok">output havok component</param>
        void MigrateRigidBodyProperties(ShapeComponent physX, ShapeComponent havok)
        {
            {
                // Havok: "Dynamic/Keyframed/Fixed/Sphere Inertia/Box Inertia/Thin Box Inertia/Character"
                // PhysX: "Dynamic/Static/Kinematic"
                string sValue = (string)physX.GetPropertyValue("m_ePhysicsType", false); // since it is an enum, we get it as a string
                if (sValue == "Static")
                {
                    sValue = "Fixed";
                }
                else if (sValue == "Kinematic")
                {
                    sValue = "Keyframed";
                }
                havok.SetPropertyValue("Havok_MotionType", sValue, false);
            }

            {
                // Havok: "Box/Sphere/Convex Hull/File/Capsule/Cylinder/Mesh"
                // PhysX: "Box/Sphere/File/Hull/Mesh"
                string sValue = (string)physX.GetPropertyValue("m_ePhysicsGeom", false); // since it is an enum, we get it as a string
                if (sValue == "Hull" || sValue == "File")
                {
                    sValue = "Convex Hull";                               // since "PhysXFile" + "Havok_FileResourceName" does not match, convert "File" to "Convex Hull"
                }
                havok.SetPropertyValue("Shape_Type", sValue, false);
            }

            // mass of zero is not legal for dynamic rigid bodies in Havok
            float fMass = (float)physX.GetPropertyValue("m_fMass", false);

            if (fMass > 0.0f)
            {
                havok.SetPropertyValue("Havok_Mass", fMass);
            }

            havok.SetPropertyValue("Shape_Height", physX.GetPropertyValue("m_fHeight", false));
            havok.SetPropertyValue("Shape_Radius", physX.GetPropertyValue("m_fRadius", false));
            havok.SetPropertyValue("Shape_PivotOffset", physX.GetPropertyValue("m_vLocalOffset", false));
            havok.SetPropertyValue("Shape_BoxSize", physX.GetPropertyValue("m_bboxSize", false));
            havok.SetPropertyValue("Debug_Render", physX.GetPropertyValue("DebugRendering", false));
        }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Map properties from the START_VAR_TABLE(vPhysXRigidBody,... to the counterparts in START_VAR_TABLE(vHavokRigidBody...
        /// </summary>
        /// <param name="physX">Input physX rigid body property</param>
        /// <param name="havok">output havok component</param>
        void MigrateRigidBodyProperties(ShapeComponent physX, ShapeComponent havok)
        {
            {
            // Havok: "Dynamic/Keyframed/Fixed/Sphere Inertia/Box Inertia/Thin Box Inertia/Character"
            // PhysX: "Dynamic/Static/Kinematic"
            string sValue = (string)physX.GetPropertyValue("m_ePhysicsType", false); // since it is an enum, we get it as a string
            if (sValue == "Static") sValue = "Fixed";
            else if (sValue == "Kinematic") sValue = "Keyframed";
            havok.SetPropertyValue("Havok_MotionType", sValue, false);
              }

              {
            // Havok: "Box/Sphere/Convex Hull/File/Capsule/Cylinder/Mesh"
            // PhysX: "Box/Sphere/File/Hull/Mesh"
            string sValue = (string)physX.GetPropertyValue("m_ePhysicsGeom", false); // since it is an enum, we get it as a string
            if (sValue == "Hull" || sValue == "File") sValue = "Convex Hull"; // since "PhysXFile" + "Havok_FileResourceName" does not match, convert "File" to "Convex Hull"
            havok.SetPropertyValue("Shape_Type", sValue, false);
              }

              // mass of zero is not legal for dynamic rigid bodies in Havok
              float fMass = (float)physX.GetPropertyValue("m_fMass", false);
              if (fMass > 0.0f)
            havok.SetPropertyValue("Havok_Mass", fMass);

              havok.SetPropertyValue("Shape_Height", physX.GetPropertyValue("m_fHeight", false));
              havok.SetPropertyValue("Shape_Radius", physX.GetPropertyValue("m_fRadius", false));
              havok.SetPropertyValue("Shape_PivotOffset", physX.GetPropertyValue("m_vLocalOffset", false));
              havok.SetPropertyValue("Shape_BoxSize", physX.GetPropertyValue("m_bboxSize", false));
              havok.SetPropertyValue("Debug_Render", physX.GetPropertyValue("DebugRendering", false));
        }
Exemplo n.º 5
0
 void MigrateCharacterControllerProperties(ShapeComponent physX, ShapeComponent havok)
 {
     havok.SetPropertyValue("Max_Slope", physX.GetPropertyValue("m_fSlopeLimit", false));
       float fRadius = (float)physX.GetPropertyValue("m_fRadius", false);
       float fHeight = (float)physX.GetPropertyValue("m_fHeight", false);
       if (fRadius > 0.0f && fHeight > 0.0f)
       {
     havok.SetPropertyValue("Capsule_Radius", fRadius);
     Vector3F top = new Vector3F(0.0f, 0.0f, fHeight + fRadius);
     havok.SetPropertyValue("Character_Top", top);
     Vector3F bottom = new Vector3F(0.0f, 0.0f, fRadius);
     havok.SetPropertyValue("Character_Bottom", bottom);
       }
       havok.SetPropertyValue("Debug", physX.GetPropertyValue("DebugRendering", false));
 }