144 lines
3.3 KiB
C++
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;
|
|
}
|