Ejemplo n.º 1
0
        private void sendEquidistentRays()
        {
            float theta  = (angledLight) ? angleFacingRad : 0;
            float amount = ((angledLight) ? angleLimRad : Mathf.PI * 2) / (float)lightSegments;

            for (int i = 0; i < lightSegments; i++)
            {
                LightInteractVertex vert = new LightInteractVertex();

                //Creates a position vector of magnitude lightRadius in the angle defined by this loop
                float sine   = (approximateTrigVals) ? FastTrigCalculator.SinRadApprox(theta) : Mathf.Sin(theta);
                float cosine = (approximateTrigVals) ? FastTrigCalculator.CosRadApprox(theta) : Mathf.Cos(theta);
                vert.positionRelToLight  = new Vector3(cosine, sine, 0);
                vert.positionRelToLight *= lightRadius;
                //Must save angle calculated by same fxn for every vert
                vert.angleRelToLight = FastTrigCalculator.getAngleTo(vert.positionRelToLight.x, vert.positionRelToLight.y, approximateTrigVals);
                //Now, send a ray from the lightsource to the position we just created
                RaycastHit2D ray = Physics2D.Raycast(transform.position, vert.positionRelToLight, lightRadius, interactionLayers);

                if (ray)
                {
                    //it will still have the same exact angle as before but just a new position
                    vert.positionRelToLight = transform.InverseTransformPoint(ray.point);
                }
                allVertices.Add(vert);
                if (drawEqRays && !uniformColoredSortOrder)
                {
                    Debug.DrawLine(transform.position, transform.TransformPoint(vert.positionRelToLight), Color.magenta);
                }

                theta = (theta + amount) % (Mathf.PI * 2);
            }
        }
Ejemplo n.º 2
0
        private List <LightInteractVertex> raycastAtCollider(PolygonCollider2D collider)
        {
            List <LightInteractVertex> thisCollider = new List <LightInteractVertex> ();

            for (int i = 0; i < collider.GetTotalPointCount(); i++)
            {
                LightInteractVertex vert = new LightInteractVertex();
                // The collider.points[i] vector contains positions relative to the collider itslef
                // We transform the point like this to bring it from colliderN.transform's locality to world locality
                Vector3 worldPoint = collider.transform.TransformPoint(collider.points[i]);
                Vector3 direction  = worldPoint - transform.position;                //Offset from worldPoint
                vert.angleRelToLight = FastTrigCalculator.getAngleTo(direction.x, direction.y, approximateTrigVals);

                //If we're using angled light and this point isn't in the angle, don't bother doing any of this
                if (angledLight && !withinRange(vert.angleRelToLight, angleFacingRad, angleFacingRad + angleLimRad))
                {
                    continue;
                }

                //TODO: consider doing this instead: float dist = Mathf.Sqrt(Mathf.Min (lightRadius*lightRadius, direction.sqrMagnitude));
                float        dist = direction.magnitude;
                RaycastHit2D ray  = Physics2D.Raycast(transform.position, direction, dist, interactionLayers);

                if (ray)                   //If this hit anything at all (it's possible to miss when a collider has a point further than lightradius but has one within lightradius
                {
                    if (transform.InverseTransformPoint(ray.point).sqrMagnitude > lightRadius * lightRadius)
                    {
                        vert.positionRelToLight = direction.normalized * lightRadius;
                    }
                    else
                    {
                        if (almostEquals(ray.point.sqrMagnitude, worldPoint.sqrMagnitude, 0.15f))
                        {
                            //very fast way of seeing if the point in the mesh was the point hit by the raycast
                            //if that's not the case, then we know this vertexNI blocks the path from light to colliderN.points[i]
                            vert.hitIntendedPolygon = true;
                        }
                        vert.positionRelToLight = transform.InverseTransformPoint(ray.point);
                    }
                }
                else
                {
                    //If we hit nothing, this is only because of floating point rounding error causing us to miss
                    //So we can simply assume that we did actually hit the corner
                    vert.positionRelToLight = (direction.sqrMagnitude > lightRadius * lightRadius) ? direction.normalized * lightRadius : direction;
                    vert.hitIntendedPolygon = true;
                }
                thisCollider.Add(vert);
                //We need the angle rel to collider for sorting, but vec3.angle gives only positive angles
                vert.angleRelToCollider = Vector3.Angle(thisCollider [0].positionRelToLight, vert.positionRelToLight);
                //Solution: use cross product.
                vert.angleRelToCollider = (Vector3.Cross(thisCollider [0].positionRelToLight, vert.positionRelToLight).z < 0) ? vert.angleRelToCollider : -vert.angleRelToCollider;
                if (drawDebugLines && !uniformColoredSortOrder)
                {
                    Debug.DrawLine(transform.position, transform.TransformPoint(vert.positionRelToLight), Color.white);
                }
            }
            return(thisCollider);
        }
Ejemplo n.º 3
0
        void Start()
        {
            if (calculateApproxTrigValsOnLoad)
            {
                //loads lots of default vals for trig ops
                FastTrigCalculator.memoize(loadedTrigValPrecision);
            }

            allVertices = new List <LightInteractVertex>();
            angleLimRad = degreeOfLightCast * Mathf.Deg2Rad;
            MeshFilter   meshFilter   = (MeshFilter)gameObject.AddComponent(typeof(MeshFilter));
            MeshRenderer meshRenderer = (MeshRenderer)gameObject.AddComponent(typeof(MeshRenderer));


            // For a MeshRenderer, sharedMaterial is a statically used material for all meshRendererers,
            // whereas 'material' is simply used by this instance of renderer,
            // so for performance-sensitive stuff like this, we use sharedMaterial and avoid updating individual materials
            meshRenderer.sharedMaterial = lightMaterial;

            //This creates the mesh, associates our meshfilter with it, and optimizes it for frequent changes
            lightMesh       = new Mesh();
            meshFilter.mesh = lightMesh;
            lightMesh.MarkDynamic();
        }
Ejemplo n.º 4
0
        /**
         * This function is sort of confusing, so to document:
         *
         *  We take the position (world coordinates) of the vertex on the edge of the polygon
         *  We take the direction from the light to the polygon
         *  Then, we fudge the location of that vertex by a bit in that same direction,
         *      and since that direction is the direction that got us there, if this is a corner,
         *      we will slip just slightly past the corner and see what is past it.
         *  We then raycast from that fudged point in the same direction by the amount
         *  that we can reach with our lightradius defined minus how far the vertex was
         *
         *  After that, we either hit something, and we can add that point, or we didn't,
         *  and we need to add the point at lightradius away from light in same direction
         */
        private void checkEdge(LightInteractVertex vert)
        {
            if (vert.hitIntendedPolygon)             //If it was obstructed at the very edge angles, we don't need to bother
            {
                Vector2 from = transform.TransformPoint(vert.positionRelToLight);
                Vector2 dir  = (Vector2)vert.positionRelToLight;
                Vector2 off  = dir * 0.01f;
                from += off;
                float        dist    = lightRadius - dir.magnitude;
                RaycastHit2D peekRay = Physics2D.Raycast(from, dir, dist, interactionLayers);

                Vector3 worldPointNewVert;

                LightInteractVertex vL = new LightInteractVertex();

                if (peekRay)
                {
                    //This means that fudging the edge very slightly made us hit another object which we want to shine light on
                    worldPointNewVert = peekRay.point;
                }
                else
                {
                    worldPointNewVert = from + dir.normalized * dist;
                }

                if (drawDebugLines && !uniformColoredSortOrder)
                {
                    Debug.DrawLine(from - off, worldPointNewVert, Color.green);
                }


                vL.positionRelToLight = transform.InverseTransformPoint(worldPointNewVert);
                vL.angleRelToLight    = FastTrigCalculator.getAngleTo(vL.positionRelToLight.x, vL.positionRelToLight.y, approximateTrigVals);
                allVertices.Add(vL);
            }
        }