示例#1
0
        /// <summary>
        /// Evaluate this building design spec to create a set of building internals (floors and vertical elements)
        /// </summary>
        /// <param name="random"></param>
        /// <param name="metadata"></param>
        /// <param name="finder"></param>
        /// <returns></returns>
        public Internals Internals(Func <double> random, INamedDataCollection metadata, Func <KeyValuePair <string, string>[], Type[], ScriptReference> finder)
        {
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Requires(finder != null);
            Contract.Ensures(Contract.Result <Internals>() != null);

            var ground      = _floorSelectors.OfType <GroundMarker>().Single();
            var aboveGround = _floorSelectors.TakeWhile(a => !(a is GroundMarker)).Append(ground).ToArray();
            var belowGround = _floorSelectors.SkipWhile(a => !(a is GroundMarker)).Skip(1).ToArray();

            List <FootprintSelection> footprints = new List <FootprintSelection>();

            //Select above ground floors, then assign indices
            var   above          = SelectFloors(random, metadata, finder, aboveGround, ground, aboveGround: true);
            int   index          = 0;
            float compoundHeight = 0;

            foreach (var run in above.Reverse())
            {
                if (run.Selection.Count > 0)
                {
                    footprints.Add(new FootprintSelection(run.Marker, index));
                    foreach (var floor in run.Selection.Reverse())
                    {
                        floor.Index          = index++;
                        floor.CompoundHeight = compoundHeight;

                        compoundHeight += floor.Height;
                    }
                }
            }

            //Select below ground floors, then assign indices
            var below = SelectFloors(random, metadata, finder, belowGround, ground, aboveGround: false);

            index          = 0;
            compoundHeight = 0;
            foreach (var run in below)
            {
                foreach (var floor in run.Selection)
                {
                    floor.Index          = --index;
                    floor.CompoundHeight = compoundHeight;

                    compoundHeight -= floor.Height;
                }
                footprints.Add(new FootprintSelection(run.Marker, index));
            }

            //Create result object (with floors)
            var internals = new Internals(this, above.Select(a => a.Selection.ToArray()).ToArray(), below.Select(a => a.Selection.ToArray()).ToArray(), footprints.ToArray());

            //Select vertical elements for floors and add to result
            internals.Verticals = SelectVerticals(random, finder, _verticalSelectors, internals.Floors).ToArray();

            //return result
            return(internals);
        }
        public override void Subdivide(Prism bounds, ISubdivisionGeometry geometry, INamedDataCollection hierarchicalParameters)
        {
            _internals = _designer.Internals(Random, HierarchicalParameters, ScriptReference.Find(Random));

            HierarchicalParameters.Set(BuildingInternalsName, _internals);

            base.Subdivide(bounds, geometry, hierarchicalParameters);

            //Create the node which will create the building form the spec
            var building = (SpecBuilding)CreateChild(bounds, Quaternion.Identity, Vector3.Zero, new ScriptReference(typeof(SpecBuilding)));

            //Make sure sibling container subdivide before building
            foreach (var sibling in Parent.Children.OfType <IBuildingContainer>())
            {
                building.AddPrerequisite(sibling, false);
            }

            //Copy neighbour data into building (from container)
            building.Neighbours = Neighbours;
        }