예제 #1
0
    /// <summary>
    /// Builds the chunk's mesh.
    /// </summary>
    public void RegenerateVisualMesh(float aVoxelScale)
    {
        //float startTime = Time.realtimeSinceStartup;
        VoxelBlob blob     = manager.m_blob;
        int3      blobSize = blob.size;

        if (sm_regenInUse)
        {
            Debug.Log("Somehow calling two regens at the same time");
            //throw new System.Exception("Cannot run two RegenerateVisualMesh at the same time. If needed, make more static RegenData");
            return;
        }
        sm_regenInUse = true;
        sm_regenData.Clear();

        needsRegen = false;

        int chunkSize = manager.chunkSize;

        for (int i = 0; i < 6; ++i)
        {
            m_hasBuild[0][i] = false;
            m_hasWater[i]    = false;
            m_hasPattern[i]  = false;
        }

        m_mesh.Clear();
        m_mesh.subMeshCount = kSubMeshCount;

        int3 currVoxel = new int3();

        bool hasFaces = false;

        int3 maxVals = blobSize - position;

        for (int i = 0; i < 3; ++i)
        {
            maxVals[i] = Mathf.Min(maxVals[i], chunkSize);
        }
        //Debug.Log("Starting main block");
        for (int z = 0; z < maxVals.z && z + position.z < blobSize.z; z += 2)
        {
            for (int y = 0; y < maxVals.y && y + position.y < blobSize.y; y += 2)
            {
                for (int x = 0; x < maxVals.x && x + position.x < blobSize.x; x += 2)
                {
                    currVoxel.x = x;
                    currVoxel.y = y;
                    currVoxel.z = z;

                    int2[][] buildIndex = new int2[kNumBuildMats][];
                    for (int i = 0; i < kNumBuildMats; ++i)
                    {
                        buildIndex[i] = new int2[6];
                    }
                    int2[] waterIndex   = new int2[6];
                    int2[] patternIndex = new int2[6];

                    byte voxel;

                    for (int i = 0; i < 2 && x + i + position.x < blobSize.x; ++i)
                    {
                        for (int j = 0; j < 2 && y + j + position.y < blobSize.y; ++j)
                        {
                            for (int k = 0; k < 2 && z + k + position.z < blobSize.z; ++k)
                            {
                                int3 curr = new int3(currVoxel.x + i, currVoxel.y + j, currVoxel.z + k);
                                voxel = VoxelAt(curr, blob);
                                if (voxel != 0)
                                {
                                    int2[] voxelIndex = null;
                                    switch (voxel)
                                    {
                                    case MeshManager.kVoxelWater:
                                        voxelIndex = waterIndex;
                                        break;

                                    case MeshManager.kVoxelObjectDef:
                                        voxelIndex = patternIndex;
                                        break;

                                    default:
                                        voxelIndex = buildIndex[(int)(voxel - MeshManager.kVoxelFirstMat)];
                                        break;
                                    }
                                    if (curr.x + position.x == 0 || VoxelAt(curr.x - 1, curr.y, curr.z, blob) == 0)
                                    {
                                        voxelIndex[0][i] += (1 << (j * 2 + k));
                                    }
                                    if (curr.x + position.x == blobSize.x - 1 || VoxelAt(curr.x + 1, curr.y, curr.z, blob) == 0)
                                    {
                                        voxelIndex[1][i] += (1 << (j * 2 + k));
                                    }
                                    if (curr.y + position.y == 0 || VoxelAt(curr.x, curr.y - 1, curr.z, blob) == 0)
                                    {
                                        voxelIndex[2][j] += (1 << (k * 2 + i));
                                    }
                                    if (curr.y + position.y == blobSize.y - 1 || VoxelAt(curr.x, curr.y + 1, curr.z, blob) == 0)
                                    {
                                        voxelIndex[3][j] += (1 << (k * 2 + i));
                                    }
                                    if (curr.z + position.z == 0 || VoxelAt(curr.x, curr.y, curr.z - 1, blob) == 0)
                                    {
                                        voxelIndex[4][k] += (1 << (i * 2 + j));
                                    }
                                    if (curr.z + position.z == blobSize.z - 1 || VoxelAt(curr.x, curr.y, curr.z + 1, blob) == 0)
                                    {
                                        voxelIndex[5][k] += (1 << (i * 2 + j));
                                    }
                                }
                            }
                        }
                    }

                    for (int i = 0; i < kNumBuildMats; ++i)
                    {
                        GenNegXFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenPosXFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenNegYFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenPosYFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenNegZFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                        GenPosZFaces(currVoxel, ref hasFaces, m_hasBuild[i], buildIndex[i], m_buildOffsets[i]);
                    }

                    GenNegXFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenNegXFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                    GenPosXFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenPosXFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);

                    GenNegYFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenNegYFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                    GenPosYFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenPosYFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);

                    GenNegZFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenNegZFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                    GenPosZFaces(currVoxel, ref hasFaces, m_hasWater, waterIndex, kWaterOffset);
                    GenPosZFaces(currVoxel, ref hasFaces, m_hasPattern, patternIndex, kPatternOffset);
                }
            }
        }

        //Debug.Log("Finished main block");

        if (!hasFaces)
        {
            sm_regenInUse = false;
            return;
        }
        m_mesh.name     = "Visual Mesh";
        m_mesh.vertices = sm_regenData.verts.ToArray();
        for (int i = 0; i < kSubMeshCount; ++i)
        {
            if (sm_regenData.tris[i].Count > 0)
            {
                m_mesh.SetTriangles(sm_regenData.tris[i].ToArray(), i);
            }
        }
        if (m_mesh.vertexCount > 0)
        {
            manager.EnableMesh(this);
        }
        else
        {
            manager.DisableMesh(this);
        }

        m_mesh.Optimize();
        sm_regenInUse = false;
    }