SFML_Experiments/3DTest/RayMarch.hpp

144 lines
3.3 KiB
C++

#include "SynGame.hpp"
class RayMarch
{
private:
Sphere *spheres;
Sphere *closest;
Vector3 direction;
Vector3 position;
int sphereSize;
int stepLimit;
int stepCounter;
float minDistance;
float maxDistance;
float GetClosestDistance();
Sphere *GetClosestSphere();
public:
RayMarch();
RayMarch(Vector3, Vector3, Sphere *, int = 0);
void SetRay(Vector3, Vector3, Sphere *, int = 0, int = 100, float = 0.01);
void SetPosition(Vector3, Vector3);
int GetStepCount();
sf::Color FireRay();
};
RayMarch::RayMarch()
{
this -> position = (0.0, 0.0);
this -> direction = (0.0, 0.0);
this -> spheres = NULL;
stepCounter = 0;
sphereSize = 0;
minDistance = 0.01;
stepLimit = 100;
maxDistance = 100.0;
}
RayMarch::RayMarch(Vector3 position, Vector3 direction, Sphere *spheres, int size)
{
this -> position = position;
this -> direction = direction;
this -> spheres = spheres;
sphereSize = size;
stepCounter = 0;
minDistance = 0.01;
stepLimit = 100;
maxDistance = 100.0;
}
void RayMarch::SetRay(Vector3 position, Vector3 direction, Sphere *spheres, int size, int stepLimit, float minDistance)
{
this -> position = position;
this -> direction = direction;
this -> spheres = spheres;
this -> sphereSize = size;
this -> stepLimit = stepLimit;
this -> minDistance = minDistance;
stepCounter = 0;
}
void RayMarch::SetPosition(Vector3 position, Vector3 direction)
{
this -> position = position;
this -> direction = direction;
stepCounter = 0;
}
Sphere *RayMarch::GetClosestSphere()
{
int i;
Sphere *ptr = spheres;
Sphere *closestSphere = NULL;
float closestDistance;
float distance;
if(!ptr) return NULL;
closestDistance = position.Distance((*ptr).position) - (*ptr).radius;
for (i = 0; i < sphereSize; i++)
{
distance = position.Distance((*ptr).position) - (*ptr).radius;
if(distance < closestDistance)
{
closestDistance = distance;
closestSphere = ptr;
}
ptr++;
}
return closestSphere;
}
float RayMarch::GetClosestDistance()
{
int i;
Sphere *ptr = spheres;
float closestDistance;
float distance;
if(!ptr) return 0.0;
closestDistance = position.Distance((*ptr).position) - (*ptr).radius;
for (i = 0; i < sphereSize; i++)
{
distance = position.Distance((*ptr).position) - (*ptr).radius;
if(distance < closestDistance)
{
closestDistance = distance;
closest = ptr;
}
ptr++;
}
return closestDistance;
}
int RayMarch::GetStepCount() { return stepCounter; }
sf::Color RayMarch::FireRay()
{
float distance;
stepCounter = 0;
if(!spheres) return sf::Color::Black;
for (stepCounter = 0; stepCounter < stepLimit; stepCounter++)
{
distance = GetClosestDistance();
if(distance <= minDistance)
return closest -> color;
if(distance >= maxDistance)
{
sf::Uint8 val = 256 * stepCounter / stepLimit;
return sf::Color(val, val, val);
}
position += direction * distance;
}
return sf::Color::Black;
}