private void ChangeTexture(string texture) { if (selection.Is3D()) { GD.Print("3D Selections are not implemented!"); return; } var(start, end, normal) = selection.GetSelectionTuple(); if (normal == Vector3.Zero) { return; } // TODO: Stuff needs to be cached here for performance and memory. foreach (int x in Range(start.x, end.x)) { foreach (int y in Range(start.y, end.y)) { foreach (int z in Range(start.z, end.z)) { VoxelPos pos = new VoxelPos(x, y, z); Voxel voxel = level.GetVoxel(pos, false); if (voxel.IsEmpty()) { continue; } if (normal == Vector3.Up) { voxel.topTexture = texture; } else if (normal == Vector3.Down) { voxel.bottomTexture = texture; } else if (normal == Vector3.Left) { voxel.leftTexture = texture; } else if (normal == Vector3.Right) { voxel.rightTexture = texture; } else if (normal == Vector3.Forward) { voxel.frontTexture = texture; } else if (normal == Vector3.Back) { voxel.backTexture = texture; } } } } level.UpdateMesh(); }
public void ResetSelection() { start = VoxelPos.Origin; end = VoxelPos.Origin; normal = Vector3.Zero; started = false; completed = false; }
public void UpdateSelection(VoxelPos pos) { if (completed) { throw new InvalidOperationException("Selection has been completed."); } if (!started) { throw new InvalidOperationException("Selection has not been started."); } end = pos; }
public void StartSelection(VoxelPos pos, Vector3 normal) { if (started) { throw new InvalidOperationException("Selection has already been started!"); } this.start = pos; this.end = pos; this.normal = normal; started = true; completed = false; }
private void CreateVoxelShape(VoxelPos from, VoxelPos to, Voxel voxel) { for (int x = from.x; x <= to.x; x++) { for (int y = from.y; y <= to.y; y++) { for (int z = from.z; z <= to.z; z++) { var pos = new VoxelPos(x, y, z); level.SetVoxel(pos, voxel.Copy()); } } } }
public override bool Equals(object obj) { if (obj is VoxelPos) { VoxelPos other = (VoxelPos)obj; if (x == other.x && y == other.y && z == other.z) { return(true); } } return(false); }
public Voxel GetVoxel(VoxelPos pos, bool addToLevel) { if (Voxels.ContainsKey(pos)) { return(Voxels[pos]); } var voxel = new Voxel(); if (addToLevel) { Voxels[pos] = voxel; } return(voxel); }
private void Extrude(bool intrude) { if (selection.Is3D()) { GD.Print("3D Selections are not implemented!"); return; } var(start, end, normal) = selection.GetSelectionTuple(); if (normal == Vector3.Zero) { return; } // TODO: Stuff needs to be cached here for performance and memory. foreach (int x in Range(start.x, end.x)) { foreach (int y in Range(start.y, end.y)) { foreach (int z in Range(start.z, end.z)) { VoxelPos pos = new VoxelPos(x, y, z); Voxel voxel = level.GetVoxel(pos, false); string texture = ""; if (voxel.IsEmpty()) { continue; } if (normal == Vector3.Up) { texture = voxel.topTexture; } else if (normal == Vector3.Down) { texture = voxel.bottomTexture; } else if (normal == Vector3.Left) { texture = voxel.leftTexture; } else if (normal == Vector3.Right) { texture = voxel.rightTexture; } else if (normal == Vector3.Forward) { texture = voxel.frontTexture; } else if (normal == Vector3.Back) { texture = voxel.backTexture; } if (texture == "") { texture = "white"; } if (intrude) { level.RemoveVoxel(pos, texture); } else { pos = pos.Translate(normal); level.SetVoxel(pos, new Voxel(texture)); } } } } if (intrude) { selection.Translate(-normal); } else { selection.Translate(normal); } UpdateSelectionHighlight(); }
private void UpdateSelection(Vector3 start, Vector3 direction) { var current = start; // Prevent infinite looping. for (int i = 0; i < 500; i++) { var next = current + direction; var pos = VoxelPos.FromVector3(next); //GD.Print(pos); // Move head and tail of segment to origin. var offset = pos.ToVector3(); var head = next - offset; var tail = current - offset; var voxel = level.GetVoxel(pos, false); //GD.Print(voxel); List <Plane> faces = new List <Plane>(); if (voxel.HasTop()) { faces.Add(TopPlane); } if (voxel.HasBottom()) { faces.Add(BottomPlane); } if (voxel.HasLeft()) { faces.Add(LeftPlane); } if (voxel.HasRight()) { faces.Add(RightPlane); } if (voxel.HasFront()) { faces.Add(FrontPlane); } if (voxel.HasBack()) { faces.Add(BackPlane); } if (faces.Count > 0) { foreach (Plane face in faces) { //GD.Print("here!"); Vector3?intersection = face.IntersectSegment(tail, head); // Note: Both the head and the tail are allowed to end up inside the voxel; because I can't be bothered to properly account for that edge case, // This null check is necessary. if (intersection != null) { Vector3 point = (Vector3)intersection; var normal = face.Normal; // Continue to the next face if the intersection is not within bounds. if (normal.x == 0 && (point.x < 0 || point.x > 1)) { continue; } if (normal.y == 0 && (point.y < 0 || point.y > 1)) { continue; } if (normal.z == 0 && (point.z < 0 || point.z > 1)) { continue; } // Update the selection and exit the search. if (selection.Started()) { selection.UpdateSelection(pos); } else { selection.StartSelection(pos, normal); } UpdateSelectionHighlight(); return; } } } current = next; } UpdateSelectionHighlight(); }
public void SetVoxel(VoxelPos pos, Voxel voxel) { var positions = new VoxelPos[] { pos.Forward(), pos.Backwards(), pos.Right(), pos.Left(), pos.Up(), pos.Down() }.ToList(); for (int i = 0; i < 6; i++) { var neighborPos = positions[i]; var neighbor = GetVoxel(neighborPos, false); if (!neighbor.IsEmpty()) { switch (i) { // Front Neighbor case 0: if (neighbor.HasBack()) { neighbor.backTexture = ""; voxel.frontTexture = ""; } break; // Back Neighbord case 1: if (neighbor.HasFront()) { neighbor.frontTexture = ""; voxel.backTexture = ""; } break; // Right Neighbor case 2: if (neighbor.HasLeft()) { neighbor.leftTexture = ""; voxel.rightTexture = ""; } break; // Left Neighbor case 3: if (neighbor.HasRight()) { neighbor.rightTexture = ""; voxel.leftTexture = ""; } break; // Up Neighbor case 4: if (neighbor.HasBottom()) { neighbor.bottomTexture = ""; voxel.topTexture = ""; } break; // Down Neighbor case 5: if (neighbor.HasTop()) { neighbor.topTexture = ""; voxel.bottomTexture = ""; } break; } } if (neighbor.IsEmpty()) { Voxels.Remove(neighborPos); } } Voxels[pos] = voxel; updateMesh = true; }
public void RemoveVoxel(VoxelPos pos, string texture) { var offsets = new Vector3[] { Vector3.Forward, Vector3.Back, Vector3.Left, Vector3.Right, Vector3.Up, Vector3.Down }.ToList(); var voxel = GetVoxel(pos, false); for (int i = 0; i < 6; i++) { var neighborPos = pos.Translate(offsets[i]); var neighbor = GetVoxel(neighborPos, true); switch (i) { // Front Neighbor case 0: if (!voxel.HasFront()) { neighbor.backTexture = texture; } break; // Back Neighbord case 1: if (!voxel.HasBack()) { neighbor.frontTexture = texture; } break; // Left Neighbor case 2: if (!voxel.HasLeft()) { neighbor.rightTexture = texture; } break; // Right Neighbor case 3: if (!voxel.HasRight()) { neighbor.leftTexture = texture; } break; // Up Neighbor case 4: if (!voxel.HasTop()) { neighbor.bottomTexture = texture; } break; // Down Neighbor case 5: if (!voxel.HasBottom()) { neighbor.topTexture = texture; } break; } } Voxels.Remove(pos); updateMesh = true; }
public void Translate(Vector3 normal) { start = start.Translate(normal); end = end.Translate(normal); }