예제 #1
0
    public void rebuild(float newSize, int newResolution, int newNodesPerMesh, float newColliderDepth, int newSortingLayer, int newSortingOrder)
    {
        Texture2D oldValues = new Texture2D(resolution + 1, resolution + 1);

        for (int x = 0; x < resolution; x++)
        {
            for (int y = 0; y < resolution; y++)
            {
                Destroy2DNode node = getNode(x, resolution - y);
                if (node != null)
                {
                    oldValues.SetPixel(x, y, new Color(0, 0, 0, node.tl));
                    oldValues.SetPixel(x + 1, y, new Color(0, 0, 0, node.tr));
                    oldValues.SetPixel(x, y + 1, new Color(0, 0, 0, node.bl));
                    oldValues.SetPixel(x + 1, y + 1, new Color(0, 0, 0, node.br));
                }
                else
                {
                    oldValues.SetPixel(x, y, new Color(0, 0, 0, 0));
                    oldValues.SetPixel(x + 1, y, new Color(0, 0, 0, 0));
                    oldValues.SetPixel(x, y + 1, new Color(0, 0, 0, 0));
                    oldValues.SetPixel(x + 1, y + 1, new Color(0, 0, 0, 0));
                }
            }
        }

        oldValues.Apply();

        clean();

        terrainSize   = newSize;
        resolution    = newResolution;
        nodesPerMesh  = newNodesPerMesh;
        colliderDepth = newColliderDepth;
        sortingLayer  = newSortingLayer;
        sortingOrder  = newSortingOrder;

        createTerrain(oldValues);
    }
예제 #2
0
    private void buildMesh(Material material, float colliderDepth, int sortingLayer, int sortingOrder, Destroy2D terrain)
    {
        if (GetComponent <MeshCollider>() != null)
        {
            DestroyImmediate(GetComponent <MeshCollider>());
        }

        MeshRenderer      mr           = gameObject.GetComponent <MeshRenderer>();
        MeshFilter        mf           = gameObject.GetComponent <MeshFilter>();
        PolygonCollider2D polyCollider = gameObject.GetComponent <PolygonCollider2D>();

        Mesh m;

        if (mr != null)
        {
            DestroyImmediate(mr);
        }

        if (mf != null)
        {
            if (mf.sharedMesh != null)
            {
                mf.sharedMesh.Clear();
            }

            DestroyImmediate(mf);
        }

        if (terrain == null)
        {
            //GameObject.DestroyImmediate(gameObject);
            return;
        }

        if (polyCollider != null)
        {
            DestroyImmediate(polyCollider);
            polyCollider = null;
        }

        mr = gameObject.AddComponent <MeshRenderer>();
        mf = gameObject.AddComponent <MeshFilter>();

        m = new Mesh();

        mf.sharedMesh = m;

        int vertexCount = 0;
        int indexCount  = 0;
        int uvCount     = 0;
        int uv1Count    = 0;

        int colliderCount = 0;

        for (int x = 0; x < meshNodeCount; x++)
        {
            for (int y = 0; y < meshNodeCount; y++)
            {
                Destroy2DNode node = terrain.getNode(x + meshX, y + meshY);
                if (node != null)
                {
                    if (node.isFull || node.isGeometry)
                    {
                        vertexCount += node.vertices.Length;
                        indexCount  += node.indexes.Length;
                        uvCount     += node.uv.Length;
                        uv1Count    += node.uv1.Length;

                        if (node.isGeometry)
                        {
                            colliderCount++;

                            if (node.hasSecondNormal)
                            {
                                colliderCount++;
                            }
                        }
                    }
                }
            }
        }

        Vector3[] vertices = new Vector3[vertexCount];
        Vector3[] normals  = new Vector3[vertexCount];
        Vector4[] tangents = new Vector4[vertexCount];
        int[]     indexes  = new int[indexCount];
        Vector2[] uv       = new Vector2[uvCount];
        Vector2[] uv1      = new Vector2[uv1Count];

        vertexCount = 0;
        indexCount  = 0;
        uvCount     = 0;
        uv1Count    = 0;

        colliderCount = 0;

        for (int x = 0; x < meshNodeCount; x++)
        {
            for (int y = 0; y < meshNodeCount; y++)
            {
                Destroy2DNode node = terrain.getNode(x + meshX, y + meshY);
                if (node != null)
                {
                    if (node.isFull || node.isGeometry)
                    {
                        Vector3 nodePos = node.nodePosition - gameObject.transform.localPosition;

                        for (int i = 0; i < node.vertices.Length; i++)
                        {
                            vertices[vertexCount + i] = node.vertices[i] + nodePos;
                            normals[vertexCount + i]  = Vector3.back;
                            tangents[vertexCount + i] = new Vector4(1, 0, 0, -1);
                        }

                        for (int i = 0; i < node.indexes.Length; i++)
                        {
                            indexes[indexCount + i] = node.indexes[i] + vertexCount;
                        }

                        for (int i = 0; i < node.uv.Length; i++)
                        {
                            uv[uvCount + i] = node.uv[i];
                        }

                        for (int i = 0; i < node.uv1.Length; i++)
                        {
                            uv1[uv1Count + i] = node.uv1[i];
                        }

                        vertexCount += node.vertices.Length;
                        indexCount  += node.indexes.Length;
                        uvCount     += node.uv.Length;
                        uv1Count    += node.uv1.Length;

                        if (node.isGeometry)
                        {
                            if (polyCollider == null)
                            {
                                polyCollider = gameObject.AddComponent <PolygonCollider2D>();
                            }

                            node.addPolygonCollider(polyCollider);

                            /*node.addToCollisionMesh(collVertices, collIndexes, collNormals, colliderCount, colliderDepth, nodePos);
                             *
                             * if (node.hasSecondNormal) {
                             *      colliderCount++;
                             * }
                             *
                             * colliderCount++;*/
                        }
                    }
                }
            }
        }

        m.vertices  = vertices;
        m.triangles = indexes;
        m.uv        = uv;
        m.uv1       = uv1;
        m.normals   = normals;
        m.tangents  = tangents;

        m.Optimize();

        renderer.material = material;

        gameObject.layer = terrain.gameObject.layer;

        isDirty = false;
    }
예제 #3
0
    void createTerrain(Texture2D mapTexture)
    {
        clean();

        createColorMask();

        nodes = new Destroy2DNode[resolution * resolution];

        int meshCount = Mathf.FloorToInt(resolution / nodesPerMesh);

        if ((resolution % nodesPerMesh) > 0)
        {
            meshCount++;
        }
        nodeMeshes = new Destroy2DMesh[meshCount * meshCount];
        Destroy2DMesh currentMesh = null;

        //nodeValuesTexture = new Texture2D(resolution, resolution);

        float nodeSize = terrainSize / resolution;
        float uvDelta  = 1.0f / resolution;

        for (int x = 0; x < resolution; x++)
        {
            for (int y = 0; y < resolution; y++)
            {
                Destroy2DNode node = Destroy2DNode.createNewNode();
                node.terrainSize = terrainSize;

                node.nodePosition = new Vector3(x * nodeSize, y * -nodeSize, 0);

                nodes[x + y * resolution] = node;

                currentMesh = nodeMeshes[Mathf.FloorToInt(x / nodesPerMesh) + Mathf.FloorToInt(y / nodesPerMesh) * meshCount];

                if (currentMesh == null)
                {
                    currentMesh = Destroy2DMesh.instantiate();
                    currentMesh.gameObject.transform.parent        = gameObject.transform;
                    currentMesh.gameObject.transform.localPosition = node.nodePosition;

                    nodeMeshes[Mathf.FloorToInt(x / nodesPerMesh) + Mathf.FloorToInt(y / nodesPerMesh) * meshCount] = currentMesh;

                    currentMesh.meshX         = x;
                    currentMesh.meshY         = y;
                    currentMesh.meshNodeCount = nodesPerMesh;
                }

                if (node.init(mapTexture, x * uvDelta, 1 - y * uvDelta, uvDelta, nodeSize, colorValue, material))
                {
                }

                //nodeValuesTexture.SetPixel(x,-y, Color.white * (colorValue + (node.tl + node.tr + node.bl + node.br) * 0.25f));
            }
        }

        //nodeValuesTexture.Apply();

        foreach (Destroy2DMesh mesh in GetComponentsInChildren <Destroy2DMesh>())
        {
            mesh.commit(material, colliderDepth, sortingLayer, sortingOrder, this);
        }
    }
예제 #4
0
    public void paintColorMask(int type, Vector3 pos, float radius, float intensity)
    {
        createColorMask();

        float nodeSize   = terrainSize / resolution;
        int   radiusSize = Mathf.FloorToInt(radius / nodeSize) + 1;
        int   posX       = Mathf.FloorToInt((pos.x - transform.position.x) / nodeSize);
        int   posY       = Mathf.FloorToInt(-(pos.y - transform.position.y) / nodeSize);

        for (int x = posX - radiusSize; x < posX + radiusSize; x++)
        {
            for (int y = posY - radiusSize; y < posY + radiusSize; y++)
            {
                if ((x >= 0) && (x < resolution) && (y >= 0) && (y < resolution))
                {
                    Destroy2DNode node = nodes[x + y * resolution];

                    if (node != null)
                    {
                        float rad = ((node.nodePosition + transform.position) - pos).magnitude;
                        if (rad < radius)
                        {
                            Color currentColor = colorMasks.GetPixel(x, -y);
                            float factor       = (1 - (rad / radius)) * intensity;

                            if (type == 0)
                            {
                                currentColor.r += factor;
                                currentColor.g -= factor;
                                currentColor.b -= factor;
                                currentColor.a -= factor;
                            }

                            if (type == 1)
                            {
                                currentColor.r -= factor;
                                currentColor.g += factor;
                                currentColor.b -= factor;
                                currentColor.a -= factor;
                            }

                            if (type == 2)
                            {
                                currentColor.r -= factor;
                                currentColor.g -= factor;
                                currentColor.b += factor;
                                currentColor.a -= factor;
                            }

                            if (type == 3)
                            {
                                currentColor.r -= factor;
                                currentColor.g -= factor;
                                currentColor.b -= factor;
                                currentColor.a += factor;
                            }

                            if (type == 4)
                            {
                                currentColor.r -= factor;
                                currentColor.g -= factor;
                                currentColor.b -= factor;
                                currentColor.a -= factor;
                            }

                            currentColor.r = Mathf.Clamp01(currentColor.r);
                            currentColor.g = Mathf.Clamp01(currentColor.g);
                            currentColor.b = Mathf.Clamp01(currentColor.b);
                            currentColor.a = Mathf.Clamp01(currentColor.a);


                            colorMasks.SetPixel(x, -y, currentColor);
                        }
                    }
                }
            }
        }

        colorMasks.Apply();

        updateMaterial();
    }
예제 #5
0
    private void changeTerrain(Vector3 pos, float radius, float intensity)
    {
        int           meshCount   = Mathf.FloorToInt(resolution / nodesPerMesh);
        Destroy2DMesh currentMesh = null;

        float nodeSize   = terrainSize / resolution;
        int   radiusSize = Mathf.FloorToInt(radius / nodeSize) + 1;
        int   posX       = Mathf.FloorToInt((pos.x - transform.position.x) / nodeSize);
        int   posY       = Mathf.FloorToInt(-(pos.y - transform.position.y) / nodeSize);
        float uvDelta    = 1.0f / resolution;

        for (int x = posX - radiusSize; x < posX + radiusSize; x++)
        {
            for (int y = posY - radiusSize; y < posY + radiusSize; y++)
            {
                if ((x >= 0) && (x < resolution) && (y >= 0) && (y < resolution))
                {
                    Destroy2DNode node = nodes[x + y * resolution];

                    if (node == null)
                    {
                        node             = nodes[x + y * resolution] = Destroy2DNode.createNewNode();
                        node.terrainSize = terrainSize;
                        node.setValues(x * uvDelta, 1 - y * uvDelta, uvDelta, nodeSize);
                        node.nodePosition = new Vector3(x * nodeSize, y * -nodeSize, 0);
                    }

                    if (node != null)
                    {
                        bool shouldUpdate = false;

                        float rad_tl = ((node.nodePosition + transform.position) - pos).magnitude;
                        float rad_tr = ((node.nodePosition + transform.position + Vector3.right * nodeSize) - pos).magnitude;
                        float rad_bl = ((node.nodePosition + transform.position + Vector3.down * nodeSize) - pos).magnitude;
                        float rad_br = ((node.nodePosition + transform.position + Vector3.right * nodeSize + Vector3.down * node.size) - pos).magnitude;

                        if (rad_tl < radius)
                        {
                            node.tl     -= intensity * (1 - (rad_tl / radius));
                            shouldUpdate = true;
                        }

                        if (rad_tr < radius)
                        {
                            node.tr     -= intensity * (1 - (rad_tr / radius));
                            shouldUpdate = true;
                        }

                        if (rad_bl < radius)
                        {
                            node.bl     -= intensity * (1 - (rad_bl / radius));
                            shouldUpdate = true;
                        }

                        if (rad_br < radius)
                        {
                            node.br     -= intensity * (1 - (rad_br / radius));
                            shouldUpdate = true;
                        }

                        if (shouldUpdate)
                        {
                            node.tl = Mathf.Clamp01(node.tl);
                            node.tr = Mathf.Clamp01(node.tr);
                            node.bl = Mathf.Clamp01(node.bl);
                            node.br = Mathf.Clamp01(node.br);

                            currentMesh = nodeMeshes[Mathf.FloorToInt(x / nodesPerMesh) + Mathf.FloorToInt(y / nodesPerMesh) * meshCount];

                            currentMesh.isDirty = true;

                            Destroy2DNode otherNode = null;
                            Destroy2DMesh otherMesh = null;

                            //top left
                            if ((x > 1) && (y > 1))
                            {
                                otherNode    = nodes[(x - 1) + (y - 1) * resolution];
                                otherNode.br = node.tl;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x - 1) / nodesPerMesh) + Mathf.FloorToInt((y - 1) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            //top
                            if (y > 1)
                            {
                                otherNode    = nodes[(x) + (y - 1) * resolution];
                                otherNode.bl = node.tl;
                                otherNode.br = node.tr;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x) / nodesPerMesh) + Mathf.FloorToInt((y - 1) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            //top right
                            if ((x < (resolution - 2)) && (y > 1))
                            {
                                otherNode    = nodes[(x + 1) + (y - 1) * resolution];
                                otherNode.bl = node.tr;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x + 1) / nodesPerMesh) + Mathf.FloorToInt((y - 1) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            //right
                            if (x < (resolution - 2))
                            {
                                otherNode    = nodes[(x + 1) + (y) * resolution];
                                otherNode.tl = node.tr;
                                otherNode.bl = node.br;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x + 1) / nodesPerMesh) + Mathf.FloorToInt((y) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            //bottom right
                            if ((x < (resolution - 2)) && (y < (resolution - 2)))
                            {
                                otherNode    = nodes[(x + 1) + (y + 1) * resolution];
                                otherNode.tl = node.br;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x + 1) / nodesPerMesh) + Mathf.FloorToInt((y + 1) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            //bottom
                            if (y < (resolution - 2))
                            {
                                otherNode    = nodes[(x) + (y + 1) * resolution];
                                otherNode.tl = node.bl;
                                otherNode.tr = node.br;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x) / nodesPerMesh) + Mathf.FloorToInt((y + 1) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            //bottom left
                            if ((x > 1) && (y < (resolution - 2)))
                            {
                                otherNode    = nodes[(x - 1) + (y + 1) * resolution];
                                otherNode.tr = node.bl;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x - 1) / nodesPerMesh) + Mathf.FloorToInt((y + 1) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            //left
                            if (x > 1)
                            {
                                otherNode    = nodes[(x - 1) + (y) * resolution];
                                otherNode.tr = node.tl;
                                otherNode.br = node.bl;

                                otherNode.reInit(colorValue);

                                otherMesh         = nodeMeshes[Mathf.FloorToInt((x - 1) / nodesPerMesh) + Mathf.FloorToInt((y) / nodesPerMesh) * meshCount];
                                otherMesh.isDirty = true;
                            }

                            node.reInit(colorValue);

                            //nodeValuesTexture.SetPixel(x,-y, Color.white * (colorValue + (node.tl + node.tr + node.bl + node.br) * 0.25f));
                        }
                    }
                }
            }
        }

        //nodeValuesTexture.Apply();
    }