private void LoadChunk(VoxelWorld _voxel_world, intVector3 _position) { if (_voxel_world.GetChunk(_position.x, _position.y, _position.z) == null) { _voxel_world.CreateChunk(_position.x, _position.y, _position.z); } }
public void ReuseChunk(Chunk _chunk, intVector3 _position) { // intVector3 voxel_world_position = new intVector3(_x, _y, _z);//the coordinates of chunk in the world if (_chunk == null) { CreateChunk(_position.x, _position.y, _position.z); } _chunk.transform.position = _position; _chunk.voxel_world_position = _position; _chunk.gameObject.SetActive(true); _chunk.voxel_world = this; _chunk.transform.parent = transform; _chunk.name = "World Chunk"; _chunk.gameObject.isStatic = true; chunks.Add(_position, _chunk);//store chunk in dictionary by its position _chunk = terrain_generator.GenerateChunk(_chunk); _chunk.SetVoxelsUnEdited(); VoxelWorldSaver.Load(_chunk); }
public void CreateChunk(int _x, int _y, int _z) { intVector3 voxel_world_position = new intVector3(_x, _y, _z);//the coordinates of chunk in the world if (chunks.ContainsKey(voxel_world_position)) { return; } GameObject chunk_object = Instantiate(chunk_prefab, new Vector3(voxel_world_position.x, voxel_world_position.y, voxel_world_position.z), Quaternion.Euler(Vector3.zero));//create chunk //set chunk parameters Chunk chunk = chunk_object.GetComponent <Chunk>(); chunk.voxel_world_position = voxel_world_position; chunk.voxel_world = this; chunk.transform.parent = transform; chunk.name = "World Chunk"; chunk.gameObject.isStatic = true; chunks.Add(voxel_world_position, chunk);//store chunk in dictionary by its position chunk = terrain_generator.GenerateChunk(chunk); chunk.SetVoxelsUnEdited(); VoxelWorldSaver.Load(chunk); }
public Chunk GetChunkUnFloored(intVector3 _position) { Chunk chunk = null; chunks.TryGetValue(_position, out chunk); return(chunk); }
public void SetBoundary(Vector3 _size, ComputeBuffer _obstacle_grid, intVector3 _thread_count) { compute_shader.SetVector("size", _size); int kernel_id = compute_shader.FindKernel("Boundary"); compute_shader.SetBuffer(kernel_id, "write_R", _obstacle_grid); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); }
private void ReuseChunk(VoxelWorld _voxel_world, intVector3 _position) { if (_voxel_world.GetChunk(_position.x, _position.y, _position.z) != null) { return; } _voxel_world.ReuseChunk(GetChunkFromPool(), _position);//reuse chunk if available }
public override bool Equals(object _object)// Override equals operator { if (!(_object is intVector3)) { return(false);// Ignore } intVector3 position = (intVector3)_object; return(position.x == x && position.y == y && position.z == z); }
public override bool Equals(object _object) //override equals operator { if (!(_object is intVector3)) //if not a world position { return(false); //ignore } intVector3 position = (intVector3)_object; //cast to world position return(position.x == x && position.y == y && position.z == z); }
private intVector3 CustomOutputThreadCount() { intVector3 custom_thread_count = intVector3.Zero; custom_thread_count.x = (int)(output_resolution.x / THREAD_GROUP_COUNT); // Compute shaders use thread groups custom_thread_count.y = (int)(output_resolution.y / THREAD_GROUP_COUNT); // Divide by the amount of groups to get required thread count for grid size custom_thread_count.z = (int)(output_resolution.z / THREAD_GROUP_COUNT); return(custom_thread_count); }
private void OnDrawGizmos() { Gizmos.color = Color.red; foreach (intVector3 chunk_pos in chunk_positions) { intVector3 chunk_relative_pos = new intVector3(chunk_pos.x * Chunk.chunk_size + current_world_position.x, current_world_position.y, chunk_pos.z * Chunk.chunk_size + current_world_position.z); Gizmos.DrawWireCube(chunk_relative_pos, Vector3.one * Chunk.chunk_size); } }
private void Update() { current_world_position = VoxelWorld.PositionToWorldPosition(transform.position); if (multithreading) { ThreadedUpdate(); return; } RegularUpdate(); }
protected override RenderTexture ConvertGridToVolume(GridType _grid_type) { if (_grid_type != GridType.DENSITY) { return(base.ConvertGridToVolume(_grid_type)); // Let base handle other output conversions } intVector3 custom_thread_count = CustomOutputThreadCount(); output_module.FuelParticleToVolume(output_resolution, fuel_particles_buffer, custom_volume_output, particle_count, explosion_params.trace_particles, custom_thread_count); return(custom_volume_output); }
public static bool SetVoxel(RaycastHit _hit, Voxel _voxel, bool _adjacent = false) { Chunk chunk = _hit.collider.GetComponent <Chunk>();//try get chunk if (chunk == null) { return(false);//failed to get chunk } intVector3 position = GetVoxelCentrePosition(_hit, _adjacent); chunk.voxel_world.SetVoxel(position.x, position.y, position.z, _voxel); return(true); }
public static Voxel GetVoxel(RaycastHit _hit, bool _adjacent = false) { Chunk chunk = _hit.collider.GetComponent <Chunk>(); if (chunk == null) { return(null); } intVector3 position = GetVoxelCentrePosition(_hit, _adjacent); Voxel voxel = chunk.voxel_world.GetVoxel(position.x, position.y, position.z); return(voxel); }
void SetNeighbourEditedIfEqual(int _voxel_chunk_position, int _check_value, intVector3 _position) { if (_voxel_chunk_position != _check_value) { return; } Chunk chunk = GetChunk(_position.x, _position.y, _position.z); if (chunk != null) { chunk.edited = true;//set chunk as edited so it updates } }
public Chunk GetChunk(int _x, int _y, int _z) { intVector3 position = new intVector3(); float chunk_size = Chunk.chunk_size;//convert to float for division position.x = Mathf.FloorToInt(_x / chunk_size) * Chunk.chunk_size; position.y = Mathf.FloorToInt(_y / chunk_size) * Chunk.chunk_size; position.z = Mathf.FloorToInt(_z / chunk_size) * Chunk.chunk_size; Chunk chunk = null; chunks.TryGetValue(position, out chunk); return(chunk); }
public void ApplyImpulse(float _dt, Vector3 _size, float _amount, float _impulse_radius, Vector3 _impulse_position, ComputeBuffer[] _grids, intVector3 _thread_count) { compute_shader.SetVector("size", _size); compute_shader.SetFloat("radius", _impulse_radius); compute_shader.SetFloat("source_amount", _amount); compute_shader.SetFloat("dt", _dt); compute_shader.SetVector("source_pos", _impulse_position); int kernel_id = compute_shader.FindKernel("Impulse"); compute_shader.SetBuffer(kernel_id, "read_R", _grids[READ]); compute_shader.SetBuffer(kernel_id, "write_R", _grids[WRITE]); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); Swap(_grids); }
private void AddChunkPositionsToLoadLists(intVector3 _chunk_pos) { int column_height = Mathf.FloorToInt(max_chunk_y * 0.5f); for (int y = -column_height; y < column_height; ++y) //load a column of chunks in this position { for (int x = _chunk_pos.x - Chunk.chunk_size; x <= _chunk_pos.x + Chunk.chunk_size; x += Chunk.chunk_size) //add adjacent chunks as well so they get updated { for (int z = _chunk_pos.z - Chunk.chunk_size; z <= _chunk_pos.z + Chunk.chunk_size; z += Chunk.chunk_size) { load_list.Add(new intVector3(x, y * Chunk.chunk_size, z)); } } update_list.Add(new intVector3(_chunk_pos.x, y * Chunk.chunk_size, _chunk_pos.z)); } }
public void CalculatePressure(Vector3 _size, ComputeBuffer _divergence_grid, ComputeBuffer _obstacle_grid, uint _jacobi_iterations, ComputeBuffer[] _pressure_grids, intVector3 _thread_count) { compute_shader.SetVector("size", _size); int kernel_id = compute_shader.FindKernel("Jacobi"); compute_shader.SetBuffer(kernel_id, "divergence", _divergence_grid); compute_shader.SetBuffer(kernel_id, "obstacles", _obstacle_grid); for (int i = 0; i < _jacobi_iterations; ++i)// Pressure gradient is calculated iteratively, most expensive part { compute_shader.SetBuffer(kernel_id, "write_R", _pressure_grids[WRITE]); compute_shader.SetBuffer(kernel_id, "pressure", _pressure_grids[READ]); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); Swap(_pressure_grids); } }
void LoadAndUpdateThreadSafe() { if (load_list.Count != 0) { for (int i = 0; i < load_list.Count; ++i) { intVector3 temp = load_list[0]; thread_manager.QueueForMainThread(() => { if (object_pooling) { ReuseChunk(voxel_world, temp); } else { LoadChunk(voxel_world, temp); } }); load_list.RemoveAt(0);//index 0 as entries are removed } } if (update_list.Count == 0) { return; } for (int i = 0; i < update_list.Count; ++i) { intVector3 temp = update_list[0]; thread_manager.QueueForMainThread(() => { Chunk chunk = voxel_world.GetChunk(temp.x, temp.y, temp.z);//try and get chunk if (chunk != null) { chunk.edited = true;//set it to update its mesh } }); update_list.RemoveAt(0); } }
public void SetVoxel(int _x, int _y, int _z, Voxel _voxel) { Chunk chunk = GetChunk(_x, _y, _z); if (chunk == null) { return; } intVector3 voxel_chunk_pos = new intVector3(_x - chunk.voxel_world_position.x, _y - chunk.voxel_world_position.y, _z - chunk.voxel_world_position.z); chunk.SetVoxel(voxel_chunk_pos.x, voxel_chunk_pos.y, voxel_chunk_pos.z, _voxel); chunk.edited = true; //update neighbouring chunks SetNeighbourEditedIfEqual(voxel_chunk_pos.x, 0, new intVector3(_x - 1, _y, _z));//if offset x - 1 less than zero (in adjacent chunk) the neighbouring chunk should update SetNeighbourEditedIfEqual(voxel_chunk_pos.x, Chunk.chunk_size - 1, new intVector3(_x + 1, _y, _z)); SetNeighbourEditedIfEqual(voxel_chunk_pos.y, 0, new intVector3(_x, _y - 1, _z)); SetNeighbourEditedIfEqual(voxel_chunk_pos.y, Chunk.chunk_size - 1, new intVector3(_x, _y + 1, _z)); SetNeighbourEditedIfEqual(voxel_chunk_pos.z, 0, new intVector3(_x, _y, _z - 1)); SetNeighbourEditedIfEqual(voxel_chunk_pos.z, Chunk.chunk_size - 1, new intVector3(_x, _y, _z + 1)); }
private void FindChunksToLoad() { if (update_list.Count != 0)//if there are chunks to build don't load more { return; } for (int i = 0; i < chunk_positions.Count; ++i)//for every pre calculated chunk position { //calculate chunk position intVector3 chunk_pos = new intVector3(chunk_positions[i].x * Chunk.chunk_size + current_world_position.x, 0, chunk_positions[i].z * Chunk.chunk_size + current_world_position.z); //offset array pos to players pos then convert to chunk pos Chunk chunk = voxel_world.GetChunk(chunk_pos.x, chunk_pos.y, chunk_pos.z); //try find chunk at position if (ChunkScheduled(chunk, chunk_pos)) //if chunk is already loaded or scheduled to build, skip it { continue; } AddChunkPositionsToLoadLists(chunk_pos); return; } }
public void ConvertToVolume(Vector3 _size, ComputeBuffer _grid, RenderTexture _target, intVector3 _thread_count) { // Convert structured buffer to 3d volume texture using gpu int kernel_id = compute_shader.FindKernel("ConvertToVolume"); compute_shader.SetBuffer(kernel_id, "read_R", _grid); compute_shader.SetTexture(kernel_id, "write_tex", _target); compute_shader.SetVector("size", _size); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); }
public void FuelParticleToVolume(Vector3 _size, ComputeBuffer _particles, RenderTexture _target, uint _particle_count, bool _trace_particles, intVector3 _thread_count) { // Convert particles buffer to 3d volume texture using gpu int kernel_id = compute_shader.FindKernel("ParticleToVolume"); compute_shader.SetBuffer(kernel_id, "particles", _particles); compute_shader.SetTexture(kernel_id, "write_tex", _target); compute_shader.SetVector("size", _size); if (!_trace_particles) // If not tracing particles I have to clear the volume each frame { int clear_kernel = compute_shader.FindKernel("ClearVolume"); // GL.Clear doesn't seem to work for 3D RenderTexture compute_shader.SetTexture(clear_kernel, "write_tex", _target); compute_shader.Dispatch(clear_kernel, _thread_count.x, _thread_count.y, _thread_count.z); } compute_shader.Dispatch(kernel_id, (int)_particle_count / 8, 1, 1); }
private bool ChunkScheduled(Chunk _chunk, intVector3 _chunk_pos) { return(_chunk != null && (_chunk.rendered || update_list.Contains(_chunk_pos))); }
public void CalculateProjection(Vector3 _size, ComputeBuffer[] _pressure_grids, ComputeBuffer _obstacle_grid, ComputeBuffer[] _velocity_grids, intVector3 _thread_count) { compute_shader.SetVector("size", _size); int kernel_id = compute_shader.FindKernel("Projection"); compute_shader.SetBuffer(kernel_id, "obstacles", _obstacle_grid); compute_shader.SetBuffer(kernel_id, "pressure", _pressure_grids[READ]); compute_shader.SetBuffer(kernel_id, "velocity", _velocity_grids[READ]); compute_shader.SetBuffer(kernel_id, "write_RGB", _velocity_grids[WRITE]); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); Swap(_velocity_grids); }
public void ApplyBuoyancy(float _dt, Vector3 _size, float _buoyancy, float _particle_weight, float _ambient_temperature, ComputeBuffer[] _velocity_grids, ComputeBuffer[] _density_grids, ComputeBuffer[] _temperature_grids, intVector3 _thread_count) { compute_shader.SetVector("size", _size); compute_shader.SetVector("up", new Vector4(0, 1, 0, 0));// Up is up, normally compute_shader.SetFloat("buoyancy", _buoyancy); compute_shader.SetFloat("weight", _particle_weight); compute_shader.SetFloat("ambient_temperature", _ambient_temperature); compute_shader.SetFloat("dt", _dt); int kernel_id = compute_shader.FindKernel("ApplyBuoyancy"); compute_shader.SetBuffer(kernel_id, "write_RGB", _velocity_grids[WRITE]); compute_shader.SetBuffer(kernel_id, "velocity", _velocity_grids[READ]); compute_shader.SetBuffer(kernel_id, "density", _density_grids[READ]); compute_shader.SetBuffer(kernel_id, "temperature", _temperature_grids[READ]); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); Swap(_velocity_grids); }
public static string GetChunkFileName(intVector3 _chunk_position) { return(_chunk_position.x + "," + _chunk_position.y + "," + _chunk_position.z + ".bin"); }
public void CalculateDivergence(Vector3 _size, ComputeBuffer _divergence_grid, ComputeBuffer[] _velocity_grids, ComputeBuffer _obstacle_grid, intVector3 _thread_count) { compute_shader.SetVector("size", _size); int kernel_id = compute_shader.FindKernel("Divergence"); compute_shader.SetBuffer(kernel_id, "write_R", _divergence_grid); compute_shader.SetBuffer(kernel_id, "velocity", _velocity_grids[READ]); compute_shader.SetBuffer(kernel_id, "obstacles", _obstacle_grid); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); }
public void AddSphereObstacle(Vector3 _size, Vector3 _position, float _radius, bool _is_container, ComputeBuffer _obstacle_grid, intVector3 _thread_count) { compute_shader.SetVector("size", _size); int kernel_id = _is_container ? compute_shader.FindKernel("AddSphereContainer") : compute_shader.FindKernel("AddSphereObstacle");// Separate function for container to avoid branching on GPU compute_shader.SetBuffer(kernel_id, "write_R", _obstacle_grid); compute_shader.SetFloat("sphere_radius", _radius); compute_shader.SetVector("sphere_position", _position); compute_shader.Dispatch(kernel_id, _thread_count.x, _thread_count.y, _thread_count.z); }