Exemple #1
0
        public void AddModelPathObject(bool logPathGeneration, PathObjectType type, string modelName,
                                       Vector3 modelPosition, Matrix4 modelTransform,
                                       List <CollisionShape> shapes, float terrainHeight)
        {
            PathGenerator pathGenerator = new PathGenerator(logPathGeneration, modelName, type, terrainHeight,
                                                            modelTransform, shapes);

            // Perform traversal and creation of polygons, arcs
            // between polygons, and portals to the terrain
            pathGenerator.GeneratePolygonsArcsAndPortals();
            List <PathPolygon> polygons = new List <PathPolygon>();
            List <PathArc>     portals  = new List <PathArc>();
            List <PathArc>     arcs     = new List <PathArc>();

            foreach (GridPolygon r in pathGenerator.CVPolygons)
            {
                polygons.Add(new PathPolygon(r.Index, PolygonKind.CV, r.CornerLocs));
            }
            foreach (GridPolygon r in pathGenerator.TerrainPolygons)
            {
                polygons.Add(new PathPolygon(r.Index, PolygonKind.Terrain, r.CornerLocs));
            }
            foreach (PolygonArc portal in pathGenerator.TerrainPortals)
            {
                portals.Add(new PathArc(portal.Kind, portal.Poly1Index, portal.Poly2Index, MakePathEdge(portal.Edge)));
            }
            foreach (PolygonArc arc in pathGenerator.PolygonArcs)
            {
                arcs.Add(new PathArc(arc.Kind, arc.Poly1Index, arc.Poly2Index, MakePathEdge(arc.Edge)));
            }
            pathObjects.Add(new PathObject(pathGenerator.ModelName, type.name, pathGenerator.FirstTerrainIndex,
                                           new PathPolygon(0, PolygonKind.Bounding, pathGenerator.ModelCorners),
                                           polygons, portals, arcs));
        }
Exemple #2
0
 public PathObjectType(PathObjectType other)
 {
     name                = other.name;
     height              = other.height;
     width               = other.width;
     maxClimbSlope       = other.maxClimbSlope;
     gridResolution      = other.gridResolution;
     maxDisjointDistance = other.maxDisjointDistance;
     minimumFeatureSize  = other.minimumFeatureSize;
 }
 public void Execute()
 {
     float modelHeight = 1.8f;
     float modelWidth = .5f;
     float maxClimbSlope = 0.3f;
     float gridResolution = .25f;
     float maxDisjointDistance = .1f;  //.1f * oneMeter;
     int minimumFeatureSize = 3;    // 3 grid cells
     float terrainLevel = WorldEditor.Instance.GetTerrainHeight(modelObj.Position.x, modelObj.Position.z) - modelObj.Position.y;
     PathObjectType poType = new PathObjectType(modelObj.Name, modelHeight, modelWidth, maxClimbSlope,
                                                gridResolution, maxDisjointDistance, minimumFeatureSize);
     List<CollisionShape> shapes = WorldEditor.Instance.FindMeshCollisionShapes(modelObj.MeshName, modelObj.DisplayObject.Entity);
     PathGenerator pathGenerator = new PathGenerator(WorldEditor.Instance.LogPathGeneration, modelObj.Name, poType, terrainLevel,
                                                     modelObj.DisplayObject.SceneNode.FullTransform, shapes);
     // Perform traversal and creation of rectangles, arcs
     // between rectangles, and portals to the terrain
     pathGenerator.GeneratePolygonsArcsAndPortals();
 }
        public PathGenerator(bool logPathGeneration, string modelName, PathObjectType poType, float terrainLevel, 
                             Matrix4 modelTransform, List<CollisionShape> collisionVolumes)
        {
            this.dumpGrid = logPathGeneration;
            this.modelName = modelName;
            this.poType = poType;
            this.modelWidth = poType.width * oneMeter;
            this.cellWidth = poType.gridResolution * modelWidth;
            this.boxHeight = poType.height * oneMeter;
            this.maxClimbDistance = poType.maxClimbSlope * cellWidth;
            this.maxDisjointDistance = poType.maxDisjointDistance * oneMeter;
            this.minimumFeatureSize = poType.minimumFeatureSize;
            this.terrainLevel = terrainLevel;
            this.modelTransform = modelTransform;
            this.collisionVolumes = collisionVolumes;
            stopwatch = new Stopwatch();
            stopwatch.Start();

            // Create the collisionAPI object
            collisionAPI = new CollisionAPI(false);

            // Ugly workaround for a modularity problem do to
            // unadvised use of static variables: remember the
            // existing state of rendering collision volumes
            RenderedNode.RenderState oldRenderState = RenderedNode.renderState;
            RenderedNode.renderState = RenderedNode.RenderState.None;

            // Form the union of the collision volumes; we don't care
            // about Y coordinate, only the X and Z coordinates
            Vector3 min = Vector3.Zero;
            Vector3 max = Vector3.Zero;
            for (int i=0; i<collisionVolumes.Count; i++) {
                CollisionShape shape = collisionVolumes[i];
                // Add the shape to the sphere tree
                collisionAPI.SphereTree.AddCollisionShape(shape);
                AxisAlignedBox vol = shape.BoundingBox();
                // If this is the first iteration, set up the min and
                // max
                if (i == 0) {
                    min = vol.Minimum;
                    max = vol.Maximum;
                    min.y = terrainLevel;
                    max.y = terrainLevel;
                    continue;
                }
                // Enlarge the box by the dimensions of the shape
                min.x = Math.Min(min.x, vol.Minimum.x);
                min.z = Math.Min(min.z, vol.Minimum.z);
                max.x = Math.Max(max.x, vol.Maximum.x);
                max.z = Math.Max(max.z, vol.Maximum.z);
            }

            // Restore RenderState
            RenderedNode.renderState = oldRenderState;

            // Round out the max and min by 4 times the grid
            // resolution, so we can just divide to find the
            // horizontal and vertical numbers are cells
            Vector3 margin = Vector3.UnitScale * 4 * cellWidth;
            min -= margin;
            max += margin;

            // Now adjust the max the min coords so that they are
            // exactly a multiple of the grid resolution
            min.x = MultipleOfResolution(min.x);
            min.z = MultipleOfResolution(min.z);
            max.x = MultipleOfResolution(max.x);
            max.z = MultipleOfResolution(max.z);

            // Set the lower left  and upper right corners
            lowerLeftCorner = min;
            upperRightCorner = max;

            // Set the horizontal and vertical counts
            xCount = (int)((max.x - min.x) / cellWidth);
            zCount = (int)((max.z - min.z) / cellWidth);

            // Initial the gridBox
            gridBox = new AxisAlignedBox(min, max);

            // Allocate the grid
            grid = new List<GridCell>[xCount, zCount];
            for (int i=0; i<xCount; i++)
                for (int j=0; j<zCount; j++)
                    grid[i,j] = new List<GridCell>();

            // Initialize the work list, adding the cell at 0,0 and
            // the terrain height as the first member
            workList = new List<CellLocation>();
            workList.Add(new CellLocation(0, 0, terrainLevel, null));

            // Create the moving box at the center of the 0, 0 cell,
            // and the MovingObject object that contains the moving box
            movingBox = new CollisionAABB(
                new Vector3(min.x, terrainLevel, min.z),
                new Vector3(min.x + cellWidth, terrainLevel + boxHeight, min.z + terrainLevel));
            movingObject = new MovingObject(collisionAPI);
            movingObject.AddPart(movingBox);
        }
 private void okButton_Click(object sender, EventArgs e)
 {
     // Validate the fields
     string name = pathObjectTypeName.Text;
     if (name.Length == 0) {
         barf("The path object type name may not be null");
         return;
     }
     int minimumFeatureSize;
     float height, width, maxClimbSlope, gridResolution, maxDisjointDistance;
     if (parseFloat(pathObjectTypeHeight, out height, "path object type class height", float.MaxValue) &&
         parseFloat(pathObjectTypeWidth, out width, "path object type class width", float.MaxValue) &&
         parseFloat(pathObjectTypeSlope, out maxClimbSlope, "path object type class maximum climb slope", 1.0f) &&
         parseFloat(pathObjectTypeGridResolution, out gridResolution, "path object type class grid resolution fraction", 1.0f) &&
         parseFloat(pathObjectTypeMaxDisjointDistance, out maxDisjointDistance,
             "path object type class distance between collision volumes", float.MaxValue) &&
         parseInt(pathObjectTypeMinimumFeatureSize, out minimumFeatureSize,
             "maximum number of grid cells to ignore when constructing grid rectangles", int.MaxValue)) {
         // If we're editing, copy updated values to the instance
         if (pathObjectType != null) {
             pathObjectType.AcceptValues(name, height, width, maxClimbSlope,
                 gridResolution, maxDisjointDistance, minimumFeatureSize);
         }
             // Else create a new instance
         else {
             pathObjectType = new PathObjectType(name, height, width, maxClimbSlope,
                 gridResolution, maxDisjointDistance, minimumFeatureSize);
         }
         WorldRoot.Instance.PathObjectTypes.AllObjectsDirty = true;
         DialogResult = DialogResult.OK;
     }
 }
 public AddPathObjectTypeCommand(WorldEditor worldEditor, PathObjectTypeContainer parent, PathObjectType pathObjectType)
 {
     this.app = worldEditor;
     this.parent = parent;
     this.pathObjectType = pathObjectType;
 }
 public PathObjectTypeNode(WorldEditor app, PathObjectTypeContainer parent, XmlReader r)
 {
     this.app = app;
     this.parent = parent;
     this.pathObjectType = new PathObjectType(r);
 }
 public PathObjectTypeNode(WorldEditor app, PathObjectTypeContainer parent, PathObjectType pathObjectType)
 {
     this.app = app;
     this.pathObjectType = pathObjectType;
     this.parent = parent;
 }
 public ICommand CreateCommand()
 {
     PathObjectTypeDialog dialog = new PathObjectTypeDialog();
     dialog.pathObjectType = pathObjectTypeNode.PathObjectType;
     PathObjectType beforePathObjectType = new PathObjectType(dialog.pathObjectType);
     if (dialog.ShowDialog() == DialogResult.OK) {
         PathObjectType afterPathObjectType = new PathObjectType(dialog.pathObjectType);
         ICommand cmd = new EditPathObjectTypeCommand(app, parent, pathObjectTypeNode,
                                                      beforePathObjectType, afterPathObjectType);
         return cmd;
     }
     else
         return null;
 }
 public EditPathObjectTypeCommand(WorldEditor worldEditor, IWorldObject parent, PathObjectTypeNode pathObjectTypeNode,
                                  PathObjectType beforePathObjectType, PathObjectType afterPathObjectType)
 {
     this.app = worldEditor;
     this.parent = parent;
     this.pathObjectTypeNode = pathObjectTypeNode;
     this.beforePathObjectType = beforePathObjectType;
     this.afterPathObjectType = afterPathObjectType;
 }
 public PathObjectType(PathObjectType other)
 {
     name = other.name;
     height = other.height;
     width = other.width;
     maxClimbSlope = other.maxClimbSlope;
     gridResolution = other.gridResolution;
     maxDisjointDistance = other.maxDisjointDistance;
     minimumFeatureSize = other.minimumFeatureSize;
 }
 public void AddModelPathObject(bool logPathGeneration, PathObjectType type, string modelName,
                                Vector3 modelPosition, Matrix4 modelTransform, 
                                List<CollisionShape> shapes, float terrainHeight)
 {
     PathGenerator pathGenerator = new PathGenerator(logPathGeneration, modelName, type, terrainHeight,
                                                     modelTransform, shapes);
     // Perform traversal and creation of polygons, arcs
     // between polygons, and portals to the terrain
     pathGenerator.GeneratePolygonsArcsAndPortals();
     List<PathPolygon> polygons = new List<PathPolygon>();
     List<PathArc> portals = new List<PathArc>();
     List<PathArc> arcs = new List<PathArc>();
     foreach(GridPolygon r in pathGenerator.CVPolygons)
         polygons.Add(new PathPolygon(r.Index, PolygonKind.CV, r.CornerLocs));
     foreach(GridPolygon r in pathGenerator.TerrainPolygons)
         polygons.Add(new PathPolygon(r.Index, PolygonKind.Terrain, r.CornerLocs));
     foreach(PolygonArc portal in pathGenerator.TerrainPortals)
         portals.Add(new PathArc(portal.Kind, portal.Poly1Index, portal.Poly2Index, MakePathEdge(portal.Edge)));
     foreach(PolygonArc arc in pathGenerator.PolygonArcs)
         arcs.Add(new PathArc(arc.Kind, arc.Poly1Index, arc.Poly2Index, MakePathEdge(arc.Edge)));
     pathObjects.Add(new PathObject(pathGenerator.ModelName, type.name, pathGenerator.FirstTerrainIndex,
                                    new PathPolygon(0, PolygonKind.Bounding, pathGenerator.ModelCorners),
             polygons, portals, arcs));
 }