byte[] MergeWaterData(IntVector4 chunkPos, byte[] baseChunkData)
        {
            List <string> files = _riverChunkFileList[chunkPos];
            int           n     = files.Count;

            if (n > 0)
            {
                byte[] chunkData = baseChunkData;
                for (int i = 0; i < n; i++)
                {
                    chunkData = VFDataReader.MergeChunkData(chunkData, File.ReadAllBytes(files[i]), chunkPos.w);
                }

                if (chunkPos.w == 0)                // || chunkData.Length > VFVoxel.c_VTSize){  //let waterchunk_lod(not full/empty) do minus
                {
                    VFVoxelChunkData tChunk = _terraReader.ReadChunkImm(chunkPos);
                    chunkData = VFDataReader.MinusChunkData(chunkData, tChunk.DataVT, 0);
                }
                return(chunkData);
            }
            return(baseChunkData);
        }
Beispiel #2
0
    private void GenARiverChunk(ref Vector3 boundMin, ref Vector3 boundMax, MeshCollider mc, IntVector4 chunkPos, string filePrefix)
    {
        int lodPrefix   = VoxelTerrainConstants._numVoxelsPrefix << chunkPos.w;
        int lodAxisSize = VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE << chunkPos.w;
        int sx          = (chunkPos.x << VoxelTerrainConstants._shift) - lodPrefix;
        int sy          = (chunkPos.y << VoxelTerrainConstants._shift) - lodPrefix;
        int sz          = (chunkPos.z << VoxelTerrainConstants._shift) - lodPrefix;
        int ex          = sx + lodAxisSize;
        int ey          = sy + lodAxisSize;
        int ez          = sz + lodAxisSize;
        int minx        = Mathf.Max((int)boundMin.x, sx);
        int miny        = Mathf.Max((int)boundMin.y, sy);
        int minz        = Mathf.Max((int)boundMin.z, sz);
        int maxx        = Mathf.Min((int)boundMax.x, ex);
        int maxy        = Mathf.Min((int)boundMax.y, ey);
        int maxz        = Mathf.Min((int)boundMax.z, ez);

        if (minx >= maxx || miny >= maxy || minz >= maxz)
        {
            return;
        }
        //if(miny < VFVoxelWater.c_fWaterLvl)	miny = (int)VFVoxelWater.c_fWaterLvl;

        VFVoxelChunkData terraChunkData = terraReader.ReadChunkImm(chunkPos);

        byte[] terraData = terraChunkData.DataVT;

        VFVoxelChunkData waterChunkData0 = waterReader.ReadChunkImm(chunkPos);

        byte[] waterData0 = waterChunkData0.DataVT;

        //int idxOfs = 32*VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT;
        //int yOverlap = VoxelTerrainConstants._numVoxelsPrefix + VoxelTerrainConstants._numVoxelsPostfix;

        Ray ray = new Ray();

        ray.direction = Vector3.down;
        Vector3    origin   = new Vector3(0, boundMax.y + 0.5f, 0);
        float      distance = boundMax.y - miny + 1;
        RaycastHit hitInfo;
        int        step = 1 << chunkPos.w;
        int        mask = (-1) << chunkPos.w;

        minx &= mask;
        miny &= mask;
        minz &= mask;
        int  minYIdx      = sy < 0 ? 1 : 0;     // ignore pos -1;
        int  start        = VFVoxelChunkData.OneIndexNoPrefix((minx - sx) >> chunkPos.w, 0, (minz - sz) >> chunkPos.w);
        bool bChunkDirty0 = false;
        bool bColDirty;
        int  cur, y, idx, leftVol, tmpVol;

        for (int z = minz; z < maxz; z += step, start += VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SQUARED)
        {
            cur      = start;
            origin.z = z;
            for (int x = minx; x < maxx; x += step, cur++)
            {
                origin.x   = x;
                ray.origin = origin;
                if (mc.Raycast(ray, out hitInfo, distance) &&
                    hitInfo.point.y >= VFVoxelWater.c_fWaterLvl)                   // this check of y can be removed if neccessary
                {
                    float fHitY = hitInfo.point.y;
                    int   iHitY = (int)(fHitY + 0.5f * step);
                    int   iy    = (iHitY - sy) >> chunkPos.w;
                    if (iy >= 0)
                    {
                        bColDirty = false;
                        if (iy >= VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE)
                        {
                            iy  = VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE;
                            y   = (VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE - 1);
                            idx = (cur << 1) + y * VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT;
                        }
                        else
                        {
                            idx     = (cur << 1) + iy * VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT;
                            leftVol = 255 - terraData[idx];
                            byte surfVol = 0;
                            if (leftVol > 0)
                            {
                                float fLodHitY    = fHitY / step;
                                float fLodHitYDec = fLodHitY - (int)fLodHitY;
                                surfVol = fLodHitYDec < 0.5f ? (byte)(256.0f * 0.5f / (1 - fLodHitYDec)) : (byte)(255.999f * (1 - 0.5f / fLodHitYDec));
                                if (surfVol > waterData0[idx])
                                {
                                    waterData0[idx]     = surfVol;
                                    waterData0[idx + 1] = (byte)VFVoxel.EType.WaterSourceBeg;
                                    bColDirty           = true;
                                }
                            }
                            idx -= VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT;
                            y    = iy - 1;
                            if (bColDirty && y >= 0)                            //for seamlessness with terrain
                            {
                                if (surfVol < 128)
                                {
                                    waterData0[idx]     = 255;
                                    waterData0[idx + 1] = (byte)VFVoxel.EType.WaterSourceBeg;
                                    idx -= VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT;
                                    y--;
                                }
                                else
                                {
                                    waterData0[idx]     = 128;
                                    waterData0[idx + 1] = (byte)VFVoxel.EType.WaterSourceBeg;
                                }
                            }
                        }
                        bool bOverChanged = false, bTmpOverChange = false;
                        for (; y >= minYIdx; y--, idx -= VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT)
                        {
                            bTmpOverChange = false;
                            leftVol        = 255 - terraData[idx];
                            if (bOverChanged)
                            {
                                leftVol += VolPlus;
                            }
                            if (leftVol > waterData0[idx])
                            {
                                if (!bOverChanged)
                                {
                                    leftVol += VolPlus;
                                }
                                if (leftVol > 255)
                                {
                                    if (y + 1 < iy)
                                    {
                                        tmpVol = waterData0[idx + VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT];
                                        if (tmpVol < 255)
                                        {
                                            tmpVol += VolPlus;
                                            if (tmpVol > 255)
                                            {
                                                tmpVol = 255;
                                            }
                                            waterData0[idx + VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT]     = (byte)tmpVol;
                                            waterData0[idx + VoxelTerrainConstants.VOXEL_ARRAY_AXIS_SIZE_VT + 1] = (byte)VFVoxel.EType.WaterSourceBeg;
                                        }
                                    }
                                    bTmpOverChange = true;
                                    leftVol        = 255;
                                }
                                waterData0[idx]     = (byte)(leftVol);
                                waterData0[idx + 1] = (byte)VFVoxel.EType.WaterSourceBeg;
                                bColDirty           = true;
                            }
                            bOverChanged = bTmpOverChange;
                        }

                        if (bColDirty)
                        {
                            bChunkDirty0 = true;
                        }
                    }
                }
            }
        }
        if (bChunkDirty0)
        {
            WriteChunkToFile(filePrefix, waterChunkData0);
        }

        waterChunkData0.ClearMem();
        terraChunkData.ClearMem();
    }