1
0
Fork 0
Toy-Raytracer/World.cpp
trotFunky 2d396269e0 Pick back up and comment
Clean placeholder code to get it running.
Add comments to clarify working, add TODOs in main,
add some references for the maths.
2023-12-30 14:50:35 +01:00

149 lines
3.5 KiB
C++

//
// Created by trotfunky on 27/05/19.
//
#include "World.h"
World::World(int w, int h, sf::Color groundColor, sf::Color ceilingColor, std::vector<BlockType> worldMap) : w(w), h(h),
groundColor(groundColor), ceilingColor(ceilingColor), map(std::move(worldMap)), player(0,0,0)
{
map.resize(w*h,BlockType::WALL);
}
int World::getW() const
{
return w;
}
int World::getH() const
{
return h;
}
BlockType World::getBlock(float x, float y) const
{
return(map.at(static_cast<int>(x)+w* static_cast<int>(y)));
}
void World::setBlock(BlockType block, int x, int y, int width, int height)
{
for(int i = 0;i<height;i++)
{
for(int j = 0;j<width;j++)
{
if(x+j<w && y+i < h)
{
map.at((y+i)*w+x+j) = block;
}
}
}
}
std::ostream& operator<<(std::ostream& ostream, World const& world)
{
for(int i = 0;i<world.w*world.h;i++)
{
if(i%world.w == 0)
{
ostream << std::endl;
}
switch(world.getBlock(i%world.w,i/world.w))
{
case BlockType::AIR:
{
if(static_cast<int>(world.player.x) == i%world.w && static_cast<int>(world.player.y) == i/world.h)
{
ostream << "P";
}
else
{
ostream << " ";
}
break;
}
case BlockType::WALL:
{
ostream << "W";
break;
}
case BlockType::DOOR:
{
ostream << "D";
break;
}
case BlockType::WINDOW:
{
ostream << "W";
break;
}
}
}
return(ostream);
}
void World::fillColumn(sf::RenderWindow& window, int column, float scale, sf::Color wallColor) const
{
float columnHeight = window.getSize().y*scale;
sf::RectangleShape pixelColumn(sf::Vector2f(1,columnHeight));
pixelColumn.setPosition(column,(window.getSize().y-columnHeight)/2.0);
pixelColumn.setFillColor(wallColor);
window.draw(pixelColumn);
}
float World::castRay(float originX, float originY, float orientation)
{
/*
* Reference used for ray intersection computations :
* https://web.archive.org/web/20220628034315/https://yunes.informatique.univ-paris-diderot.fr/wp-content/uploads/cours/INFOGRAPHIE/08-Raycasting.pdf
*/
float deltaX;
float deltaY;
if(orientation < 45 || orientation > 315)
{
}
else if(orientation < 135)
{
}
else if(orientation < 225)
{
}
else
{
}
return 0;
}
void World::render(sf::RenderWindow& window) const
{
/*
* Draw ground and sky planes through half of the screen, as the walls
* will get drawn over them.
* This doesn't work if we support textures/levels.
*/
sf::RectangleShape ground = sf::RectangleShape(sf::Vector2f(window.getSize().x,window.getSize().y/2.0));
ground.setFillColor(groundColor);
ground.setPosition(0,window.getSize().y/2.0);
sf::RectangleShape ceiling = sf::RectangleShape(sf::Vector2f(window.getSize().x,window.getSize().y/2.0));
ceiling.setFillColor(ceilingColor);
window.draw(ground);
window.draw(ceiling);
/*
* Throw rays and draw walls over the ceiling and ground.
* Only throws in the plane, which doesn't work for levels/3D.
*/
for(int i = 0;i<window.getSize().x;i++)
{
fillColumn(window, i, 0.5);
}
}