public void generateData() { vertexList.Clear(); // get all objects with mesh rendering enabled MeshFilter[] filters = (MeshFilter[])GameObject.FindObjectsOfType(typeof(MeshFilter)); if (filters != null) { for (int i = 0; i < filters.Length; i++) { if (filters[i].GetComponent <Renderer>() == null) { continue; } // check if renderer is actually enabled before batching data if (!filters[i].GetComponent <Renderer>().enabled) { continue; } // if so, continue with batching process Mesh mesh = filters[i].sharedMesh; if (filters[i].gameObject.isStatic) { if (maxTriCount <= 0 || (maxTriCount * 3) >= mesh.triangles.Length) { rawCount += mesh.vertexCount; OptiMesh opt = ScriptableObject.CreateInstance <OptiMesh>(); //OptiMesh opt = new OptiMesh(); //opt.onEnable(); opt.objRef = filters[i].gameObject; //OptiMesh opt = new OptiMesh(filters[i].gameObject); for (int j = 0; j < mesh.triangles.Length; j += 3) { Vector3 p1 = mesh.vertices[mesh.triangles[j + 0]]; Vector3 p2 = mesh.vertices[mesh.triangles[j + 1]]; Vector3 p3 = mesh.vertices[mesh.triangles[j + 2]]; opt.addTriangle(p1, p2, p3); } opt.transform(); vertexList.Add(opt); } } } } // nothing was added, check your shit if (vertexList.Count == 0) { return; } // find lowest and highest points float lowestX = float.PositiveInfinity; float highestX = float.NegativeInfinity; float lowestY = float.PositiveInfinity; float highestY = float.NegativeInfinity; float lowestZ = float.PositiveInfinity; float highestZ = float.NegativeInfinity; for (int i = 0; i < vertexList.Count; i++) { OptiMesh om = vertexList[i]; // x value if (om.lowestX < lowestX) { lowestX = om.lowestX; } if (om.highestX > highestX) { highestX = om.highestX; } // y value if (om.lowestY < lowestY) { lowestY = om.lowestY; } if (om.highestY > highestY) { highestY = om.highestY; } // z value if (om.lowestZ < lowestZ) { lowestZ = om.lowestZ; } if (om.highestZ > highestZ) { highestZ = om.highestZ; } } // offset our values by a little bit to ensure everything fits in grid perfectly /*lowestX -= 10.0f; * highestX += 10.0f; * lowestY -= 10.0f; * highestY += 10.0f; * lowestZ -= 10.0f; * highestZ += 10.0f;*/ // build the axis aligned box around the scanned level center = new Vector3((lowestX + highestX) / 2, (lowestY + highestY) / 2, (lowestZ + highestZ) / 2); length = Mathf.Abs(lowestX - highestX); width = Mathf.Abs(lowestZ - highestZ); height = Mathf.Abs(lowestY - highestY); int max = (int)Mathf.Max(Mathf.Max(length, width), height); Vector3 halfsize = new Vector3(max / 2, max / 2, max / 2); Vector3 offset = new Vector3( center.x - halfsize.x + (CELL_SIZE / 2), center.y - halfsize.y + (CELL_SIZE / 2), center.z - halfsize.z + (CELL_SIZE / 2)); //Debug.Log("Length: " + ((max + CELL_SIZE - 1) / CELL_SIZE) + " @ " + CELL_SIZE); grid.setup(max, CELL_SIZE, vertexList, offset); }
public void setup(int size, int cellSize, List <OptiMesh> data, Vector3 offset) { //grid = new GridDataPointer[0]; retList.Clear(); this.cellSize = cellSize; this.offset = offset; rows = (size + cellSize - 1) / cellSize; cols = (size + cellSize - 1) / cellSize; depth = (size + cellSize - 1) / cellSize; grid = new GridDataPointer[rows * cols * depth]; pxyz = new int[(rows * 3) * 2]; // fill with empty data for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { for (int z = 0; z < depth; z++) { int hash = x + rows * (y + depth * z); GridDataPointer gdp = ScriptableObject.CreateInstance <GridDataPointer>(); grid[hash] = gdp; } } } // let us populate our broadphase for (int i = 0; i < data.Count; i++) { OptiMesh om = data[i]; TriangleData[] tri = om.getTriangleData(); for (int j = 0; j < tri.Length; j++) { Vector3 center = tri[j].getTransCenter() - offset; // map our coordinates int topLeftX = Mathf.Max(0, Mathf.FloorToInt(center.x / cellSize)); int topLeftY = Mathf.Max(0, Mathf.FloorToInt(center.y / cellSize)); int topLeftZ = Mathf.Max(0, Mathf.FloorToInt(center.z / cellSize)); int bottomRightX = Mathf.Min(cols - 1, Mathf.CeilToInt((center.x + tri[j].getRadius() - 1) / cellSize)); int bottomRightY = Mathf.Min(rows - 1, Mathf.CeilToInt((center.y + tri[j].getRadius() - 1) / cellSize)); int bottomRightZ = Mathf.Min(depth - 1, Mathf.CeilToInt((center.z + tri[j].getRadius() - 1) / cellSize)); //Debug.Log("TOP" + topLeftX + " " + topLeftY + " " + topLeftZ); //Debug.Log("BOT" + bottomRightX + " " + bottomRightY + " " + bottomRightZ); for (int x = topLeftX; x <= bottomRightX; x++) { for (int y = topLeftY; y <= bottomRightY; y++) { for (int z = topLeftZ; z <= bottomRightZ; z++) { int hash = x + rows * (y + depth * z); grid[hash].dataPt.Add(tri[j]); } } } } } //for (int j = 0; j < tri.Length; j++) { //Vector3 triCent = tri[j].getTransCenter(); /*int cellX = (int)((triCent.x - offset.x) / cellSize); * int cellY = (int)((triCent.y - offset.y) / cellSize); * int cellZ = (int)((triCent.z - offset.z) / cellSize);*/ //Debug.Log("Adding to cell X: " + cellX + " Y: " + cellY + " Z: " + cellZ); //grid[cellX,cellY,cellZ].Add(new GridDataPointer(tri[j])); // do same with other triangle points //Vector3[] triTPt = tri[j].getTransformedPoints(); // get all triangles and convert them to grid-coordinate frame by applying offset /*Vector3 pt1 = new Vector3((triTPt[0].x - offset.x) / cellSize,(triTPt[0].y - offset.y) / cellSize,(triTPt[0].z - offset.z) / cellSize); * Vector3 pt2 = new Vector3((triTPt[1].x - offset.x) / cellSize,(triTPt[1].y - offset.y) / cellSize,(triTPt[1].z - offset.z) / cellSize); * Vector3 pt3 = new Vector3((triTPt[2].x - offset.x) / cellSize,(triTPt[2].y - offset.y) / cellSize,(triTPt[2].z - offset.z) / cellSize);*/ // plot all cells between point 1 and point 2 //int length1 = plotAll(pt1.x, pt1.y, pt1.z, pt2.x, pt2.y, pt2.z, pxyz); /*int length1 = plotAll(triTPt[0].x, triTPt[0].y, triTPt[0].z, triTPt[1].x, triTPt[1].y, triTPt[1].z, pxyz); * * if (length1 > 0) { * for (int k = 0; k < length1 - 3; k+=3) { * // add this triangle to grid locations * grid[pxyz[k],pxyz[k+1],pxyz[k+2]].Add(new GridDataPointer(tri[j])); * } * }*/ // plot all cells between point 2 and point 3 //int length2 = plotAll(pt2.x, pt2.y, pt2.z, pt3.x, pt3.y, pt3.z, pxyz); /*int length2 = plotAll(triTPt[1].x, triTPt[1].y, triTPt[1].z, triTPt[2].x, triTPt[2].y, triTPt[2].z, pxyz); * * if (length2 > 0) { * for (int k = 0; k < length2 - 3; k+=3) { * // add this triangle to grid locations * grid[pxyz[k],pxyz[k+1],pxyz[k+2]].Add(new GridDataPointer(tri[j])); * } * }*/ // plot all cells between point 3 and point 1 //int length3 = plotAll(pt3.x, pt3.y, pt3.z, pt1.x, pt1.y, pt1.z, pxyz); /*int length3 = plotAll(triTPt[2].x, triTPt[2].y, triTPt[2].z, triTPt[0].x, triTPt[0].y, triTPt[0].z, pxyz); * * if (length3 > 0) { * for (int k = 0; k < length3 - 3; k+=3) { * // add this triangle to grid locations * grid[pxyz[k],pxyz[k+1],pxyz[k+2]].Add(new GridDataPointer(tri[j])); * } * }*/ /*for (int k = 0; k < triTPt.Length; k++) { * cellX = (int)((triTPt[k].x - offset.x) / cellSize); * cellY = (int)((triTPt[k].y - offset.y) / cellSize); * cellZ = (int)((triTPt[k].z - offset.z) / cellSize); * * grid[cellX,cellY,cellZ].Add(new GridDataPointer(tri[j])); * }*/ //} }
void OnDrawGizmos() { Vector3 gizmoSize = new Vector3(0.2f, 0.2f, 0.2f); if (gridGizmosEnabled && vertexList.Count > 0) { float max = Mathf.Max(Mathf.Max(length, width), height); int rows = (int)((max + CELL_SIZE - 1) / CELL_SIZE); Vector3 halfsize = new Vector3(max / 2, max / 2, max / 2); Vector3 offset = new Vector3( center.x - halfsize.x + (CELL_SIZE / 2), center.y - halfsize.y + (CELL_SIZE / 2), center.z - halfsize.z + (CELL_SIZE / 2)); for (int x = 0; x < rows; x++) { for (int y = 0; y < rows; y++) { for (int z = 0; z < rows; z++) { Vector3 location = new Vector3( (x * CELL_SIZE) + offset.x, (y * CELL_SIZE) + offset.y, (z * CELL_SIZE) + offset.z); Gizmos.color = new Color(0, 0, 0, 0.05f); Gizmos.DrawWireCube(location, new Vector3(CELL_SIZE, CELL_SIZE, CELL_SIZE)); } } } } if (gizmosEnabled && vertexList.Count > 0) { for (int i = 0; i < vertexList.Count; i++) { OptiMesh ms = vertexList[i]; TriangleData[] dat = ms.getTriangleData(); for (int j = 0; j < dat.Length; j++) { Vector3[] tPoints = dat[j].getTransformedPoints(); Vector3 tCenter = dat[j].getTransCenter(); Gizmos.color = new Color(0, 1, 0, 1); Gizmos.DrawCube(tCenter, gizmoSize); Gizmos.color = new Color(1, 0, 0, 1); Gizmos.DrawCube(tPoints[0], gizmoSize); Gizmos.DrawCube(tPoints[1], gizmoSize); Gizmos.DrawCube(tPoints[2], gizmoSize); Gizmos.color = new Color(0, 0, 1, 1); Gizmos.DrawLine(tPoints[0], tPoints[1]); Gizmos.DrawLine(tPoints[1], tPoints[2]); Gizmos.DrawLine(tPoints[2], tPoints[0]); } } } }