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)); }
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)); }