Ejemplo n.º 1
0
		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;
					 }
				 }
			 }
		 }
Ejemplo n.º 2
0
		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;
		}
Ejemplo n.º 3
0
		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]);
					 }
				 }
			 }
		 }
Ejemplo n.º 4
0
		public void SetBlock(WorldPos pos, VoxBlockType blockType, Color blockColor, bool createChunkIfNull = false)
		{
			SetBlock(pos.x, pos.y, pos.z, blockType, blockColor, createChunkIfNull);
		}
Ejemplo n.º 5
0
		public Block GetBlock(WorldPos pos)
		{
			return GetBlock(pos.x, pos.y, pos.z);
		}
Ejemplo n.º 6
0
		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;
		}
Ejemplo n.º 7
0
		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);

		}
Ejemplo n.º 8
0
		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;
		}
Ejemplo n.º 9
0
		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;
		}
Ejemplo n.º 10
0
		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;
		}
Ejemplo n.º 11
0
		// 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();
		}
Ejemplo n.º 12
0
		public static string FileName(WorldPos chunkLocation)
		{
			return chunkLocation.x + "," + chunkLocation.y + "," + chunkLocation.z + ".bin";
		}
Ejemplo n.º 13
0
		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;
		}
Ejemplo n.º 14
0
		void BuildChunk(WorldPos pos)
		{
			if (world.GetChunk(pos.x, pos.y, pos.z) == null)
				world.CreateTerrainChunk(pos.x, pos.y, pos.z);
		}
Ejemplo n.º 15
0
		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;
			}
		}
Ejemplo n.º 16
0
		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);
				//		}
				//	}
				//}
			}
		}
Ejemplo n.º 17
0
		public static Vector3 GetUnityPosition(WorldPos pos)
		{
			return new Vector3(pos.x * World.UnitScale, pos.y * World.UnitScale, pos.z * World.UnitScale);
		}