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); }
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(); }