public SavedChunkInfo(Chunk chunk) { unityPosition = chunk.transform.position; worldPos = chunk.Pos; initEmpty = chunk.initEmpty; hasBlocks = false; for (var x = 0; x < World.ChunkSize; x++) { for (var y = 0; y < World.ChunkSize; y++) { for (var z = 0; z < World.ChunkSize; z++) { if (!chunk.isDefault && chunk.Blocks[x, y, z].BlockType == VoxBlockType.Empty) continue; if (!chunk.Blocks[x, y, z].Modified) continue; var pos = new WorldPos(x,y,z); Blocks.Add(pos, chunk.Blocks[x, y, z]); hasBlocks = true; } } } }
public void RecalculateWorldPositions() { WorldPositions = new WorldPos[BlockPositions.Length]; for (var i = 0; i < BlockPositions.Length; i++) { var b = BlockPositions[i]; WorldPositions[i] = new WorldPos((int)b.x, (int)b.y, (int)b.z); } WorldPositionsCalculated = true; }
public VoxSave(Chunk chunk) { for (var x = 0; x < World.ChunkSize; x++) { for (var y = 0; y < World.ChunkSize; y++) { for (var z = 0; z < World.ChunkSize; z++) { if (!chunk.Blocks[x, y, z].Modified) continue; var pos = new WorldPos(x,y,z); Blocks.Add(pos, chunk.Blocks[x, y, z]); } } } }
public void SetBlock(WorldPos pos, VoxBlockType blockType, Color blockColor, bool createChunkIfNull = false) { SetBlock(pos.x, pos.y, pos.z, blockType, blockColor, createChunkIfNull); }
public Block GetBlock(WorldPos pos) { return GetBlock(pos.x, pos.y, pos.z); }
public Chunk GetChunk(int x, int y, int z, bool createChunkIfNull = false) { var pos = new WorldPos(); float multiple = ChunkSize; pos.x = Mathf.FloorToInt(x/multiple)*ChunkSize; pos.y = Mathf.FloorToInt(y/multiple)*ChunkSize; pos.z = Mathf.FloorToInt(z/multiple)*ChunkSize; Chunk containerChunk = null; Chunks.TryGetValue(pos, out containerChunk); if (createChunkIfNull && containerChunk == null) { containerChunk = CreateChunk(pos.x, pos.y, pos.z, true); } return containerChunk; }
public void CreateChunk2(int x, int y, int z) { WorldPos worldPos = new WorldPos(x, y, z); //Instantiate the chunk at the coordinates using the chunk prefab GameObject newChunkObject = Instantiate( ChunkPrefab, new Vector3(x, y, z), Quaternion.Euler(Vector3.zero) ) as GameObject; var newChunk = newChunkObject.GetComponent<Chunk>(); newChunk.Pos = worldPos; newChunk.World = this; //Add it to the chunks dictionary with the position as the key Chunks.Add(worldPos, newChunk); //Add these lines: //var terrainGen = new TerrainGen(); newChunk = terrainGenerator.ChunkGen(newChunk); newChunk.SetBlocksUnmodified(); //bool loaded = Serialization.Load(newChunk); }
public Chunk CreateTerrainChunk(int x, int y, int z) { var worldPos = new WorldPos(x, y, z); if (Chunks.ContainsKey(worldPos)) return null; //Instantiate the chunk at the coordinates using the chunk prefab var newChunkObject = Instantiate(ChunkPrefab, new Vector3(x * UnitScale, y * UnitScale, z * UnitScale), Quaternion.identity) as GameObject; newChunkObject.hideFlags = HideFlags.HideInHierarchy; // Keeps the hierachy clean. var newChunk = newChunkObject.GetComponent<Chunk>(); newChunk.initEmpty = false; newChunk.Pos = worldPos; newChunk.World = this; newChunk.RebuildNeeded = true; //Add it to the chunks dictionary with the position as the key Chunks.Add(worldPos, newChunk); newChunk = terrainGenerator.ChunkGen(newChunk); newChunk.SetBlocksUnmodified(); //bool loaded = Serialization.Load(newChunk); return newChunk; }
public Chunk CreateChunk(int x, int y, int z, bool empty = false) { var worldPos = new WorldPos(x, y, z); //Instantiate the chunk at the coordinates using the chunk prefab var newChunkObject = Instantiate(ChunkPrefab, new Vector3(x * UnitScale, y * UnitScale, z * UnitScale), Quaternion.identity) as GameObject; var newChunk = newChunkObject.GetComponent<Chunk>(); newChunk.initEmpty = empty; newChunk.Pos = worldPos; newChunk.World = this; newChunk.RebuildNeeded = true; //Add it to the chunks dictionary with the position as the key Chunks.Add(worldPos, newChunk); var counter = 0; //for (var xi = 0; xi < ChunkSize; xi++) //{ // for (var yi = 0; yi < ChunkSize; yi++) // { // for (var zi = 0; zi < ChunkSize; zi++) // { // if (!empty) // { // SetBlock(x + xi, y + yi, z + zi, new Block(GetRandomColor(colorA, colorB))); // } // else // { // SetBlock(x + xi, y + yi, z + zi, new BlockEmpty()); // } // } // } //} newChunk.SetBlocksUnmodified(); return newChunk; }
public static bool SetBlock(RaycastHit hit, WorldPos pos, VoxBlockType block, Color blockColor) { var chunk = hit.collider.GetComponent<Chunk>(); if (chunk == null) return false; chunk.World.SetBlock(pos, block, blockColor, true); return true; }
// Update is called once per frame private void Update() { if (GenChunk) { GenChunk = false; var chunkPos = new WorldPos(NewChunkX, NewChunkY, NewChunkZ); Chunk chunk = null; if (Chunks.TryGetValue(chunkPos, out chunk)) { DestroyChunk(chunkPos.x, chunkPos.y, chunkPos.z); } else { CreateChunk(chunkPos.x, chunkPos.y, chunkPos.z); } } if (genWorld) { genWorld = false; CreateProceduralTerrain(); } //if(Input.GetKeyDown(KeyCode.J)) SaveAll(); //if (Input.GetKeyDown(KeyCode.L)) LoadAll(); //if(Input.GetKeyDown(KeyCode.G)) NewWorld(); //if(Input.GetKeyDown(KeyCode.Escape)) Application.Quit(); }
public static string FileName(WorldPos chunkLocation) { return chunkLocation.x + "," + chunkLocation.y + "," + chunkLocation.z + ".bin"; }
void FindChunksToLoad() { var player = VoxManager.ViewPosition; //Get the position of this gameobject to generate around WorldPos playerPos = new WorldPos( Mathf.FloorToInt(player.x * World.WorldToVoxScaler / World.ChunkSize) * World.ChunkSize, Mathf.FloorToInt(player.y * World.WorldToVoxScaler / World.ChunkSize) * World.ChunkSize, Mathf.FloorToInt(player.z * World.WorldToVoxScaler / World.ChunkSize) * World.ChunkSize ); //If there aren't already chunks to generate if (updateList.Count == 0) { //Cycle through the array of positions for (int i = positionIndex; i < chunkPositions.Length; i++) { positionIndex = i; //translate the player position and array position into chunk position WorldPos newChunkPos = new WorldPos( chunkPositions[i].x * World.ChunkSize + playerPos.x, 0, chunkPositions[i].z * World.ChunkSize + playerPos.z ); var distance = Vector3.Distance( VoxTerrain.GetUnityPosition(newChunkPos), new Vector3(player.x, 0, player.z)); if (distance >= MaxChunkDistance) continue; //Get the chunk in the defined position Chunk newChunk = world.GetChunk( newChunkPos.x, newChunkPos.y, newChunkPos.z); //If the chunk already exists and it's already //rendered or in queue to be rendered continue if (newChunk != null && (newChunk.Rendered || updateList.Contains(newChunkPos))) continue; //load a column of chunks in this position for (int y = -world.worldYNegative; y < world.worldY; y++) { for (int x = newChunkPos.x - World.ChunkSize; x <= newChunkPos.x + World.ChunkSize; x += World.ChunkSize) { for (int z = newChunkPos.z - World.ChunkSize; z <= newChunkPos.z + World.ChunkSize; z += World.ChunkSize) { buildList.Add(new WorldPos( x, y * World.ChunkSize, z)); } } updateList.Add(new WorldPos( newChunkPos.x, y * World.ChunkSize, newChunkPos.z)); } //if (updateList.Count > 4) return; break; } positionsChecked = true; } if (!playerPos.Equals(LastPlayerPos)) positionIndex = 0; LastPlayerPos = playerPos; }
void BuildChunk(WorldPos pos) { if (world.GetChunk(pos.x, pos.y, pos.z) == null) world.CreateTerrainChunk(pos.x, pos.y, pos.z); }
void UpdateIfEqual(int value1, int value2, WorldPos pos) { if (value1 == value2) { var chunk = GetChunk(pos.x, pos.y, pos.z); if (chunk != null) chunk.RebuildNeeded = true; } }
protected void InterfaceWithBlocks() { RaycastHit hit; var viewPos = VoxManager.ViewPosition; var viewForward = VoxManager.ViewForward; var ray = VoxManager.ViewRay; var blocksModified = false; var click = false; var clickDown = false; var clickUp = false; if (Input.GetKeyDown(KeyCode.F2)) { // OVRManager.display.RecenterPose(); UnityEngine.VR.InputTracking.Recenter(); } if (Input.GetButtonDown(VoxInput.rightShoulder)) { clickDown = true; //interactionMode = VoxInteractionMode.AddBlocks; AddMode = true; } if (Input.GetButtonDown(VoxInput.leftShoulder)) { clickDown = true; //interactionMode = VoxInteractionMode.SubtractBlocks; AddMode = false; } if (VoxInput.GetSelectDown()) { clickDown = true; } if (mouseLeftRightSwitchesAddAndSubtract) { if (Input.GetMouseButtonDown(0)) { clickDown = true; //interactionMode = VoxInteractionMode.SubtractBlocks; AddMode = true; } if (Input.GetMouseButtonDown(1)) { clickDown = true; //interactionMode = VoxInteractionMode.SubtractBlocks; AddMode = false; } } if (Input.GetMouseButton(1)) { click = true; } if (Input.GetMouseButtonUp(1)) { clickUp = true; } if (Input.GetButton(VoxInput.rightShoulder)) click = true; if (Input.GetButton(VoxInput.leftShoulder)) click = true; if (VoxInput.GetSelect()) click = true; if (Input.GetButtonUp(VoxInput.rightShoulder)) clickUp = true; if (Input.GetButtonUp(VoxInput.leftShoulder)) clickUp = true; if (VoxInput.GetSelectUp()) clickUp = true; if (clickUp) click = false; var doubleClick = false; if (clickDown && doubleClickTimer <= doubleClickDelay) { doubleClick = true; } else if (clickDown) { doubleClickTimer = 0; } doubleClickTimer += Time.deltaTime; //if (Input.GetKeyDown(KeyCode.X)) //{ // interactionMode++; // if ((int) interactionMode >= Enum.GetValues(typeof (VoxInteractionMode)).Length) // { // interactionMode = 0; // } // //AddMode = !AddMode; //} var sampleColor = Input.GetButtonDown(VoxInput.ButtonB) || Input.GetKeyDown(KeyCode.C); if (Input.GetButtonDown(VoxInput.Select) || Input.GetKeyDown(KeyCode.P)) { PaintButton.isSelected = !PaintButton.isSelected; if (PaintButton.isSelected) { interactionMode = VoxInteractionMode.Paint; PaintButton.isSelected = true; AddButton.isSelected = false; SubtractButton.isSelected = false; VoxManager.ShowMessage("Paint Mode Enabled"); } else { interactionMode = VoxInteractionMode.Create; if (AddMode) { AddButton.isSelected = true; SubtractButton.isSelected = false; } else { AddButton.isSelected = false; SubtractButton.isSelected = true; } VoxManager.ShowMessage("Create Mode Enabled"); } } if (Input.GetButtonDown(VoxInput.ButtonX) || Input.GetKeyDown(KeyCode.T)) { DrawStraightButton.isSelected = !DrawStraightButton.isSelected; drawStraight = DrawStraightButton.isSelected; if (drawStraight) { secondBlockDrawn = false; startBlockPos = lastBlockPos; } VoxManager.ShowMessage(drawStraight ? "Draw Straight Mode Enabled" : "Draw Straight Mode Disabled"); } if (Input.GetButtonDown(VoxInput.Start) || Input.GetKeyDown(KeyCode.U)) { CreateAtFixedDistanceButton.isSelected = !CreateAtFixedDistanceButton.isSelected; createAtFixedDistance = CreateAtFixedDistanceButton.isSelected; if (createAtFixedDistance) { fixedDistance = Vector3.Distance(VoxManager.ViewPosition, VoxTerrain.GetUnityPosition(lastBlockPos)); } else { //var bpu = VoxTerrain.GetUnityPosition(lastBlockPos); //var tobpu = viewPos - bpu; //constructionPlane = new Plane(viewForward, bpu); drawStarted = false; if(interactionMode == VoxInteractionMode.Create) clickDown = true; } VoxManager.ShowMessage(createAtFixedDistance ? "Draw At Fixed Distance Mode Enabled" : "Draw At Fixed Distance Mode Disabled"); } if (Input.GetButtonDown(VoxInput.ButtonY) || Input.GetKeyDown(KeyCode.Y)) { switch (interactionMode) { case VoxInteractionMode.Create: DoubleClickLayerButton.isSelected = !DoubleClickLayerButton.isSelected; doubleClickToIncreaseHeight = DoubleClickLayerButton.isSelected; VoxManager.ShowMessage(doubleClickToIncreaseHeight ? "Match Height Mode Enabled" : "Match Height Mode Disabled"); break; case VoxInteractionMode.Paint: PaintUsingPlanesButton.isSelected = !PaintUsingPlanesButton.isSelected; paintUsingConstructionPlanes = PaintUsingPlanesButton.isSelected; VoxManager.ShowMessage(paintUsingConstructionPlanes ? "Paint Using Construction Planes Enabled" : "Paint Using Construction Planes Disabled"); break; } } var dpadX = Input.GetAxis(VoxInput.DPadX); if (Input.GetKeyDown(KeyCode.X)) dpadX = 1; if (Input.GetKeyDown(KeyCode.Z)) dpadX = -1; if (dpadX <= -0.95f && lastDPadX > -0.95f) { PrefabIndex--; if (PrefabIndex < 0) PrefabIndex = Prefabs.Length - 1; VoxManager.ShowMessage("Brush " + (PrefabIndex + 1).ToString("D")); } else if (dpadX >= 0.95f && lastDPadX < 0.95f) { PrefabIndex++; if (PrefabIndex >= Prefabs.Length) PrefabIndex = 0; VoxManager.ShowMessage("Brush " + (PrefabIndex + 1).ToString("D")); } lastDPadX = dpadX; Crosshair.SetCrosshairMode(AddMode); //Crosshair.mode = AddMode ? VoxCrosshair.CrosshairMode.Add : VoxCrosshair.CrosshairMode.Subtract; if (!drawStarted) // No drawing is happening, we need to create a cube by first clicking, then the draw starts until we release button { drawSecondLayer = false; inverseAdd = false; secondBlockDrawn = false; if (Physics.Raycast(ray, out hit, RayCastDistance, Layers.value)) // Looking at a block { //Debug.Log("Raycasting"); var chunk = hit.collider.GetComponent<Chunk>(); if (chunk != null) { var distance = hit.distance; //Debug.Log("Block hit"); var blockPos = VoxTerrain.GetBlockPos(hit); var adjacentPos = VoxTerrain.GetBlockPos(hit, true); var blockPosUnity = VoxTerrain.GetUnityPosition(blockPos); var adjacentPosUnity = VoxTerrain.GetUnityPosition(adjacentPos); var facePosUnity = blockPosUnity + hit.normal*World.HalfUnitScale; if (sampleColor) { var block = chunk.World.GetBlock(VoxTerrain.GetBlockPos(hit)); NewBlockColor = block.BlockColor; //VoxManager.ShowMessage("Color sampled"); } // Place the crosshair on the face Crosshair.newPosition = facePosUnity; Crosshair.transform.forward = hit.normal; if (distance >= minBuildDistance) { switch (interactionMode) { case VoxInteractionMode.Create: if (clickDown) // Just pressed { if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; var positions = prefab.GetWorldPositions(); if (AddMode) // Add { PlayClip(sndCreate, true); if (doubleClickToIncreaseHeight) { var buildPos = doubleClick ? blockPos + hit.normal : blockPos; //lastBlockPos = buildPos; startBlockPos = buildPos; foreach (var pos in positions) { var newPos = buildPos + pos; //VoxWorld.SetBlock(newPos, new Block(NewBlockColor), true); VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, true); } constructionBlockPos = blockPosUnity + hit.normal*World.UnitScale - hit.normal*World.HalfUnitScale; if (doubleClick) { drawSecondLayer = true; //constructionBlockPos = constructionBlockPos + constructionPlane.normal * World.UnitScale; //constructionPlane = new Plane(constructionPlane.normal, constructionBlockPos); } else { //constructionPlane = new Plane(hit.normal, constructionBlockPos); } constructionPlane = new Plane(hit.normal, constructionBlockPos); startBlockPos = buildPos; } else { var buildPos = adjacentPos; startBlockPos = buildPos; if (doubleClick) { } else { //lastBlockPos = buildPos; foreach (var pos in positions) { var newPos = buildPos + pos; VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, true); } constructionBlockPos = adjacentPosUnity - hit.normal*World.HalfUnitScale; constructionPlane = new Plane(hit.normal, constructionBlockPos); } } } else // Subtract { PlayClip(sndDelete, true); var buildPos = blockPos; startBlockPos = buildPos; foreach (var pos in positions) { var newPos = buildPos + pos; VoxWorld.SetBlock(newPos, VoxBlockType.Empty, NewBlockColor, true); } constructionBlockPos = adjacentPosUnity - hit.normal*World.HalfUnitScale; constructionPlane = new Plane(hit.normal, constructionBlockPos); } adjacentPlane = new Plane(hit.normal, hit.point); drawStarted = true; blocksModified = true; } break; case VoxInteractionMode.Paint: if (clickDown) { PlayClip(sndPaint, true); if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; var buildPos = blockPos; var positions = prefab.GetWorldPositions(); startBlockPos = buildPos; foreach (var pos in positions) { var newPos = buildPos + pos; var block = VoxWorld.GetBlock(newPos); if (!block.IsEmpty()) { VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, false); //block.BlockColor = NewBlockColor; //block.Modified = true; //VoxWorld.GetChunk(newPos.x, newPos.y, newPos.z, false).RebuildNeeded = true; } } constructionPlane = new Plane(hit.normal, blockPosUnity + hit.normal*World.HalfUnitScale); adjacentPlane = new Plane(hit.normal, hit.point); drawStarted = true; } break; case VoxInteractionMode.Teleport: if (clickDown) { PlayClip(sndTeleport, true); VoxManager.TeleportPlayer(blockPosUnity); constructionPlane = new Plane(hit.normal, adjacentPosUnity - hit.normal*World.HalfUnitScale); adjacentPlane = new Plane(hit.normal, hit.point); } break; } } } } else // Not looking at anything { //Debug.Log("Not Raycasting"); // Raycast against the construction plane float enter = 0f; var posOnPlaneUnity = Vector3.zero; if (constructionPlane.Raycast(ray, out enter)) { posOnPlaneUnity = viewPos + viewForward*enter; } //if (adjacentPlane.Raycast(ray, out enter)) //{ // posOnPlaneUnity = viewPos + viewForward * enter; // var sign = constructionPlane.GetSide(posOnPlaneUnity) ? 1 : -1; // posOnPlaneUnity += constructionPlane.normal * constructionPlane.GetDistanceToPoint(posOnPlaneUnity) * sign; //} var blockPos = VoxTerrain.GetBlockPos(posOnPlaneUnity + constructionPlane.normal * World.HalfUnitScale); var blockPosUnity = VoxTerrain.GetUnityPosition(blockPos); var facePosUnity = blockPosUnity - constructionPlane.normal*World.HalfUnitScale; Crosshair.newPosition = facePosUnity; Crosshair.transform.forward = constructionPlane.normal; if (enter >= minBuildDistance) { switch (interactionMode) { case VoxInteractionMode.Create: if (clickDown) // Create a block in air that is built on the construction plane { if (AddMode) // Add { if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; PlayClip(sndCreate, true); var positions = prefab.GetWorldPositions(); blockPos = doubleClickToIncreaseHeight ? VoxTerrain.GetBlockPos(posOnPlaneUnity - constructionPlane.normal*World.HalfUnitScale) : VoxTerrain.GetBlockPos(posOnPlaneUnity + constructionPlane.normal*World.HalfUnitScale); var buildPos = blockPos; startBlockPos = buildPos; //if (doubleClickToIncreaseHeight) buildPos = buildPos - hit.normal * 2; //lastBlockPos = buildPos; foreach (var pos in positions) { var newPos = buildPos + pos; VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, true); } adjacentPlane = constructionPlane; } else // Subtract { if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; PlayClip(sndDelete, true); inverseAdd = true; // Draw opposite of construction plane var positions = prefab.GetWorldPositions(); //var buildPos = doubleClick ? blockPos + hit.normal : blockPos; var buildPos = VoxTerrain.GetBlockPos(posOnPlaneUnity - constructionPlane.normal*World.HalfUnitScale); //VoxWorld.SetBlock(oppositeBlockPos, new Block(NewBlockColor), true); startBlockPos = buildPos; //lastBlockPos = buildPos; foreach (var pos in positions) { var newPos = buildPos + pos; VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, true); } //constructionPlane = new Plane(constructionPlane.normal, VoxTerrain.GetUnityPosition(buildPos)); adjacentPlane = constructionPlane; //if (UsePrefab) //{ //} //else //{ //} } drawStarted = true; blocksModified = true; } break; case VoxInteractionMode.Paint: break; } } } if (createAtFixedDistance) { fixedDistance = Vector3.Distance(VoxManager.ViewPosition, VoxTerrain.GetUnityPosition(startBlockPos)); } if (drawStarted) { lastBlockPos = startBlockPos; DrawTimer = ActivateDrawTime; } //drawStarted = false; // stop draw when the click is released } else // Now we're drawing, new cubes are always added on construction plane, so we'll only raycast the construction plane { if (!click) drawStarted = false; // stop draw when the click is released if (DrawTimer < 0) { float enter = 0f; var posOnPlaneUnity = Vector3.zero; WorldPos blockPos; Vector3 blockPosUnity; Vector3 facePosUnity; switch (interactionMode) { case VoxInteractionMode.Create: if (createAtFixedDistance) { if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; blockPosUnity = viewPos + viewForward * fixedDistance; blockPos = VoxTerrain.GetBlockPos(blockPosUnity); var positions = prefab.GetWorldPositions(); if (!blockPos.Equals(lastBlockPos)) { foreach (var pos in positions) { var newPos = blockPos + pos; if (AddMode) { VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, true); } else { VoxWorld.SetBlock(newPos, VoxBlockType.Empty, NewBlockColor, true); } } PlayClip(sndCreateDrag); } lastBlockPos = blockPos; } else { if (AddMode) { if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; if (doubleClickToIncreaseHeight) { if (constructionPlane.Raycast(ray, out enter)) { posOnPlaneUnity = viewPos + viewForward*enter; if (!drawSecondLayer) posOnPlaneUnity -= constructionPlane.normal*World.UnitScale; } } else { if (adjacentPlane.Raycast(ray, out enter)) { posOnPlaneUnity = viewPos + viewForward*enter; var sign = constructionPlane.GetSide(posOnPlaneUnity) ? 1 : -1; posOnPlaneUnity += constructionPlane.normal*constructionPlane.GetDistanceToPoint(posOnPlaneUnity)*sign; } } //if (adjacentPlane.Raycast(ray, out enter)) //{ // posOnPlaneUnity = viewPos + viewForward * enter; // var sign = constructionPlane.GetSide(posOnPlaneUnity) ? 1 : -1; // posOnPlaneUnity += constructionPlane.normal * constructionPlane.GetDistanceToPoint(posOnPlaneUnity) * sign; //} //if (constructionPlane.Raycast(ray, out enter)) //{ // posOnPlaneUnity = viewPos + viewForward * enter; // //var sign = constructionPlane.GetSide(posOnPlaneUnity) ? 1 : -1; // //posOnPlaneUnity += constructionPlane.normal * constructionPlane.GetDistanceToPoint(posOnPlaneUnity) * sign; // //if (constructionPlane.Raycast(new Ray(posOnPlaneUnity, adjacentPlane.normal), out enter)) // //{ // // posOnPlaneUnity = viewPos + viewForward * enter; // //} //} //if (doubleClickToIncreaseHeight) //{ // blockPos = VoxTerrain.GetBlockPos(posOnPlaneUnity - constructionPlane.normal * World.HalfUnitScale - constructionPlane.normal * World.UnitScale); //} //else //{ // blockPos = VoxTerrain.GetBlockPos(posOnPlaneUnity + constructionPlane.normal * World.HalfUnitScale); //} blockPos = VoxTerrain.GetBlockPos(posOnPlaneUnity + constructionPlane.normal*World.HalfUnitScale); blockPosUnity = VoxTerrain.GetUnityPosition(blockPos); if (drawStraight) { if (!secondBlockDrawn) { if (!blockPos.Equals(startBlockPos)) { secondBlockPos = blockPos; secondBlockDrawn = true; var drawNormal = secondBlockPos.vector - startBlockPos.vector; if (Mathf.Abs(Vector3.Dot(drawNormal, Vector3.up)) > 0.7f) { secondBlockPos.x = startBlockPos.x; secondBlockPos.z = startBlockPos.z; } else if (Mathf.Abs(Vector3.Dot(drawNormal, Vector3.forward)) > 0.7f) { secondBlockPos.x = startBlockPos.x; secondBlockPos.y = startBlockPos.y; } else if (Mathf.Abs(Vector3.Dot(drawNormal, Vector3.right)) > 0.7f) { secondBlockPos.y = startBlockPos.y; secondBlockPos.z = startBlockPos.z; } } } if (secondBlockDrawn) { var toNewBlock = blockPos.vector - startBlockPos.vector; var drawNormal = secondBlockPos.vector - startBlockPos.vector; var p = Vector3.Project(toNewBlock, drawNormal); blockPos = startBlockPos + p; } } facePosUnity = blockPosUnity - constructionPlane.normal*World.HalfUnitScale; Crosshair.newPosition = facePosUnity; var positions = prefab.GetWorldPositions(); if (!blockPos.Equals(lastBlockPos)) { foreach (var pos in positions) { var newPos = blockPos + pos; VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, true); } PlayClip(sndCreateDrag); } lastBlockPos = blockPos; } else // Subtract mode { if (constructionPlane.Raycast(ray, out enter)) { posOnPlaneUnity = viewPos + viewForward*enter - constructionPlane.normal*World.UnitScale; } //if (inverseAdd) blockPos = VoxTerrain.GetBlockPos(posOnPlaneUnity - constructionPlane.normal * World.HalfUnitScale); //else blockPos = VoxTerrain.GetBlockPos(posOnPlaneUnity + constructionPlane.normal*World.HalfUnitScale); blockPosUnity = VoxTerrain.GetUnityPosition(blockPos); if (drawStraight) { if (!secondBlockDrawn) { if (!blockPos.Equals(startBlockPos)) { secondBlockPos = blockPos; secondBlockDrawn = true; var drawNormal = secondBlockPos.vector - startBlockPos.vector; if (Mathf.Abs(Vector3.Dot(drawNormal, Vector3.up)) > 0.7f) { secondBlockPos.x = startBlockPos.x; secondBlockPos.z = startBlockPos.z; } else if (Mathf.Abs(Vector3.Dot(drawNormal, Vector3.forward)) > 0.7f) { secondBlockPos.x = startBlockPos.x; secondBlockPos.y = startBlockPos.y; } else if (Mathf.Abs(Vector3.Dot(drawNormal, Vector3.right)) > 0.7f) { secondBlockPos.y = startBlockPos.y; secondBlockPos.z = startBlockPos.z; } } } if (secondBlockDrawn) { var toNewBlock = blockPos.vector - startBlockPos.vector; var drawNormal = secondBlockPos.vector - startBlockPos.vector; var p = Vector3.Project(toNewBlock, drawNormal); blockPos = startBlockPos + p; } } facePosUnity = blockPosUnity - constructionPlane.normal*World.HalfUnitScale; Crosshair.newPosition = facePosUnity; if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; var positions = prefab.GetWorldPositions(); if (!lastBlockPos.Equals(blockPos)) { foreach (var pos in positions) { var newPos = blockPos + pos; if (inverseAdd) VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, true); else VoxWorld.SetBlock(newPos, VoxBlockType.Empty, NewBlockColor, true); } PlayClip(sndDeleteDrag); } lastBlockPos = blockPos; } } blocksModified = true; break; case VoxInteractionMode.Paint: if (paintUsingConstructionPlanes) { if (constructionPlane.Raycast(ray, out enter)) { posOnPlaneUnity = viewPos + viewForward*enter; } blockPos = VoxTerrain.GetBlockPos(posOnPlaneUnity - constructionPlane.normal*World.HalfUnitScale); //blockPosUnity = VoxTerrain.GetUnityPosition(blockPos); //facePosUnity = blockPosUnity + constructionPlane.normal*World.HalfUnitScale; Crosshair.newPosition = posOnPlaneUnity; if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; var positions = prefab.GetWorldPositions(); if (!lastBlockPos.Equals(blockPos)) { foreach (var pos in positions) { var newPos = blockPos + pos; var block = VoxWorld.GetBlock(newPos); if (!block.IsEmpty()) { //block.BlockColor = NewBlockColor; //block.Modified = true; //VoxWorld.GetChunk(newPos.x, newPos.y, newPos.z, false).RebuildNeeded = true; VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, false); } } PlayClip(sndPaintDrag); } lastBlockPos = blockPos; } else { if (Physics.Raycast(ray, out hit, RayCastDistance, Layers.value)) // Looking at a block { var chunk = hit.collider.GetComponent<Chunk>(); if (chunk != null) { blockPos = VoxTerrain.GetBlockPos(hit); if (PrefabIndex >= Prefabs.Length || PrefabIndex < 0) break; var prefab = Prefabs[PrefabIndex]; var positions = prefab.GetWorldPositions(); if (!lastBlockPos.Equals(blockPos)) { foreach (var pos in positions) { var newPos = blockPos + pos; var block = VoxWorld.GetBlock(newPos); if (!block.IsEmpty()) { //block.BlockColor = NewBlockColor; //block.Modified = true; //VoxWorld.GetChunk(newPos.x, newPos.y, newPos.z, false).RebuildNeeded = true; VoxWorld.SetBlock(newPos, VoxBlockType.Default, NewBlockColor, false); } } PlayClip(sndPaintDrag); } lastBlockPos = blockPos; } } } break; } } } DrawTimer -= Time.deltaTime; if (blocksModified) { //var playerPos = VoxTerrain.GetBlockPos(VoxManager.Player.position); //for (var px = -3; px < 3; px++) //{ // for (var py = -3; py < 5; py++) // { // for (var pz = -3; pz < 3; pz++) // { // var p = playerPos + new WorldPos(px, py, pz); // var b = VoxWorld.GetBlock(p); // if (b.JustCreated && !b.IsEmpty()) VoxWorld.SetBlock(p, VoxBlockType.Empty, Color.white); // } // } //} } }
public static Vector3 GetUnityPosition(WorldPos pos) { return new Vector3(pos.x * World.UnitScale, pos.y * World.UnitScale, pos.z * World.UnitScale); }