Beispiel #1
0
 public bool TryGetValue(int key, out JaggedIndexing value)
 {
     if (dictionaryToIndex.TryGetValue(key, out var index))
     {
         value = rawData[index];
         return(true);
     }
     value = default;
     return(false);
 }
 public float EvaluateExpression(
     NativeArray <float> inputParameters,
     JaggedIndexing parameterSampleSpace,
     NativeArray <OperatorDefinition> operatorData)
 {
     var evaler = new DynamicExpressionEvaluator
     {
         expression            = this,
         inputParameters0      = inputParameters,
         parameterSampleSpace0 = parameterSampleSpace,
         inputParameters1      = default,
Beispiel #3
0
    private void AssertFunctionResults(string expressionString, float[,] calls, object[] results, string[] paramNames = null)
    {
        var expressionCompiler = new ExpressionCompiler(paramNames == null ? new string[0] : paramNames);
        var operatorData       = expressionCompiler.CompileToExpression(expressionString);
        var builder            = new DynamicExpressionData(operatorData, expressionCompiler.parameters.Values.ToArray());

        using var nativeOpData = new NativeArray <OperatorDefinition>(builder.OperatorSpaceNeeded, Allocator.Persistent);

        var paramSize   = (ushort)calls.GetLength(1);
        var inputParams = new NativeArray <float>(paramSize, Allocator.Persistent);
        var opDataSpace = new JaggedIndexing
        {
            index  = 0,
            length = builder.OperatorSpaceNeeded
        };
        var expression = builder.WriteIntoOpDataArray(
            nativeOpData,
            opDataSpace);

        for (int call = 0; call < calls.GetLength(0); call++)
        {
            for (int param = 0; param < calls.GetLength(1); param++)
            {
                inputParams[param] = calls[call, param];
            }
            var result = expression.EvaluateExpression(
                inputParams,
                new JaggedIndexing
            {
                index  = 0,
                length = paramSize
            },
                nativeOpData);
            if (results[call] is float floatVal)
            {
                Assert.AreEqual(result, floatVal);
            }
            else if (results[call] is bool boolValue)
            {
                if (boolValue)
                {
                    Assert.IsTrue(result > 0);
                }
                else
                {
                    Assert.IsFalse(result > 0);
                }
            }
        }

        inputParams.Dispose();
    }
Beispiel #4
0
        public void WriteIntoNativeData(NativeTurtleData nativeData, TurtleNativeDataWriter writer)
        {
            var vertexSlice = new JaggedIndexing
            {
                index  = writer.indexInVertexes,
                length = (ushort)draft.vertexCount
            };

            for (int i = 0; i < vertexSlice.length; i++)
            {
                var vertexDatum = new NativeVertexDatum
                {
                    vertex  = draft.vertices[i],
                    normal  = draft.normals[i],
                    uv      = draft.uvs[i],
                    tangent = draft.tangents[i]
                };
                nativeData.vertexData[i + writer.indexInVertexes] = vertexDatum;
            }
            writer.indexInVertexes += vertexSlice.length;

            var triangleCount = new JaggedIndexing
            {
                index  = writer.indexInTriangles,
                length = (ushort)draft.triangles.Length
            };

            for (int i = 0; i < triangleCount.length; i++)
            {
                nativeData.triangleData[i + writer.indexInTriangles] = draft.triangles[i];
            }
            writer.indexInTriangles += triangleCount.length;

            var existingMaterialIndex = writer.materialsInOrder.IndexOf(material);

            if (existingMaterialIndex == -1)
            {
                existingMaterialIndex = writer.materialsInOrder.Count;
                writer.materialsInOrder.Add(material);
            }
            var blittable = new Blittable
            {
                translation   = translation,
                alsoMove      = alsoMove,
                vertexes      = vertexSlice,
                trianges      = triangleCount,
                materialIndex = (byte)existingMaterialIndex
            };

            nativeData.allOrganData[writer.indexInOrganTemplates] = blittable;
            writer.indexInOrganTemplates++;
        }
        public JaggedIndexing WriteDataFromArray(T[] array)
        {
            for (int i = 0; i < array.Length; i++)
            {
                data[filledIndexInData + i] = array[i];
            }
            var jaggedIndex = new JaggedIndexing
            {
                index  = filledIndexInData,
                length = (ushort)array.Length
            };

            filledIndexInData += array.Length;
            return(jaggedIndex);
        }
 public StructExpression WriteIntoOpDataArray(
     NativeArray <OperatorDefinition> dataArray,
     JaggedIndexing opSpace)
 {
     if (opSpace.length != OperatorSpaceNeeded)
     {
         throw new Exception("not enough space");
     }
     for (int i = 0; i < opSpace.length; i++)
     {
         dataArray[i + opSpace.index] = definitionList[i];
     }
     return(new StructExpression
     {
         operationDataSlice = opSpace
     });
 }
Beispiel #7
0
 private static byte SelectOutcomeIndex(
     ref Unity.Mathematics.Random rand,
     NativeArray <RuleOutcome.Blittable> outcomes,
     JaggedIndexing allOutcomes)
 {
     if (allOutcomes.length > 1)
     {
         var    sample           = rand.NextDouble();
         double currentPartition = 0;
         for (byte i = 0; i < allOutcomes.length; i++)
         {
             var possibleOutcome = outcomes[i + allOutcomes.index];
             currentPartition += possibleOutcome.probability;
             if (sample <= currentPartition)
             {
                 return(i);
             }
         }
         throw new LSystemRuntimeException("possible outcome probabilities do not sum to 1");
     }
     return(0);
 }
Beispiel #8
0
        public void WriteDataIntoMemory(
            SystemLevelRuleNativeData dataArray,
            SymbolSeriesMatcherNativeDataWriter dataWriter)
        {
            ContextSuffix = forwardsMatchBuilder.BuildIntoManagedMemory(dataArray, dataWriter);
            ContextPrefix = backwardsMatchBuilder.BuildIntoManagedMemory(dataArray, dataWriter);

            foreach (var outcome in possibleOutcomes)
            {
                outcome.WriteIntoMemory(dataArray, dataWriter);
            }

            possibleOutcomeIndexing = new JaggedIndexing
            {
                index  = dataWriter.indexInRuleOutcomes,
                length = (ushort)possibleOutcomes.Length
            };
            for (int i = 0; i < possibleOutcomeIndexing.length; i++)
            {
                var possibleOutcome = possibleOutcomes[i];
                dataArray.ruleOutcomeMemorySpace[i + dataWriter.indexInRuleOutcomes] = possibleOutcome.AsBlittable();
            }
            dataWriter.indexInRuleOutcomes += possibleOutcomeIndexing.length;
            if (conditionalChecker != null)
            {
                var opSize = conditionalChecker.OperatorSpaceNeeded;
                conditionalCheckerBlittable = conditionalChecker.WriteIntoOpDataArray(
                    dataArray.dynamicOperatorMemory,
                    new JaggedIndexing
                {
                    index  = dataWriter.indexInOperatorMemory,
                    length = opSize
                });
                dataWriter.indexInOperatorMemory += opSize;
            }
        }
Beispiel #9
0
    public void BasicRuleRejectsApplicationIfAnyParameters()
    {
        var ruleFromString = new BasicRule(
            RuleParser.ParseToRule("A -> AB", x => x),
            '[', ']');
        var totalIncluded = new HashSet <int>("[]AB".Select(x => (int)x));

        using var ruleNativeData = new SystemLevelRuleNativeData(new[] { ruleFromString });
        var nativeWriter = new SymbolSeriesMatcherNativeDataWriter();

        ruleFromString.WriteDataIntoMemory(ruleNativeData, nativeWriter);

        var symbols = new DependencyTracker <SymbolString <float> >(
            new SymbolString <float>(new int[] { 'A' }, new float[][] { new float[0] })
            );

        try
        {
            var globalParams = new float[0];
            using var globalNative = new NativeArray <float>(globalParams, Allocator.Persistent);
            using var paramMemory  = new NativeArray <float>(0, Allocator.Persistent);
            using var branchCache  = new SymbolStringBranchingCache('[', ']', new[] { totalIncluded }, ruleNativeData);
            branchCache.BuildJumpIndexesFromSymbols(symbols);
            var random          = new Unity.Mathematics.Random();
            var matchSingleData = new LSystemSingleSymbolMatchData
            {
                isTrivial = false,
                tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(0)
            };

            var preMatchSuccess = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional(
                branchCache,
                symbols.Data,
                0,
                paramMemory,
                matchSingleData.tmpParameterMemorySpace.index,
                ref matchSingleData,
                new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5),
                globalNative,
                ruleNativeData.dynamicOperatorMemory,
                ref random,
                ruleNativeData.ruleOutcomeMemorySpace
                );
            Assert.IsTrue(preMatchSuccess);
            Assert.AreEqual(0, matchSingleData.selectedReplacementPattern);
            Assert.AreEqual(0, matchSingleData.tmpParameterMemorySpace.length);
            Assert.AreEqual(2, matchSingleData.replacementSymbolIndexing.length);
            Assert.AreEqual(0, matchSingleData.replacementParameterIndexing.length);

            var symbolRawData = symbols.Data;
            symbolRawData.parameters[0] = new JaggedIndexing
            {
                index  = 0,
                length = 1
            };

            matchSingleData = new LSystemSingleSymbolMatchData
            {
                isTrivial = false,
                tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(0)
            };
            preMatchSuccess = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional(
                branchCache,
                symbols.Data,
                0,
                paramMemory,
                matchSingleData.tmpParameterMemorySpace.index,
                ref matchSingleData,
                new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5),
                globalNative,
                ruleNativeData.dynamicOperatorMemory,
                ref random,
                ruleNativeData.ruleOutcomeMemorySpace
                );
            Assert.IsFalse(preMatchSuccess);
        }
        finally
        {
            symbols.Dispose();
        }
    }
Beispiel #10
0
    private void AssertRuleReplacement(
        string ruleText,
        int[] sourceSymbols            = null,
        float[][] sourceParameters     = null,
        string expectedReplacementText = null,
        string axiom = null,
        int ruleParamMemoryStartIndex = 0,
        int matchIndex                      = 0,
        int paramTempMemorySize             = 0,
        float[] globalParams                = null,
        string[] globalParamNames           = null,
        int expectedReplacementPatternIndex = 0,
        string includedSymbols              = "[]ABCDE"
        )
    {
        var totalIncluded = new HashSet <int>(includedSymbols.Select(x => (int)x));

        globalParamNames = globalParamNames ?? new string[0];

        using var symbols = new DependencyTracker <SymbolString <float> >(
                  axiom == null ?
                  new SymbolString <float>(sourceSymbols, sourceParameters)
            : SymbolString <float> .FromString(axiom, Allocator.Persistent)
                  );
        using var expectedReplacement = SymbolString <float> .FromString(expectedReplacementText, Allocator.Persistent);

        var ruleFromString = new BasicRule(
            RuleParser.ParseToRule(ruleText, x => x, globalParameters: globalParamNames),
            '[', ']');

        using var ruleNativeData = new SystemLevelRuleNativeData(new[] { ruleFromString });
        var nativeWriter = new SymbolSeriesMatcherNativeDataWriter();

        ruleFromString.WriteDataIntoMemory(ruleNativeData, nativeWriter);

        globalParams           = globalParams ?? new float[0];
        using var globalNative = new NativeArray <float>(globalParams, Allocator.Persistent);

        var expectedTotalParamReplacement = expectedReplacement.parameters.data.Length;

        using var paramMemory = new NativeArray <float>(paramTempMemorySize, Allocator.Persistent);
        using var branchCache = new SymbolStringBranchingCache('[', ']', new[] { totalIncluded }, ruleNativeData);
        branchCache.BuildJumpIndexesFromSymbols(symbols);
        var random          = new Unity.Mathematics.Random();
        var matchSingleData = new LSystemSingleSymbolMatchData
        {
            isTrivial = false,
            tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(ruleParamMemoryStartIndex)
        };

        var potentialMatch = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional(
            branchCache,
            symbols.Data,
            matchIndex,
            paramMemory,
            matchSingleData.tmpParameterMemorySpace.index,
            ref matchSingleData,
            new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5),
            globalNative,
            ruleNativeData.dynamicOperatorMemory,
            ref random,
            ruleNativeData.ruleOutcomeMemorySpace
            );

        Assert.IsTrue(potentialMatch);
        Assert.AreEqual(expectedReplacementPatternIndex, matchSingleData.selectedReplacementPattern);
        Assert.AreEqual(paramTempMemorySize, matchSingleData.tmpParameterMemorySpace.length, "parameter temp memory size mismatch");
        Assert.AreEqual(expectedReplacement.symbols.Length, matchSingleData.replacementSymbolIndexing.length, "replacement symbols size mismatch");
        Assert.AreEqual(expectedReplacement.parameters.data.Length, matchSingleData.replacementParameterIndexing.length, "replacement parameter size mismatch");

        matchSingleData.replacementSymbolIndexing.index    = 0;
        matchSingleData.replacementParameterIndexing.index = 0;

        using var resultSymbols = new SymbolString <float>(
                  expectedReplacement.symbols.Length,
                  expectedReplacement.parameters.data.Length,
                  Allocator.Persistent);
        ruleFromString.AsBlittable().WriteReplacementSymbols(
            globalNative,
            paramMemory,
            resultSymbols,
            matchSingleData,
            ruleNativeData.dynamicOperatorMemory,
            ruleNativeData.replacementsSymbolMemorySpace,
            ruleNativeData.ruleOutcomeMemorySpace,
            ruleNativeData.structExpressionMemorySpace
            );

        Assert.AreEqual(expectedReplacementText, resultSymbols.ToString());
        Assert.IsTrue(expectedReplacement.Equals(resultSymbols));
    }
Beispiel #11
0
 public TValue this[JaggedIndexing keyIndex, int indexInList]
 {
     get => rawData[keyIndex, indexInList];
Beispiel #12
0
            public bool PreMatchCapturedParametersWithoutConditional(
                SymbolStringBranchingCache branchingCache,
                SymbolString <float> source,
                int indexInSymbols,
                NativeArray <float> parameterMemory,
                int startIndexInParameterMemory,
                ref LSystemSingleSymbolMatchData matchSingletonData,
                TmpNativeStack <SymbolStringBranchingCache.BranchEventData> helperStack,
                NativeArray <float> globalParams,
                NativeArray <OperatorDefinition> globalOperatorData,
                ref Unity.Mathematics.Random random,
                NativeArray <RuleOutcome.Blittable> outcomes)
            {
                var target = targetSymbolWithParameters;

                // parameters
                byte matchedParameterNum = 0;

                // context match
                if (contextPrefix.IsValid && contextPrefix.graphNodeMemSpace.length > 0)
                {
                    var backwardsMatchMatches = branchingCache.MatchesBackwards(
                        branchingCache.includeSymbols[ruleGroupIndex],
                        indexInSymbols,
                        contextPrefix,
                        source,
                        startIndexInParameterMemory + matchedParameterNum,
                        parameterMemory,
                        out var copiedParameters
                        );
                    if (!backwardsMatchMatches)
                    {
                        return(false);
                    }
                    matchedParameterNum += copiedParameters;
                }

                var coreParametersIndexing = source.parameters[indexInSymbols];

                if (coreParametersIndexing.length != target.parameterLength)
                {
                    return(false);
                }
                if (coreParametersIndexing.length > 0)
                {
                    for (int i = 0; i < coreParametersIndexing.length; i++)
                    {
                        var paramValue = source.parameters[coreParametersIndexing, i];

                        parameterMemory[startIndexInParameterMemory + matchedParameterNum] = paramValue;
                        matchedParameterNum++;
                    }
                }

                if (contextSuffix.IsCreated && contextSuffix.graphNodeMemSpace.length > 0)
                {
                    var forwardMatch = branchingCache.MatchesForward(
                        branchingCache.includeSymbols[ruleGroupIndex],
                        indexInSymbols,
                        contextSuffix,
                        source,
                        startIndexInParameterMemory + matchedParameterNum,
                        parameterMemory,
                        out var copiedParameters,
                        helperStack);
                    if (!forwardMatch)
                    {
                        return(false);
                    }
                    matchedParameterNum += copiedParameters;
                }

                matchSingletonData.tmpParameterMemorySpace = new JaggedIndexing
                {
                    index  = startIndexInParameterMemory,
                    length = matchedParameterNum
                };
                if (conditional.IsValid)
                {
                    var conditionalMatch = conditional.EvaluateExpression(
                        globalParams,
                        new JaggedIndexing {
                        index = 0, length = (ushort)globalParams.Length
                    },
                        parameterMemory,
                        matchSingletonData.tmpParameterMemorySpace,
                        globalOperatorData) > 0;
                    if (!conditionalMatch)
                    {
                        return(false);
                    }
                }

                matchSingletonData.selectedReplacementPattern = SelectOutcomeIndex(ref random, outcomes, possibleOutcomeIndexing);
                var outcomeObject = outcomes[matchSingletonData.selectedReplacementPattern + possibleOutcomeIndexing.index];


                matchSingletonData.replacementSymbolIndexing    = JaggedIndexing.GetWithOnlyLength(outcomeObject.replacementSymbolSize);
                matchSingletonData.replacementParameterIndexing = JaggedIndexing.GetWithOnlyLength(outcomeObject.replacementParameterCount);


                return(true);
            }