public void AddVoxel(VoxelChunk chunk, int voxelIndex, Vector3 position, Quaternion rotation, Vector3 scale) { VoxelDefinition voxelDefinition = env.voxelDefinitions [chunk.voxels [voxelIndex].typeIndex]; // Ensure there're batches for this voxel definition if (voxelDefinition.batchedIndex < 0) { BatchedMesh batchedMesh = new BatchedMesh(voxelDefinition); Material material = voxelDefinition.material; if (material == null) { material = defaultInstancingMaterial; } batchedMesh.material = material; voxelDefinition.batchedIndex = batchedMeshes.Add(batchedMesh); } // Add chunk and voxel to the rendering lists InstancedChunk instancedChunk; if (!instancedChunks.TryGetValue(chunk, out instancedChunk)) { instancedChunk = new InstancedChunk(chunk); instancedChunks.Add(chunk, instancedChunk); } InstancedVoxel instancedVoxel = new InstancedVoxel(); instancedVoxel.voxelDefinition = voxelDefinition; instancedVoxel.meshSize = voxelDefinition.mesh.bounds.size; instancedVoxel.position = position; instancedVoxel.matrix.SetTRS(position, rotation, scale); instancedVoxel.color = chunk.voxels [voxelIndex].color; instancedVoxel.light = chunk.voxels [voxelIndex].lightMesh / 15f; instancedChunk.instancedVoxels.Add(instancedVoxel); rebuild = true; }
void RebuildZoneRenderingLists(Vector3 observerPos, float visibleDistance) { // rebuild batch lists to be used in the rendering loop for (int k = 0; k < batchedMeshes.count; k++) { BatchedMesh batchedMesh = batchedMeshes.values [k]; batchedMesh.batches.Clear(); } float cullDistance = (visibleDistance * 16) * (visibleDistance * 16); for (int j = 0; j <= instancedChunks.lastIndex; j++) { InstancedChunk instancedChunk = instancedChunks.values [j]; if (instancedChunk == null) { continue; } // check if chunk is in area Vector3 chunkCenter = instancedChunk.chunk.position; if (FastVector.SqrDistance(ref chunkCenter, ref observerPos) > cullDistance) { continue; } // add instances to batch InstancedVoxel[] voxels = instancedChunk.instancedVoxels.values; for (int i = 0; i < instancedChunk.instancedVoxels.count; i++) { VoxelDefinition vd = voxels [i].voxelDefinition; BatchedMesh batchedMesh = batchedMeshes.values [vd.batchedIndex]; Batch batch = batchedMesh.batches.last; if (batch == null || batch.instancesCount >= Batch.MAX_INSTANCES) { batch = batchedMesh.batches.FetchDirty(); if (batch == null) { batch = new Batch(); batchedMesh.batches.Add(batch); } else { batch.Init(); } } int pos = batch.instancesCount++; // just copying the matrix triggers lot of expensive memcpy() calls so we directly copy the fields // batch.matrices[pos] = voxels[i].matrix; batch.matrices [pos].m00 = voxels [i].matrix.m00; batch.matrices [pos].m01 = voxels [i].matrix.m01; batch.matrices [pos].m02 = voxels [i].matrix.m02; batch.matrices [pos].m03 = voxels [i].matrix.m03; batch.matrices [pos].m10 = voxels [i].matrix.m10; batch.matrices [pos].m11 = voxels [i].matrix.m11; batch.matrices [pos].m12 = voxels [i].matrix.m12; batch.matrices [pos].m13 = voxels [i].matrix.m13; batch.matrices [pos].m20 = voxels [i].matrix.m20; batch.matrices [pos].m21 = voxels [i].matrix.m21; batch.matrices [pos].m22 = voxels [i].matrix.m22; batch.matrices [pos].m23 = voxels [i].matrix.m23; batch.matrices [pos].m30 = voxels [i].matrix.m30; batch.matrices [pos].m31 = voxels [i].matrix.m31; batch.matrices [pos].m32 = voxels [i].matrix.m32; batch.matrices [pos].m33 = voxels [i].matrix.m33; batch.color [pos].x = voxels [i].color.r / 255f; batch.color [pos].y = voxels [i].color.g / 255f; batch.color [pos].z = voxels [i].color.b / 255f; batch.color [pos].w = 1f; batch.light [pos] = voxels [i].light; batch.UpdateBounds(voxels[i].position, voxels[i].meshSize); } } for (int k = 0; k < batchedMeshes.count; k++) { BatchedMesh batchedMesh = batchedMeshes.values [k]; for (int j = 0; j < batchedMesh.batches.count; j++) { Batch batch = batchedMesh.batches.values [j]; batch.materialPropertyBlock.SetVectorArray("_TintColor", batch.color); batch.materialPropertyBlock.SetFloatArray("_VoxelLight", batch.light); } } }