private void AddNode(CsgNode node) { if (root == null) { return; } CsgNodeWrapper wrapper = root.Node.Repository.GetWrapper(node); CsgNodeTreeViewItem item = nodeView.SelectedItem as CsgNodeTreeViewItem; CsgGroupWrapper selected = null; while (item != null) { selected = item.Node as CsgGroupWrapper; if (selected != null) { break; } item = item.Parent as CsgNodeTreeViewItem; } if (selected == null) { selected = root.Node as CsgGroupWrapper; } if (selected != null) { selected.AddChild(wrapper); } }
public CsgNodeWrapper(CsgNodeWrapperRepository repo, CsgNode node) { Repository = repo; Node = node; if (string.IsNullOrEmpty(node.Id)) { node.Id = Guid.NewGuid().ToString(); } }
public CsgNode Clone() { var node = new CsgNode(); node.Plane = Plane?.Clone(); node.Front = Front?.Clone(); node.Back = Back?.Clone(); node.Polygons = Polygons.Select(p => p.Clone()).ToList(); return(node); }
public CsgNodeWrapper GetWrapper(CsgNode node) { CsgNodeWrapper wrapper; if (!Wrappers.TryGetValue(node, out wrapper)) { if (node is CsgCube) { wrapper = new CsgCubeWrapper(this, (CsgCube)node); } else if (node is CsgTranslate) { wrapper = new CsgTranslateWrapper(this, (CsgTranslate)node); } else if (node is CsgScale) { wrapper = new CsgScaleWrapper(this, (CsgScale)node); } else if (node is CsgRotate) { wrapper = new CsgRotateWrapper(this, (CsgRotate)node); } else if (node is CsgUnion) { wrapper = new CsgUnionWrapper(this, (CsgUnion)node); } else if (node is CsgSubtract) { wrapper = new CsgSubtractWrapper(this, (CsgSubtract)node); } else if (node is CsgIntersect) { wrapper = new CsgIntersectWrapper(this, (CsgIntersect)node); } else if (node is CsgGroup) { wrapper = new CsgGroupWrapper(this, (CsgGroup)node); } else { wrapper = new CsgNodeWrapper(this, node); } Wrappers[node] = wrapper; WrapperIds[wrapper.Id] = wrapper; wrapper.PropertyChanged += WrapperPropertyChanged; OnObjectRootsChanged(); SetDirty(); } return(wrapper); }
public void Invert() { for (int i = 0; i < Polygons.Count; i++) { Polygons[i].Flip(); } Plane.Flip(); Front?.Invert(); Back?.Invert(); var temp = Front; Front = Back; Back = temp; }
public Csgjs Union(Csgjs csg) { if (Polygons.Count == 0) { return(csg.Clone()); } if (csg.Polygons.Count == 0) { return(Clone()); } var a = new CsgNode(Clone().Polygons); var b = new CsgNode(csg.Clone().Polygons); a.ClipTo(b); b.ClipTo(a); b.Invert(); b.ClipTo(a); b.Invert(); a.Build(b.AllPolygons()); return(FromPolygons(a.AllPolygons())); }
public void Build(List <CsgPolygon> polygons) { if (polygons.Count == 0) { return; } if (Plane == null) { // Don't randomly choose a split plane. Coherent results are important. Plane = polygons[polygons.Count / 2].Plane.Clone(); } var frontPolygons = new List <CsgPolygon>(); var backPolygons = new List <CsgPolygon>(); for (int i = 0; i < polygons.Count; i++) { Plane.SplitPolygon(polygons[i], Polygons, Polygons, frontPolygons, backPolygons); } if (frontPolygons.Count > 0) { if (Front == null) { Front = new CsgNode(); } Front.Build(frontPolygons); } if (backPolygons.Count > 0) { if (Back == null) { Back = new CsgNode(); } Back.Build(backPolygons); } }
public void ClipTo(CsgNode bsp) { Polygons = bsp.ClipPolygons(Polygons); Front?.ClipTo(bsp); Back?.ClipTo(bsp); }
public void Dig(CsgNode shape, BoundingSphere shapeBoundary, DigMode digMode, IEnumerable <int> materialFilter) { CsgNode digShape = null; // constraintDiffNode performs the constraint as a CSG operation // by cutting away anything of thge digging shape not inside the allowed area. CsgOpDiff constraintDiffNode = new CsgOpDiff(); // Assemble difference operation by applying all drone constraints. player.AddDroneConstraints(constraintDiffNode, shapeBoundary.Center); // When placing material, add a safety margin around the player to prevent it from physically glitching trough the terrain if (digMode == DigMode.Add) { playerNode.SetParameterFloat("playerRadius", player.Character.CharacterDiameter * 0.5f + 0.2f); playerNode.SetParameterVec3("playerPosition", player.Character.Position); playerNode.SetParameterVec3("digDirX", new vec3(1, 0, 0)); playerNode.SetParameterVec3("digDirZ", new vec3(0, 0, 1)); playerNode.SetParameterVec3("digDirY", new vec3(0, 0, player.Character.BodyHeight * 0.5f + 0.2f)); constraintDiffNode.AddNode(playerNode); } // We apply the constraint by substracting it from the given shape. CsgOpConcat constraintedShape = new CsgOpConcat(); constraintedShape.AddNode(shape); constraintedShape.AddNode(constraintDiffNode); digShape = constraintedShape; CsgNode digNode = null; // Depending on the digging mode, we either add or substract the digging shape from the terrain. if (digMode == DigMode.Substract) { digNode = new CsgOpDiff(digShape); } else { digNode = new CsgOpUnion(digShape); } // Filter for tools CsgNode filterNode = digNode; if (materialFilter != null) { CsgFilterNode filter = new CsgFilterNode(true, digNode); foreach (int mat in materialFilter) { filter.AddMaterial(mat); } filter.AddMaterial(0); // Air must be white-listed, too! filterNode = filter; } // Float elimination CsgOpConcat collapser = new CsgOpConcat(filterNode); collapser.AddNode(new CsgCollapseNode()); // Callback for statistical purposes. CsgStatCallback finalNode = new CsgStatCallback(collapser, 4, 4); finalNode.AddSimpleVolumeCallback("UpvoidMiner", UpvoidMiner.ModDomain, "UpvoidMiner.DiggingController", "StatCallback"); finalNode.AddVolumeChangePointCallback("UpvoidMiner", UpvoidMiner.ModDomain, "UpvoidMiner.DiggingController", "PointCallback"); world.Terrain.ModifyTerrain(shapeBoundary, finalNode); }
protected virtual void UpdateModel() { while (viewport.Children.Count > 1) { viewport.Children.RemoveAt(1); } CsgNodeWrapper wrapper = null; bool resetView = lastModel == null; if (LockToggle.IsChecked.GetValueOrDefault()) { wrapper = lastModel; lastModel.IsViewing = true; } else if (lastModel != null) { lastModel.IsViewing = false; } if (wrapper == null) { wrapper = SelectedItem; } if (lastModel != null) { lastModel.MeshChanged -= ModelMeshChanged; lastModel = null; } if (wrapper == null) { return; } CsgNode root = wrapper.Node; lastModel = wrapper; lastModel.MeshChanged += ModelMeshChanged; modelMin = new Point3D(double.MaxValue, double.MaxValue, double.MaxValue); modelMax = new Point3D(double.MinValue, double.MinValue, double.MinValue); meshGeometry.Clear(); foreach (Mesh3 mesh in GetMeshes()) { mesh.CalculateNormals(); viewport.Children.Add(new ModelVisual3D() { Content = meshGeometry[mesh] = new GeometryModel3D() { Material = defaultMaterial, Geometry = new MeshGeometry3D() { TriangleIndices = new Int32Collection(mesh.TriangleIndices), Normals = new Vector3DCollection(mesh.VertexNormals.Select(x => new Vector3D(x.X, x.Y, x.Z)).ToArray()), Positions = new Point3DCollection(mesh.Vertices.Select(x => { Vector3 transformed = mesh.Transform.Transform(x) + mesh.Position; if (transformed.X < modelMin.X) { modelMin.X = transformed.X; } if (transformed.X > modelMax.X) { modelMax.X = transformed.X; } if (transformed.Y < modelMin.Y) { modelMin.Y = transformed.Y; } if (transformed.Y > modelMax.Y) { modelMax.Y = transformed.Y; } if (transformed.Z < modelMin.Z) { modelMin.Z = transformed.Z; } if (transformed.Z > modelMax.Z) { modelMax.Z = transformed.Z; } return(new Point3D(x.X, x.Y, x.Z)); }).ToArray()) }, Transform = new MatrixTransform3D(mesh.Transform.ToMatrix3D(mesh.Position)) } }); } if (resetView) { ResetView(); } }