Exemplo n.º 1
0
    void Start()
    {
        //-- Set Layer mask --//
        setLayerMask();

        TablaSenoCoseno.initSenCos();

        Rebuild();

        getAllMeshes();
    }
Exemplo n.º 2
0
        // Called at beginning of script execution
        void Start()
        {
            TablaSenoCoseno.initSenCos();

            //Debug.Log((int) LayerMask.NameToLayer("Default"));


            //-- Step 1: obtain all active meshes in the scene --//
            //---------------------------------------------------------------------//

            MeshFilter meshFilter = (MeshFilter)gameObject.AddComponent(typeof(MeshFilter));                                            // Add a Mesh Filter component to the light game object so it can take on a form	// Add a Mesh Renderer component to the light game object so the form can become visible

            //gameObject.name = "2DLight";
            //renderer.material.shader = Shader.Find ("Transparent/Diffuse");							// Find the specified type of material shader
            meshRenderer.sharedMaterial = lightMaterial;                                                                                                                // Add this texture
            lightMesh       = new Mesh();                                                                                                                               // create a new mesh for our light mesh
            meshFilter.mesh = lightMesh;                                                                                                                                // Set this newly created mesh to the mesh filter
            lightMesh.name  = "Light Mesh";                                                                                                                             // Give it a name
            lightMesh.MarkDynamic();
        }
Exemplo n.º 3
0
    void setLight()
    {
        bool sortAngles = false;

        //objectsReached.Clear(); // sweep all last objects reached

        allVertices.Clear();        // Since these lists are populated every frame, clear them first to prevent overpopulation



        //--Step 2: Obtain vertices for each mesh --//
        //---------------------------------------------------------------------//

        // las siguientes variables usadas para arregla bug de ordenamiento cuando
        // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4)
        bool  lows     = false;   // check si hay menores a -0.5
        bool  his      = false;   // check si hay mayores a 2.0
        float magRange = 0.15f;

        // -- CLEAR TEMPVERTS --// ver 1.1.0v
        tempVerts.Clear();



        // reset counter vertices;
        vertexWorking = 0;

        for (int m = 0; m < allMeshes.Length; m++)
        {
            //for (int m = 0; m < 1; m++) {
            tempVerts.Clear();
            PolygonCollider2D mf = allMeshes[m];

            // -- DELETE CASTER MANUALLY --//
            if (mf == null)
            {
                // se ha eliminado un caster
                reloadMeshes = true;
                return;
            }

            // las siguientes variables usadas para arregla bug de ordenamiento cuando
            // los angulos calcuados se encuentran en cuadrantes mixtos (1 y 4)
            lows = false;                         // check si hay menores a -0.5
            his  = false;                         // check si hay mayores a 2.0

            if (notifyGameObjectsReached == true) // work only in neccesary cases -- optimization ver 1.1.0--
            {
                objReached.Clear();
            }



            // Method for check every point in each collider
            // if is closer from light, any point, then add collider to work.

            bool mfInWorks = false;

            for (int i = 0; i < mf.GetTotalPointCount(); i++)
            {
                Vector3 worldPoint = mf.transform.TransformPoint(mf.points[i]);
                if ((worldPoint - gameObject.transform.position).sqrMagnitude <= lightRadius * lightRadius)
                {
                    // -- Here check if first collider point is in Z=0 pos --// for depth position
                    if (flipXYtoXZ)
                    {
                        if (mf.transform.TransformPoint(mf.points[i]).y == gameObject.transform.position.y)
                        {
                            mfInWorks = true;
                            i         = mf.GetTotalPointCount();
                        }
                    }
                    else
                    {
                        if (mf.transform.TransformPoint(mf.points[i]).z == gameObject.transform.position.z)
                        {
                            mfInWorks = true;
                            i         = mf.GetTotalPointCount();
                        }
                    }
                }
            }



            if (mfInWorks == true)

            {
                if (((1 << mf.transform.gameObject.layer) & Layer) != 0)
                {
                    // Add all vertices that interact
                    vertexWorking += mf.GetTotalPointCount();

                    for (int i = 0; i < mf.GetTotalPointCount(); i++)                                                                                      // ...and for ever vertex we have of each mesh filter...

                    {
                        verts v = new verts();

                        Vector2 worldPoint = (Vector2)mf.transform.TransformPoint(mf.points[i]);
                        Vector2 to         = worldPoint - (Vector2)transform.position;

                        // Reforma fecha 24/09/2014 (ultimo argumento lighradius X worldPoint.magnitude (expensivo pero preciso))
                        RaycastHit2D ray = Physics2D.Raycast(transform.position, to, to.magnitude, Layer);


                        if (ray)
                        {
                            v.pos = ray.point;
                            //v.pos = new Vector3(v.pos.x,v.pos.y,transform.position.z); // add depth
                            //Debug.Log(v.pos + "world");

                            if (worldPoint.sqrMagnitude >= (ray.point.sqrMagnitude - magRange) && worldPoint.sqrMagnitude <= (ray.point.sqrMagnitude + magRange))
                            {
                                v.endpoint = true;
                            }

                            if (notifyGameObjectsReached == true)                             // work only in neccesary cases -- optimization ver 1.1.0--
                            {
                                if (360 != Mathf.RoundToInt(RangeAngle))
                                {
                                    if (Vector3.Angle(transform.InverseTransformPoint(v.pos), Vector3.up) < RangeAngle * .5f)                                           // Light angle restriction
                                    //-- GO reached --> adding to mail list --//
                                    {
                                        objReached.Add(ray.collider.gameObject.transform.parent.gameObject);
                                    }
                                }
                                else
                                {
                                    //-- GO reached --> adding to main list --//
                                    objReached.Add(ray.collider.gameObject.transform.parent.gameObject);
                                }
                            }
                        }
                        else
                        {
                            v.pos      = worldPoint;
                            v.endpoint = true;
                        }



                        //--Convert To local space for build mesh (mesh craft only in local vertex)
                        v.pos = new Vector3(v.pos.x, v.pos.y, gameObject.transform.position.z);
                        if (debugLines == true)
                        {
                            Debug.DrawLine(transform.position, v.pos, Color.white);
                        }

                        v.pos = transform.InverseTransformPoint(v.pos);
                        //--Calculate angle
                        v.angle = getVectorAngle(true, v.pos.x, v.pos.y);



                        // -- bookmark if an angle is lower than 0 or higher than 2f --//
                        //-- helper method for fix bug on shape located in 2 or more quadrants
                        if (v.angle < 0f)
                        {
                            lows = true;
                        }

                        if (v.angle > 2f)
                        {
                            his = true;
                        }


                        //--Add verts to the main array
                        //-- AVOID EXTRA CALCULOUS OF Vector3.angle --//

                        if (360 != Mathf.RoundToInt(RangeAngle))
                        {
                            if (Vector3.Angle(v.pos, Vector3.up) < RangeAngle * .5f)                                    // Light angle restriction
                            {
                                if ((v.pos).sqrMagnitude <= lightRadius * lightRadius)
                                {
                                    tempVerts.Add(v);
                                    if (debugLines == true)
                                    {
                                        Debug.DrawLine(transform.position, transform.TransformPoint(v.pos), Color.white);
                                    }
                                }
                            }
                        }
                        else
                        {
                            if ((v.pos).sqrMagnitude <= lightRadius * lightRadius)
                            {
                                tempVerts.Add(v);
                                if (debugLines == true)
                                {
                                    Debug.DrawLine(transform.position, transform.TransformPoint(v.pos), Color.white);
                                }
                            }
                        }



                        if (sortAngles == false)
                        {
                            sortAngles = true;
                        }
                    }
                }



                // Indentify the endpoints (left and right)
                if (tempVerts.Count > 0)
                {
                    sortList(tempVerts);                     // sort first

                    int posLowAngle  = 0;                    // save the indice of left ray
                    int posHighAngle = 0;                    // same last in right side

                    //Debug.Log(lows + " " + his);

                    if (his == true && lows == true)                      //-- FIX BUG OF SORTING CUANDRANT 1-4 --//

                    {
                        if (tempVerts.Count > 1)
                        {
                            float lowestAngle  = -1f;                           //tempVerts[0].angle; // init with first data
                            float highestAngle = tempVerts[0].angle;


                            for (int d = 0; d < tempVerts.Count; d++)
                            {
                                if (tempVerts[d].angle <1f && tempVerts[d].angle> lowestAngle)
                                {
                                    lowestAngle = tempVerts[d].angle;
                                    posLowAngle = d;
                                }

                                if (tempVerts[d].angle > 2f && tempVerts[d].angle < highestAngle)
                                {
                                    highestAngle = tempVerts[d].angle;
                                    posHighAngle = d;
                                }
                            }
                        }
                    }
                    else
                    {
                        //-- convencional position of ray points
                        // save the indice of left ray
                        posLowAngle  = 0;
                        posHighAngle = tempVerts.Count - 1;
                    }

                    //-- fix error when sort vertex with only 1 tempvert AND rangeAngle < 360 --//
                    // --------   ver 1.0.7    ---------//
                    //--------------------------------------------------------------------------//
                    int endPointLimit = 2;

                    if (tempVerts.Count == 1)
                    {
                        endPointLimit         = 1;
                        tempVerts[0].location = 7;                         // --lucky se7en
                        // --------------------------------------------------------------------------------------------- //
                        // --------------------------------------------------------------------------------------------- //
                    }
                    else
                    {
                        // -- more than one... --//
                        tempVerts[posLowAngle].location  = 1;                        // right
                        tempVerts[posHighAngle].location = -1;                       // left
                    }



                    //--Add vertices to the main meshes vertexes--//
                    if (intelliderConvex == true && endPointLimit > 1)
                    {
                        allVertices.Add(tempVerts[posLowAngle]);
                        allVertices.Add(tempVerts[posHighAngle]);
                    }
                    else
                    {
                        allVertices.AddRange(tempVerts);
                    }



                    // -- r ==0 --> right ray
                    // -- r ==1 --> left ray


                    for (int r = 0; r < endPointLimit; r++)
                    {
                        //-- Cast a ray in same direction continuos mode, start a last point of last ray --//
                        Vector3 fromCast   = new Vector3();
                        bool    isEndpoint = false;

                        if (r == 0)
                        {
                            fromCast   = transform.TransformPoint(tempVerts[posLowAngle].pos);
                            isEndpoint = tempVerts[posLowAngle].endpoint;
                        }
                        else if (r == 1)
                        {
                            fromCast   = transform.TransformPoint(tempVerts[posHighAngle].pos);
                            isEndpoint = tempVerts[posHighAngle].endpoint;
                        }



                        if (isEndpoint == true)
                        {
                            Vector2 from = (Vector2)fromCast;
                            Vector2 dir  = (from - (Vector2)transform.position);


                            from += (dir * .001f);


                            float mag = (lightRadius);                            // - fromCast.magnitude;
                            //float mag = fromCast.magnitude;
                            RaycastHit2D rayCont = Physics2D.Raycast(from, dir, mag, Layer);



                            Vector2 hitp;
                            if (rayCont)
                            {
                                //-- IMPROVED REACHED OBJECTS --// VERSION 1.1.2
                                hitp = rayCont.point;                                   //world p

                                /*
                                 * if(notifyGameObjectsReached == true){ // work only in neccesary cases -- optimization ver 1.1.0--
                                 *      if((hitp - (Vector2)transform.position ).sqrMagnitude < (lightRadius * lightRadius)){
                                 *              // Version 1.3.0
                                 *              if(360 != Mathf.RoundToInt(RangeAngle)){
                                 *                      if (Vector3.Angle(transform.InverseTransformPoint(hitp), Vector3.up) < RangeAngle*.5f) {	// Light angle restriction
                                 *                              //-- GO reached --> adding to mail list --//
                                 *                              //objReached.Add(rayCont.collider.gameObject.transform.parent.gameObject);
                                 *                              Debug.Log("caca");
                                 *                      }
                                 *              }else{
                                 *                      //-- GO reached --> adding to mail list --//
                                 *                      //objReached.Add(rayCont.collider.gameObject.transform.parent.gameObject);
                                 *              }
                                 *      }
                                 * }
                                 */

                                if (debugLines == true)
                                {
                                    Debug.DrawLine(fromCast, new Vector3(hitp.x, hitp.y, transform.position.z), Color.green);
                                }
                            }
                            else
                            {
                                //-- FIX ERROR WEIRD MESH WHEN ENDPOINT COLLIDE OUTSIDE RADIUS VERSION 1.1.2 --//
                                //-- NEW INSTANCE OF DIR VECTOR3 ADDED --//
                                Vector2 newDir = transform.InverseTransformDirection(dir);                                      //local p
                                hitp = (Vector2)transform.TransformPoint(newDir.normalized * mag);                              //world p

                                if (debugLines == true)
                                {
                                    Debug.DrawLine(fromCast, new Vector3(hitp.x, hitp.y, transform.position.z), Color.blue);
                                }
                            }


                            // --- VER 1.0.6 -- //
                            //--- this fix magnitud of end point ray (green) ---//

                            if ((hitp - (Vector2)transform.position).sqrMagnitude > (lightRadius * lightRadius))
                            {
                                //-- FIX ERROR WEIRD MESH WHEN ENDPOINT COLLIDE OUTSIDE RADIUS VERSION 1.1.2  --//
                                dir  = (Vector2)transform.InverseTransformDirection(dir);                                       //local p
                                hitp = (Vector2)transform.TransformPoint(dir.normalized * mag);
                            }


                            Vector3 v3Hitp = new Vector3(hitp.x, hitp.y, transform.position.z);
                            verts   vL     = new verts();
                            vL.pos   = (Vector3)transform.InverseTransformPoint(v3Hitp);
                            vL.angle = getVectorAngle(true, vL.pos.x, vL.pos.y);
                            allVertices.Add(vL);
                        }
                    }
                }

                if (notifyGameObjectsReached == true)
                {
                    //notify if not null
                    if (OnReachedGameObjects != null)
                    {
                        OnReachedGameObjects(objReached.ToArray());
                    }
                }
            }
        }



        //--Step 3: Generate vectors for light cast--//
        //---------------------------------------------------------------------//

        int theta = 0;
        //		int amount = 360 / lightSegments;
        float amount = RangeAngle / lightSegments;



        for (int i = 0; i <= lightSegments; i++)
        {
            theta = Mathf.RoundToInt(amount * i);
            if (theta >= 360)
            {
                theta = 0;
            }

            verts v = new verts();

            // Initialize static tables
            TablaSenoCoseno.initSenCos();

            v.pos = new Vector3((TablaSenoCoseno.SenArray[theta]), (TablaSenoCoseno.CosArray[theta]), 0);             // in dregrees (previous calculate)

            Quaternion quat = Quaternion.AngleAxis(RangeAngle * .5f + transform.eulerAngles.z, Vector3.forward);
            v.pos = quat * v.pos;

            v.pos *= lightRadius;
            v.pos += transform.position;

            Vector3 to = v.pos - transform.position;
            to.z = gameObject.transform.position.z;


            RaycastHit2D ray = Physics2D.Raycast(transform.position, to, lightRadius, Layer);
            //Debug.DrawLine(transform.position, to, Color.blue);

            if (ray && (to.z == transform.position.z))
            {
                v.pos   = transform.InverseTransformPoint(ray.point);
                v.pos   = new Vector3(v.pos.x, v.pos.y, 0);
                v.angle = getVectorAngle(true, v.pos.x, v.pos.y);
                allVertices.Add(v);
            }
            else
            {
                v.pos   = transform.InverseTransformPoint(v.pos);
                v.angle = getVectorAngle(true, v.pos.x, v.pos.y);               // store angle without object rotation -> consistency for sorting
                allVertices.Add(v);
            }
            if (debugLines == true)
            {
                Debug.DrawLine(transform.position, transform.TransformPoint(new Vector3(v.pos.x, v.pos.y, 0)), Color.cyan);
            }
        }



        //-- Step 4: Sort each vertice by angle (along sweep ray 0 - 2PI)--//
        //---------------------------------------------------------------------//
        //if (sortAngles == true) {
        sortList(allVertices);
        //}
        //-----------------------------------------------------------------------------


        //--auxiliar step (change order vertices close to light first in position when has same direction) --//
        float rangeAngleComparision = 0.0001f;

        for (int i = 0; i < allVertices.Count; i += 1)
        {
            verts uno = allVertices[i];
            verts dos = allVertices[(i + 1) % allVertices.Count];

            // -- Comparo el angulo local de cada vertex y decido si tengo que hacer un exchange-- //
            if (uno.angle >= (dos.angle - rangeAngleComparision) && uno.angle <= (dos.angle + rangeAngleComparision))
            {
                // -- FIX BUG 1.0.7 ( exchange when rangeAngle is less than 360)  -- //
                // ----------------------------------------------------------------- //

                if (uno.location == 7)
                {
                    //Debug.Log("7");
                    if (uno.angle <= allVertices[allVertices.Count / 2].angle)
                    {
                        uno.location = 1;
                    }
                    else
                    {
                        uno.location = -1;
                    }
                }
                if (dos.location == 7)
                {
                    //Debug.Log("7");
                    if (dos.angle <= allVertices[allVertices.Count / 2].angle)
                    {
                        dos.location = 1;
                    }
                    else
                    {
                        dos.location = -1;
                    }
                }

                //--------------------------------------------------------------------------//
                //--------------------------------------------------------------------------//


                if (dos.location == -1)                 // Right Ray

                {
                    if (uno.pos.sqrMagnitude > dos.pos.sqrMagnitude)
                    {
                        allVertices[i] = dos;
                        allVertices[(i + 1) % allVertices.Count] = uno;
                    }
                }


                // ALREADY DONE!!
                if (uno.location == 1)                 // Left Ray

                {
                    if (uno.pos.sqrMagnitude < dos.pos.sqrMagnitude)
                    {
                        allVertices[i] = dos;
                        allVertices[(i + 1) % allVertices.Count] = uno;
                    }
                }
            }
        }
    }