private void ExtractEdgesAndNodes() { var branchSymbolParentStack = new TmpNativeStack <BranchEvent>(5); var currentNodeParent = -1; for (int symbolIndex = 0; symbolIndex < inPlaceSymbols.Length; symbolIndex++) { var symbol = inPlaceSymbols[symbolIndex]; if (symbol == customSymbols.diffusionNode) { if (currentNodeParent >= 0) { var newEdge = new DiffusionEdge { nodeAIndex = currentNodeParent, nodeBIndex = working.nodes.Length }; working.allEdges.Add(newEdge); } currentNodeParent = working.nodes.Length; var nodeParams = inPlaceSymbols.parameters[symbolIndex]; var newNode = new DiffusionNode { indexInTarget = symbolIndex, targetParameters = nodeParams, indexInTempAmountList = working.nodeAmountsListA.Length, totalResourceTypes = (nodeParams.length - 1) / 2, diffusionConstant = inPlaceSymbols.parameters[nodeParams, 0], }; newNode.targetParameters.length = nodeParams.length; working.nodes.Add(newNode); for (int resourceType = 0; resourceType < newNode.totalResourceTypes; resourceType++) { var currentAmount = inPlaceSymbols.parameters[nodeParams, resourceType * 2 + 1]; var maxCapacity = inPlaceSymbols.parameters[nodeParams, resourceType * 2 + 1 + 1]; working.nodeAmountsListA.Add(currentAmount); working.nodeAmountsListB.Add(0); working.nodeMaxCapacities.Add(maxCapacity); } } else if (symbol == customSymbols.diffusionAmount) { var modifiedNode = working.nodes[currentNodeParent]; var amountParameters = inPlaceSymbols.parameters[symbolIndex]; inPlaceSymbols.parameters[symbolIndex] = new JaggedIndexing { index = amountParameters.index, length = 0 }; if (currentNodeParent < 0) { // problem: the amount will dissapear continue; } for (int resourceType = 0; resourceType < modifiedNode.totalResourceTypes && resourceType < amountParameters.length; resourceType++) { working.nodeAmountsListA[modifiedNode.indexInTempAmountList + resourceType] += inPlaceSymbols.parameters[amountParameters, resourceType]; } } else if (symbol == customSymbols.branchOpenSymbol) { branchSymbolParentStack.Push(new BranchEvent { openBranchSymbolIndex = symbolIndex, currentNodeParent = currentNodeParent }); } else if (symbol == customSymbols.branchCloseSymbol) { if (branchSymbolParentStack.Count <= 0) { // uh oh. idk how this is happening but it is. probably related to the volumetric destruction and autophagy. break; } var lastBranchState = branchSymbolParentStack.Pop(); currentNodeParent = lastBranchState.currentNodeParent; } } }
public void Execute() { for (int symbolIndex = 0; symbolIndex < symbols.Length; symbolIndex++) { var symbol = symbols[symbolIndex]; if (symbol == branchStartChar) { nativeTurtleStack.Push(currentState); continue; } if (symbol == branchEndChar) { currentState = nativeTurtleStack.Pop(); continue; } if (customRules.hasIdentifiers && customRules.identifier == symbol) { currentState.organIdentity = new UIntFloatColor32(symbols.parameters[symbolIndex, 0]); continue; } if (operationsByKey.TryGetValue(symbol, out var operation)) { operation.Operate( ref currentState, newMeshSizeBySubmesh, symbolIndex, symbols, organData, organInstances, volumetricHandles, spawnEntityBuffer); if (hasVolumetricDestruction && customRules.hasAutophagy && operation.operationType == TurtleOperationType.ADD_ORGAN) { // check for an operation which may have changed the position of the turtle var turtlePosition = currentState.transformation.MultiplyPoint(Vector3.zero); // extract transformation var voxelIndex = volumetricHandles.durabilityWriter.GetVoxelIndexFromLocalSpace(turtlePosition); if (voxelIndex.IsValid) { var lastDestroyCommandTime = volumetricDestructionTimestamps[voxelIndex.Value]; if (lastDestroyCommandTime >= earliestValidDestructionCommand) { symbols[symbolIndex] = customRules.autophagicSymbol; // TODO: can skipping over this whole branching structure work here? could save some time } } } } } var totalVertexes = 0; var totalIndexes = 0; for (int i = 0; i < newMeshSizeBySubmesh.Length; i++) { var meshSize = newMeshSizeBySubmesh[i]; meshSize.indexInVertexes = totalVertexes; meshSize.indexInTriangles = totalIndexes; totalVertexes += meshSize.totalVertexes; totalIndexes += meshSize.totalTriangleIndexes; newMeshSizeBySubmesh[i] = meshSize; } }
private void ExtractEdgesAndNodes() { var branchSymbolParentStack = new TmpNativeStack <BranchEvent>(5); var currentNodeParent = -1; for (int symbolIndex = 0; symbolIndex < sourceData.Length; symbolIndex++) { var symbol = sourceData[symbolIndex]; if (symbol == customSymbols.diffusionNode) { if (currentNodeParent >= 0) { var newEdge = new DiffusionEdge { nodeAIndex = currentNodeParent, nodeBIndex = working.nodes.Length }; working.allEdges.Add(newEdge); } currentNodeParent = working.nodes.Length; var nodeParams = sourceData.parameters[symbolIndex]; var nodeSingleton = matchSingletonData[symbolIndex]; var newNode = new DiffusionNode { indexInTarget = nodeSingleton.replacementSymbolIndexing.index, targetParameters = nodeSingleton.replacementParameterIndexing, indexInTempAmountList = working.nodeAmountsListA.Length, totalResourceTypes = (nodeParams.length - 1) / 2, diffusionConstant = sourceData.parameters[nodeParams, 0], }; newNode.targetParameters.length = nodeParams.length; working.nodes.Add(newNode); for (int resourceType = 0; resourceType < newNode.totalResourceTypes; resourceType++) { var currentAmount = sourceData.parameters[nodeParams, resourceType * 2 + 1]; var maxCapacity = sourceData.parameters[nodeParams, resourceType * 2 + 1 + 1]; working.nodeAmountsListA.Add(currentAmount); working.nodeAmountsListB.Add(0); working.nodeMaxCapacities.Add(maxCapacity); } } else if (symbol == customSymbols.diffusionAmount) { var modifiedNode = working.nodes[currentNodeParent]; var amountParameters = sourceData.parameters[symbolIndex]; if (amountParameters.length == 0) { // the amount has no parameters left. removal will be happening via regular update continue; } // clear out the parameters in the target string, and write the symbol over var nodeSingleton = matchSingletonData[symbolIndex]; targetData.parameters[nodeSingleton.replacementSymbolIndexing.index] = new JaggedIndexing { index = nodeSingleton.replacementParameterIndexing.index, length = 0 }; targetData[nodeSingleton.replacementSymbolIndexing.index] = customSymbols.diffusionAmount; if (currentNodeParent < 0) { // problem: the amount will dissapear continue; } for (int resourceType = 0; resourceType < modifiedNode.totalResourceTypes && resourceType < amountParameters.length; resourceType++) { working.nodeAmountsListA[modifiedNode.indexInTempAmountList + resourceType] += sourceData.parameters[amountParameters, resourceType]; } } else if (symbol == customSymbols.branchOpenSymbol) { branchSymbolParentStack.Push(new BranchEvent { openBranchSymbolIndex = symbolIndex, currentNodeParent = currentNodeParent }); } else if (symbol == customSymbols.branchCloseSymbol) { var lastBranchState = branchSymbolParentStack.Pop(); currentNodeParent = lastBranchState.currentNodeParent; } } }