コード例 #1
0
    // Update is called once per frame
    void Update()
    {
        mesh.Clear();

        Vector3[] objverts = sceneObjects[0].GetComponent <MeshFilter>().mesh.vertices;
        for (int i = 1; i < sceneObjects.Length; i++)
        {
            objverts = ConcatArrays(objverts, sceneObjects[i].GetComponent <MeshFilter>().mesh.vertices);
        }

        angledVerts[] angledverts = new angledVerts[(objverts.Length * 2)];
        Vector3[]     verts       = new Vector3[(objverts.Length * 2) + 1];
        Vector2[]     uvs         = new Vector2[(objverts.Length * 2) + 1];

        verts[0] = lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(this.transform.position);
        uvs[0]   = new Vector2(verts[0].x, verts[0].y);

        int h = 0;

        Vector3 myLoc = this.transform.position;

        for (int i = 0; i < sceneObjects.Length; i++)
        {
            Vector3[] mesh = sceneObjects[i].GetComponent <MeshFilter>().mesh.vertices;
            for (int j = 0; j < mesh.Length; j++)
            {
                Vector3    vertLoc = sceneObjects[i].transform.localToWorldMatrix.MultiplyPoint3x4(mesh[j]);
                RaycastHit hit, hit2;

                float angle1 = Mathf.Atan2((vertLoc.y - myLoc.y - offset), (vertLoc.x - myLoc.x - offset));
                float angle2 = Mathf.Atan2((vertLoc.y - myLoc.y + offset), (vertLoc.x - myLoc.x + offset));

                Physics.Raycast(myLoc, new Vector2(vertLoc.x - myLoc.x - offset, vertLoc.y - myLoc.y - offset), out hit, 100);
                Physics.Raycast(myLoc, new Vector2(vertLoc.x - myLoc.x + offset, vertLoc.y - myLoc.y + offset), out hit2, 100);
                Debug.DrawLine(myLoc, hit.point, Color.red);
                Debug.DrawLine(myLoc, hit2.point, Color.green);

                angledverts[(h * 2)].vert  = lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(hit.point);
                angledverts[(h * 2)].angle = angle1;
                angledverts[(h * 2)].uv    = new Vector2(angledverts[(h * 2)].vert.x, angledverts[(h * 2)].vert.y);

                angledverts[(h * 2) + 1].vert  = lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(hit2.point);
                angledverts[(h * 2) + 1].angle = angle2;
                angledverts[(h * 2) + 1].uv    = new Vector2(angledverts[(h * 2) + 1].vert.x, angledverts[(h * 2) + 1].vert.y);

                h++;
            }
        }

        System.Array.Sort(angledverts, delegate(angledVerts one, angledVerts two) {
            return(one.angle.CompareTo(two.angle));
        });

        for (int i = 0; i < angledverts.Length; i++)
        {
            verts[i + 1] = angledverts[i].vert;
            uvs[i + 1]   = angledverts[i].uv;
        }

        mesh.vertices = verts;

        for (int i = 0; i < uvs.Length; i++)
        {
            uvs[i] = new Vector2(uvs[i].x + .5f, uvs[i].y + .5f);
        }

        mesh.uv = uvs;

        int[] triangles = { 0, 1, verts.Length - 1 };

        for (int i = verts.Length - 1; i > 0; i--)
        {
            triangles = AddItemsToArray(triangles, 0, i, i - 1);
        }

        mesh.triangles = triangles;
    }
コード例 #2
0
    // Update is called once per frame
    void Update()
    {
        mesh.Clear(); //clears the mesh before changing it.

        // The next few lines create an array to store all vertices of all the scene objects that should react to the light.
        Vector3[] objverts = sceneObjects[0].GetComponent <MeshFilter>().mesh.vertices;
        for (int i = 1; i < sceneObjects.Length; i++)
        {
            objverts = ConcatArrays(objverts, sceneObjects[i].GetComponent <MeshFilter>().mesh.vertices);
        }

        //these lines (1) an array of structs which will be used to populate the light mesh and (2) the vertices and UVs to ultimately populate the mesh.
        // (the "*2" is because there are twice as many rays casted as vertices, and the "+1" because the first point in the mesh should be the center of the light source)
        angledVerts[] angleds = new angledVerts[(objverts.Length * 2)];
        Vector3[]     verts   = new Vector3[(objverts.Length * 2) + 1];
        Vector2[]     uvs     = new Vector2[(objverts.Length * 2) + 1];


        //Store the vertex location and UV of the center of the light source in the first locations of verts and uvs.
        verts[0] = lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(this.transform.position);
        uvs[0]   = new Vector2(lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(this.transform.position).x, lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(this.transform.position).y);

        int h = 0;                                                                                          //a constantly increasing int to use to calculate the current location in the angleds struct array.

        for (int j = 0; j < sceneObjects.Length; j++)                                                       //cycle through all scene objects.
        {
            for (int i = 0; i < sceneObjects[j].GetComponent <MeshFilter>().mesh.vertices.Length; i++)      //cycle through all vertices in the current scene object.
            {
                Vector3 me    = this.transform.position;                                                    // just to make the current position shorter to reference.
                Vector3 other = sceneObjects[j].transform.localToWorldMatrix.MultiplyPoint3x4(objverts[h]); //get the vertex location in world space coordinates.

                float angle1 = Mathf.Atan2(((other.y - me.y) - offset), ((other.x - me.x) - offset));       // calculate the angle of the two offsets, to be stored in the structs.
                float angle3 = Mathf.Atan2(((other.y - me.y) + offset), ((other.x - me.x) + offset));

                RaycastHit hit; //create and fire the two rays from the center of the light source in the direction of the vertex, with offsets.
                Physics.Raycast(transform.position, new Vector2((other.x - me.x) - offset, (other.y - me.y) - offset), out hit, 100);
                RaycastHit hit2;
                Physics.Raycast(transform.position, new Vector2((other.x - me.x) + offset, (other.y - me.y) + offset), out hit2, 100);

                //store the hit locations as vertices in the struct, in model coordinates, as well as the angle of the ray cast and the UV at the vertex.
                angleds[(h * 2)].vert  = lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(hit.point);
                angleds[(h * 2)].angle = angle1;
                angleds[(h * 2)].uv    = new Vector2(angleds[(h * 2)].vert.x, angleds[(h * 2)].vert.y);

                angleds[(h * 2) + 1].vert  = lightRays.transform.worldToLocalMatrix.MultiplyPoint3x4(hit2.point);
                angleds[(h * 2) + 1].angle = angle3;
                angleds[(h * 2) + 1].uv    = new Vector2(angleds[(h * 2) + 1].vert.x, angleds[(h * 2) + 1].vert.y);

                h++;                                 //increment h.

                if (showRed && hit.collider != null) //for debugging: draw the rays cast.
                {
                    Debug.DrawLine(transform.position, hit.point, Color.red);
                }
                if (showGreen)
                {
                    Debug.DrawLine(transform.position, hit2.point, Color.green);
                }
            }
        }

        Array.Sort(angleds, delegate(angledVerts one, angledVerts two) {
            return(one.angle.CompareTo(two.angle));
        });                                      //sort the struct array of vertices from smallest angle to greatest.

        for (int i = 0; i < angleds.Length; i++) //store the values in the struct array in verts and uvs.
        {                                        //(offsetting one because index 0 is the center of the light source and triangle fan)
            verts[i + 1] = angleds[i].vert;
            uvs[i + 1]   = angleds[i].uv;
        }

        mesh.vertices = verts;               //update the actual mesh with the new vertices.

        for (int i = 0; i < uvs.Length; i++) //offset all the UVs by .5 on both s and t to make the texture center be at the object center.
        {
            uvs[i] = new Vector2(uvs[i].x + .5f, uvs[i].y + .5f);
        }

        mesh.uv = uvs;                                //update the actual mesh with the new UVs.

        int[] triangles = { 0, 1, verts.Length - 1 }; //init the triangles array, starting with the last triangle to orient normals properly.

        for (int i = verts.Length - 1; i > 0; i--)    //add all triangles to the triangle array, determined by three verts in the vertex array.
        {
            triangles = AddItemsToArray(triangles, 0, i, i - 1);
        }
        //triangles = AddItemsToArray(triangles, 0, 1, 2);

        mesh.triangles = triangles; //update the actual mesh with the new triangles.
    }