private void buttonResetSimulation_Click(object sender, EventArgs e) { m_simulationIteration = 0; ReadBackHeat(); m_searchPhase = SEARCH_PHASE.TARGET_ID_SEARCH; m_simulationRadius = 0.0f; if (m_simulationHotSpots.Count > 0) { m_simulationX = m_simulationHotSpots[integerTrackbarControlStartPosition.Value].X; m_simulationY = m_simulationHotSpots[integerTrackbarControlStartPosition.Value].Y; } Array.Clear(m_visited, 0, GRAPH_SIZE * GRAPH_SIZE); // Reset search result Array.Clear(m_bufferSearchResults, 0, GRAPH_SIZE * GRAPH_SIZE); UpdateSearchResults(); }
private void buttonStepSimulation_Click(object sender, EventArgs e) { if (m_simulationIteration < 0) { buttonResetSimulation_Click(sender, e); } m_simulationIteration++; ////////////////////////////////////////////////////////////////////////// // Local search: We start by finding the target ID nearby our start location and ascend the gradient, all the while descending the source gradient float4 current = m_bufferHeat[m_simulationX, m_simulationY]; switch (m_searchPhase) { case SEARCH_PHASE.TARGET_ID_SEARCH: { // At the moment, assume we're standing on a node with the target ID m_targetID = (uint)current.w - 1; // Keep current secondary ID as target ID m_currentGradient = current.x + current.z; for (uint neighborIndex = 0; neighborIndex < 8; neighborIndex++) { int tempX = m_simulationX + dXY[neighborIndex][0]; if (tempX < 0 || tempX >= GRAPH_SIZE) { continue; } int tempY = m_simulationY + dXY[neighborIndex][1]; if (tempY < 0 || tempY >= GRAPH_SIZE) { continue; } float4 neighborValue = m_bufferHeat[tempX, tempY]; uint neighborID = (uint)neighborValue.w - 1; if (neighborID != integerTrackbarControlTargetPosition.Value && m_targetID != 0) { continue; // Not our target ID } m_simulationX = tempX; m_simulationY = tempY; } m_searchPhase = SEARCH_PHASE.TARGET_ASCENT; } break; case SEARCH_PHASE.TARGET_ASCENT: { // We're descending the source gradient (in field #0) and ascending the target gradient (in field #1) float bestGradient = -1; int bestX = m_simulationX, bestY = m_simulationY; for (uint neighborIndex = 0; neighborIndex < 8; neighborIndex++) { int tempX = m_simulationX + dXY[neighborIndex][0]; if (tempX < 0 || tempX >= GRAPH_SIZE) { continue; } int tempY = m_simulationY + dXY[neighborIndex][1]; if (tempY < 0 || tempY >= GRAPH_SIZE) { continue; } if (m_visited[tempX, tempY]) { continue; // Don't bother } float4 neighborValue = m_bufferHeat[tempX, tempY]; float gradient = 0 * neighborValue.x + neighborValue.z; if (gradient < bestGradient) { continue; // Not the ridge! } bestGradient = gradient; bestX = tempX; bestY = tempY; } m_simulationX = bestX; m_simulationY = bestY; // Write a single pixel m_bufferSearchResults[m_simulationX, m_simulationY] = 0x000000FFU; m_visited[m_simulationX, m_simulationY] = true; // Check we're still following the target ID float4 newValue = m_bufferHeat[m_simulationX, m_simulationY]; uint newID = (uint)newValue.w - 1; if (newID != m_targetID) { m_targetID = newID; m_searchPhase = SEARCH_PHASE.SOURCE_DESCENT; // New phase! } } break; case SEARCH_PHASE.SOURCE_DESCENT: { // We're descending the source gradient (in field #1) and ascending the target gradient (in field #0) float bestGradient = -1; int bestX = m_simulationX, bestY = m_simulationY; for (uint neighborIndex = 0; neighborIndex < 8; neighborIndex++) { int tempX = m_simulationX + dXY[neighborIndex][0]; if (tempX < 0 || tempX >= GRAPH_SIZE) { continue; } int tempY = m_simulationY + dXY[neighborIndex][1]; if (tempY < 0 || tempY >= GRAPH_SIZE) { continue; } if (m_visited[tempX, tempY]) { continue; // Don't bother } float4 neighborValue = m_bufferHeat[tempX, tempY]; float gradient = neighborValue.x + 0 * neighborValue.z; if (gradient < bestGradient) { continue; // Not the ridge! } bestGradient = gradient; bestX = tempX; bestY = tempY; } m_simulationX = bestX; m_simulationY = bestY; // Write a single pixel m_bufferSearchResults[m_simulationX, m_simulationY] = 0x000000FFU; m_visited[m_simulationX, m_simulationY] = true; // Check we're still following the target ID float4 newValue = m_bufferHeat[m_simulationX, m_simulationY]; uint newID = (uint)newValue.w - 1; if (newID != m_targetID) { m_searchPhase = SEARCH_PHASE.FINISHED; // We're done! } } break; } // Update search results texture if (sender != null) { UpdateSearchResults(); } }