Esempio n. 1
0
        public LSystemSymbolReplacementCompletable(
            Unity.Mathematics.Random randResult,
            LSystemState <float> lastSystemState,
            int totalNewSymbolSize,
            int totalNewParamSize,
            NativeArray <float> globalParamNative,
            NativeArray <float> tmpParameterMemory,
            NativeArray <LSystemSingleSymbolMatchData> matchSingletonData,
            DependencyTracker <SystemLevelRuleNativeData> nativeData,
            SymbolStringBranchingCache branchingCache,
            CustomRuleSymbols customSymbols)
        {
            this.lastSystemState    = lastSystemState;
            this.matchSingletonData = matchSingletonData;
            this.branchingCache     = branchingCache;
            UnityEngine.Profiling.Profiler.BeginSample("allocating");
            target = new SymbolString <float>(totalNewSymbolSize, totalNewParamSize, Allocator.Persistent);
            UnityEngine.Profiling.Profiler.EndSample();

            this.randResult = randResult;

            this.nativeData = nativeData;

            // 5
            UnityEngine.Profiling.Profiler.BeginSample("generating replacements");

            var replacementJob = new RuleReplacementJob
            {
                globalParametersArray = globalParamNative,

                parameterMatchMemory = tmpParameterMemory,
                matchSingletonData   = matchSingletonData,

                sourceData            = lastSystemState.currentSymbols.Data,
                structExpressionSpace = nativeData.Data.structExpressionMemorySpace,
                globalOperatorData    = nativeData.Data.dynamicOperatorMemory,
                replacementSymbolData = nativeData.Data.replacementsSymbolMemorySpace,
                outcomeData           = nativeData.Data.ruleOutcomeMemorySpace,

                targetData = target,
                blittableRulesByTargetSymbol = nativeData.Data.blittableRulesByTargetSymbol,
                branchingCache = branchingCache,
                customSymbols  = customSymbols
            };

            currentJobHandle = replacementJob.Schedule(
                matchSingletonData.Length,
                100
                );

            if (customSymbols.hasDiffusion && !customSymbols.independentDiffusionUpdate)
            {
                diffusionHelper = new DiffusionWorkingDataPack(10, 5, 2, customSymbols, Allocator.TempJob);
                var diffusionJob = new ParallelDiffusionReplacementJob
                {
                    matchSingletonData = matchSingletonData,
                    sourceData         = lastSystemState.currentSymbols.Data,
                    targetData         = target,
                    customSymbols      = customSymbols,
                    working            = diffusionHelper
                };
                currentJobHandle = JobHandle.CombineDependencies(
                    currentJobHandle,
                    diffusionJob.Schedule()
                    );
            }
            // only parameter modifications beyond this point
            lastSystemState.currentSymbols.RegisterDependencyOnData(currentJobHandle);
            nativeData.RegisterDependencyOnData(currentJobHandle);

            currentJobHandle = JobHandle.CombineDependencies(
                JobHandle.CombineDependencies(
                    ScheduleIdAssignmentJob(currentJobHandle, customSymbols, lastSystemState),
                    ScheduleIndependentDiffusion(currentJobHandle, customSymbols)
                    ),
                JobHandle.CombineDependencies(
                    ScheduleAutophagyJob(currentJobHandle, customSymbols),
                    ScheduleImmaturityJob(currentJobHandle)
                    ));

            UnityEngine.Profiling.Profiler.EndSample();
        }
Esempio n. 2
0
        /// <summary>
        /// Returns a random element with the chances of rolling based on <paramref name="weights"/>
        /// </summary>
        /// <param name="weights">Positive floats representing weights. Negative values may lead to unpredictable behaviour.</param>
        public static T GetRandom <T>(this IReadOnlyList <T> list, IReadOnlyList <float> weights, ref MRandom random)
        {
            if (list == null)
            {
                throw new ArgumentNullException(nameof(list));
            }
            if (list.Count == 0)
            {
                throw new ArgumentException("Empty list");
            }
            if (weights == null)
            {
                throw new ArgumentNullException(nameof(weights));
            }
            if (weights.Count == 0)
            {
                throw new ArgumentException("Empty weights");
            }
            if (list.Count != weights.Count)
            {
                throw new ArgumentException("Array sizes must be equal");
            }

            if (list.Count == 1)
            {
                return(list[0]);
            }

            var cumulative = new List <float>(weights);

            for (int i = 1; i < cumulative.Count; i++)
            {
                cumulative[i] += cumulative[i - 1];
            }

            float randomValue = random.NextFloat(0, cumulative[cumulative.Count - 1]);
            int   index       = cumulative.FindIndex(a => a >= randomValue);

            if (index == -1)
            {
                throw new ArgumentException("Weights must be positive");
            }
            return(list[index]);
        }
Esempio n. 3
0
        /// <summary>
        /// Returns a random value from the dictionary
        /// </summary>
        public static TValue GetRandom <TKey, TValue>(this IDictionary <TKey, TValue> dictionary, ref MRandom random)
        {
            if (dictionary == null)
            {
                throw new ArgumentNullException(nameof(dictionary));
            }
            var keys = dictionary.Keys;

            if (keys.Count == 0)
            {
                throw new ArgumentException("Empty dictionary");
            }
            return(dictionary[new List <TKey>(keys).GetRandom(ref random)]);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="lastSystemState"></param>
        /// <param name="lSystemNativeData"></param>
        /// <param name="globalParameters"></param>
        /// <param name="maxMemoryRequirementsPerSymbol"></param>
        /// <param name="branchOpenSymbol"></param>
        /// <param name="branchCloseSymbol"></param>
        /// <param name="includedCharactersByRuleIndex"></param>
        /// <param name="customSymbols"></param>
        /// <param name="parameterModificationJobDependency">A dependency on a job which only makes changes to the parameters of the source symbol string.
        ///     the symbols themselves must be constant</param>
        public LSystemRuleMatchCompletable(
            NativeArray <LSystemSingleSymbolMatchData> matchSingletonData,
            int parameterTotalSum,
            SymbolStringBranchingCache branchingCache,
            LSystemState <float> lastSystemState,
            DependencyTracker <SystemLevelRuleNativeData> lSystemNativeData,
            float[] globalParameters,
            CustomRuleSymbols customSymbols,
            JobHandle parameterModificationJobDependency)
        {
            this.customSymbols   = customSymbols;
            this.lastSystemState = lastSystemState;
            randResult           = lastSystemState.randomProvider;
            nativeData           = lSystemNativeData;

            this.matchSingletonData = matchSingletonData;
            this.branchingCache     = branchingCache;

            // 1.
            UnityEngine.Profiling.Profiler.BeginSample("allocating");
            tmpParameterMemory = new NativeArray <float>(parameterTotalSum, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            globalParamNative  = new NativeArray <float>(globalParameters, Allocator.Persistent);
            UnityEngine.Profiling.Profiler.EndSample();

            // 2.
            UnityEngine.Profiling.Profiler.BeginSample("matching");


            var prematchJob = new RuleCompleteMatchJob
            {
                matchSingletonData = matchSingletonData,

                sourceData         = lastSystemState.currentSymbols.Data,
                tmpParameterMemory = tmpParameterMemory,

                globalOperatorData = nativeData.Data.dynamicOperatorMemory,
                outcomes           = nativeData.Data.ruleOutcomeMemorySpace,
                globalParams       = globalParamNative,

                blittableRulesByTargetSymbol = nativeData.Data.blittableRulesByTargetSymbol,
                branchingCache = branchingCache,
                seed           = randResult.NextUInt()
            };

            var matchingJobHandle = prematchJob.ScheduleBatch(
                matchSingletonData.Length,
                100,
                parameterModificationJobDependency);


            UnityEngine.Profiling.Profiler.EndSample();

            // 4.
            UnityEngine.Profiling.Profiler.BeginSample("replacement counting");

            UnityEngine.Profiling.Profiler.BeginSample("allocating");
            totalSymbolCount          = new NativeArray <int>(1, Allocator.Persistent);
            totalSymbolParameterCount = new NativeArray <int>(1, Allocator.Persistent);
            UnityEngine.Profiling.Profiler.EndSample();

            var totalSymbolLengthJob = new RuleReplacementSizeJob
            {
                matchSingletonData        = matchSingletonData,
                totalResultSymbolCount    = totalSymbolCount,
                totalResultParameterCount = totalSymbolParameterCount,
                sourceData    = lastSystemState.currentSymbols.Data,
                customSymbols = customSymbols
            };

            currentJobHandle = totalSymbolLengthJob.Schedule(matchingJobHandle);
            lastSystemState.currentSymbols.RegisterDependencyOnData(currentJobHandle);
            nativeData.RegisterDependencyOnData(currentJobHandle);

            UnityEngine.Profiling.Profiler.EndSample();
        }
Esempio n. 5
0
            unsafe int UpdateCentroids()
            {
                int *hassign = stackalloc int[k];

                for (int i = 0; i < k; ++i)
                {
                    hassign[i] = 0;
                }

                Debug.Assert(centroids.Length == d * k);

                for (int i = 0; i < centroids.Length; ++i)
                {
                    centroids[i] = 0.0f;
                }

                for (int i = 0; i < numSamples; ++i)
                {
                    int ci = distances[i].index;
                    Debug.Assert(ci >= 0 && ci < k);
                    hassign[ci]++;
                    for (int j = 0; j < d; ++j)
                    {
                        centroids[ci * d + j] += features[i * d + j];
                    }
                }

                for (int ci = 0; ci < k; ci++)
                {
                    var ni = hassign[ci];
                    if (ni != 0)
                    {
                        for (int j = 0; j < d; ++j)
                        {
                            centroids[ci * d + j] /= (float)ni;
                        }
                    }
                }

                //
                // Take care of void clusters
                //

                int nsplit = 0;

                var random = new Unity.Mathematics.Random(1234);

                for (int ci = 0; ci < k; ++ci)
                {
                    //
                    // need to redefine a centroid
                    //

                    if (hassign[ci] == 0)
                    {
                        int cj = 0;
                        while (true)
                        {
                            //
                            // probability to pick this cluster for split
                            //

                            float p = (hassign[cj] - 1.0f) / (float)(numSamples - k);
                            float r = random.NextFloat();

                            if (r < p)
                            {
                                //
                                // found our cluster to be split
                                //
                                break;
                            }

                            cj = (cj + 1) % k;
                        }

                        for (int j = 0; j < d; ++j)
                        {
                            centroids[ci * d + j] = centroids[cj * d + j];
                        }

                        //
                        // small symmetric perturbation
                        //

                        float eps = 1.0f / 1024.0f;
                        for (int j = 0; j < d; ++j)
                        {
                            if (j % 2 == 0)
                            {
                                centroids[ci * d + j] *= 1 + eps;
                                centroids[cj * d + j] *= 1 - eps;
                            }
                            else
                            {
                                centroids[ci * d + j] *= 1 - eps;
                                centroids[cj * d + j] *= 1 + eps;
                            }
                        }

                        //
                        // assume even split of the cluster
                        //

                        hassign[ci]  = hassign[cj] / 2;
                        hassign[cj] -= hassign[ci];

                        nsplit++;
                    }
                }

                return(nsplit);
            }
Esempio n. 6
0
        protected override void OnUpdate()
        {
            ComponentDataFromEntity <BugComponent> bugComponent = GetComponentDataFromEntity <BugComponent>();
            BufferFromEntity <EntityBufferElement> entityBuffer = GetBufferFromEntity <EntityBufferElement>();

            var time = Time.DeltaTime;

            timeSinceStart += time;
            var random = new Random((uint)(timeSinceStart * 1000f));

            //Recursive method of finding chains of one color, some kind of flood fill
            void FindChainRec(
                Entity entity,
                BugComponent ball,
                BugColor neededColor,
                DynamicBuffer <EntityBufferElement> adjacentEntities,
                NativeHashMap <Entity, bool> chainMap)
            {
                if (!chainMap.ContainsKey(entity) && ball.Color == neededColor)
                {
                    chainMap.Add(entity, true);
                }

                for (int i = 0; i < adjacentEntities.Length; i++)
                {
                    var adjacentEntity = adjacentEntities[i].Value;
                    var adjacentBall   = bugComponent[adjacentEntity];
                    if (!chainMap.ContainsKey(adjacentEntity) && adjacentBall.Color == neededColor)
                    {
                        chainMap.Add(adjacentEntity, true);
                        var nextBall     = bugComponent[adjacentEntity];
                        var nextAdjacent = entityBuffer[adjacentEntity];
                        FindChainRec(adjacentEntity, nextBall, neededColor, nextAdjacent, chainMap);
                    }
                }
            }

            var minChainSize  = minimumChainSize;
            var commandBuffer = barrier.CreateCommandBuffer().ToConcurrent();

            Dependency = Entities.ForEach((Entity entity, int nativeThreadIndex, int entityInQueryIndex,
                                           in BugComponent bug, in DynamicBuffer <EntityBufferElement> adjacentEntities, in ChainMarkComponent mark) =>
            {
                commandBuffer.RemoveComponent <ChainMarkComponent>(nativeThreadIndex, entity);
                BugColor neededColor = mark.NeededColor;

                //Should be HashSet as we don't need value here, but there is no NativeHashSet at the moment
                NativeHashMap <Entity, bool> chainMap = new NativeHashMap <Entity, bool>(100, Allocator.Temp);
                FindChainRec(entity, bug, neededColor, adjacentEntities, chainMap);
                var keys = chainMap.GetKeyArray(Allocator.Temp);
                if (keys.Length >= minChainSize)
                {
                    //Trigger spawning additional bugs
                    commandBuffer.AddComponent <SpawnMarkComponent>(nativeThreadIndex, entity);
                    commandBuffer.SetComponent(nativeThreadIndex, entity, new SpawnMarkComponent
                    {
                        Count = keys.Length
                    });

                    for (var i = 0; i < keys.Length; i++)
                    {
                        //Remove popped bugs with delay
                        commandBuffer.AddComponent <RemoveMarkComponent>(nativeThreadIndex, keys[i]);
                        commandBuffer.SetComponent(nativeThreadIndex, keys[i], new RemoveMarkComponent
                        {
                            DelayMs = random.NextInt(0, 20)
                        });
                    }
                }
                chainMap.Dispose();
            })
Esempio n. 7
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            float  deltaTime           = Time.DeltaTime;
            uint   seed                = (uint)(UnityEngine.Random.value * 10000);
            Random random              = new Random(seed);
            var    entityCommandBuffer = _commandBufferSystem.CreateCommandBuffer().ToConcurrent();

            JobHandle jobHandle = Entities.ForEach(
                (Entity entity, int entityInQueryIndex, ref UnitSpawnerData spawnerData) =>
            {
                if (spawnerData._spawnInActive)
                {
                    return;
                }

                // Spawn Light Enemy Update Time
                if (spawnerData._currentLightUnitTime <= 0)
                {
                    if (spawnerData._currentLightEntityInBetweenTime <= 0)
                    {
                        float value = random.NextFloat();
                        if (value <= 0.5f)
                        {
                            entityCommandBuffer.Instantiate(entityInQueryIndex, spawnerData.lightEntityA);
                        }
                        else
                        {
                            entityCommandBuffer.Instantiate(entityInQueryIndex, spawnerData.lightEntityB);
                        }

                        spawnerData._currentLightEntityCount += 1;
                        if (spawnerData._currentLightEntityCount >= spawnerData.lightEntityBurstCount)
                        {
                            spawnerData._currentLightUnitTime = spawnerData
                                                                ._currentDeadPerSec
                                                                .Map(spawnerData.minDeathPerSec, spawnerData.maxDeathPerSec,
                                                                     spawnerData.maxTimeBetweenLightEntity, spawnerData.minTimeBetweenLightEntity);

                            spawnerData._currentLightEntityCount = 0;
                        }
                        else
                        {
                            spawnerData._currentLightEntityInBetweenTime = spawnerData.lightBurstTimeBetween;
                        }
                    }
                    else
                    {
                        spawnerData._currentLightEntityInBetweenTime -= deltaTime;
                    }
                }
                else
                {
                    spawnerData._currentLightUnitTime -= deltaTime;
                }

                // Spawn Heavy Enemy Update Time
                if (spawnerData._currentHeavyUnitTime <= 0)
                {
                    float value = random.NextFloat();
                    if (value <= 0.5f)
                    {
                        entityCommandBuffer.Instantiate(entityInQueryIndex, spawnerData.heavyEntityA);
                    }
                    else
                    {
                        entityCommandBuffer.Instantiate(entityInQueryIndex, spawnerData.heavyEntityB);
                    }

                    spawnerData._currentHeavyUnitTime = spawnerData
                                                        ._currentDeadPerSec
                                                        .Map(spawnerData.minDeathPerSec, spawnerData.maxDeathPerSec,
                                                             spawnerData.maxTimeBetweenHeavyEntity, spawnerData.maxTimeBetweenHeavyEntity);
                }
                else
                {
                    spawnerData._currentHeavyUnitTime -= deltaTime;
                }
            }).Schedule(inputDeps);

            _commandBufferSystem.AddJobHandleForProducer(jobHandle);

            return(jobHandle);
        }
Esempio n. 8
0
        // returns ushort in [1..ushort.MaxValue - 1] range
        public static ushort GetRandomUShort()
        {
            var rnd = new Unity.Mathematics.Random((uint)Stopwatch.GetTimestamp());

            return((ushort)rnd.NextUInt(1, 0xffff));
        }
Esempio n. 9
0
 /// <summary>
 /// Create a new <see cref="BaseRandom"/> instance with the given <paramref name="seed"/>
 /// </summary>
 /// <param name="seed">The seed that should be used to generate random numbers.</param>
 protected BaseRandom(uint seed)
 {
     Random = new Unity.Mathematics.Random(seed);
 }
Esempio n. 10
0
 /// <summary>
 /// Create a new <see cref="BaseRandom"/> instance with a random seed.
 /// </summary>
 protected BaseRandom()
 {
     Random = new Unity.Mathematics.Random((uint)DateTime.Now.Millisecond);
 }