예제 #1
0
    public void InitLightMesh(IEnumerable <WallController> wallControllers)
    {
        _mesh = GetComponent <MeshFilter>().mesh;

        var            vertices2d         = new List <Vector2>();
        GameObject     lastHitWall        = null;
        WallController lastWallController = null;
        EdgeKind       lastHitEdgeKind    = EdgeKind.None;
        Vector3        lastHitPointLocal  = new Vector3();
        Vector3        lastHitPointWorld  = new Vector3();

        DrawRaycast(transform.position, wallControllers);

        float angle = 0;

        for (int i = 0; i < _raysToShoot; i++)
        {
            var x = Mathf.Sin(angle);
            var y = Mathf.Cos(angle);
            angle -= 2 * Mathf.PI / _raysToShoot;

            Vector3      dir = new Vector3(x, y, 0);
            RaycastHit2D hit;
            hit = Physics2D.Raycast(transform.position, dir, _distance, WallLayerMask);
            if (hit.collider != null)
            {
                Vector3 curHitPointWorld = hit.point;
                Vector3 curHitPointLocal = transform.InverseTransformPoint(curHitPointWorld);

                WallController curWallController = hit.collider.GetComponent <WallController>();
                EdgeKind       curHitEdgeKind    = curWallController.GetEdgeKind(curHitPointWorld);

                if (curHitEdgeKind == EdgeKind.None)
                {
                    //TODO this shouldn't happen!! this happens with all the points close to an intersecting point between two edges
                    //that's why the edges don't close properly

                    lastHitPointLocal = curHitPointLocal;
                    continue;

                    //draw points on if on no edge
                    //Debug.DrawLine(transform.position, hit.point, Color.white, 180);
                    //curWallController.DrawEdges();
                }

                if (lastHitWall == null)
                {
                    lastHitWall = hit.collider.gameObject;
                }
                else if (lastHitWall != hit.collider.gameObject || curHitEdgeKind != lastHitEdgeKind)
                {
                    //always add first and last hitpoint on the same wall to form an edge

                    //add last hit point
                    vertices2d.Add(lastHitPointLocal);

                    lastHitWall = hit.collider.gameObject;

                    //add current hit point
                    vertices2d.Add(curHitPointLocal);

                    AddWallHit(lastWallController, lastHitEdgeKind, lastHitPointWorld);

                    bool isCurWallParent = GetComponentInParent <WallController>() == curWallController;
                    if (isCurWallParent)
                    {
                        var curEdge = curWallController.GetEdge(curHitEdgeKind);
                        AddWallHit(curWallController, curHitEdgeKind, curEdge.Start);
                        AddWallHit(curWallController, curHitEdgeKind, curEdge.End);

                        _curentlyIgnoredWall = curWallController;
                    }
                    else
                    {
                        AddWallHit(curWallController, curHitEdgeKind, curHitPointWorld);
                    }
                }

                lastHitPointLocal = curHitPointLocal;
                lastHitPointWorld = curHitPointWorld;

                lastHitEdgeKind    = curHitEdgeKind;
                lastWallController = curWallController;
            }
            else
            {
                var tmp = transform.InverseTransformPoint(transform.position + dir);
                lastHitPointLocal = new Vector2(tmp.x, tmp.y);
                vertices2d.Add(lastHitPointLocal);
            }
        }
        vertices2d.Add(lastHitPointLocal);

        // build mesh
        List <Vector3> newVertices = new List <Vector3>();

        foreach (var curPos in vertices2d)
        {
            newVertices.Add(new Vector3(curPos.x, curPos.y, 0));
        }

        var triangles = new int[newVertices.Count * 3];

        // triangle list
        int j = -1;

        for (int n = 0; n < triangles.Length - 3; n += 3)
        {
            j++;
            triangles[n] = newVertices.Count - 1;
            if (j >= newVertices.Count)
            {
                triangles[n + 1] = 0;
            }
            else
            {
                triangles[n + 1] = j + 1;
            }
            triangles[n + 2] = j;
        }
        j++;

        // central point
        newVertices[newVertices.Count - 1] = new Vector3(0, 0, 0);
        triangles[triangles.Length - 3]    = newVertices.Count - 1;
        triangles[triangles.Length - 2]    = 0;
        triangles[triangles.Length - 1]    = j - 1;

        // Create the mesh
        _mesh.vertices  = newVertices.ToArray();
        _mesh.triangles = triangles;
        _mesh.uv        = new Vector2[newVertices.Count];

        CloseWallHitContainers();
    }