public bool isInside(float i, float j) { Paths boundingSolids = P_Plan.getTransformedSubjPaths(); Paths boundingHoles = P_Plan.getTransformedHolePaths(); bool pointIsInside = false; IntPoint ip = new IntPoint(i * AXGeometryTools.Utilities.IntPointPrecision, j * AXGeometryTools.Utilities.IntPointPrecision); if (boundingSolids != null) { if (boundingSolids != null) { foreach (Path path in boundingSolids) { if (Clipper.PointInPolygon(ip, path) == 1 && Clipper.Orientation(path)) { pointIsInside = true; break; } } } if (boundingHoles != null) { foreach (Path hole in boundingHoles) { if (Clipper.PointInPolygon(ip, hole) == 1) { pointIsInside = false; break; } } } } //exclude = (boundingIsVoid) ? ! exclude : exclude; //if (pointIsInside) //continue; return(pointIsInside); }
public void carveTerrain() { Terrain terrain = parametricObject.terrain; if (terrain != null) { if (parametricObject.heightsOrig == null) { memorizeTerrain(); } // BOUNDING_SHAPE if (P_Plan != null && P_Plan.DependsOn != null) { if (planSrc_po != null) { AXShape.thickenAndOffset(ref P_Plan, planSrc_p); // now boundin_p has offset and thickened polytree or paths. } } int hmWidth = terrain.terrainData.heightmapWidth; int hmHeight = terrain.terrainData.heightmapHeight; Paths subjPaths = P_Plan.getTransformedSubjPaths(); Paths holePaths = P_Plan.getTransformedHolePaths(); //Pather.printPaths(subjPaths); if (subjPaths == null) { return; } IntRect bounds = Clipper.GetBounds(subjPaths); // if (prevBounds.right > 0) // { // bounds.left = ( prevBounds.left < bounds.left ) ? prevBounds.left : bounds.left; // bounds.right = ( prevBounds.right > bounds.right ) ? prevBounds.right : bounds.right; // // // bounds.top = ( prevBounds.top < bounds.top ) ? prevBounds.top : bounds.top; // bounds.bottom = ( prevBounds.bottom > bounds.bottom ) ? prevBounds.bottom : bounds.bottom; // } float percentHgt = height / terrain.terrainData.size.y; //Debug.Log(bounds.left +"->"+bounds.right+" :: " + bounds.top+ "->"+bounds.bottom); int padding = 50000; bounds.left -= padding; bounds.right += padding; bounds.top -= padding; bounds.bottom += padding; int from_i = (int)((bounds.left / AXGeometryTools.Utilities.IntPointPrecision) * hmWidth / terrain.terrainData.size.x); int to_i = (int)((bounds.right / AXGeometryTools.Utilities.IntPointPrecision) * hmWidth / terrain.terrainData.size.x); int from_j = (int)((bounds.top / AXGeometryTools.Utilities.IntPointPrecision) * hmHeight / terrain.terrainData.size.z); int to_j = (int)((bounds.bottom / AXGeometryTools.Utilities.IntPointPrecision) * hmHeight / terrain.terrainData.size.z); //Debug.Log(from_i +"->"+to_i+" :: " + from_j+ "->"+to_j); from_i = Mathf.Max(0, from_i); to_i = Mathf.Min(to_i, hmWidth); from_j = Mathf.Max(0, from_j); to_j = Mathf.Min(to_j, hmHeight); //Debug.Log(from_i +"->"+to_i+" :: " + from_j+ "->"+to_j); // patch to be redrawn float[,] heights = new float[(to_j - from_j), (to_i - from_i)]; //Debug.Log(heights.GetLength(0) +" -- " + heights.GetLength(1)); if (from_i < to_i && from_j < to_j) { // we set each sample of the terrain in the size to the desired height for (int i = from_i; i < to_i; i++) { for (int j = from_j; j < to_j; j++) { // GET i, j in realworld coords float x = terrain.terrainData.size.x * i / hmWidth; float y = terrain.terrainData.size.z * j / hmHeight; //Debug.Log("[" + i + ", " + j + "] :: " + x +", " + y); if (isInside(x, y, subjPaths, holePaths)) { heights [j - from_j, i - from_i] = percentHgt; } else { heights [j - from_j, i - from_i] = parametricObject.heightsOrig [j, i]; } } } // set the new height terrain.terrainData.SetHeights(from_i, from_j, heights); } //prevBounds = bounds; } }