/// <summary> /// Splits this solid into two solids by intersecting against a plane. /// </summary> /// <param name="plane">The splitting plane</param> /// <param name="back">The back side of the solid</param> /// <param name="front">The front side of the solid</param> /// <param name="generator">The IDGenerator to use</param> /// <returns>True if the plane splits the solid, false if the plane doesn't intersect</returns> public bool Split(Plane plane, out Solid back, out Solid front, IDGenerator generator) { back = front = null; // Check that this solid actually spans the plane var classify = Faces.Select(x => x.ClassifyAgainstPlane(plane)).Distinct().ToList(); if (classify.All(x => x != PlaneClassification.Spanning)) { if (classify.Any(x => x == PlaneClassification.Back)) { back = this; } else if (classify.Any(x => x == PlaneClassification.Front)) { front = this; } return(false); } var backPlanes = new List <Plane> { plane }; var frontPlanes = new List <Plane> { new Plane(-plane.Normal, -plane.DistanceFromOrigin) }; foreach (var face in Faces) { var classification = face.ClassifyAgainstPlane(plane); if (classification != PlaneClassification.Back) { frontPlanes.Add(face.Plane); } if (classification != PlaneClassification.Front) { backPlanes.Add(face.Plane); } } back = CreateFromIntersectingPlanes(backPlanes, generator); front = CreateFromIntersectingPlanes(frontPlanes, generator); CopyBase(back, generator); CopyBase(front, generator); front.Faces.Union(back.Faces).ToList().ForEach(x => { x.Texture = Faces[0].Texture.Clone(); x.AlignTextureToFace(); x.Colour = Colour; }); // Restore textures (match the planes up on each face) foreach (var orig in Faces) { foreach (var face in back.Faces) { var classification = face.ClassifyAgainstPlane(orig.Plane); if (classification != PlaneClassification.OnPlane) { continue; } face.Texture = orig.Texture.Clone(); break; } foreach (var face in front.Faces) { var classification = face.ClassifyAgainstPlane(orig.Plane); if (classification != PlaneClassification.OnPlane) { continue; } face.Texture = orig.Texture.Clone(); break; } } front.Faces.Union(back.Faces).ToList().ForEach(x => x.CalculateTextureCoordinates(true)); return(true); }
/// <summary> /// Copies all the values of the provided object into this one, copying children and faces. /// </summary> public abstract void Paste(MapObject o, IDGenerator generator);
public override void Paste(MapObject o, IDGenerator generator) { PasteBase(o, generator); }
/// <summary> /// Creates an exact copy of this object with a new ID. /// </summary> public abstract MapObject Copy(IDGenerator generator);