예제 #1
0
    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);
    }
예제 #2
0
    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]));
         * }*/
        //}
    }
예제 #3
0
    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]);
                }
            }
        }
    }