Ejemplo n.º 1
0
        /// <summary>
        /// Calculate FIRST from concat element and a
        /// </summary>
        /// <param name="element"></param>
        /// <param name="a"></param>
        /// <returns></returns>
        private List <TerminalProduction> CalculateFirst(IProductionElement element, TerminalProduction a)
        {
            if (element is EpsilonProduction || element is EOFProduction)
            {
                return(new List <TerminalProduction>()
                {
                    a
                });
            }

            if (element is TerminalProduction)
            {
                return(new List <TerminalProduction>()
                {
                    (TerminalProduction)element
                });
            }

            var t  = (element as NonTerminalProduction).NonTerminal;
            var rv = new List <TerminalProduction>();

            rv.AddRange(t.First);
            if (t.First.Contains(new EpsilonProduction()))
            {
                rv.Add(a);
            }
            return(rv);
        }
Ejemplo n.º 2
0
 public LRNodeElement(GrammarRule rule, TerminalProduction production)
 {
     GrammarRule        = rule;
     TerminalProduction = production;
 }
Ejemplo n.º 3
0
        private void DefineTestBldg()
        {
            #region terminals
            var boxTerm   = new TerminalProduction(UnityEngine.GameObject.CreatePrimitive(PrimitiveType.Cube));
            var wallTerm  = new TerminalProduction(TerminalWall).Move(new Vector3(0, -16, 0));
            var archTerm  = new TerminalProduction(TerminalArch).Move(new Vector3(0, -16, 0));  // this particukar .obj isn't centered at 0,0,0 so we shift it's coords as needed
            var plankTerm = new TerminalProduction(WoodPlank).Rotate(Quaternion.AngleAxis(180f, Vector3.right));
            #endregion

            #region outers
            var bldg = new RegistrarProduction("Bldg", new CubeProductionScope(new Bounds(new Vector3(0, 16, 0), new Vector3(32, 32, 32)), Quaternion.identity))
                       .Rotate(Quaternion.AngleAxis(0, Vector3.up))
                       .Scale(new ScaleProduction {
                IsAbsolute = new[] { false, false, false }, Magnitude = new[] { 1f, 1f, 1f }
            });
            ProductionDictionary.Add(bldg.Name, bldg);

            var outerWall    = new RegistrarProduction("TestWall", bldg.Scope).Terminate(archTerm);
            var floorRepeatX = new Func <RegistrarProduction, RepeatProduction>(parentProd =>
                                                                                new RepeatProduction(parentProd)
            {
                Name                = "",
                IsOccluder          = false,
                Magnitude           = 5f,
                RemainderMode       = RepeatRemainderMode.MergeFirstAndLast,
                RepetitionAxis      = ProductionAxis.X,
                ReplicandProduction = parent => new RegistrarProduction("", parent.Scope).Terminate(plankTerm)
            });
            var floorRepeatZ = new Func <RegistrarProduction, RepeatProduction>(parentProd =>
                                                                                new RepeatProduction(parentProd)
            {
                Name                = "",
                IsOccluder          = false,
                Magnitude           = 1.5f,
                RemainderMode       = RepeatRemainderMode.MergeFirstAndLast,
                RepetitionAxis      = ProductionAxis.Z,
                ReplicandProduction = parent => new RegistrarProduction("", parent.Scope).Repeat(floorRepeatX)
            });

            bldg.Select(new SelectProduction(bldg)
            {
                Faces               = new[] { ScopeFace.Front, ScopeFace.Back, ScopeFace.Left, ScopeFace.Right },
                FaceBreadth         = 5f,
                IsAbsolute          = true,
                Name                = "TestWalls",
                SelectandProduction = outerWall
            });

            //bldg.Select(parentProd => new SelectProduction(parentProd)
            //{
            //    Faces = new[] { ScopeFace.Bottom },
            //    FaceBreadth = 1f,
            //    IsAbsolute = true,
            //    Name = "TestFloor",
            //    SelectandProduction = new RegistrarProduction("", parentProd.Scope).Repeat(floorRepeatZ)
            //});
            #endregion

            #region inners

            var wallTest = new Func <RegistrarProduction, SwitchProduction>(parentProd =>
                                                                            new SwitchProduction(parentProd)
            {
                Cases = new List <CaseProduction> {
                    new CaseProduction
                    {
                        Case = parent => parent.Scope.IsOccluded(),
                        Body = parent => new RegistrarProduction("", parent.Scope).Terminate(wallTerm)
                    },
                    new CaseProduction {
                        Case = delegate(RegistrarProduction parent)
                        {
                            var occlusionProbe = new RegistrarProduction("occlusionProbe", parent.Scope)
                            {
                                IsOccluder = true
                            };
                            occlusionProbe.Scale(new ScaleProduction {
                                IsAbsolute = new[] { true, false, true },
                                Magnitude  = new[] {                                                           // make the walls a bit thicker--but not as long.
                                    parent.Scope.Bounds.size.x + .01f,                                         // .51f   //so walls that meet at the corner won't mark each other as occluded;
                                    1f,                                                                        // only walls with adjacent FACES occlude each other
                                    parent.Scope.Bounds.size.z - 1.04f                                         //2.99f    // can we generalize/simplify this trick?
                                }
                            });
                            ModuleProduction.Occluders.Add(occlusionProbe.Scope);
                            return(true);

                            return(!occlusionProbe.Scope.IsOccluded());
                        },
                        Body = parent =>             //RegistrarProduction.Empty
                               new RegistrarProduction("wallOccluder", parent.Scope)
                        {
                            IsOccluder = false
                        }
                        .Scale(new ScaleProduction
                        {
                            IsAbsolute = new[] { true, false, true },
                            Magnitude  = new[] {                                                        // make the walls a bit thicker--but not as long.
                                parent.Scope.Bounds.size.x + .01f,                                      // .51f   //so walls that meet at the corner won't mark each other as occluded;
                                1f,                                                                     // only walls with adjacent FACES occlude each other
                                parent.Scope.Bounds.size.z - 1.02f                                      //2.99f    // can we generalize/simplify this trick?
                            }
                        }).Terminate(boxTerm)
                    }
                },
                DefaultProduction = RegistrarProduction.Empty,
                Name = "wallTest"
            });

            var roomTermCase = new CaseProduction {
                Case = parent => (UnityEngine.Random.Range(0, 5) > 3.5) || parent.Scope.Bounds.size.x < 8 && parent.Scope.Bounds.size.z < 8,
                Body = parent => new SelectProduction(parent)
                {
                    Faces               = new[] { ScopeFace.Front, ScopeFace.Left, ScopeFace.Back, ScopeFace.Right },
                    FaceBreadth         = .5f,
                    IsAbsolute          = true,
                    SelectandProduction = new RegistrarProduction("", parent.Scope).Switch(wallTest)
                }
            };
            var roomDivideX = new CaseProduction {
                Case = parent1 => parent1.Scope.Bounds.size.x >= parent1.Scope.Bounds.size.z,
                Body = parent1 => new DivideProduction(parent1)
                {
                    DivisionAxis = ProductionAxis.X,
                    Divisors     = new [] {
                        new DivisorProduction {
                            DividendProduction = parent2 => (RegistrarProduction)parent2.Clone(), Magnitude = .5f, IsAbsolute = false
                        },
                        new DivisorProduction {
                            DividendProduction = parent2 => (RegistrarProduction)parent2.Clone(), Magnitude = .5f, IsAbsolute = false
                        }
                    }
                }
            };
            var roomDivideZ = new CaseProduction {
                Case = parent1 => parent1.Scope.Bounds.size.x < parent1.Scope.Bounds.size.z,
                Body = parent1 => new DivideProduction(parent1)
                {
                    DivisionAxis = ProductionAxis.Z,
                    Divisors     = new[] {
                        new DivisorProduction {
                            DividendProduction = parent2 => (RegistrarProduction)parent2.Clone(), Magnitude = .5f, IsAbsolute = false
                        },
                        new DivisorProduction {
                            DividendProduction = parent2 => (RegistrarProduction)parent2.Clone(), Magnitude = .5f, IsAbsolute = false
                        }
                    }
                }
            };

            var firstFloorRooms = new RegistrarProduction("FirstFloorRooms", bldg.Scope)
                                  .Scale(new ScaleProduction {
                Magnitude = new[] { 1f, 0.1f, 1f }, IsAbsolute = new[] { false, false, false }
            })
                                  .Switch(parentProd => new SwitchProduction(parentProd)
            {
                Cases = new List <CaseProduction>
                {
                    roomTermCase,
                    roomDivideX,
                    roomDivideZ
                },
                DefaultProduction = RegistrarProduction.Empty
            });
            bldg.BoxSplit(firstFloorRooms);
            #endregion
        }