public Item SpawnItem(Type itemType, Vector3 position, Quaternion rotation, string model) { if (typeof(Item).IsAssignableFrom(itemType)) // Is an item, spawn that shit { GameObject go = (GameObject)GameObject.Instantiate(GameController.Instance.VoxPrefab, position, rotation); Item item = (Item)go.AddComponent(itemType); item.gameObject.name = item.Name; string useModel = (ModelRegister.ContainsKey(model) ? model : (ModelRegister.ContainsKey(item.DefaultModel) ? item.DefaultModel : "Default")); using (BinaryReader reader = new BinaryReader(new MemoryStream(ModelRegister[useModel]))) { VoxelUtil.FromMagica(reader, go.GetComponentInChildren <Volume>().gameObject, 0.075f, false); } Volume vol = item.GetComponentInChildren <Volume>(); vol.Pivot = (new Vector3(vol.XSize, vol.YSize, vol.ZSize) * vol.VoxelSize) / 2f; vol.UpdatePivot(); GameController.InvokeSpawned(this, item); return(item); } return(null); }
public Pawn SpawnPawn(Type pawnType, Vector3 position, Quaternion rotation, string model) { if (typeof(PlayerController).IsAssignableFrom(pawnType)) { Log("cannot spawn PlayerController via SpawnPawn; use SpawnPlayer instead.", DebugWarningLevel.ERROR); } else if (typeof(Pawn).IsAssignableFrom(pawnType)) // Is a non-player pawn, spawn that shit { GameObject go = (GameObject)GameObject.Instantiate(GameController.Instance.VoxPrefab, position, rotation); Pawn pawn = (Pawn)go.AddComponent(pawnType); pawn.gameObject.name = pawn.Name; string useModel = (ModelRegister.ContainsKey(model) ? model : (ModelRegister.ContainsKey(pawn.DefaultModel) ? pawn.DefaultModel : "Default")); using (BinaryReader reader = new BinaryReader(new MemoryStream(ModelRegister[useModel]))) { VoxelUtil.FromMagica(reader, go.GetComponentInChildren <Volume>().gameObject, 0.075f, false); } Volume vol = pawn.GetComponentInChildren <Volume>(); vol.Pivot = (new Vector3(vol.XSize, vol.YSize, vol.ZSize) * vol.VoxelSize) / 2f; vol.UpdatePivot(); GameController.InvokeSpawned(this, pawn); return(pawn); } return(null); }
public void Execute(int index) { int3 gridPosition = VoxelUtil.To3DIndex(index, chunkSize); int3 worldPosition = gridPosition + chunkPosition * chunkSize; RandomVoxel(out Voxel voxel, worldPosition); voxels[index] = voxel; }
IEnumerator UpdateMesh() { if (Updating) { yield break; } if (!generator.CanUpdate) { yield break; } generator.UpdatingChunks++; int3 chunkSizeInt3 = VoxelUtil.ToInt3(chunkSize); List <Voxel[]> neighborVoxels = generator.GetNeighborVoxels(chunkPosition, 1); lightData?.Dispose(); lightData = new VoxelLightBuilder.NativeLightData(chunkSizeInt3); yield return(lightData.ScheduleLightingJob(neighborVoxels, VoxelUtil.ToInt3(chunkPosition), chunkSizeInt3, 1, argent)); meshData?.Dispose(); meshData = new VoxelMeshBuilder.NativeMeshData(VoxelUtil.ToInt3(chunkSize)); yield return(meshData.ScheduleMeshingJob(voxels, lightData, VoxelUtil.ToInt3(chunkSize), generator.SimplifyingMethod, argent)); meshData.GetMeshInformation(out int verticeSize, out int indicesSize); if (verticeSize > 0 && indicesSize > 0) { mesh.Clear(); mesh.SetVertices(meshData.nativeVertices, 0, verticeSize); mesh.SetNormals(meshData.nativeNormals, 0, verticeSize); mesh.SetColors(meshData.nativeColors, 0, verticeSize); mesh.SetUVs(0, meshData.nativeUVs, 0, verticeSize); mesh.SetIndices(meshData.nativeIndices, 0, indicesSize, MeshTopology.Triangles, 0); mesh.RecalculateNormals(); mesh.RecalculateBounds(); if (argent) { SetSharedMesh(mesh); } else { VoxelColliderBuilder.Instance.Enqueue(this, mesh); } } lightData.Dispose(); meshData.Dispose(); dirty = false; argent = false; gameObject.layer = LayerMask.NameToLayer("Voxel"); meshUpdator = null; generator.UpdatingChunks--; }
void GenerateChunkByTargetPosition() { if (target == null) { return; } Vector3Int targetPosition = VoxelUtil.WorldToChunk(target.position, chunkSize); if (lastTargetChunkPosition == targetPosition) { return; } foreach (ChunkNode chunkNode in generateChunkQueue) { Vector3Int deltaPosition = targetPosition - chunkNode.chunkPosition; if (chunkSpawnSize.x < Mathf.Abs(deltaPosition.x) || chunkSpawnSize.y < Mathf.Abs(deltaPosition.y) || chunkSpawnSize.z < Mathf.Abs(deltaPosition.z)) { generateChunkQueue.Remove(chunkNode); continue; } generateChunkQueue.UpdatePriority(chunkNode, (targetPosition - chunkNode.chunkPosition).sqrMagnitude); } for (int x = targetPosition.x - chunkSpawnSize.x; x <= targetPosition.x + chunkSpawnSize.x; x++) { for (int y = targetPosition.y - chunkSpawnSize.y; y <= targetPosition.y + chunkSpawnSize.y; y++) { for (int z = targetPosition.z - chunkSpawnSize.z; z <= targetPosition.z + chunkSpawnSize.z; z++) { Vector3Int chunkPosition = new Vector3Int(x, y, z); if (chunks.ContainsKey(chunkPosition)) { continue; } ChunkNode newNode = new ChunkNode { chunkPosition = chunkPosition }; if (generateChunkQueue.Contains(newNode)) { continue; } generateChunkQueue.Enqueue(newNode, (targetPosition - chunkPosition).sqrMagnitude); } } } lastTargetChunkPosition = targetPosition; }
public void Set(float x, float y, float z, T data) { int xx = (int)x; int yy = (int)y; int zz = (int)z; Vector3i loc = new Vector3i(xx >> regionBits, yy >> regionBits, zz >> regionBits); RegionData <T> DataCache = GetOrCreateRegion(loc); DataCache.Set(VoxelUtil.WorldToChunkCoord(x), VoxelUtil.WorldToChunkCoord(y), VoxelUtil.WorldToChunkCoord(z), data); }
IEnumerator InitUpdator() { int numVoxels = chunkSize.x * chunkSize.y * chunkSize.z; voxels = new Voxel[numVoxels]; voxelData = new NoiseGenerator.NativeVoxelData(VoxelUtil.ToInt3(chunkSize)); yield return(voxelData.Generate(voxels, VoxelUtil.ToInt3(chunkPosition), VoxelUtil.ToInt3(chunkSize))); dirty = true; initialized = true; }
public WorldFile(int LOD, int ChunkIDX, int ChunkIDY, int X, int Y, float Scale) { LODID = LOD; IDX = ChunkIDX; IDY = ChunkIDY; WSX = X; WSY = Y; SX = (int)Math.Round(X / Scale); SY = (int)Math.Round(Y / Scale); TerrainScale = Scale; HeightMap = new int[SX + 1, SY + 1]; MaterialMap = new byte[SX * MaterialDensity, SY *MaterialDensity]; SecondaryMaterialMap = new byte[SX * MaterialDensity, SY *MaterialDensity]; BlendAlphaMap = new byte[SX * MaterialDensity, SY *MaterialDensity]; DecalMaterialMap = new byte[SX * MaterialDensity, SY *MaterialDensity]; DecalAlphaMap = new byte[SX * MaterialDensity, SY *MaterialDensity]; WaterHeightMap = new int[SX + 1, SY + 1]; WaveLengthMap = new byte[SX + 1, SY + 1]; WaveHeightMap = new byte[SX + 1, SY + 1]; FlowXMap = new byte[SX, SY]; FlowYMap = new byte[SX, SY]; FlowBackTimeMap = new byte[SX, SY]; FlowPulseSpeedMap = new byte[SX, SY]; WaterMap = new byte[SX, SY]; FoamRampMap0 = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; WaterColorFalloffMap = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; WaterColorR = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; WaterColorG = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; WaterColorB = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; WaterColorA = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; WaterNormalMap = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; WaterFresnelMap = new byte[SX * WaterColorDensity + 1, SY *WaterColorDensity + 1]; CoverHeight = new byte[SX * DisplacementDensity + 1, SY *DisplacementDensity + 1]; VoxelUtil.ReplaceValue(FlowXMap, 0, 128); VoxelUtil.ReplaceValue(FlowYMap, 0, 128); FileName = ChunkIDX + "-" + ChunkIDY + "-" + LODID; }
public IEnumerator Init(Vector3Int position, TerrainGenerator parent) { chunkPosition = position; generator = parent; meshRenderer.material = generator.ChunkMaterial; voxels = new NativeArray <Voxel>(generator.ChunkSize * generator.ChunkSize * generator.ChunkSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); noiseJobHandle = NoiseGenerator.Generate(voxels, VoxelUtil.ToInt3(chunkPosition), generator.ChunkSize); yield return(new WaitUntil(() => noiseJobHandle.IsCompleted)); noiseJobHandle.Complete(); dirty = true; }
// a raycast which returns the index of the hit voxel and the gameobject of the hit chunk public BlockInfo MasterRaycast(RaycastHit hit, Vector3 origin, Vector3 direction, float range, bool ignoreTransparent) { if (raycastHasVoxel(hit)) { // check if we're actually hitting a chunk GameObject hitObject = hit.collider.gameObject; swapMesh(hitObject); Index hitIndex = hitObject.GetComponent <Chunk>().PositionToVoxelIndex(hit.point, hit.normal, false); if (ignoreTransparent) { // punch through transparent voxels by raycasting again when a transparent voxel is hit reCast(hitIndex, hitObject, hit, range); } return(VoxelUtil.getVoxelInfo(hit, hitObject)); } return(null); }
public bool GetVoxel(Vector3Int gridPosition, out Voxel voxel) { if (!initialized) { voxel = Voxel.Empty; return(false); } if (!VoxelUtil.BoundaryCheck(gridPosition, chunkSize)) { voxel = Voxel.Empty; return(false); } voxel = voxels[VoxelUtil.To1DIndex(gridPosition, chunkSize)]; return(true); }
public bool SetVoxel(Vector3Int gridPosition, Voxel.VoxelType type) { if (!initialized) { return(false); } if (!VoxelUtil.BoundaryCheck(gridPosition, chunkSize)) { return(false); } voxels[VoxelUtil.To1DIndex(gridPosition, chunkSize)].data = type; dirty = true; argent = true; return(true); }
public T Sample(float x, float y, float z, int level = 0) { int xx = (int)x; int yy = (int)y; int zz = (int)z; RegionData <T> DataCache = null; regionStore.TryGetValue(new Vector3i(xx >> regionBits, yy >> regionBits, zz >> regionBits), out DataCache); if (DataCache != null) { return(DataCache.Sample(VoxelUtil.WorldToChunkCoord(x), VoxelUtil.WorldToChunkCoord(y), VoxelUtil.WorldToChunkCoord(z), level)); } else { return(default(T)); } }
Chunk GenerateChunk(Vector3Int chunkPosition) { if (chunks.ContainsKey(chunkPosition)) { return(chunks[chunkPosition]); } GameObject chunkGameObject = new GameObject(chunkPosition.ToString()); chunkGameObject.transform.SetParent(transform); chunkGameObject.transform.position = VoxelUtil.ChunkToWorld(chunkPosition, chunkSize); Chunk newChunk = chunkGameObject.AddComponent <Chunk>(); StartCoroutine(newChunk.Init(chunkPosition, this)); chunks.Add(chunkPosition, newChunk); return(newChunk); }
public BlockInfo getVoxelInfo(RaycastHit hit, float range, bool ignoreTransparent) { if (raycastHasVoxel(hit)) { // check if we're actually hitting a chunk GameObject hitObject = hit.collider.gameObject; if (hitObject.GetComponent <ChunkExtension>() != null) { // if we hit a mesh container instead of a chunk hitObject = hitObject.transform.parent.gameObject; // swap the mesh container for the actual chunk object } Index hitIndex = hitObject.GetComponent <Chunk>().PositionToVoxelIndex(hit.point, hit.normal, false); if (ignoreTransparent) { reCast(hitIndex, hitObject, hit, range); } return(VoxelUtil.getVoxelInfo(hit, hitObject)); } return(null); }
public Pawn SpawnPlayer(Vector3 position, Quaternion rotation, string model) { PlayerController pc = GameController.FindObjectOfType <PlayerController>(); if (pc == null) { // Instantiate the player GameObject go = (GameObject)GameObject.Instantiate(GameController.Instance.PlayerPrefab, position, rotation); pc = go.GetComponent <PlayerController>(); pc.gameObject.name = pc.Name; } // Setup player model string useModel = (ModelRegister.ContainsKey(model) ? model : (ModelRegister.ContainsKey(pc.DefaultModel) ? pc.DefaultModel : "Default")); using (BinaryReader reader = new BinaryReader(new MemoryStream(ModelRegister[useModel]))) { VoxelUtil.FromMagica(reader, pc.GetComponentInChildren <Volume>().gameObject, 0.075f, false); Volume vol = pc.GetComponentInChildren <Volume>(); vol.Pivot = (new Vector3(vol.XSize, vol.YSize, vol.ZSize) * vol.VoxelSize) / 2f; vol.UpdatePivot(); } if (pc.HasStarted) { pc.Spawn(position); } else { pc.QueuedSpawn = position; pc.SpawnAtQueue = true; } return(pc); }
public void Update(RenderManager Render, Vector3 Position, Vector3 ViewDirection, float Time) { int[] LOD = WorldSettings.LOD; Vector3 FilePosition = WorldFile.GetPosition(); float Distance = Math.Min(Math.Abs(Position.X - FilePosition.X), Math.Abs(Position.Y - FilePosition.Y)); //TODO if (WaterData0.Width != WorldFile.WaterMap.GetLength(0) || WaterData0.Height != WorldFile.WaterMap.GetLength(1)) { WaterData0.Dispose(); WaterData1.Dispose(); WaterColorData0.Dispose(); WaterColorData1.Dispose(); WaterData0 = GraphicsUtil.MaterialMapsToTexture(Render.Graphics, WorldFile.FlowXMap, WorldFile.FlowYMap, WorldFile.FlowPulseSpeedMap, WorldFile.FlowBackTimeMap); WaterData1 = GraphicsUtil.MaterialMapsToTexture(Render.Graphics, WorldFile.WaterMap); WaterColorData0 = GraphicsUtil.MaterialMapsToTexture(Render.Graphics, WorldFile.WaterColorR, WorldFile.WaterColorG, WorldFile.WaterColorB, WorldFile.WaterColorA); WaterColorData1 = GraphicsUtil.MaterialMapsToTexture(Render.Graphics, WorldFile.WaterNormalMap, WorldFile.WaterFresnelMap, WorldFile.FoamRampMap0, WorldFile.WaterColorFalloffMap); WaveData0 = GraphicsUtil.MaterialMapsToTexture(Render.Graphics, WorldFile.WaveLengthMap, WorldFile.WaveHeightMap, WorldFile.WaveHeightMap, WorldFile.WaveLengthMap); } if (WorldFile.HasTerrainUpdate) { Geom.Shader.Parameters["TerrainScale"].SetValue(WorldFile.TerrainScale); Geom.Shader.Parameters["HeightScale"].SetValue(WorldFile.HeightScale); Geom.Shader.Parameters["TerrainWidth"].SetValue(WorldFile.SX); Geom.Shader.Parameters["TerrainLength"].SetValue(WorldFile.SY); Geom.Shader.Parameters["DataWidth"].SetValue(WorldFile.FlowXMap.GetLength(0)); Geom.Shader.Parameters["DataHeight"].SetValue(WorldFile.FlowXMap.GetLength(1)); GraphicsUtil.FillTexture(WaterData0, WorldFile.FlowXMap, WorldFile.FlowYMap, WorldFile.FlowPulseSpeedMap, WorldFile.FlowBackTimeMap); GraphicsUtil.FillTexture(WaterData1, WorldFile.WaterMap); GraphicsUtil.FillTexture(WaterColorData0, WorldFile.WaterColorR, WorldFile.WaterColorG, WorldFile.WaterColorB, WorldFile.WaterColorA); GraphicsUtil.FillTexture(WaterColorData1, WorldFile.WaterNormalMap, WorldFile.WaterFresnelMap, WorldFile.FoamRampMap0, WorldFile.WaterColorFalloffMap); GraphicsUtil.FillTexture(WaveData0, WorldFile.WaveLengthMap, WorldFile.WaveHeightMap, WorldFile.FoamRampMap0, WorldFile.WaterColorFalloffMap); Geom.Shader.Parameters["WaterDataMap0"].SetValue(WaterData0); Geom.Shader.Parameters["WaterDataMap1"].SetValue(WaterData1); Geom.Shader.Parameters["ColorDataMap0"].SetValue(WaterColorData0); Geom.Shader.Parameters["ColorDataMap1"].SetValue(WaterColorData1); Geom.Shader.Parameters["WaveDataMap0"].SetValue(WaveData0); Geom.Shader.Parameters["HeightMap"].SetValue(Terrain.HeightMap); WaterHeightMap.Dispose(); WaterHeightMap = GraphicsUtil.MaterialMapsToTexture(Render.Graphics, WorldFile.WaterHeightMap); //GraphicsUtil.FillTexture(WaterHeightMap, WorldFile.WaterHeightMap); Geom.Shader.Parameters["WaterHeightMap"].SetValue(WaterHeightMap); WaterClipMap.Dispose(); WaterClipMap = GraphicsUtil.MaterialMapsToTexture(Render.Graphics, VoxelUtil.AddValues(WorldFile.HeightMap, WorldFile.WaterHeightMap)); ReflectionRenderTarget.SetClipPlaneMap(Name, WaterClipMap); RefractionRenderTarget.SetClipPlaneMap(Name, WaterClipMap); DepthMapRenderTarget.SetClipPlaneMap(Name, WaterClipMap); } Geom.Shader.Parameters["ShineDamper"].SetValue(WorldSettings.WaterShineDamper); Geom.Shader.Parameters["Reflectivity"].SetValue(WorldSettings.WaterReflectivity); Geom.Shader.Parameters["MinSpecular"].SetValue(WorldSettings.MinimumSpecular); Geom.Shader.Parameters["WaterRepeatTime"].SetValue(WorldSettings.WaterRepeatTime); Geom.Shader.Parameters["WaterSpeed"].SetValue(WorldSettings.WaterSpeed); Geom.PassSetting = WorldSettings.WaterPassSetting; Geom.PassMipSetting = WorldSettings.WaterPassMipSetting; Geom.Shader.Parameters["TexSize"].SetValue(WorldSettings.TextureSize); Vector3 ChunkPosition = new Vector3(WorldFile.IDX * WorldFile.SX * WorldFile.TerrainScale, WorldFile.IDY * WorldFile.SX * WorldFile.TerrainScale, 0); Geom.Shader.Parameters["Position"].SetValue(ChunkPosition); Geom.Position = WorldFile.GetPosition(); }
public static void GeneratePatternImage(int [,] Voxels, float ScaleX, float ScaleY, LockBitMap PatternImage, LockBitMap TextureLookup) { float VoxelSizeX = PatternImage.Width / (Voxels.GetLength(0)); float VoxelSizeY = PatternImage.Height / (Voxels.GetLength(1)); int ISX = TextureLookup.Width / 16; int ISY = TextureLookup.Height / 16; Vector2[] Position = new Vector2[] { new Vector2(0, 0), new Vector2(VoxelSizeX, 0), new Vector2(0, VoxelSizeY), new Vector2(VoxelSizeX, VoxelSizeY), new Vector2(VoxelSizeX / 2, 0), new Vector2(0, VoxelSizeY / 2), new Vector2(VoxelSizeX, VoxelSizeY / 2), new Vector2(VoxelSizeX / 2, VoxelSizeY), new Vector2(VoxelSizeX / 2, VoxelSizeY / 2) }; PatternImage.Clear(); List <int[, ]> SplitVoxelFields = VoxelUtil.SplitVoxels(Voxels, 239); Vector2 Scale = new Vector2(1.0f / VoxelSizeX, 1.0f / VoxelSizeY); for (int index = 0; index < SplitVoxelFields.Count; index++) { int[,] VoxelField = SplitVoxelFields[index]; for (int i = 0; i < VoxelField.GetLength(0) - 1; i++) { for (int j = 0; j < VoxelField.GetLength(1) - 1; j++) { int Val = 0; Val += VoxelField[i, j] != 0 ? 1 : 0; Val += VoxelField[i + 1, j] != 0 ? 2 : 0; Val += VoxelField[i, j + 1] != 0 ? 4 : 0; Val += VoxelField[i + 1, j + 1] != 0 ? 8 : 0; //int Material = MathUtil.CalculateMost(new int[] { VoxelField[i, j], VoxelField[i + 1, j], VoxelField[i, j + 1], VoxelField[i + 1, j + 1] }); Vector2 VoxelPosition = new Vector2(i * VoxelSizeX, j * VoxelSizeY); for (int k = 0; k < MarchingSquaresIndices[Val].Length; k += 3) { Vector2 P1 = Position[MarchingSquaresIndices[Val][k]] + VoxelPosition; Vector2 P2 = Position[MarchingSquaresIndices[Val][k + 1]] + VoxelPosition; Vector2 P3 = Position[MarchingSquaresIndices[Val][k + 2]] + VoxelPosition; int Material = VoxelUtil.GetClosestMaterialVertex(P1, P2, P3, Scale, VoxelField); int MX = (Material / 16); int MY = (Material % 16); FillTriangle(VoxelSizeX, VoxelSizeY, ISX, ISY, MX, MY, ScaleX, ScaleY, P1, P2, P3, PatternImage, TextureLookup); } } } } }