Esempio n. 1
0
        void DrawRule <T>(string caption, ref bool ruleEnabled, ref string ruleClassName) where T : ScriptableObject
        {
            GUI.enabled = true;
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(CATEGORY_SPACING);
            ruleEnabled = EditorGUILayout.ToggleLeft(caption, ruleEnabled);
            GUI.enabled = ruleEnabled;
            MonoScript script = null;

            if (ruleClassName != null)
            {
                var rule = instanceCache.GetInstance(ruleClassName) as ScriptableObject;
                if (rule != null)
                {
                    script = MonoScript.FromScriptableObject(rule);
                }
            }
            var oldScript = script;

            script = EditorGUILayout.ObjectField(script, typeof(MonoScript), false) as MonoScript;
            if (oldScript != script && script != null)
            {
                ruleClassName = script.GetClass().FullName;
            }
            else if (script == null)
            {
                ruleClassName = null;
            }

            EditorGUILayout.EndHorizontal();
            GUI.enabled = true;
        }
Esempio n. 2
0
        public virtual void ApplyTheme(List <DungeonPropDataAsset> Themes, DungeonSceneProvider SceneProvider)
        {
            var instanceCache       = new InstanceCache();
            var constraintProcessor = GetComponent <SpatialConstraintProcessor>();

            if (constraintProcessor != null)
            {
                constraintProcessor.Initialize(model, propSockets);
            }

            PropBySocketTypeByTheme_t PropBySocketTypeByTheme = new PropBySocketTypeByTheme_t();

            foreach (DungeonPropDataAsset Theme in Themes)
            {
                CreatePropLookup(Theme, PropBySocketTypeByTheme);
            }

            // Collect all the theme override volumes and prepare their theme lookup
            var overrideVolumes = new List <ThemeOverrideVolume>();
            Dictionary <Graph, DungeonPropDataAsset> GraphToThemeMapping = new Dictionary <Graph, DungeonPropDataAsset>();

            var dungeon = GetComponent <Dungeon>();

            // Process the theme override volumes
            var themeOverrides = GameObject.FindObjectsOfType <ThemeOverrideVolume>();

            foreach (var themeOverride in themeOverrides)
            {
                if (themeOverride.dungeon != dungeon)
                {
                    continue;
                }

                overrideVolumes.Add(themeOverride);
                var graph = themeOverride.overrideTheme;
                if (graph != null && !GraphToThemeMapping.ContainsKey(graph))
                {
                    DungeonPropDataAsset theme = new DungeonPropDataAsset();
                    theme.BuildFromGraph(themeOverride.overrideTheme);
                    GraphToThemeMapping.Add(themeOverride.overrideTheme, theme);

                    CreatePropLookup(theme, PropBySocketTypeByTheme);
                }
            }

            var srandom = new PMRandom(config.Seed);

            // Fill up the prop sockets with the defined mesh data
            for (int i = 0; i < PropSockets.Count; i++)
            {
                PropSocket socket = PropSockets[i];

                DungeonPropDataAsset ThemeToUse = GetBestMatchedTheme(Themes, socket, PropBySocketTypeByTheme); // PropAsset;

                // Check if this socket resides within a override volume
                {
                    var socketPosition = Matrix.GetTranslation(ref socket.Transform);
                    foreach (var volume in overrideVolumes)
                    {
                        if (volume.GetBounds().Contains(socketPosition))
                        {
                            var graph = volume.overrideTheme;
                            if (graph != null && GraphToThemeMapping.ContainsKey(graph))
                            {
                                ThemeToUse = GraphToThemeMapping[volume.overrideTheme];
                                break;
                            }
                        }
                    }
                }

                if (ThemeToUse == null)
                {
                    continue;
                }

                PropBySocketType_t PropBySocketType = PropBySocketTypeByTheme[ThemeToUse];

                if (PropBySocketType.ContainsKey(socket.SocketType))
                {
                    List <PropTypeData> props = PropBySocketType[socket.SocketType];
                    foreach (PropTypeData prop in props)
                    {
                        bool      insertMesh = false;
                        Matrix4x4 transform  = socket.Transform * prop.Offset;

                        if (prop.UseSelectionRule && prop.SelectorRuleClassName != null)
                        {
                            var selectorRule = instanceCache.GetInstance(prop.SelectorRuleClassName) as SelectorRule;
                            if (selectorRule != null)
                            {
                                // Run the selection rule logic to determine if we need to insert this mesh in the scene
                                insertMesh = selectorRule.CanSelect(socket, transform, model, random.UniformRandom);
                            }
                        }
                        else
                        {
                            // Perform probability based selection logic
                            float probability = srandom.GetNextUniformFloat();
                            insertMesh = (probability < prop.Affinity);
                        }

                        if (insertMesh && prop.useSpatialConstraint && prop.spatialConstraint != null)
                        {
                            Matrix4x4 spatialOffset;
                            if (!ProcessSpatialConstraint(constraintProcessor, prop.spatialConstraint, socket, out spatialOffset))
                            {
                                // Fails spatial constraint
                                insertMesh = false;
                            }
                            else
                            {
                                // Apply the offset
                                var markerOffset = socket.Transform;
                                if (prop.spatialConstraint != null && !prop.spatialConstraint.applyMarkerRotation)
                                {
                                    var markerPosition = Matrix.GetTranslation(ref markerOffset);
                                    var markerScale    = Matrix.GetScale(ref markerOffset);
                                    markerOffset = Matrix4x4.TRS(markerPosition, Quaternion.identity, markerScale);
                                }
                                transform = markerOffset * spatialOffset * prop.Offset;
                            }
                        }

                        if (insertMesh)
                        {
                            // Attach this prop to the socket
                            // Apply transformation logic, if specified
                            if (prop.UseTransformRule && prop.TransformRuleClassName != null && prop.TransformRuleClassName.Length > 0)
                            {
                                var transformer = instanceCache.GetInstance(prop.TransformRuleClassName) as TransformationRule;
                                if (transformer != null)
                                {
                                    Vector3    _position, _scale;
                                    Quaternion _rotation;
                                    transformer.GetTransform(socket, model, transform, random.UniformRandom, out _position, out _rotation, out _scale);
                                    var offset = Matrix4x4.TRS(_position, _rotation, _scale);
                                    transform = transform * offset;
                                }
                            }

                            if (prop is GameObjectPropTypeData)
                            {
                                var gameObjectProp = prop as GameObjectPropTypeData;
                                SceneProvider.AddGameObject(gameObjectProp, transform);
                            }
                            else if (prop is GameObjectArrayPropTypeData)
                            {
                                var gameObjectArrayProp = prop as GameObjectArrayPropTypeData;
                                int count = gameObjectArrayProp.Templates.Length;
                                int index = Mathf.FloorToInt(random.GetNextUniformFloat() * count) % count;
                                SceneProvider.AddGameObjectFromArray(gameObjectArrayProp, index, transform);
                            }
                            else if (prop is SpritePropTypeData)
                            {
                                var spriteProp = prop as SpritePropTypeData;
                                SceneProvider.AddSprite(spriteProp, transform);
                            }
                            // TODO: Handle light creation


                            // Add child sockets if any
                            foreach (PropChildSocketData ChildSocket in prop.ChildSockets)
                            {
                                Matrix4x4 childTransform = transform * ChildSocket.Offset;
                                EmitMarker(ChildSocket.SocketType, childTransform, socket.gridPosition, socket.cellId);
                            }

                            if (prop.ConsumeOnAttach)
                            {
                                // Attach no more on this socket
                                break;
                            }
                        }
                    }
                }
            }

            if (constraintProcessor != null)
            {
                constraintProcessor.Cleanup();
            }
        }