Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
ademirtug committed May 18, 2023
1 parent 46fce24 commit bdbb63f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 77 deletions.
2 changes: 1 addition & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ int main()
eng.init();
eng.programs["c_t_direct"] = std::make_shared<program>("c_t_direct", "shaders/c_t_direct.vert", "shaders/c_t_direct.frag");

spheroid s(6378137.0f, 6356752.3f);
spheroid s(earth_a, earth_b);
registry world;
renderer_system renderer;

Expand Down
131 changes: 61 additions & 70 deletions spheroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "util.h"
#include "map_provider.h"
#include <glm/gtx/vector_angle.hpp>
#include <stdlib.h>

void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
//task: find visible plates
Expand All @@ -23,15 +24,15 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
//|---------------------------------|


//default value should be around 70, only infinite distance
//default value is 60 degrees, only infinite distance
//can get 90, like in the directional lighting.
float max_visible_angle = 90;
constexpr float max_visible_angle = glm::pi<float>() / 3;
auto vp = de2::get_instance().viewport;
glm::vec2 l1{ 0, 0 }, l4{ vp.x / 2, 0 }, l6{ vp.x, 0 }, l8{ 0, vp.y / 2 }, l12{ vp.x, vp.y / 2 };
glm::vec2 l16{ 0, vp.y }, l17{ vp.x / 2, vp.y }, l20{ vp.x, vp.y };

std::vector<glm::vec2> points;
points.insert(points.end(), { l1, l4, l6, l8, l12, l16, l17, l20 });
std::vector<glm::vec2> corner_points;
corner_points.insert(corner_points.end(), { l1, l6, l16, l20 });

//we are still using sphere not spheroid
//so -> hit_normal = glm::normalize(ecef)
Expand All @@ -41,6 +42,7 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
glm::vec3 cam = glm::vec4(renderer.cam_->get_world_pos(), 0.0) * renderer.get_view();
cam.y *= -1;
float hit_angle = glm::angle(glm::normalize(edge_hit), glm::normalize(cam));
hit_angle = std::isnan(hit_angle) ? max_visible_angle : hit_angle;
auto hit_geo = ecef_to_geo({ edge_hit.x, edge_hit.y, edge_hit.z });

//coords under mouse cursor
Expand All @@ -50,24 +52,15 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
auto mouse_geo = ecef_to_geo({ mouse_hit.x, mouse_hit.y, mouse_hit.z });




//////////////////////////////////////////////////
std::map<std::string, size_t> node_count;
std::vector<std::string> plates_to_draw;
std::vector<std::string> plates;
std::set<std::string> visible_roots;
std::set<std::string> in, out;

std::set<std::string> visible_plates;

std::queue<std::string> plates_to_check;
plates_to_check.push("a");
plates_to_check.push("b");
plates_to_check.push("c");
plates_to_check.push("d");

std::string visible = "(visible) -> (";

while (!plates_to_check.empty()) {
std::string plate_path = plates_to_check.front();
plates_to_check.pop();
Expand All @@ -77,48 +70,54 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
for (size_t i = 0; i < 4; i++){
auto ca = glm::angle(cn[i], glm::normalize(glm::vec3{cam.x, -cam.y, cam.z }));
if (ca < ( hit_angle * 1.50)) {
//visible plate has been found!
is_visible = true;
visible += plate_path +" ";
break;
}
}
//if (!is_visible) {
// //reverse check to completely rule out.
// for (size_t i = 0; i < corner_points.size(); i++) {
// }
//}

if (!is_visible) {
//check in a reverse manner.
for (size_t i = 0; i < points.size(); i++) {


if (is_visible) {
visible_plates.emplace(plate_path);
if (plate_path.size() < renderer.cam_->zoom_) {
plates_to_check.push(plate_path + "a");
plates_to_check.push(plate_path + "b");
plates_to_check.push(plate_path + "c");
plates_to_check.push(plate_path + "d");
}
}
}


////visible plate has been found! just add its siblings to queue
////so we can see if they are visible or not
//if (plate_path.size() < renderer.cam_->zoom_) {
// visible_plates.emplace(plate_path);

// plates_to_check.push(plate_path + "a");
// plates_to_check.push(plate_path + "b");
// plates_to_check.push(plate_path + "c");
// plates_to_check.push(plate_path + "d");
//}
//make async requests for visible plates
for (auto plate_path : visible_plates) {
if (!de2::get_instance().has_model(plate_path) && requests_made_.find(plate_path) == requests_made_.end()) {
requests_made_[plate_path] = de2::get_instance().load_model_async<earth_plate>(plate_path, plate_path, resolution);
}
}
visible += ")";

//set title
std::string s_mgeo = std::format("edge_hit -> ({:02.2f},{:02.2f},{:02.2f}) | hit_angle -> {:02.2f} | camera -> ({:02.2f},{:02.2f},{:02.2f}) | (sphere coords) -> ({:02.2f},{:02.2f}) {}",
edge_hit.x, edge_hit.y, edge_hit.z, hit_angle * 180 / glm::pi<float>(), cam.x, cam.y, cam.z, /*renderer.mouse_pos.x, renderer.mouse_pos.y*/mouse_geo[0], mouse_geo[1], visible);
de2::get_instance().set_title(s_mgeo);
//world.truncate_component<visible>();
evaluate_completed_requests(world);

std::vector<std::string> plates_to_draw;

//world.view<plate_name, model>([&](ecs_s::entity& e, plate_name& pn, model& m) {
// if (visible_plates.find(pn.name) != visible_plates.end()) {
// world.add_component(e, visible{});
// }
//});

//iterate over all the plates and get a full quad tree
std::map<std::string, size_t> node_count;
world.view<plate_name>([&node_count](ecs_s::entity& e, plate_name& pn) {
std::string plate_root = pn.name.substr(0, pn.name.size() - 1);
if (node_count.find(plate_root) == node_count.end())
node_count[plate_root] = 0;

node_count[pn.name] = 1;
node_count[pn.name] = 1;
node_count[plate_root]++;
});

Expand All @@ -127,42 +126,34 @@ void spheroid::process(ecs_s::registry& world, renderer_system& renderer) {
plates_to_draw.push_back(kv.first);
}
}

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 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], resolution);
//system("cls");
//set title
std::string s_mgeo = std::format("edge_hit -> ({:02.2f},{:02.2f},{:02.2f}) | hit_angle -> {:02.2f} | camera -> ({:02.2f},{:02.2f},{:02.2f}) | (sphere coords) -> ({:02.2f},{:02.2f})",
edge_hit.x, edge_hit.y, edge_hit.z, hit_angle * 180 / glm::pi<float>(), cam.x, cam.y, cam.z, /*renderer.mouse_pos.x, renderer.mouse_pos.y*/mouse_geo[0], mouse_geo[1]);
de2::get_instance().set_title(s_mgeo);
};
void spheroid::evaluate_completed_requests(ecs_s::registry& world) {
std::vector<std::string> completed_requests;
for (auto it = requests_made_.begin(); it != requests_made_.end(); ++it) {
if (it->second.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready) {
//TODO: object may never appear in the list after all, that means this function will block main thread!!!
auto m = de2::get_instance().load_model<earth_plate>(it->first, it->first);
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{ it->first });
world.add_component(e, m);
world.add_component(e, visible{});
cn_cache.put(it->first, std::static_pointer_cast<plate>(ep->m)->cn);
completed_requests.push_back(it->first);
}
}

//evaluate any plate request that has been completed
for (size_t i = 0; i < plates_to_draw.size(); i++) {
if (requests_made_.find(plates_to_draw[i]) != requests_made_.end()) {
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!!!

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);
}
}
for (auto plate_path : completed_requests) {
requests_made_.erase(plate_path);
}
};
}
corner_normals& spheroid::get_corner_normals(std::string plate_path) {
if (!cn_cache.exists(plate_path)) {
cn_cache.put(plate_path, calculate_corner_normals(plate_path, resolution));
Expand Down
8 changes: 3 additions & 5 deletions spheroid.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@
#include "util.h"
#include "map_provider.h"

struct earth {

};
struct earth {};

struct plate_name {
std::string name;
};


class plate : public mesh {
size_t resolution_{ 0 };
public:
Expand Down Expand Up @@ -43,8 +40,9 @@ class spheroid : public sub_system<renderer_system> {


corner_normals& get_corner_normals(std::string plate_path);
size_t resolution{ 32 };
size_t resolution{ 16 };
private:
void evaluate_completed_requests(ecs_s::registry& world);
using rtype = decltype(std::declval<de2>().load_model_async<model>());
double earth_a{ .0f }, c{ .0f };
std::map<std::string, rtype> requests_made_;
Expand Down
2 changes: 1 addition & 1 deletion util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ double merc_y_to_lat(double merc_y, double map_size){

while ((abs(dphi) > 0.000000001) && (i < 25)) {
double con = e * sin(phi);
dphi = glm::pi<double>() / 2.0 - 2.0 * atan(ts * powf((1.0 - con) / (1.0 + con), e / 2.0)) - phi;
dphi = glm::pi<double>() / 2.0 - 2.0 * atan(ts * pow((1.0 - con) / (1.0 + con), e / 2.0)) - phi;
phi += dphi;
i++;
}
Expand Down

0 comments on commit bdbb63f

Please sign in to comment.