float CalculateEdgeCost(PseudoGridCell src, PseudoGridCell tgt)
 {
     switch(edgeCostAlgorithm) {
         case EdgeCostAlgorithm.EUCLIDEAN_DISTANCE:
             return Vector3.Distance(tgt.transform.position,
                 src.transform.position);
         case EdgeCostAlgorithm.ONE_PLUS_POS_SLOPE:
             return 1.0f + Mathf.Max(0f,
                 Vector3.Dot((tgt.transform.position - src.transform.position),
                     transform.up));
         case EdgeCostAlgorithm.ONE:
             break;
     }
     return 1.0f;
 }
Example #2
0
    public override NavMeshNode Quantize(Vector3 pos)
    {
        // FIXME this is slow
        float          minDist = float.PositiveInfinity;
        PseudoGridCell nearest = null;

        foreach (PseudoGridCell cell in cells)
        {
            float dist = (pos - cell.transform.position).sqrMagnitude;
            if (dist < minDist)
            {
                nearest = cell;
                minDist = dist;
            }
        }
        return(nearest);
    }
Example #3
0
    float CalculateEdgeCost(PseudoGridCell src, PseudoGridCell tgt)
    {
        switch (edgeCostAlgorithm)
        {
        case EdgeCostAlgorithm.EUCLIDEAN_DISTANCE:
            return(Vector3.Distance(tgt.transform.position,
                                    src.transform.position));

        case EdgeCostAlgorithm.ONE_PLUS_POS_SLOPE:
            return(1.0f + Mathf.Max(0f,
                                    Vector3.Dot((tgt.transform.position - src.transform.position),
                                                transform.up)));

        case EdgeCostAlgorithm.ONE:
            break;
        }
        return(1.0f);
    }
Example #4
0
    public void FindCells()
    {
        List <GameObject> del = new List <GameObject>();

        foreach (Transform child in transform)
        {
            del.Add(child.gameObject);
        }

        foreach (GameObject obj in del)
        {
            DestroyImmediate(obj);
        }

        Sample sampler = null;

        switch (samplingType)
        {
        case SamplerType.CENTER: sampler = SampleCenter; break;

        case SamplerType.CORNERS_AVG: sampler = SampleCornersAvg; break;

        case SamplerType.CORNERS_MIN: sampler = SampleCornersMin; break;

        case SamplerType.CORNERS_MAX: sampler = SampleCornersMax; break;

        case SamplerType.MONTE_CARLO: sampler = SampleMonteCarlo; break;
        }
        float   xSize     = transform.localScale.x / xRes;
        float   ySize     = transform.localScale.z / yRes;
        float   thickness = transform.localScale.y * 0.1f;
        float   xOff      = xSize * 0.5f;
        float   yOff      = ySize * 0.5f;
        Vector3 down      = transform.up * -transform.localScale.y;
        Vector3 top       = Vector3.up * transform.localScale.y * 0.5f;
        Vector3 scale     = new Vector3(xSize, thickness, ySize);
        Vector3 start     = new Vector3(-xOff * xRes + xOff, 0.0f, -yOff * yRes + yOff);

        float localMaxHeight = maxHeight / transform.localScale.y;

        PseudoGridCell[,] cells = new PseudoGridCell[yRes, xRes];
        // Node creation pass
        for (int y = 0; y < yRes; y++)
        {
            for (int x = 0; x < xRes; x++)
            {
                Vector3 rayPos = transform.position + transform.rotation *
                                 (new Vector3(xSize * x, 0f, ySize * y) + start + top);
                Vector3 pos = Vector3.zero;
                if (!sampler(rayPos, down, out pos) && noHitNoCell)
                {
                    continue;
                }
                Vector3 localPos = transform.InverseTransformPoint(pos);
                if (localPos.y + 0.5f > localMaxHeight)
                {
                    continue;
                }
                GameObject cell = new GameObject("Cell (" + x + "," + y + ")");
                cell.transform.position   = pos;
                cell.transform.rotation   = transform.rotation;
                cell.transform.parent     = transform;
                cell.transform.localScale = scale;
                cell.gameObject.layer     = gameObject.layer;
                BoxCollider box = cell.AddComponent <BoxCollider>();
                box.isTrigger = true;
                Vector3 s = transform.localScale;
                box.size    = new Vector3(1.0f / s.x, 1.0f / s.y, 1.0f / s.z);
                cells[y, x] = cell.AddComponent <PseudoGridCell>();
            }
        }

        // Edge creation pass
        List <GameObjectEdge> edges = new List <GameObjectEdge>();

        for (int y = 0; y < yRes; y++)
        {
            for (int x = 0; x < xRes; x++)
            {
                edges.Clear();
                PseudoGridCell src = cells[y, x];
                if (src == null)
                {
                    continue;
                }
                for (int dy = -1; dy <= 1; dy++)
                {
                    for (int dx = -1; dx <= 1; dx++)
                    {
                        if (gridType == GridType.FOUR_GRID &&
                            Mathf.Abs(dx) + Mathf.Abs(dy) >= 2)
                        {
                            continue;
                        }
                        int x2 = x + dx, y2 = y + dy;
                        // Skip the center
                        if ((dx == 0 && dy == 0) || x2 < 0 || x2 >= cells.GetLength(1) ||
                            y2 < 0 || y2 >= cells.GetLength(0))
                        {
                            // TODO add 4-/8- criteria
                            continue;
                        }
                        PseudoGridCell dest = cells[y2, x2];
                        if (dest == null)
                        {
                            continue;
                        }
                        Vector3 diff        = dest.transform.position - src.transform.position;
                        float   slope       = Mathf.Abs(Vector3.Dot(diff, transform.up));
                        if (slope < maxSlope)
                        {
                            edges.Add(new GameObjectEdge(dest,
                                                         CalculateEdgeCost(src, dest)));
                        }
                    }
                }
                src.edges = edges.ToArray();
            }
        }
        if (removeOrphans)
        {
            for (int y = 0; y < yRes; y++)
            {
                for (int x = 0; x < xRes; x++)
                {
                    if (cells[y, x] == null)
                    {
                        continue;
                    }
                    if (cells[y, x].edges.Length == 0)
                    {
                        DestroyImmediate(cells[y, x]);
                    }
                }
            }
        }
    }
    public void FindCells()
    {
        List<GameObject> del = new List<GameObject>();
        foreach(Transform child in transform) {
            del.Add(child.gameObject);
        }

        foreach(GameObject obj in del) {
            DestroyImmediate(obj);
        }

        Sample sampler = null;
        switch(samplingType) {
            case SamplerType.CENTER: sampler = SampleCenter; break;
            case SamplerType.CORNERS_AVG: sampler = SampleCornersAvg; break;
            case SamplerType.CORNERS_MIN: sampler = SampleCornersMin; break;
            case SamplerType.CORNERS_MAX: sampler = SampleCornersMax; break;
            case SamplerType.MONTE_CARLO: sampler = SampleMonteCarlo; break;
        }
        float xSize = transform.localScale.x / xRes;
        float ySize = transform.localScale.z / yRes;
        float thickness = transform.localScale.y * 0.1f;
        float xOff = xSize * 0.5f;
        float yOff = ySize * 0.5f;
        Vector3 down = transform.up * -transform.localScale.y;
        Vector3 top = Vector3.up * transform.localScale.y * 0.5f;
        Vector3 scale = new Vector3(xSize, thickness, ySize);
        Vector3 start = new Vector3(-xOff * xRes + xOff, 0.0f, -yOff * yRes + yOff);

        float localMaxHeight = maxHeight / transform.localScale.y;
        PseudoGridCell[,] cells = new PseudoGridCell[yRes, xRes];
        // Node creation pass
        for(int y = 0; y < yRes ; y ++) {
            for(int x = 0; x < xRes ; x ++) {
                Vector3 rayPos = transform.position + transform.rotation *
                    (new Vector3(xSize * x, 0f, ySize * y) + start + top);
                Vector3 pos = Vector3.zero;
                if(!sampler(rayPos, down, out pos) && noHitNoCell) {
                    continue;
                }
                Vector3 localPos = transform.InverseTransformPoint(pos);
                if(localPos.y + 0.5f > localMaxHeight) {
                    continue;
                }
                GameObject cell = new GameObject("Cell (" + x + "," + y + ")");
                cell.transform.position = pos;
                cell.transform.rotation = transform.rotation;
                cell.transform.parent = transform;
                cell.transform.localScale = scale;
                cell.gameObject.layer = gameObject.layer;
                BoxCollider box = cell.AddComponent<BoxCollider>();
                box.isTrigger = true;
                Vector3 s = transform.localScale;
                box.size = new Vector3(1.0f/s.x, 1.0f/s.y, 1.0f/s.z);
                cells[y, x] = cell.AddComponent<PseudoGridCell>();
            }
        }

        // Edge creation pass
        List<GameObjectEdge> edges = new List<GameObjectEdge>();
        for(int y = 0; y < yRes ; y ++) {
            for(int x = 0; x < xRes ; x ++) {
                edges.Clear();
                PseudoGridCell src = cells[y, x];
                if(src == null) {
                    continue;
                }
                for(int dy = -1; dy <= 1; dy ++) {
                    for(int dx = -1; dx <= 1; dx ++) {
                        if(gridType == GridType.FOUR_GRID
                            && Mathf.Abs(dx) + Mathf.Abs(dy) >= 2)
                        {
                            continue;
                        }
                        int x2 = x + dx, y2 = y + dy;
                        // Skip the center
                        if((dx == 0 && dy == 0) || x2 < 0 || x2 >= cells.GetLength(1)
                            || y2 < 0 || y2 >= cells.GetLength(0))
                        {
                            // TODO add 4-/8- criteria
                            continue;
                        }
                        PseudoGridCell dest = cells[y2, x2];
                        if(dest == null) {
                            continue;
                        }
                        Vector3 diff = dest.transform.position - src.transform.position;
                        float slope = Mathf.Abs(Vector3.Dot(diff, transform.up));
                        if(slope < maxSlope) {
                            edges.Add(new GameObjectEdge(dest,
                                CalculateEdgeCost(src, dest)));
                        }
                    }
                }
                src.edges = edges.ToArray();
            }
        }
        if(removeOrphans) {
            for(int y = 0; y < yRes ; y ++) {
                for(int x = 0; x < xRes ; x ++) {
                    if(cells[y, x] == null) {
                        continue;
                    }
                    if(cells[y, x].edges.Length == 0) {
                        DestroyImmediate(cells[y, x]);
                    }
                }
            }
        }
    }