In the middle of a couple of things right now, but decided to focus a

little bit less on the lighting and start laying groundwork for the SVO
The map section was in real need of some love so I deleted a bunch of
stuff and started prototyping the pointer arithmetic that I need to do
master
MitchellHansen 8 years ago
parent 4c31cfaf48
commit de2f0ad6a1

@ -15,7 +15,7 @@ public:
int set_position(sf::Vector3f position);
int add_static_impulse(sf::Vector3f impulse);
int add_relative_impulse(DIRECTION direction);
int add_relative_impulse(DIRECTION direction, float speed);
int slew_camera(sf::Vector2f input);

@ -8,295 +8,44 @@
#include <cmath>
#define _USE_MATH_DEFINES
#include <math.h>
#include <unordered_map>
#include <deque>
class Map {
public:
// In addition to traversing the voxel hierarchy, we must also be able to
// tell which block a given voxel resides in.This is accomplished us -
// ing 32 - bit page headers spread amongst the child descriptors.Page
// headers are placed at every 8 kilobyte boundary, and each contains
// a relative pointer to the block info section.By placing the begin -
// ning of the child descriptor array at such a boundary, we can always
// find a page header by simply clearing the lowest bits of any child
// descriptor pointer.
struct page_header {
int bitmask;
};
struct leaf_node {
long bitmask;
};
short scale;
void generate_octree() {
uint64_t *octree = new uint64_t[200];
long tree_node = 0;
std::vector<long> page_array;
// Page placed every 8 kilobytes
// contains a relative pointer to the block info section
uint32_t page = 255;
// Child pointer points to the first non-leaf child of this node
uint16_t child_pointer = 20;
uint32_t pointer = page | child_pointer;
};
Map(sf::Vector3i dim) {
//generate_octree();
//return;
dimensions = dim;
std::mt19937 gen;
std::uniform_real_distribution<double> dis(-1.0, 1.0);
auto f_rand = std::bind(dis, gen);
list = new char[dim.x * dim.y * dim.z];
height_map = new double[dim.x * dim.y];
for (int i = 0; i < dim.x * dim.y * dim.z; i++) {
list[i] = 0;
}
for (int i = 0; i < dim.x * dim.y; i++) {
height_map[i] = 0;
}
//for (int x = -dim.x / 2; x < dim.x/2; x++) {
// for (int y = -dim.y / 2; y < dim.y/2; y++) {
//
// double height = 20;
// height += std::pow(x / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * x / 50.0);
// height += std::pow(y / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * y / 50.0);
//
// list[(x + dim.x/2) + dim.x * ((y +dim.y/2) + dim.z * (int)height)] = 5;
// }
//}
//int xx = 0;
//int yy = 0;
//for (int x = -dim.x / 2; x < dim.x / 2; x++) {
// for (int y = -dim.y / 2; y < dim.y / 2; y++) {
// double z = 150;
////for (int x = 0; x < dim.x; x++) {
//// for (int y = 0; y < dim.y; y++) {
// double height = 0;
// z += -x*2 * std::sin(std::sqrt(abs(x*2 - y*2 - 47))) -
// (y*2 + 47) * std::sin(std::sqrt(std::abs(y*2 + 47 + x*2 / 2)));
//
// //z += x * std::sin(std::sqrt(std::abs(y - x + 1))) *
// // std::cos(std::sqrt(std::abs(y + x + 1))) +
// // (y + 1) *
// // std::cos(std::sqrt(std::abs(y - x + 1))) *
// // std::sin(std::sqrt(std::abs(y + x + 1)));
//
// // Pathological
// //z += 0.5 +
// // (std::pow(std::sin(std::sqrt(100 * std::pow(x/20, 2) + std::pow(y/20, 2))), 2) - 0.5) /
// // (1 + 0.001 * std::pow(std::pow(x/20, 2) - 2 * x/20 * y/20 + std::pow(y/20, 2), 2));
// // Ackleys
// //z += 20 + M_E -
// // (20 / (std::pow(M_E, 0.2) * std::sqrt((std::pow(x / 16.0, 2) + std::pow(y / 16.0, 2) + 1) / 2))) -
// // std::pow(M_E, 0.5 * std::cos(2 * M_PI * x / 16.0) + cos(2 * M_PI * y / 16.0));
// //
// //z += -20 * std::pow(M_E, -0.2 * sqrt(0.5 * std::pow(x/64.0, 2) + std::pow(y/64.0, 2))) - std::pow(M_E, 0.5 * (cos(2 * M_PI * x/64.0) + (cos(2 * M_PI * y/64.0)))) + 20 + M_E;
//
// //list[x + dim.x * (y + dim.z * (int)height)] = 5;
// double m = 0.2;
// while ((z*m) > 0){
// list[xx + dim.x * (yy + dim.z * (int)(z*m))] = 5;
// z -= 1/m;
// }
// yy++;
// }
// yy = 0;
// xx++;
//}
//
//return;
//int featuresize = 2;
//for (int y = 0; y < dim.y; y += featuresize)
// for (int x = 0; x < dim.x; x += featuresize) {
// double t = dis(gen);
// setSample(x, y, t); //IMPORTANT: frand() is a random function that returns a value between -1 and 1.
// }
//int samplesize = featuresize;
//double scale = 10.0;
//while (samplesize > 1) {
// DiamondSquare(samplesize, scale);
// samplesize /= 2;
// scale /= 2.0;
//}
//size of grid to generate, note this must be a
//value 2^n+1
int DATA_SIZE = dim.x + 1;
//an initial seed value for the corners of the data
double SEED = rand() % 25 + 25;
//seed the data
setSample(0, 0, SEED);
setSample(0, dim.y, SEED);
setSample(dim.x, 0, SEED);
setSample(dim.x, dim.y, SEED);
double h = 30.0;//the range (-h -> +h) for the average offset
//for the new value in range of h
//side length is distance of a single square side
//or distance of diagonal in diamond
for (int sideLength = DATA_SIZE - 1;
//side length must be >= 2 so we always have
//a new value (if its 1 we overwrite existing values
//on the last iteration)
sideLength >= 2;
//each iteration we are looking at smaller squares
//diamonds, and we decrease the variation of the offset
sideLength /= 2, h /= 2.0) {
//half the length of the side of a square
//or distance from diamond center to one corner
//(just to make calcs below a little clearer)
int halfSide = sideLength / 2;
//generate the new square values
for (int x = 0; x < DATA_SIZE - 1; x += sideLength) {
for (int y = 0; y < DATA_SIZE - 1; y += sideLength) {
//x, y is upper left corner of square
//calculate average of existing corners
double avg = sample(x, y) + //top left
sample(x + sideLength,y) +//top right
sample(x,y + sideLength) + //lower left
sample(x + sideLength,y + sideLength);//lower right
avg /= 4.0;
//center is average plus random offset
setSample(x + halfSide,y + halfSide,
//We calculate random value in range of 2h
//and then subtract h so the end value is
//in the range (-h, +h)
avg + (f_rand() * 2 * h) - h);
}
}
//generate the diamond values
//since the diamonds are staggered we only move x
//by half side
//NOTE: if the data shouldn't wrap then x < DATA_SIZE
//to generate the far edge values
for (int x = 0; x < DATA_SIZE - 1; x += halfSide) {
//and y is x offset by half a side, but moved by
//the full side length
//NOTE: if the data shouldn't wrap then y < DATA_SIZE
//to generate the far edge values
for (int y = (x + halfSide) % sideLength; y < DATA_SIZE - 1; y += sideLength) {
//x, y is center of diamond
//note we must use mod and add DATA_SIZE for subtraction
//so that we can wrap around the array to find the corners
double avg =
sample((x - halfSide + DATA_SIZE) % DATA_SIZE,y) + //left of center
sample((x + halfSide) % DATA_SIZE,y) + //right of center
sample(x,(y + halfSide) % DATA_SIZE) + //below center
sample(x,(y - halfSide + DATA_SIZE) % DATA_SIZE); //above center
avg /= 4.0;
//new value = average plus random offset
//We calculate random value in range of 2h
//and then subtract h so the end value is
//in the range (-h, +h)
avg = avg + (f_rand() * 2 * h) - h;
//update value for center of diamond
setSample(x,y, avg);
//wrap values on the edges, remove
//this and adjust loop condition above
//for non-wrapping values.
if (x == 0) setSample(DATA_SIZE - 1,y, avg);
if (y == 0) setSample(x, DATA_SIZE - 1, avg);
}
}
}
for (int x = 0; x < dim.x; x++) {
for (int y = 0; y < dim.y; y++) {
if (height_map[x + y * dim.x] > 0) {
int z = height_map[x + y * dim.x];
while (z > 0){
list[x + dim.x * (y + dim.z * z)] = 5;
z--;
}
}
}
}
#include <deque>
#define CHUNK_DIM 32
for (int x = 0; x < dim.x / 10; x++) {
for (int y = 0; y < dim.y / 10; y++) {
for (int z = 0; z < dim.z; z++) {
if (rand() % 1000 < 1)
list[x + dim.x * (y + dim.z * z)] = rand() % 6;
}
}
}
struct KeyHasher {
std::size_t operator()(const sf::Vector3i& k) const {
return ((std::hash<int>()(k.x)
^ (std::hash<int>()(k.y) << 1)) >> 1)
^ (std::hash<int>()(k.z) << 1);
}
};
~Map() {
}
struct Chunk {
Chunk(int type) { voxel_data = new int[CHUNK_DIM * CHUNK_DIM * CHUNK_DIM]; set(type); };
Chunk() { };
void set(int type);
~Chunk() { voxel_data = nullptr; };
int* voxel_data;
};
class Map {
public:
Map(sf::Vector3i dim);
void generate_octree();
void load_unload(sf::Vector3i world_position);
void load_single(sf::Vector3i world_position);
sf::Vector3i getDimensions();
char *list;
sf::Vector3i dimensions;
void setVoxel(sf::Vector3i position, int val){
list[position.x + dimensions.x * (position.y + dimensions.z * position.z)] = val;
//sf::Vector3i dimensions;
};
void setVoxel(sf::Vector3i position, int val);
void moveLight(sf::Vector2f in);
sf::Vector3f global_light;
@ -304,72 +53,21 @@ public:
protected:
private:
double* height_map;
double sample(int x, int y) {
return height_map[(x & (dimensions.x - 1)) + (y & (dimensions.y - 1)) * dimensions.x];
}
void setSample(int x, int y, double value) {
height_map[(x & (dimensions.x - 1)) + (y & (dimensions.y - 1)) * dimensions.x] = value;
}
std::unordered_map<sf::Vector3i, Chunk, KeyHasher> chunk_map;
void sampleSquare(int x, int y, int size, double value) {
int hs = size / 2;
// a b
//
// x
//
// c d
double a = sample(x - hs, y - hs);
double b = sample(x + hs, y - hs);
double c = sample(x - hs, y + hs);
double d = sample(x + hs, y + hs);
setSample(x, y, ((a + b + c + d) / 4.0) + value);
}
void sampleDiamond(int x, int y, int size, double value) {
int hs = size / 2;
// c
//
//a x b
//
// d
double a = sample(x - hs, y);
double b = sample(x + hs, y);
double c = sample(x, y - hs);
double d = sample(x, y + hs);
setSample(x, y, ((a + b + c + d) / 4.0) + value);
}
void DiamondSquare(int stepsize, double scale) {
std::mt19937 generator;
std::uniform_real_distribution<double> uniform_distribution(-1.0, 1.0);
auto f_rand = std::bind(uniform_distribution, std::ref(generator));
int halfstep = stepsize / 2;
for (int y = halfstep; y < dimensions.y + halfstep; y += stepsize) {
for (int x = halfstep; x < dimensions.x + halfstep; x += stepsize) {
sampleSquare(x, y, stepsize, f_rand() * scale);
}
}
double* height_map;
for (int y = 0; y < dimensions.y; y += stepsize) {
for (int x = 0; x < dimensions.x; x += stepsize) {
sampleDiamond(x + halfstep, y, stepsize, f_rand() * scale);
sampleDiamond(x, y + halfstep, stepsize, f_rand() * scale);
}
}
// 2^k
int chunk_radius = 6;
sf::Vector3i world_to_chunk(sf::Vector3i world_coords) {
return sf::Vector3i(
world_coords.x / CHUNK_DIM + 1,
world_coords.y / CHUNK_DIM + 1,
world_coords.z / CHUNK_DIM + 1
);
}
};

@ -20,27 +20,40 @@ float4 cast_light_rays(float3 eye_direction, float3 ray_origin, float4 voxel_col
// set the ray origin to be where the initial ray intersected the voxel
// which side z, and the x and y position
float ambient_constant = 0.5;
float intensity = 1.2;
float intensity = 0;
for (int i = 0; i < *light_count; i++) {
float distance = sqrt(
pow(lights[10 * i + 4] - ray_origin.x, 2) +
pow(lights[10 * i + 5] - ray_origin.y, 2) +
pow(lights[10 * i + 6] - ray_origin.z, 2));
if (distance > 50)
continue;
float3 light_direction = (lights[10 * i + 7], lights[10 * i + 8], lights[10 * i + 9]);
float c = 1.0;
float c = 10.0;
if (dot(light_direction, voxel_normal) > 0.0) {
//if (dot(light_direction, voxel_normal) > 0.0) {
float3 halfwayVector = normalize(light_direction + eye_direction);
float dot_prod = dot(voxel_normal, halfwayVector);
float specTmp = max((float)dot_prod, 0.0f);
intensity += pow(specTmp, c);
}
//}
}
if (get_global_id(0) == 1037760) {
printf("%f", intensity);
voxel_color = (float4)(1.0, 1.0, 1.0, 1.0);
return voxel_color;
}
//if (get_global_id(0) == 0)
// printf("%i", *light_count);
voxel_color *= intensity;
voxel_color.w *= intensity;
voxel_color.w += ambient_constant;
return voxel_color;
// for every light
@ -176,8 +189,8 @@ __kernel void min_kern(
float3 vox = convert_float3(voxel);
float3 norm = normalize(fabs(convert_float3(mask)));
float4 color = (float4)(0.25, 0.00, 0.25, 1.00);
float3 norm = normalize(convert_float3(mask) * convert_float3(voxel_step));
float4 color = (float4)(0.95, 0.00, 0.25, 1.00);
write_imagef(image, pixel,

@ -25,7 +25,7 @@ int Camera::add_static_impulse(sf::Vector3f impulse) {
return 1;
}
int Camera::add_relative_impulse(DIRECTION impulse_direction) {
int Camera::add_relative_impulse(DIRECTION impulse_direction, float speed) {
// No sense in doing fancy dot products, adding Pi's will suffice
// Always add PI/2 to X initially to avoid negative case
@ -55,6 +55,7 @@ int Camera::add_relative_impulse(DIRECTION impulse_direction) {
}
movement += SphereToCart(dir);
movement *= speed;
return 1;
}

@ -5,39 +5,67 @@
#include <SFML/System/Vector2.hpp>
#include "util.hpp"
sf::Vector3i Map::getDimensions() {
return dimensions;
Map::Map(sf::Vector3i position) {
load_unload(position);
}
void Map::moveLight(sf::Vector2f in) {
sf::Vector3f light_spherical = CartToSphere(global_light);
light_spherical.y += in.y;
light_spherical.x += in.x;
global_light = SphereToCart(light_spherical);
return;
int BitCount(unsigned int u) {
unsigned int uCount;
uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
return ((uCount + (uCount >> 3)) & 030707070707) % 63;
}
struct block {
int header = 0;
double* data = new double[1000];
};
void Map::generate_octree() {
int* dataset = new int[32 * 32 * 32];
for (int i = 0; i < 32 * 32 * 32; i++) {
dataset[0] = i;
}
char* arr[8192];
for (int i = 0; i < 8192; i++) {
arr[i] = 0;
}
std::list<int> parent_stack;
int byte_pos = 0;
int levels = log2(32);
unsigned int parent = 0;
for (int i = 0; i < 16; i++) {
parent ^= 1 << i;
}
unsigned int leafmask = 255;
unsigned int validmask = leafmask << 8;
parent &= validmask;
parent &= leafmask;
std::cout << BitCount(parent & leafmask);
unsigned int children[8] = {0, 0, 0, 0, 0, 0, 0, 0};
for (int i = 0; i < levels; i++) {
}
}
@ -52,19 +80,312 @@ void Map::moveLight(sf::Vector2f in) {
//void Map::generate_test() {
//
// //generate_octree();
// //return;
//
// //dimensions = dim;
// //std::mt19937 gen;
// //std::uniform_real_distribution<double> dis(-1.0, 1.0);
// //auto f_rand = std::bind(dis, gen);
//
//
// //list = new char[dim.x * dim.y * dim.z];
//
// //height_map = new double[dim.x * dim.y];
//
// //for (int i = 0; i < dim.x * dim.y * dim.z; i++) {
// // list[i] = 0;
// //}
//
// //for (int i = 0; i < dim.x * dim.y; i++) {
// // height_map[i] = 0;
// //}
//
//
// //for (int x = 50; x < 60; x += 2) {
// // for (int y = 50; y < 60; y += 2) {
// // for (int z = 50; z < 60; z += 2) {
// // list[x + dimensions.x * (y + dimensions.z * z)] = 5;
// // }
// // }
// //}
//
// //list[71 + dimensions.x * (61 + dimensions.z * 51)] = 5;
//
// ////for (int x = -dim.x / 2; x < dim.x/2; x++) {
// //// for (int y = -dim.y / 2; y < dim.y/2; y++) {
// ////
// //// double height = 20;
//
// //// height += std::pow(x / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * x / 50.0);
// //// height += std::pow(y / 50.0, 2) - 10 * std::cos(2 * 3.1415926 * y / 50.0);
// ////
// //// list[(x + dim.x/2) + dim.x * ((y +dim.y/2) + dim.z * (int)height)] = 5;
// //// }
// ////}
//
// ////int xx = 0;
// ////int yy = 0;
// ////for (int x = -dim.x / 2; x < dim.x / 2; x++) {
// //// for (int y = -dim.y / 2; y < dim.y / 2; y++) {
//
// //// double z = 150;
// //////for (int x = 0; x < dim.x; x++) {
// ////// for (int y = 0; y < dim.y; y++) {
// //// double height = 0;
//
// //// z += -x*2 * std::sin(std::sqrt(abs(x*2 - y*2 - 47))) -
// //// (y*2 + 47) * std::sin(std::sqrt(std::abs(y*2 + 47 + x*2 / 2)));
// ////
//
// //// //z += x * std::sin(std::sqrt(std::abs(y - x + 1))) *
// //// // std::cos(std::sqrt(std::abs(y + x + 1))) +
// //// // (y + 1) *
// //// // std::cos(std::sqrt(std::abs(y - x + 1))) *
// //// // std::sin(std::sqrt(std::abs(y + x + 1)));
// ////
// //// // Pathological
// //// //z += 0.5 +
// //// // (std::pow(std::sin(std::sqrt(100 * std::pow(x/20, 2) + std::pow(y/20, 2))), 2) - 0.5) /
// //// // (1 + 0.001 * std::pow(std::pow(x/20, 2) - 2 * x/20 * y/20 + std::pow(y/20, 2), 2));
//
// //// // Ackleys
// //// //z += 20 + M_E -
// //// // (20 / (std::pow(M_E, 0.2) * std::sqrt((std::pow(x / 16.0, 2) + std::pow(y / 16.0, 2) + 1) / 2))) -
// //// // std::pow(M_E, 0.5 * std::cos(2 * M_PI * x / 16.0) + cos(2 * M_PI * y / 16.0));
//
// //// //
// //// //z += -20 * std::pow(M_E, -0.2 * sqrt(0.5 * std::pow(x/64.0, 2) + std::pow(y/64.0, 2))) - std::pow(M_E, 0.5 * (cos(2 * M_PI * x/64.0) + (cos(2 * M_PI * y/64.0)))) + 20 + M_E;
// ////
// //// //list[x + dim.x * (y + dim.z * (int)height)] = 5;
//
// //// double m = 0.2;
// //// while ((z*m) > 0){
// //// list[xx + dim.x * (yy + dim.z * (int)(z*m))] = 5;
// //// z -= 1/m;
// //// }
// //// yy++;
//
// //// }
// //// yy = 0;
// //// xx++;
// ////}
// ////
//
// ////return;
//
//
//
// ////int featuresize = 2;
//
// ////for (int y = 0; y < dim.y; y += featuresize)
// //// for (int x = 0; x < dim.x; x += featuresize) {
// //// double t = dis(gen);
// //// setSample(x, y, t); //IMPORTANT: frand() is a random function that returns a value between -1 and 1.
// //// }
//
// ////int samplesize = featuresize;
//
// ////double scale = 10.0;
//
// ////while (samplesize > 1) {
//
// //// DiamondSquare(samplesize, scale);
//
// //// samplesize /= 2;
// //// scale /= 2.0;
// ////}
//
//
//
//
// ////size of grid to generate, note this must be a
// ////value 2^n+1
// //int DATA_SIZE = dim.x + 1;
// ////an initial seed value for the corners of the data
// //double SEED = rand() % 25 + 25;
//
// ////seed the data
// //setSample(0, 0, SEED);
// //setSample(0, dim.y, SEED);
// //setSample(dim.x, 0, SEED);
// //setSample(dim.x, dim.y, SEED);
//
// //double h = 30.0;//the range (-h -> +h) for the average offset
// // //for the new value in range of h
// // //side length is distance of a single square side
// // //or distance of diagonal in diamond
// //for (int sideLength = DATA_SIZE - 1;
// ////side length must be >= 2 so we always have
// ////a new value (if its 1 we overwrite existing values
// ////on the last iteration)
// //sideLength >= 2;
// // //each iteration we are looking at smaller squares
// // //diamonds, and we decrease the variation of the offset
// // sideLength /= 2, h /= 2.0) {
// // //half the length of the side of a square
// // //or distance from diamond center to one corner
// // //(just to make calcs below a little clearer)
// // int halfSide = sideLength / 2;
//
// // //generate the new square values
// // for (int x = 0; x < DATA_SIZE - 1; x += sideLength) {
// // for (int y = 0; y < DATA_SIZE - 1; y += sideLength) {
// // //x, y is upper left corner of square
// // //calculate average of existing corners
// // double avg = sample(x, y) + //top left
// // sample(x + sideLength, y) +//top right
// // sample(x, y + sideLength) + //lower left
// // sample(x + sideLength, y + sideLength);//lower right
// // avg /= 4.0;
//
// // //center is average plus random offset
// // setSample(x + halfSide, y + halfSide,
// // //We calculate random value in range of 2h
// // //and then subtract h so the end value is
// // //in the range (-h, +h)
// // avg + (f_rand() * 2 * h) - h);
// // }
// // }
//
// // //generate the diamond values
// // //since the diamonds are staggered we only move x
// // //by half side
// // //NOTE: if the data shouldn't wrap then x < DATA_SIZE
// // //to generate the far edge values
// // for (int x = 0; x < DATA_SIZE - 1; x += halfSide) {
// // //and y is x offset by half a side, but moved by
// // //the full side length
// // //NOTE: if the data shouldn't wrap then y < DATA_SIZE
// // //to generate the far edge values
// // for (int y = (x + halfSide) % sideLength; y < DATA_SIZE - 1; y += sideLength) {
// // //x, y is center of diamond
// // //note we must use mod and add DATA_SIZE for subtraction
// // //so that we can wrap around the array to find the corners
// // double avg =
// // sample((x - halfSide + DATA_SIZE) % DATA_SIZE, y) + //left of center
// // sample((x + halfSide) % DATA_SIZE, y) + //right of center
// // sample(x, (y + halfSide) % DATA_SIZE) + //below center
// // sample(x, (y - halfSide + DATA_SIZE) % DATA_SIZE); //above center
// // avg /= 4.0;
//
// // //new value = average plus random offset
// // //We calculate random value in range of 2h
// // //and then subtract h so the end value is
// // //in the range (-h, +h)
// // avg = avg + (f_rand() * 2 * h) - h;
// // //update value for center of diamond
// // setSample(x, y, avg);
//
// // //wrap values on the edges, remove
// // //this and adjust loop condition above
// // //for non-wrapping values.
// // if (x == 0) setSample(DATA_SIZE - 1, y, avg);
// // if (y == 0) setSample(x, DATA_SIZE - 1, avg);
// // }
// // }
// //}
//
//
// //for (int x = 0; x < dim.x; x++) {
// // for (int y = 0; y < dim.y; y++) {
//
// // if (height_map[x + y * dim.x] > 0) {
// // int z = height_map[x + y * dim.x];
// // while (z > 0) {
// // list[x + dim.x * (y + dim.z * z)] = 5;
// // z--;
// // }
// // }
//
// // }
// //}
//
//
// //for (int x = 0; x < dim.x / 10; x++) {
// // for (int y = 0; y < dim.y / 10; y++) {
// // for (int z = 0; z < dim.z; z++) {
// // if (rand() % 1000 < 1)
// // list[x + dim.x * (y + dim.z * z)] = rand() % 6;
// // }
// // }
// //}
//
//}
//
void Map::load_unload(sf::Vector3i world_position) {
sf::Vector3i chunk_pos(world_to_chunk(world_position));
//Don't forget the middle chunk
if (chunk_map.find(chunk_pos) == chunk_map.end()) {
chunk_map[chunk_pos] = Chunk(5);
}
for (int x = chunk_pos.x - chunk_radius / 2; x < chunk_pos.x + chunk_radius / 2; x++) {
for (int y = chunk_pos.y - chunk_radius / 2; y < chunk_pos.y + chunk_radius / 2; y++) {
for (int z = chunk_pos.z - chunk_radius / 2; z < chunk_pos.z + chunk_radius / 2; z++) {
if (chunk_map.find(sf::Vector3i(x, y, z)) == chunk_map.end()) {
chunk_map.emplace(sf::Vector3i(x, y, z), Chunk(rand() % 6));
//chunk_map[sf::Vector3i(x, y, z)] = Chunk(rand() % 6);
}
}
}
}
}
void Map::load_single(sf::Vector3i world_position) {
sf::Vector3i chunk_pos(world_to_chunk(world_position));
//Don't forget the middle chunk
if (chunk_map.find(chunk_pos) == chunk_map.end()) {
chunk_map[chunk_pos] = Chunk(0);
}
}
sf::Vector3i Map::getDimensions() {
return sf::Vector3i(0, 0, 0);
}
void Map::setVoxel(sf::Vector3i world_position, int val) {
load_single(world_position);
sf::Vector3i chunk_pos(world_to_chunk(world_position));
sf::Vector3i in_chunk_pos(
world_position.x % CHUNK_DIM,
world_position.y % CHUNK_DIM,
world_position.z % CHUNK_DIM
);
chunk_map.at(chunk_pos).voxel_data[in_chunk_pos.x + CHUNK_DIM * (in_chunk_pos.y + CHUNK_DIM * in_chunk_pos.z)]
= val;
}
void Map::moveLight(sf::Vector2f in) {
//
// sf::Vector3f light_spherical = CartToSphere(global_light);
//
// light_spherical.y += in.y;
// light_spherical.x += in.x;
//
// global_light = SphereToCart(light_spherical);
//
// return;
}
void Chunk::set(int type) {
for (int i = 0; i < CHUNK_DIM * CHUNK_DIM * CHUNK_DIM; i++) {
voxel_data[i] = 0;
}
for (int x = 0; x < CHUNK_DIM; x+=2) {
for (int y = 0; y < CHUNK_DIM; y+=2) {
//list[x + dim.x * (y + dim.z * z)]
voxel_data[x + CHUNK_DIM * (y + CHUNK_DIM * 1)] = type;
}
}
}

@ -34,8 +34,8 @@
#include "Vector4.hpp"
#include <Camera.h>
const int WINDOW_X = 1000;
const int WINDOW_Y = 1000;
const int WINDOW_X = 1920;
const int WINDOW_Y = 1080;
const int WORK_SIZE = WINDOW_X * WINDOW_Y;
const int MAP_X = 512;
@ -65,297 +65,306 @@ sf::Texture window_texture;
int main() {
//Map m(sf::Vector3i (50, 50, 50));
//return 1;
sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
// Setup CL, instantiate and pass in values to the kernel
CL_Wrapper c;
query_platform_devices();
c.acquire_platform_and_device();
c.create_shared_context();
c.create_command_queue();
if (c.compile_kernel("../kernels/ray_caster_kernel.cl", true, "min_kern") < 0) {
std::cin.get();
return -1;
}
std::cout << "map...";
sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z);
Map* map = new Map(map_dim);
c.create_buffer("map_buffer", sizeof(char) * map_dim.x * map_dim.y * map_dim.z, map->list);
c.create_buffer("dim_buffer", sizeof(int) * 3, &map_dim);
sf::Vector2i view_res(WINDOW_X, WINDOW_Y);
c.create_buffer("res_buffer", sizeof(int) * 2, &view_res);
double y_increment_radians = DegreesToRadians(50.0 / view_res.y);
double x_increment_radians = DegreesToRadians(80.0 / view_res.x);
std::cout << "view matrix...";
sf::Vector4f* view_matrix = new sf::Vector4f[WINDOW_X * WINDOW_Y * 4];
for (int y = -view_res.y / 2; y < view_res.y / 2; y++) {
for (int x = -view_res.x / 2; x < view_res.x / 2; x++) {
// The base ray direction to slew from
sf::Vector3f ray(1, 0, 0);
// Y axis, pitch
ray = sf::Vector3f(
ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y),
ray.y,
ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y)
);
// Z axis, yaw
ray = sf::Vector3f(
ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x),
ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x),
ray.z
);
int index = (x + view_res.x / 2) + view_res.x * (y + view_res.y / 2);
ray = Normalize(ray);
view_matrix[index] = sf::Vector4f(
ray.x,
ray.y,
ray.z,
0
);
}
}
c.create_buffer("view_matrix_buffer", sizeof(float) * 4 * view_res.x * view_res.y, view_matrix);
Camera camera(
sf::Vector3f(256, 256, 256),
sf::Vector2f(0.0f, 1.00f)
);
c.create_buffer("cam_dir_buffer", sizeof(float) * 4, (void*)camera.get_direction_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
c.create_buffer("cam_pos_buffer", sizeof(float) * 4, (void*)camera.get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
int light_count = 2;
c.create_buffer("light_count_buffer", sizeof(int), &light_count);
// {r, g, b, i, x, y, z, x', y', z'}
sf::Vector3f v = Normalize(sf::Vector3f(1.0, 1.0, 0.0));
sf::Vector3f v2 = Normalize(sf::Vector3f(1.1, 0.4, 0.7));
float light[] = { 0.4, 0.8, 0.1, 1, 50, 50, 50, v.x, v.y, v.z,
0.4, 0.8, 0.1, 1, 50, 50, 50, v2.x, v2.y, v2.z};
c.create_buffer("light_buffer", sizeof(float) * 10 * light_count, light, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
// The drawing canvas
unsigned char* pixel_array = new sf::Uint8[WINDOW_X * WINDOW_Y * 4];
for (int i = 0; i < WINDOW_X * WINDOW_Y * 4; i += 4) {
pixel_array[i] = 255; // R?
pixel_array[i + 1] = 255; // G?
pixel_array[i + 2] = 255; // B?
pixel_array[i + 3] = 100; // A?
}
sf::Texture t;
t.create(WINDOW_X, WINDOW_Y);
t.update(pixel_array);
int error;
cl_mem image_buff = clCreateFromGLTexture(
c.getContext(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D,
0, t.getNativeHandle(), &error);
if (c.assert(error, "clCreateFromGLTexture"))
return -1;
c.store_buffer(image_buff, "image_buffer");
c.set_kernel_arg("min_kern", 0, "map_buffer");
c.set_kernel_arg("min_kern", 1, "dim_buffer");
c.set_kernel_arg("min_kern", 2, "res_buffer");
c.set_kernel_arg("min_kern", 3, "view_matrix_buffer");
c.set_kernel_arg("min_kern", 4, "cam_dir_buffer");
c.set_kernel_arg("min_kern", 5, "cam_pos_buffer");
c.set_kernel_arg("min_kern", 6, "light_buffer");
c.set_kernel_arg("min_kern", 7, "light_count_buffer");
c.set_kernel_arg("min_kern", 8, "image_buffer");
sf::Sprite s;
s.setTexture(t);
s.setPosition(0, 0);
// The step size in milliseconds between calls to Update()
// Lets set it to 16.6 milliseonds (60FPS)
float step_size = 0.0166f;
// Timekeeping values for the loop
double frame_time = 0.0,
elapsed_time = 0.0,
delta_time = 0.0,
accumulator_time = 0.0,
current_time = 0.0;
fps_counter fps;
// ============================= RAYCASTER SETUP ==================================
// Setup the sprite and texture
window_texture.create(WINDOW_X, WINDOW_Y);
window_sprite.setPosition(0, 0);
// State values
sf::Vector3f cam_vec(0, 0, 0);
RayCaster ray_caster(map, map_dim, view_res);
sf::Vector2f *dp = camera.get_direction_pointer();
debug_text cam_text_x(1, 30, &dp->x, "X: ");
debug_text cam_text_y(2, 30, &dp->y, "Y: ");
sf::Vector3f *mp = camera.get_movement_pointer();
debug_text cam_text_mov_x(4, 30, &mp->x, "X: ");
debug_text cam_text_mov_y(5, 30, &mp->y, "Y: ");
debug_text cam_text_mov_z(6, 30, &mp->y, "Z: ");
//debug_text cam_text_z(3, 30, &p->z);
debug_text light_x (7, 30, &light[7], "X: ");
debug_text light_y(8, 30, &light[8], "Y: ");
debug_text light_z(9, 30, &light[9], "Z: ");
// ===============================================================================
// Mouse capture
sf::Vector2i deltas;
sf::Vector2i fixed(window.getSize());
bool mouse_enabled = true;
sf::Vector3f cam_mov_vec;
while (window.isOpen()) {
// Poll for events from the user
sf::Event event;
while (window.pollEvent(event)) {
// If the user tries to exit the application via the GUI
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Space) {
if (mouse_enabled)
mouse_enabled = false;
else
mouse_enabled = true;
}
}
}
cam_vec.x = 0;
cam_vec.y = 0;
cam_vec.z = 0;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
camera.add_relative_impulse(Camera::DIRECTION::DOWN);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) {
camera.add_relative_impulse(Camera::DIRECTION::UP);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
camera.add_relative_impulse(Camera::DIRECTION::FORWARD);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
camera.add_relative_impulse(Camera::DIRECTION::REARWARD);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
camera.add_relative_impulse(Camera::DIRECTION::LEFT);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
camera.add_relative_impulse(Camera::DIRECTION::RIGHT);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) {
camera.set_position(sf::Vector3f(50, 50, 50));
}
camera.add_static_impulse(cam_vec);
if (mouse_enabled) {
deltas = fixed - sf::Mouse::getPosition();
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
// Mouse movement
sf::Mouse::setPosition(fixed);
camera.slew_camera(sf::Vector2f(
deltas.y / 300.0f,
deltas.x / 300.0f
));
}
}
// Time keeping
elapsed_time = elap_time();
delta_time = elapsed_time - current_time;
current_time = elapsed_time;
if (delta_time > 0.2f)
delta_time = 0.2f;
accumulator_time += delta_time;
while ((accumulator_time - step_size) >= step_size) {
accumulator_time -= step_size;
// ==== DELTA TIME LOCKED ====
}
float l[] = {
light[9] * sin(delta_time) + light[7] * cos(delta_time),
light[8],
light[9] * cos(delta_time) - light[7] * sin(delta_time)
};
float l2[] = {
l[0] * cos(delta_time) - l[2] * sin(delta_time),
l[0] * sin(delta_time) + l[2] * cos(delta_time),
l[2]
};
light[7] = l[0];
light[8] = l[1];
light[9] = l[2];
// ==== FPS LOCKED ====
camera.update(delta_time);
// Run the raycast
c.run_kernel("min_kern", WORK_SIZE);
// ==== RENDER ====
window.clear(sf::Color::Black);
window.draw(s);
// Give the frame counter the frame time and draw the average frame time
fps.frame(delta_time);
fps.draw(&window);
cam_text_x.draw(&window);
cam_text_y.draw(&window);
cam_text_mov_x.draw(&window);
cam_text_mov_y.draw(&window);
cam_text_mov_z.draw(&window);
light_x.draw(&window);
light_y.draw(&window);
light_z.draw(&window);
window.display();
}
Map m(sf::Vector3i (50, 50, 50));
m.generate_octree();
return 1;
//sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
//// Setup CL, instantiate and pass in values to the kernel
//CL_Wrapper c;
//query_platform_devices();
//c.acquire_platform_and_device();
//c.create_shared_context();
//c.create_command_queue();
//if (c.compile_kernel("../kernels/ray_caster_kernel.cl", true, "min_kern") < 0) {
// std::cin.get();
// return -1;
//}
//
//std::cout << "map...";
// sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z);
// Map* map = new Map(map_dim);
//
//c.create_buffer("map_buffer", sizeof(char) * map_dim.x * map_dim.y * map_dim.z, map->list);
//c.create_buffer("dim_buffer", sizeof(int) * 3, &map_dim);
//sf::Vector2i view_res(WINDOW_X, WINDOW_Y);
//c.create_buffer("res_buffer", sizeof(int) * 2, &view_res);
//
// double y_increment_radians = DegreesToRadians(50.0 / view_res.y);
// double x_increment_radians = DegreesToRadians(80.0 / view_res.x);
//std::cout << "view matrix...";
//
//sf::Vector4f* view_matrix = new sf::Vector4f[WINDOW_X * WINDOW_Y * 4];
// for (int y = -view_res.y / 2; y < view_res.y / 2; y++) {
// for (int x = -view_res.x / 2; x < view_res.x / 2; x++) {
// // The base ray direction to slew from
// sf::Vector3f ray(1, 0, 0);
// // Y axis, pitch
// ray = sf::Vector3f(
// ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y),
// ray.y,
// ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y)
// );
// // Z axis, yaw
// ray = sf::Vector3f(
// ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x),
// ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x),
// ray.z
// );
//
// int index = (x + view_res.x / 2) + view_res.x * (y + view_res.y / 2);
// ray = Normalize(ray);
// view_matrix[index] = sf::Vector4f(
// ray.x,
// ray.y,
// ray.z,
// 0
// );
// }
// }
//c.create_buffer("view_matrix_buffer", sizeof(float) * 4 * view_res.x * view_res.y, view_matrix);
//Camera camera(
// sf::Vector3f(70, 60, 50),
// sf::Vector2f(0.0f, 1.00f)
//);
//
//c.create_buffer("cam_dir_buffer", sizeof(float) * 4, (void*)camera.get_direction_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
//c.create_buffer("cam_pos_buffer", sizeof(float) * 4, (void*)camera.get_position_pointer(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
//
//int light_count = 2;
//c.create_buffer("light_count_buffer", sizeof(int), &light_count);
//// {r, g, b, i, x, y, z, x', y', z'}
//sf::Vector3f v = Normalize(sf::Vector3f(1.0, 0.0, 0.0));
//sf::Vector3f v2 = Normalize(sf::Vector3f(1.1, 0.4, 0.7));
//float light[] = { 0.4, 0.8, 0.1, 1, 50, 50, 50, v.x, v.y, v.z,
// 0.4, 0.8, 0.1, 1, 50, 50, 50, v2.x, v2.y, v2.z};
//c.create_buffer("light_buffer", sizeof(float) * 10 * light_count, light, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
//// The drawing canvas
// unsigned char* pixel_array = new sf::Uint8[WINDOW_X * WINDOW_Y * 4];
// for (int i = 0; i < WINDOW_X * WINDOW_Y * 4; i += 4) {
// pixel_array[i] = 255; // R?
// pixel_array[i + 1] = 255; // G?
// pixel_array[i + 2] = 255; // B?
// pixel_array[i + 3] = 100; // A?
// }
//sf::Texture t;
// t.create(WINDOW_X, WINDOW_Y);
// t.update(pixel_array);
// int error;
// cl_mem image_buff = clCreateFromGLTexture(
// c.getContext(), CL_MEM_WRITE_ONLY, GL_TEXTURE_2D,
// 0, t.getNativeHandle(), &error);
// if (c.assert(error, "clCreateFromGLTexture"))
// return -1;
// c.store_buffer(image_buff, "image_buffer");
// c.set_kernel_arg("min_kern", 0, "map_buffer");
// c.set_kernel_arg("min_kern", 1, "dim_buffer");
// c.set_kernel_arg("min_kern", 2, "res_buffer");
// c.set_kernel_arg("min_kern", 3, "view_matrix_buffer");
// c.set_kernel_arg("min_kern", 4, "cam_dir_buffer");
// c.set_kernel_arg("min_kern", 5, "cam_pos_buffer");
//c.set_kernel_arg("min_kern", 6, "light_buffer");
//c.set_kernel_arg("min_kern", 7, "light_count_buffer");
//c.set_kernel_arg("min_kern", 8, "image_buffer");
//sf::Sprite s;
//s.setTexture(t);
//s.setPosition(0, 0);
// // The step size in milliseconds between calls to Update()
// // Lets set it to 16.6 milliseonds (60FPS)
// float step_size = 0.0166f;
// // Timekeeping values for the loop
// double frame_time = 0.0,
// elapsed_time = 0.0,
// delta_time = 0.0,
// accumulator_time = 0.0,
// current_time = 0.0;
// fps_counter fps;
//// ============================= RAYCASTER SETUP ==================================
//// Setup the sprite and texture
//window_texture.create(WINDOW_X, WINDOW_Y);
//window_sprite.setPosition(0, 0);
//// State values
//sf::Vector3f cam_vec(0, 0, 0);
//RayCaster ray_caster(map, map_dim, view_res);
//sf::Vector2f *dp = camera.get_direction_pointer();
//debug_text cam_text_x(1, 30, &dp->x, "X: ");
//debug_text cam_text_y(2, 30, &dp->y, "Y: ");
//sf::Vector3f *mp = camera.get_movement_pointer();
//debug_text cam_text_mov_x(4, 30, &mp->x, "X: ");
//debug_text cam_text_mov_y(5, 30, &mp->y, "Y: ");
//debug_text cam_text_mov_z(6, 30, &mp->y, "Z: ");
////debug_text cam_text_z(3, 30, &p->z);
//debug_text light_x(7, 30, &light[7], "X: ");
//debug_text light_y(8, 30, &light[8], "Y: ");
//debug_text light_z(9, 30, &light[9], "Z: ");
//// ===============================================================================
//// Mouse capture
//sf::Vector2i deltas;
//sf::Vector2i fixed(window.getSize());
//bool mouse_enabled = true;
//sf::Vector3f cam_mov_vec;
//while (window.isOpen()) {
// // Poll for events from the user
// sf::Event event;
// while (window.pollEvent(event)) {
// // If the user tries to exit the application via the GUI
// if (event.type == sf::Event::Closed)
// window.close();
// if (event.type == sf::Event::KeyPressed) {
// if (event.key.code == sf::Keyboard::Space) {
// if (mouse_enabled)
// mouse_enabled = false;
// else
// mouse_enabled = true;
// }
// }
// }
// cam_vec.x = 0;
// cam_vec.y = 0;
// cam_vec.z = 0;
// float speed = 1.0f;
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
// speed = 0.2f;
// }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
// camera.add_relative_impulse(Camera::DIRECTION::DOWN, speed);
// }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::E)) {
// camera.add_relative_impulse(Camera::DIRECTION::UP, speed);
// }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
// camera.add_relative_impulse(Camera::DIRECTION::FORWARD, speed);
// }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
// camera.add_relative_impulse(Camera::DIRECTION::REARWARD, speed);
// }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
// camera.add_relative_impulse(Camera::DIRECTION::LEFT, speed);
// }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
// camera.add_relative_impulse(Camera::DIRECTION::RIGHT, speed);
// }
// if (sf::Keyboard::isKeyPressed(sf::Keyboard::T)) {
// camera.set_position(sf::Vector3f(50, 50, 50));
// }
// camera.add_static_impulse(cam_vec);
// if (mouse_enabled) {
// deltas = fixed - sf::Mouse::getPosition();
// if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
// // Mouse movement
// sf::Mouse::setPosition(fixed);
// camera.slew_camera(sf::Vector2f(
// deltas.y / 300.0f,
// deltas.x / 300.0f
// ));
// }
// }
// // Time keeping
// elapsed_time = elap_time();
// delta_time = elapsed_time - current_time;
// current_time = elapsed_time;
// if (delta_time > 0.2f)
// delta_time = 0.2f;
// accumulator_time += delta_time;
// while ((accumulator_time - step_size) >= step_size) {
// accumulator_time -= step_size;
// // ==== DELTA TIME LOCKED ====
// }
// float l[] = {
// light[9] * sin(delta_time / 1) + light[7] * cos(delta_time / 1),
// light[8],
// light[9] * cos(delta_time / 1) - light[7] * sin(delta_time / 1)
// };
// float l2[] = {
// l[0] * cos(delta_time) - l[2] * sin(delta_time),
// l[0] * sin(delta_time) + l[2] * cos(delta_time),
// l[2]
// };
// light[7] = l[0];
// light[8] = l[1];
// light[9] = l[2];
// // ==== FPS LOCKED ====
// camera.update(delta_time);
// // Run the raycast
// c.run_kernel("min_kern", WORK_SIZE);
//
// // ==== RENDER ====
// window.clear(sf::Color::Black);
// window.draw(s);
// // Give the frame counter the frame time and draw the average frame time
// fps.frame(delta_time);
// fps.draw(&window);
// cam_text_x.draw(&window);
// cam_text_y.draw(&window);
// cam_text_mov_x.draw(&window);
// cam_text_mov_y.draw(&window);
// cam_text_mov_z.draw(&window);
// light_x.draw(&window);
// light_y.draw(&window);
// light_z.draw(&window);
//
// window.display();
//}
return 0;
}

Loading…
Cancel
Save