Пример #1
0
        /// <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);
        }
Пример #2
0
 /// <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);
Пример #3
0
 public override void Paste(MapObject o, IDGenerator generator)
 {
     PasteBase(o, generator);
 }
Пример #4
0
 /// <summary>
 /// Creates an exact copy of this object with a new ID.
 /// </summary>
 public abstract MapObject Copy(IDGenerator generator);