Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
ademirtug committed May 16, 2023
1 parent 20e1b35 commit 7bd9ea4
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 82 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 1 addition & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ int main()
float e2 = 2 * glm::pi<float>() * ((gmtime(&rawtime)->tm_hour) / 24.0);
renderer.l = std::make_shared<directional_light>(glm::vec3({ cos(e2), sin(e2), 0 }));


//de2::get_instance().enable_wireframe_mode();

de2::get_instance().on<pre_render>([&](std::chrono::nanoseconds ns) {
s.process(world, renderer);
Expand All @@ -56,15 +54,14 @@ int main()
auto begin = std::chrono::high_resolution_clock::now();
auto end = begin;
de2::get_instance().on<render>([&](std::chrono::nanoseconds ns) {

renderer.process(world, ns);

//Coordinates, based on sphere not WGS84 spheroid!!!!
auto from = cast_ray(renderer.mouse_pos, { de2::get_instance().viewport.x , de2::get_instance().viewport.y }, renderer.get_projection(), renderer.get_view(), -1.0f);
auto to = cast_ray(renderer.mouse_pos, { de2::get_instance().viewport.x , de2::get_instance().viewport.y }, renderer.get_projection(), renderer.get_view(), 1.0f);

auto m_geo = sphere_intersection(from, to - from);
std::string s_mgeo = std::format("lat:{:02.2f} lon:{:02.2f}", m_geo[0], m_geo[1]);
std::string s_mgeo = std::format("(sphere coords) -> ({:02.2f},{:02.2f})", m_geo[0], m_geo[1]);
de2::get_instance().set_title(s_mgeo);

});
Expand Down
113 changes: 45 additions & 68 deletions spheroid.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "spheroid.h"
#include "spheroid.h"
//http://github.com/ademirtug/ecs_s/
#include "../../ecs_s/ecs_s.hpp"
#include "util.h"
Expand All @@ -9,24 +9,41 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
std::vector<std::string> plates_to_draw;
std::vector<std::string> plates;
std::set<std::string> visible_plates;
std::set<std::string> visible_roots;
std::set<std::string> in, out;


//here we goooooo!
//we need to confirm two things
//1-is dot(normal, camera.pos()) < 90? means that is it facing to us?
//We need to confirm two things...
//1-is dot(normal, camera.pos()) < 90?
//2-is that point within NDC cube?
//if answer for both questions are yes then we are going to draw it.
std::array<std::string, 4> pn{ "a", "b", "c", "d" };
std::string root = "";
for (size_t i = 0; i < renderer.cam_->zoom_; i++) {
for (size_t x = 0; x < 4; x++) {
std::string plate = root + pn[x];
//now check is it facing to us or not?
}

}


//std::array<std::string, 4> pn{ "a", "b", "c", "d" };
//in.emplace("a");
//in.emplace("b");
//in.emplace("c");
//in.emplace("d");

//std::string root = "";
//for (size_t i = 0; i < renderer.cam_->zoom_; i++) {
// for (std::string plate : in){
// //now check is it facing to us or not?
// bool is_facing = false;
// corner_normals cn = get_corner_normals(plate);

// for (size_t z = 0; z < 4; z++){
// if (glm::dot(glm::normalize(renderer.cam_->getpos()), cn[z]) < 90) {
// is_facing = true;
// break;
// }
// }
//
// }
// //for (size_t x = 0; x < in.size(); x++) {
// // std::string plate = in.;
// // //now check is it facing to us or not?
// // bool is_facing = false;

// // corner_normals cn = get_corner_normals(plate);
// //}
//}


//iterate over all the plates and get a full quad tree
Expand All @@ -45,16 +62,14 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
}
}



if (plates_to_draw.size() == 0) {
plates_to_draw.push_back("a");
plates_to_draw.push_back("b");
plates_to_draw.push_back("c");
plates_to_draw.push_back("d");
}

//make requests for required plates
//make async requests for required plates
for (size_t i = 0; i < plates_to_draw.size(); i++){
if (!de2::get_instance().has_model(plates_to_draw[i]) && requests_made_.find(plates_to_draw[i]) == requests_made_.end()) {
requests_made_[plates_to_draw[i]] = de2::get_instance().load_model_async<earth_plate>(plates_to_draw[i], plates_to_draw[i]);
Expand All @@ -67,18 +82,25 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
if (requests_made_[plates_to_draw[i]].wait_for(std::chrono::milliseconds(0)) == std::future_status::ready) {
requests_made_.erase(plates_to_draw[i]);
//TODO: object may never appear in the list after all, that means this function will block main thread!!!
ecs_s::entity e = world.new_entity();

auto m = de2::get_instance().load_model<earth_plate>(plates_to_draw[i], plates_to_draw[i]);
m->upload();
m->attach_program(de2::get_instance().programs["c_t_direct"]);

auto ep = std::static_pointer_cast<earth_plate>(m);
ecs_s::entity e = world.new_entity();
world.add_component(e, plate_name{ plates_to_draw[i] });
world.add_component(e, m);

cn_cache.put(plates_to_draw[i], std::static_pointer_cast<plate>(ep->m)->cn);
}
}
}
};

corner_normals& spheroid::get_corner_normals(std::string plate_path) {
corner_normals cc;
return cc;
}
plate::plate(std::string plate_path, size_t resolution) : plate_path_(plate_path), resolution_(resolution) {
size_t map_size = (size_t)std::pow(2, plate_path.size()) * 256;
b = path_to_box(plate_path);
Expand Down Expand Up @@ -145,52 +167,7 @@ plate::plate(std::string plate_path, size_t resolution) : plate_path_(plate_path
size_of_indices = indices.size();

//pre calculate corner normals;
calculate_corner_normals();
}

void plate::calculate_corner_normals() {
size_t map_size = (size_t)std::pow(2, plate_path_.size()) * 256;
double step = ((float)b.a) / resolution_;

// resolution_ = 3, plate_path = generic
// |<-----------b.a----------->|
// v7-------v8--------v10------v11 -
// | n2 | | n3 | |
// | | | | |
// v6-------|---------|--------v9 |
// |<-step->| | | b.a
// | | | | |
// v2-------|---------|--------v5 |
// | n0 | | n1 | |
// | | | | |
// v0-------v1--------v3-------v4 -
//(b.x, b.y)

//for lower left corner
glm::vec3 v0 = merc_to_ecef({ b.x, b.y, 0 }, map_size);
glm::vec3 v1 = merc_to_ecef({ b.x + step, b.y, 0 }, map_size);
glm::vec3 v2 = merc_to_ecef({ b.x, b.y + step, 0 }, map_size);

//for lower right corner
glm::vec3 v3 = merc_to_ecef({ b.x + b.a - step, b.y, 0 }, map_size);
glm::vec3 v4 = merc_to_ecef({ b.x + b.a, b.y, 0 }, map_size);
glm::vec3 v5 = merc_to_ecef({ b.x + b.a, b.y + step, 0 }, map_size);

//for upper left corner
glm::vec3 v6 = merc_to_ecef({ b.x, b.y + b.a - step, 0 }, map_size);
glm::vec3 v7 = merc_to_ecef({ b.x, b.y + b.a, 0 }, map_size);
glm::vec3 v8 = merc_to_ecef({ b.x + step, b.y + b.a, 0 }, map_size);

//for upper right corner
glm::vec3 v9 = merc_to_ecef({ b.x + b.a, b.y + b.a - step, 0 }, map_size);
glm::vec3 v10 = merc_to_ecef({ b.x + b.a - step, b.y, 0 }, map_size);
glm::vec3 v11 = merc_to_ecef({ b.x + b.a, b.y + step, 0 }, map_size);

//anti clock wise
corner_normals[0] = calc_normal(v0, v1, v2);
corner_normals[1] = calc_normal(v4, v5, v3);
corner_normals[2] = calc_normal(v7, v6, v8);
corner_normals[3] = calc_normal(v11, v10, v9);
cn = calculate_corner_normals(plate_path_, resolution_, b);
}


Expand Down
13 changes: 8 additions & 5 deletions spheroid.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ struct plate_name {
std::string name;
};


class plate : public mesh {
size_t resolution_{ 0 };
public:
plate(std::string plate_path, size_t resolution);
void calculate_corner_normals();

box b;
std::string plate_path_;
std::array<glm::vec3, 4> corner_normals{ glm::vec3{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f} };
corner_normals cn;
};


Expand All @@ -38,14 +38,17 @@ class earth_plate : public texture_model {

class spheroid : public sub_system<renderer_system> {
public:
spheroid(double semi_axis_a, double semi_axis_c) : earth_a(semi_axis_a), c(semi_axis_c) {
}

spheroid(double semi_axis_a, double semi_axis_c) : earth_a(semi_axis_a), c(semi_axis_c) {}
void process(ecs_s::registry& world, renderer_system& renderer);


corner_normals& get_corner_normals(std::string plate_path);
private:
using rtype = decltype(std::declval<de2>().load_model_async<model>());
double earth_a{ .0f }, c{ .0f };
std::map<std::string, rtype> requests_made_;
std::vector<rtype> vertices;
//corner normals cache;
lru_cache<std::string, corner_normals> cn_cache;
};

53 changes: 49 additions & 4 deletions util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,60 @@ box path_to_box(const std::string& plate_path) {
return b;
}

corner_normals calculate_corner_normals(std::string plate_path_, size_t resolution_, box b) {
size_t map_size = (size_t)std::pow(2, plate_path_.size()) * 256;
double step = ((float)b.a) / resolution_;
corner_normals cn;

// resolution_ = 3, plate_path = generic
// |<-----------b.a----------->|
// v7-------v8--------v10------v11 -
// | n2 | | n3 | |
// | | | | |
// v6-------|---------|--------v9 |
// |<-step->| | | b.a
// | | | | |
// v2-------|---------|--------v5 |
// | n0 | | n1 | |
// | | | | |
// v0-------v1--------v3-------v4 -
//(b.x, b.y)

//for lower left corner
glm::vec3 v0 = merc_to_ecef({ b.x, b.y, 0 }, map_size);
glm::vec3 v1 = merc_to_ecef({ b.x + step, b.y, 0 }, map_size);
glm::vec3 v2 = merc_to_ecef({ b.x, b.y + step, 0 }, map_size);

//for lower right corner
glm::vec3 v3 = merc_to_ecef({ b.x + b.a - step, b.y, 0 }, map_size);
glm::vec3 v4 = merc_to_ecef({ b.x + b.a, b.y, 0 }, map_size);
glm::vec3 v5 = merc_to_ecef({ b.x + b.a, b.y + step, 0 }, map_size);

//for upper left corner
glm::vec3 v6 = merc_to_ecef({ b.x, b.y + b.a - step, 0 }, map_size);
glm::vec3 v7 = merc_to_ecef({ b.x, b.y + b.a, 0 }, map_size);
glm::vec3 v8 = merc_to_ecef({ b.x + step, b.y + b.a, 0 }, map_size);

//for upper right corner
glm::vec3 v9 = merc_to_ecef({ b.x + b.a, b.y + b.a - step, 0 }, map_size);
glm::vec3 v10 = merc_to_ecef({ b.x + b.a - step, b.y, 0 }, map_size);
glm::vec3 v11 = merc_to_ecef({ b.x + b.a, b.y + step, 0 }, map_size);

//anti clock wise
cn[0] = glm::normalize(calc_normal(v0, v1, v2));
cn[1] = glm::normalize(calc_normal(v4, v5, v3));
cn[2] = glm::normalize(calc_normal(v7, v6, v8));
cn[3] = glm::normalize(calc_normal(v11, v10, v9));

return cn;
}

double N(double phi){
return earth_a * earth_a / sqrt(earth_a * earth_a * cos(phi) * cos(phi) + earth_b * earth_b * sin(phi) * sin(phi));
}

//note: don't reinvent the wheel
//https://danceswithcode.net/engineeringnotes/geodetic_to_ecef/geodetic_to_ecef.html
//Convert Earth-Centered-Earth-Fixed (ECEF) to lat, Lon, Altitude
//Input is a three element array containing x, y, z in meters
//Returned array contains lat and lon in radians, and altitude in meters
std::array<double, 3> ecef_to_geo(std::array<double, 3> ecef) {

std::array<double, 3> geo{ 0, 0, 0 }; //Results go here (Lat, Lon, Altitude)
Expand Down Expand Up @@ -207,7 +252,7 @@ glm::vec3 sphere_intersection(glm::vec3 ray_origin, glm::vec3 ray_direction) {

glm::vec3 hit1 = ray_origin + ray_direction * t0;
glm::vec3 hit2 = ray_origin + ray_direction * t1;
//TODO: find the cause of this left hand - right hand difference, probably in inverse transformations.
//TODO: find the cause of this left hand - right hand difference, probably in the inverse transformations.
auto r1 = ecef_to_geo({ -hit1.x, hit1.y, -hit1.z });
auto r2 = ecef_to_geo({ -hit2.x, hit2.y, -hit2.z });

Expand Down
15 changes: 14 additions & 1 deletion util.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,18 @@ double constexpr circumference = 2 * glm::pi<double>() * earth_a;
struct box {
size_t x{ 0 }, y{ 0 }, a{ 0 };
};
struct corner_normals {
std::array<glm::vec3, 4> data{ glm::vec3{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f} };

glm::vec3& operator[](size_t idx) {
return data[idx];
}
};


box path_to_box(const std::string& plate_path);
corner_normals calculate_corner_normals(std::string plate_path_, size_t resolution_, box b);


//GIS functions
double N(double phi);
Expand All @@ -35,4 +46,6 @@ glm::vec3 calc_normal(glm::vec3 pt1, glm::vec3 pt2, glm::vec3 pt3);

glm::vec3 cast_ray(glm::vec2 mouse, glm::vec2 viewport, glm::mat4 projection, glm::mat4 view, float dir = -1.0f);
bool solve_quadratic(float a, float b, float c, float& t0, float& t1);
glm::vec3 sphere_intersection(glm::vec3 ray_origin, glm::vec3 ray_direction);
glm::vec3 sphere_intersection(glm::vec3 ray_origin, glm::vec3 ray_direction);


Binary file modified x64/Debug/de2.lib
Binary file not shown.

0 comments on commit 7bd9ea4

Please sign in to comment.