// addCompetition public void addCompetition(BudType budType, float distanceToBud, Metamer metamer) { if (competition == null) { competition = new MarkerCompetition(budType, distanceToBud, metamer); } else if (competition.budType == budType && competition.distanceToBud > distanceToBud) { competition.distanceToBud = distanceToBud; competition.metamer = metamer; } }
public List <MetamerMarker> getAssociatedMarkers(BudType budType, Metamer metamer) { List <MetamerMarker> associatedMarkers = new List <MetamerMarker>(); for (int n = 0; n < markers.Count; n++) { if (markers[n].competition != null && markers[n].competition.budType == budType && markers[n].competition.metamer == metamer) { associatedMarkers.Add(markers[n]); } } return(associatedMarkers); }
public void addMarkerCompetition(int markerIndex, BudType budType, float distanceToBud, Metamer metamer) { markers[markerIndex].addCompetition(budType, distanceToBud, metamer); }
// appendNewShoots public void appendNewShoots() { if (isBroken) return; // Chain metamer calls if (mainMetamer != null) mainMetamer.appendNewShoots(); if (lateralMetamer != null) lateralMetamer.appendNewShoots(); if (activeBud != BudType.NONE) { // Check bud quality if (budQuality > 0) { // Create shoots... Debug.Assert(activeBud != BudType.NONE); if (activeBud == BudType.TERMINAL) { if (terminalBudState != BudState.DEAD) { mainMetamer = assembleShoot(); terminalBudState = mainMetamer == null ? BudState.DEAD : BudState.NODE; } activeBud = BudType.LATERAL; } else if (activeBud == BudType.LATERAL) { if (lateralBudState != BudState.DEAD) { lateralMetamer = assembleShoot(); lateralBudState = lateralMetamer == null ? BudState.DEAD : BudState.NODE; } activeBud = BudType.NONE; } } } }
// findMarkersInPerceptionCone private void findMarkersInPerceptionCone(BudType budType, float axis, float axisTolerance) { int gridX = tree.treeSystem.getPlantGridX(position.X); int gridY = tree.treeSystem.getPlantGridY(position.Y); Dictionary<int, Dictionary<int, MarkerCell>> levelMarkerGrid; Dictionary<int, MarkerCell> gridRow; MarkerCell gridCell; int gridRange = (int)Math.Floor(tree.perceptionRadius / TreeSystem.PLANT_CELL_SIZE) + 2; if (tree.treeSystem.markerGrid.TryGetValue(tree.levelUid, out levelMarkerGrid)) { for (int i = -gridRange; i < gridRange; i++) { for (int j = -gridRange; j < gridRange; j++) { if (levelMarkerGrid.TryGetValue(gridX + i, out gridRow) && gridRow.TryGetValue(gridY + j, out gridCell)) { for (int n = 0; n < gridCell.markers.Count; n++) { Vector2 relativePosition = (gridCell.markers[n].point - position); float distanceToBud = relativePosition.Length(); Matrix rotationMatrix = Matrix.CreateRotationZ(-axis); relativePosition = Vector2.Transform(relativePosition, rotationMatrix); float markerAngle = (float)Math.Atan2(relativePosition.Y, relativePosition.X); if (markerAngle <= axisTolerance && markerAngle >= -axisTolerance && distanceToBud <= tree.perceptionRadius) { // Add competition results to grid cell gridCell.addMarkerCompetition(n, budType, distanceToBud, this); } } } } } } }
// findAssociatedMarkers private void findAssociatedMarkers(BudType budType) { int gridX = tree.treeSystem.getPlantGridX(position.X); int gridY = tree.treeSystem.getPlantGridY(position.Y); Dictionary<int, Dictionary<int, MarkerCell>> levelMarkerGrid; Dictionary<int, MarkerCell> gridRow; MarkerCell gridCell; int gridRange = (int)Math.Floor(tree.perceptionRadius / TreeSystem.PLANT_CELL_SIZE) + 2; associatedMarkers.Clear(); if (tree.treeSystem.markerGrid.TryGetValue(tree.levelUid, out levelMarkerGrid)) { for (int i = -gridRange; i < gridRange; i++) { for (int j = -gridRange; j < gridRange; j++) { if (levelMarkerGrid.TryGetValue(gridX + i, out gridRow) && gridRow.TryGetValue(gridY + j, out gridCell)) { associatedMarkers.AddRange(gridCell.getAssociatedMarkers(budType, this)); } } } } }
public Metamer(Tree tree, Metamer previousMetamer, BudType activeBud, BudState terminalBudState, BudState lateralBudState, float axis, bool placeBudOnLeft) { this.tree = tree; this.activeBud = activeBud; this.previousMetamer = previousMetamer; this.terminalBudState = terminalBudState; this.lateralBudState = lateralBudState; this.axis = axis; this.placeBudOnLeft = placeBudOnLeft; aabb = new AABB(); isRoot = previousMetamer == null; constraintPoints = new List<Metamer>(); previousConstraintPoints = new List<Metamer>(); associatedMarkers = new List<MetamerMarker>(); fixturesToTest = new Fixture[MAX_FIXTURES_TO_TEST]; localGridHalfWidth = (int)Math.Floor(tree.perceptionRadius / TreeSystem.PLANT_CELL_SIZE) + 2; localGridHalfHeight = (int)Math.Floor(tree.perceptionRadius / TreeSystem.PLANT_CELL_SIZE) + 2; currentAngle = axis; currentTextureAngle = axis; collisionVertices = new Vector2[FarseerPhysics.Settings.MaxPolygonVertices]; collisionNormals = new Vector2[FarseerPhysics.Settings.MaxPolygonVertices]; constraints = new List<MetamerConstraint>(); relatedConstraints = new List<MetamerConstraint>(); _vertices = new VertexPositionColorTexture[2]; // Mass mass = 1f; inverseMass = 1f / mass; // Calculate position position = (isRoot ? tree.position : previousMetamer.position + new Vector2((float)Math.Cos(axis), (float)Math.Sin(axis)) * tree.internodeLength); oldPosition = position; // Trunk constraints if (!isRoot) { if (isApex() && tree.iterations < 2) { // Create anchor constraints Vector2 relative = position - tree.rootPosition; Vector2 anchorA = tree.rootPosition + tree.anchorNormal * 3f; float distance = (anchorA - position).Length(); constraints.Add(new TrunkMetamerConstraint(this, anchorA, distance)); Vector2 anchorB = tree.rootPosition + tree.anchorNormal * -3f; distance = (anchorB - position).Length(); constraints.Add(new TrunkMetamerConstraint(this, anchorB, distance)); } // Create metamer-metamer links if (!previousMetamer.isBroken) internodeConstraint = new DistanceMetamerConstraint(this, previousMetamer, tree.internodeLength * 0.8f, 0.5f); } // Put this metamer in a cell in the metamer grid ci = tree.treeSystem.getPlantGridX(position.X); cj = tree.treeSystem.getPlantGridY(position.Y); if (!tree.treeSystem.metamerGrid.ContainsKey(tree.levelUid)) { tree.treeSystem.metamerGrid.Add(tree.levelUid, new Dictionary<int, Dictionary<int, List<Metamer>>>()); } if (!tree.treeSystem.metamerGrid[tree.levelUid].ContainsKey(ci)) { tree.treeSystem.metamerGrid[tree.levelUid][ci] = new Dictionary<int, List<Metamer>>(); } if (!tree.treeSystem.metamerGrid[tree.levelUid][ci].ContainsKey(cj)) { tree.treeSystem.metamerGrid[tree.levelUid][ci][cj] = new List<Metamer>(); } tree.treeSystem.metamerGrid[tree.levelUid][ci][cj].Add(this); // Destroy markers in the occupied zone destroyMarkersInOccupiedZone(); // Expand level boundary tree.treeSystem.levelSystem.expandFallbackBoundary(tree.levelUid, position); // Determine z-index _z = tree.layerDepth + StasisMathHelper.floatBetween(-0.02f, 0.01f, tree.random); }
public MarkerCompetition(BudType budType, float distanceToBud, Metamer metamer) { this.budType = budType; this.distanceToBud = distanceToBud; this.metamer = metamer; }