コード例 #1
0
ファイル: LightUtility.cs プロジェクト: whpskyeagle/Graphics
        public static Bounds GenerateSpriteMesh(Light2D light, Sprite sprite)
        {
            var mesh = light.lightMesh;

            if (sprite == null)
            {
                mesh.Clear();
                return(new Bounds(Vector3.zero, Vector3.zero));
            }

            // this needs to be called before getting UV at the line below.
            // Venky fixed it, enroute to trunk
            var uvs = sprite.uv;

            var srcVertices = sprite.GetVertexAttribute <Vector3>(VertexAttribute.Position);
            var srcUVs      = sprite.GetVertexAttribute <Vector2>(VertexAttribute.TexCoord0);
            var srcIndices  = sprite.GetIndices();

            var center   = 0.5f * (sprite.bounds.min + sprite.bounds.max);
            var vertices = new NativeArray <LightMeshVertex>(srcIndices.Length, Allocator.Temp);
            var color    = new Color(0, 0, 0, 1);

            for (var i = 0; i < srcVertices.Length; i++)
            {
                vertices[i] = new LightMeshVertex
                {
                    position = new Vector3(srcVertices[i].x, srcVertices[i].y, 0) - center,
                    color    = color,
                    uv       = srcUVs[i]
                };
            }
            mesh.SetVertexBufferParams(vertices.Length, LightMeshVertex.VertexLayout);
            mesh.SetVertexBufferData(vertices, 0, 0, vertices.Length);
            mesh.SetIndices(srcIndices, MeshTopology.Triangles, 0, true);

            light.vertices = new LightMeshVertex[vertices.Length];
            NativeArray <LightMeshVertex> .Copy(vertices, light.vertices, vertices.Length);

            light.indices = new ushort[srcIndices.Length];
            NativeArray <ushort> .Copy(srcIndices, light.indices, srcIndices.Length);

            return(mesh.GetSubMesh(0).bounds);
        }
コード例 #2
0
ファイル: LightUtility.cs プロジェクト: Kideya/Brawlgame
        public static Bounds GenerateParametricMesh(Light2D light, float radius, float falloffDistance, float angle, int sides)
        {
            var angleOffset = Mathf.PI / 2.0f + Mathf.Deg2Rad * angle;

            if (sides < 3)
            {
                radius = 0.70710678118654752440084436210485f * radius;
                sides  = 4;
            }

            if (sides == 4)
            {
                angleOffset = Mathf.PI / 4.0f + Mathf.Deg2Rad * angle;
            }

            var vertexCount = 1 + 2 * sides;
            var indexCount  = 3 * 3 * sides;
            var vertices    = new NativeArray <LightMeshVertex>(vertexCount, Allocator.Temp);
            var triangles   = new NativeArray <ushort>(indexCount, Allocator.Temp);
            var centerIndex = (ushort)(2 * sides);
            var mesh        = light.lightMesh;

            // Only Alpha value in Color channel is ever used. May remove it or keep it for batching params in the future.
            var color = new Color(0, 0, 0, 1);

            vertices[centerIndex] = new LightMeshVertex
            {
                position = float3.zero,
                color    = color
            };

            var radiansPerSide = 2 * Mathf.PI / sides;
            var min            = new float3(float.MaxValue, float.MaxValue, 0);
            var max            = new float3(float.MinValue, float.MinValue, 0);

            for (var i = 0; i < sides; i++)
            {
                var endAngle   = (i + 1) * radiansPerSide;
                var extrudeDir = new float3(math.cos(endAngle + angleOffset), math.sin(endAngle + angleOffset), 0);
                var endPoint   = radius * extrudeDir;

                var vertexIndex = (2 * i + 2) % (2 * sides);
                vertices[vertexIndex] = new LightMeshVertex
                {
                    position = endPoint,
                    color    = new Color(extrudeDir.x, extrudeDir.y, 0, 0)
                };
                vertices[vertexIndex + 1] = new LightMeshVertex
                {
                    position = endPoint,
                    color    = color
                };

                // Triangle 1 (Tip)
                var triangleIndex = 9 * i;
                triangles[triangleIndex]     = (ushort)(vertexIndex + 1);
                triangles[triangleIndex + 1] = (ushort)(2 * i + 1);
                triangles[triangleIndex + 2] = centerIndex;

                // Triangle 2 (Upper Top Left)
                triangles[triangleIndex + 3] = (ushort)(vertexIndex);
                triangles[triangleIndex + 4] = (ushort)(2 * i);
                triangles[triangleIndex + 5] = (ushort)(2 * i + 1);

                // Triangle 2 (Bottom Top Left)
                triangles[triangleIndex + 6] = (ushort)(vertexIndex + 1);
                triangles[triangleIndex + 7] = (ushort)(vertexIndex);
                triangles[triangleIndex + 8] = (ushort)(2 * i + 1);

                min = math.min(min, endPoint + extrudeDir * falloffDistance);
                max = math.max(max, endPoint + extrudeDir * falloffDistance);
            }

            mesh.SetVertexBufferParams(vertexCount, LightMeshVertex.VertexLayout);
            mesh.SetVertexBufferData(vertices, 0, 0, vertexCount);
            mesh.SetIndices(triangles, MeshTopology.Triangles, 0, false);

            light.vertices = new LightMeshVertex[vertexCount];
            NativeArray <LightMeshVertex> .Copy(vertices, light.vertices, vertexCount);

            light.indices = new ushort[indexCount];
            NativeArray <ushort> .Copy(triangles, light.indices, indexCount);

            return(new Bounds
            {
                min = min,
                max = max
            });
        }
コード例 #3
0
ファイル: LightUtility.cs プロジェクト: Kideya/Brawlgame
        public static Bounds GenerateShapeMesh(Light2D light, Vector3[] shapePath, float falloffDistance)
        {
            var         ix            = 0;
            var         vcount        = 0;
            var         icount        = 0;
            const float kClipperScale = 10000.0f;
            var         mesh          = light.lightMesh;

            // todo Revisit this while we do Batching.
            var meshInteriorColor = new Color(0.0f, 0, 0, 1.0f);
            var meshExteriorColor = new Color(0.0f, 0, 0, 0.0f);
            var vertices          = new NativeArray <LightMeshVertex>(shapePath.Length * 256, Allocator.Temp);
            var indices           = new NativeArray <ushort>(shapePath.Length * 256, Allocator.Temp);

            // Create shape geometry
            var inputPointCount = shapePath.Length;
            var inner           = new ContourVertex[inputPointCount + 1];

            for (var i = 0; i < inputPointCount; ++i)
            {
                inner[ix++] = new ContourVertex()
                {
                    Position = new Vec3()
                    {
                        X = shapePath[i].x, Y = shapePath[i].y, Z = 0
                    }
                }
            }
            ;
            inner[ix++] = inner[0];

            var tess = new Tess();

            tess.AddContour(inner, ContourOrientation.CounterClockwise);
            Tessellate(tess, ElementType.Polygons, indices, vertices, meshInteriorColor, ref vcount, ref icount);

            // Create falloff geometry
            List <IntPoint> path = new List <IntPoint>();

            for (var i = 0; i < inputPointCount; ++i)
            {
                var newPoint = new Vector2(inner[i].Position.X, inner[i].Position.Y) * kClipperScale;
                var addPoint = new IntPoint((System.Int64)(newPoint.x), (System.Int64)(newPoint.y));
                addPoint.N = i; addPoint.D = -1;
                path.Add(addPoint);
            }
            var lastPointIndex = inputPointCount - 1;

            // Generate Bevels.
            List <List <IntPoint> > solution   = new List <List <IntPoint> >();
            ClipperOffset           clipOffset = new ClipperOffset(24.0f);

            clipOffset.AddPath(path, JoinType.jtRound, EndType.etClosedPolygon);
            clipOffset.Execute(ref solution, kClipperScale * falloffDistance, path.Count);

            if (solution.Count > 0)
            {
                // Fix path for Pivots.
                var outPath = solution[0];
                var minPath = (long)inputPointCount;
                for (int i = 0; i < outPath.Count; ++i)
                {
                    minPath = (outPath[i].N != -1) ? Math.Min(minPath, outPath[i].N) : minPath;
                }
                var containsStart = minPath == 0;
                outPath = FixPivots(outPath, path);

                // Tessellate.
                var innerIndices = new ushort[inputPointCount];

                // Inner Vertices. (These may or may not be part of the created path. Beware!!)
                for (int i = 0; i < inputPointCount; ++i)
                {
                    vertices[vcount++] = new LightMeshVertex()
                    {
                        position = new float3(inner[i].Position.X, inner[i].Position.Y, 0),
                        color    = meshInteriorColor
                    };
                    innerIndices[i] = (ushort)(vcount - 1);
                }

                var saveIndex = (ushort)vcount;
                var pathStart = saveIndex;
                var prevIndex = outPath[0].N == -1 ? 0 : outPath[0].N;

                for (int i = 0; i < outPath.Count; ++i)
                {
                    var curr      = outPath[i];
                    var currPoint = new float2(curr.X / kClipperScale, curr.Y / kClipperScale);
                    var currIndex = curr.N == -1 ? 0 : curr.N;

                    vertices[vcount++] = new LightMeshVertex()
                    {
                        position = new float3(currPoint.x, currPoint.y, 0),
                        color    = meshExteriorColor
                    };

                    if (prevIndex != currIndex)
                    {
                        indices[icount++] = innerIndices[prevIndex];
                        indices[icount++] = innerIndices[currIndex];
                        indices[icount++] = (ushort)(vcount - 1);
                    }

                    indices[icount++] = innerIndices[prevIndex];
                    indices[icount++] = saveIndex;
                    indices[icount++] = saveIndex = (ushort)(vcount - 1);
                    prevIndex         = currIndex;
                }

                // Close the Loop.
                {
                    indices[icount++] = pathStart;
                    indices[icount++] = innerIndices[minPath];
                    indices[icount++] = containsStart ? innerIndices[lastPointIndex] : saveIndex;

                    indices[icount++] = containsStart ? pathStart : saveIndex;
                    indices[icount++] = containsStart ? saveIndex : innerIndices[minPath];
                    indices[icount++] = containsStart ? innerIndices[lastPointIndex] : innerIndices[minPath - 1];
                }
            }

            mesh.SetVertexBufferParams(vcount, LightMeshVertex.VertexLayout);
            mesh.SetVertexBufferData(vertices, 0, 0, vcount);
            mesh.SetIndices(indices, 0, icount, MeshTopology.Triangles, 0, true);

            light.vertices = new LightMeshVertex[vcount];
            NativeArray <LightMeshVertex> .Copy(vertices, light.vertices, vcount);

            light.indices = new ushort[icount];
            NativeArray <ushort> .Copy(indices, light.indices, icount);

            return(mesh.GetSubMesh(0).bounds);
        }