Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add artifact demoing grid based approach to state management and light marching #230

Merged
merged 3 commits into from
Sep 26, 2024

Conversation

p4stoboy
Copy link
Contributor

Description

Extends on initial collision casting pattern to show how managing state as grid of cell types can facilitate cool graphics and render patterns (also intro to rudimentary ray marching in 2 dimensions).

Type of change

  • Documentation (update or new)

How Has This Been Tested?

Compiled and ran.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have requested a review from team members on the Pull Request

@lexlam1524
Copy link

this project is so amazing and interesting , cant imagine it can be done by using Splashkit, so i made some change to see can we apply another light source , then we can add another player if we use it in the game project, here is my screen for testing.
image

i made change for march_light() function.
here is the code for marchlight():

void march_light(Grid& grid, std::vector<point_2d> light_sources, int num_rays, double max_distance) {
    // Create a temporary grid to store the luminance values for each light source
    for (auto& cell : grid.cells) {
            cell.luminance = 0.0;
        }
    
    for (const auto& light_source : light_sources){
        Grid temp_grid = grid;
        // Reset luminance for the current light source
        for (int i = 0; i < num_rays; ++i) {
            double angle = i * (360.0 / num_rays);
            vector_2d direction = vector_from_angle(angle, 1.0);

            // Current position along the ray
            double current_x = light_source.x;
            double current_y = light_source.y;

            double total_distance = 0.0;

            while (total_distance <= max_distance) {
                int cell_x = static_cast<int>(current_x / CELL_SIZE);
                int cell_y = static_cast<int>(current_y / CELL_SIZE);

                // Calculate next cell in both X and Y directions
                int next_cell_x = static_cast<int>((current_x + direction.x * (CELL_SIZE / 2.0)) / CELL_SIZE);
                int next_cell_y = static_cast<int>((current_y + direction.y * (CELL_SIZE / 2.0)) / CELL_SIZE);

                bool hit_wall = false;

                // Check current and next cells for walls (to account for diagonal gaps)
                if (cell_x >= 0 && cell_x < grid.width && cell_y >= 0 && cell_y < grid.height) {
                    Cell& current_cell = grid.cells[cell_y * grid.width + cell_x];

                    // Update luminance
                    double luminosity = std::max(0.0, 1.0 - total_distance / max_distance);
                    if (luminosity > current_cell.luminance) {
                        current_cell.luminance = luminosity;
                    }

                    // Check for wall hit in current cell
                    if (current_cell.type == CellType::Wall) {
                        hit_wall = true;
                    }
                }

                // Check next cells for diagonal wall detection
                if (!hit_wall && next_cell_x >= 0 && next_cell_x < grid.width && cell_y >= 0 && cell_y < grid.height &&
                    grid.cells[cell_y * grid.width + next_cell_x].type == CellType::Wall) {
                    hit_wall = true;
                }
                if (!hit_wall && cell_x >= 0 && cell_x < grid.width && next_cell_y >= 0 && next_cell_y < grid.height &&
                    grid.cells[next_cell_y * grid.width + cell_x].type == CellType::Wall) {
                    hit_wall = true;
                }

                if (hit_wall || cell_x < 0 || cell_x >= grid.width || cell_y < 0 || cell_y >= grid.height) {
                    // We've hit a wall or left the grid
                    break;
                }

                // Move to next position
                current_x += direction.x * (CELL_SIZE / 2.0);
                current_y += direction.y * (CELL_SIZE / 2.0);
                total_distance += CELL_SIZE / 2.0;
            }
        }

        // Add the luminance values from the current light source to the main grid
        for (int i = 0; i < grid.cells.size(); ++i) {
            grid.cells[i].luminance += temp_grid.cells[i].luminance;
        }
    }
}
```, 
and call it inside main():

point_2d light_source2 = {100, 100}; // one more position
point_2d mouse = mouse_position();
std::vector<point_2d> light_sources = {mouse, light_source2};
march_light(grid, light_sources, NUM_RAYS, MAX_LIGHT_DISTANCE);
```

also change the types.h for march_light() .
it is very amazing that you can apply light effect so smoothly.
i can make a commit if you want

@AmberPotion AmberPotion merged commit 14bf03f into thoth-tech:main Sep 26, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants