cmake + tile loading
This commit is contained in:
7
CMakeLists.txt
Normal file
7
CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
project(llmr)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(macosx)
|
||||
18
Makefile
18
Makefile
@@ -1,5 +1,5 @@
|
||||
CXXFLAGS = -Wall -Wextra -std=c++11 -stdlib=libc++ -fno-exceptions
|
||||
CPPFLAGS = -O3 -DDEBUG
|
||||
CXXFLAGS = -O2 -Wall -Wextra -std=c++11 -stdlib=libc++ -fno-exceptions
|
||||
CPPFLAGS = -DDEBUG
|
||||
INCLUDE = -Iinclude
|
||||
|
||||
|
||||
@@ -21,8 +21,9 @@ main: macosx
|
||||
|
||||
macosx: SRCS += macosx/main.mm
|
||||
emscripten: SRCS += emscripten/main.cpp
|
||||
emscripten3: SRCS += emscripten/main.cpp
|
||||
|
||||
macosx emscripten: OBJS = $(patsubst %.mm,%.o,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(SRCS))))
|
||||
macosx emscripten emscripten3: OBJS = $(patsubst %.mm,%.o,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(SRCS))))
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDE) -c -o $@ $^
|
||||
@@ -36,13 +37,18 @@ macosx emscripten: OBJS = $(patsubst %.mm,%.o,$(patsubst %.cpp,%.o,$(patsubst %.
|
||||
|
||||
.SECONDEXPANSION:
|
||||
macosx: $$(OBJS)
|
||||
$(CXX) $(OBJS) $(INCLUDE) -lglfw3 -framework OpenGL -framework Foundation -o macosx/main
|
||||
$(CXX) -O3 $(OBJS) $(INCLUDE) -lglfw3 -framework OpenGL -framework Foundation -o macosx/main
|
||||
|
||||
emscripten: $$(OBJS)
|
||||
$(CXX) $(OBJS) $(INCLUDE) -o emscripten/main.js
|
||||
|
||||
emscripten3: $$(OBJS)
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OBJS) $(INCLUDE) -s DOUBLE_MODE=0 -s FORCE_ALIGNED_MEMORY=1 -s PRECISE_I64_MATH=0 --closure 1 -o emscripten/main.js
|
||||
uglifyjs emscripten/main.js -mc > emscripten/main.dist.js
|
||||
gzip -c emscripten/main.dist.js > emscripten/main.dist.js.gz
|
||||
|
||||
clean:
|
||||
rm -rf src/*/*.o
|
||||
rm -rf macosx/main
|
||||
rm -rf */*.o */*/*.o
|
||||
rm -rf macosx/main emscripten/main.js emscripten/main.js.map
|
||||
|
||||
.PHONY: macosx emscripten
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <llmr/llmr.hpp>
|
||||
#include <llmr/map/tile.hpp>
|
||||
@@ -18,8 +19,7 @@ public:
|
||||
MapView() :
|
||||
dirty(true),
|
||||
platform(new llmr::platform(this)),
|
||||
painter(new llmr::painter(platform)),
|
||||
map(new llmr::map(platform, painter)) {
|
||||
map(new llmr::map(platform)) {
|
||||
|
||||
// Initialize GLFW
|
||||
if (!glfwInit()) {
|
||||
@@ -42,14 +42,13 @@ public:
|
||||
exit(1);
|
||||
}
|
||||
|
||||
painter->setup();
|
||||
painter->resize(width, height);
|
||||
map->setup();
|
||||
map->resize(width, height);
|
||||
|
||||
}
|
||||
|
||||
~MapView() {
|
||||
delete map;
|
||||
delete painter;
|
||||
delete platform;
|
||||
glfwTerminate();
|
||||
}
|
||||
@@ -65,7 +64,7 @@ public:
|
||||
static void scroll(float pos) {
|
||||
double delta = pos;
|
||||
|
||||
bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0;
|
||||
// bool is_wheel = delta != 0 && fmod(delta, 4.000244140625) == 0;
|
||||
|
||||
double absdelta = delta < 0 ? -delta : delta;
|
||||
double scale = 2.0 / (1.0 + exp(-absdelta / 100.0));
|
||||
@@ -86,6 +85,8 @@ public:
|
||||
static void mouseclick(int button, int action) {
|
||||
if (button == GLFW_MOUSE_BUTTON_1) {
|
||||
view->tracking = action == GLFW_PRESS;
|
||||
} else if (button == GLFW_MOUSE_BUTTON_RIGHT) {
|
||||
fprintf(stderr, "right mouse\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +111,6 @@ public:
|
||||
|
||||
|
||||
llmr::platform *platform;
|
||||
llmr::painter *painter;
|
||||
llmr::map *map;
|
||||
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ class tile;
|
||||
|
||||
class map {
|
||||
public:
|
||||
map(class platform *platform);
|
||||
map();
|
||||
~map();
|
||||
|
||||
void setup();
|
||||
@@ -26,10 +26,15 @@ public:
|
||||
void tileFailed(tile *tile);
|
||||
|
||||
private:
|
||||
platform *platform;
|
||||
void updateTiles();
|
||||
|
||||
private:
|
||||
transform *transform;
|
||||
painter *painter;
|
||||
|
||||
// int32_t min_zoom;
|
||||
// int32_t max_zoom;
|
||||
|
||||
std::vector<tile *> tiles;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <llmr/util/vec2.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
@@ -18,9 +19,15 @@ public:
|
||||
void parseFeature(const uint8_t *data, uint32_t bytes);
|
||||
void loadGeometry(const uint8_t *data, uint32_t bytes);
|
||||
|
||||
void cancel();
|
||||
|
||||
static uint64_t toID(int32_t z, int32_t x, int32_t y, int32_t w = 0);
|
||||
static vec4<int32_t> fromID(uint64_t id);
|
||||
|
||||
public:
|
||||
const int32_t z, x, y;
|
||||
bool loaded;
|
||||
bool cancelled;
|
||||
linevertexbuffer lineVertex;
|
||||
|
||||
private:
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace llmr {
|
||||
|
||||
struct box;
|
||||
|
||||
class tile;
|
||||
|
||||
class transform {
|
||||
@@ -24,8 +27,13 @@ public:
|
||||
|
||||
// Getters
|
||||
void matrixFor(float matrix[16], uint32_t z, uint32_t x, uint32_t y) const;
|
||||
int32_t getZoom() const;
|
||||
void getLonLat(double& lon, double& lat) const;
|
||||
|
||||
|
||||
// Temporary
|
||||
void mapCornersToBox(uint32_t z, box& b) const;
|
||||
|
||||
private:
|
||||
double pixel_x() const;
|
||||
double pixel_y() const;
|
||||
@@ -40,6 +48,8 @@ private:
|
||||
double angle;
|
||||
double scale;
|
||||
|
||||
double min_scale, max_scale;
|
||||
|
||||
// tile size
|
||||
const int32_t size = 512;
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#error Unsupported Apple platform
|
||||
#endif
|
||||
|
||||
@@ -5,18 +5,13 @@ namespace llmr {
|
||||
|
||||
class tile;
|
||||
|
||||
class platform {
|
||||
public:
|
||||
platform(void *obj) : obj(obj) {}
|
||||
void restart();
|
||||
void request(tile *tile);
|
||||
namespace platform {
|
||||
|
||||
private:
|
||||
void *obj;
|
||||
};
|
||||
void restart(void *obj);
|
||||
void request(void *obj, tile *tile);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class platform;
|
||||
class transform;
|
||||
class tile;
|
||||
|
||||
class painter {
|
||||
public:
|
||||
painter(class platform *platform, class transform *tranform);
|
||||
painter(class transform *tranform);
|
||||
|
||||
void setup();
|
||||
void teardown();
|
||||
@@ -31,7 +30,6 @@ private:
|
||||
public:
|
||||
|
||||
private:
|
||||
platform *platform;
|
||||
transform *transform;
|
||||
float matrix[16];
|
||||
|
||||
@@ -39,7 +37,7 @@ private:
|
||||
FillShader *fillShader;
|
||||
LineShader *lineShader;
|
||||
|
||||
uint32_t vertexArray;
|
||||
// uint32_t vertexArray;
|
||||
uint32_t triangleVertexBuffer;
|
||||
uint32_t fillVertexBuffer;
|
||||
};
|
||||
|
||||
40
include/llmr/util/vec2.hpp
Normal file
40
include/llmr/util/vec2.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef llmr_util_vec2_
|
||||
#define llmr_util_vec2_
|
||||
|
||||
namespace llmr {
|
||||
|
||||
template <typename T = double>
|
||||
struct vec2 {
|
||||
T x, y;
|
||||
|
||||
// inline bool operator==(const vec2& rhs) const {
|
||||
// return x == rhs.x && y == rhs.y;
|
||||
// }
|
||||
};
|
||||
|
||||
template <typename T = double>
|
||||
struct vec3 {
|
||||
T x, y, z;
|
||||
|
||||
// inline bool operator==(const vec3& rhs) const {
|
||||
// return x == rhs.x && y == rhs.y && z == rhs.z;
|
||||
// }
|
||||
};
|
||||
|
||||
template <typename T = double>
|
||||
struct vec4 {
|
||||
T x, y, z, w;
|
||||
|
||||
// inline bool operator==(const vec4& rhs) const {
|
||||
// return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
|
||||
// }
|
||||
};
|
||||
|
||||
|
||||
struct box {
|
||||
vec2<double> tl, tr, bl, br;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
37
macosx/CMakeLists.txt
Normal file
37
macosx/CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
FIND_LIBRARY(COCOA_LIBRARY Cocoa)
|
||||
FIND_LIBRARY(OPENGL_LIBRARY OpenGL)
|
||||
FIND_LIBRARY(IOKIT_LIBRARY IOKit)
|
||||
FIND_LIBRARY(COREVIDEO_LIBRARY CoreVidoe)
|
||||
|
||||
FIND_PACKAGE(PkgConfig REQUIRED)
|
||||
PKG_SEARCH_MODULE(GLFW REQUIRED glfw3)
|
||||
|
||||
|
||||
SET(macosx_SOURCES
|
||||
main.mm
|
||||
)
|
||||
|
||||
SET(macosx_HEADERS
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
../include
|
||||
${GLFW_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
LINK_DIRECTORIES(
|
||||
${GLFW_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(macosx
|
||||
${macosx_SOURCES}
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(macosx
|
||||
llmr
|
||||
${COCOA_LIBRARY}
|
||||
${OPENGL_LIBRARY}
|
||||
${IOKIT_LIBRARY}
|
||||
${COREVIDOE_LIBRARY}
|
||||
${GLFW_LIBRARIES}
|
||||
)
|
||||
@@ -11,8 +11,10 @@ public:
|
||||
tracking(false),
|
||||
rotating(false),
|
||||
last_click(-1),
|
||||
platform(new llmr::platform(this)),
|
||||
map(new llmr::map(platform)) {
|
||||
map(new llmr::map()) {
|
||||
}
|
||||
|
||||
void init() {
|
||||
if (!glfwInit()) {
|
||||
fprintf(stderr, "Failed to initialize glfw\n");
|
||||
exit(1);
|
||||
@@ -143,7 +145,6 @@ public:
|
||||
|
||||
~MapView() {
|
||||
delete map;
|
||||
delete platform;
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
@@ -158,19 +159,25 @@ public:
|
||||
double last_click;
|
||||
|
||||
GLFWwindow *window;
|
||||
llmr::platform *platform;
|
||||
llmr::map *map;
|
||||
};
|
||||
|
||||
void llmr::platform::restart() {
|
||||
((MapView *)obj)->dirty = true;
|
||||
|
||||
MapView *view;
|
||||
|
||||
namespace llmr {
|
||||
namespace platform {
|
||||
|
||||
void restart(void *) {
|
||||
view->dirty = true;
|
||||
}
|
||||
|
||||
void llmr::platform::request(tile *tile) {
|
||||
void request(void *, tile *tile) {
|
||||
fprintf(stderr, "request %d/%d/%d\n", tile->z, tile->x, tile->y);
|
||||
|
||||
fprintf(stderr, "requesting tile\n");
|
||||
NSString *urlTemplate = @"http://api.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/%d/%d/%d.vector.pbf";
|
||||
// NSString *urlTemplate = @"http://api.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/%d/%d/%d.vector.pbf";
|
||||
NSString *urlTemplate = @"http://localhost:3333/gl/tiles/%d-%d-%d.vector.pbf";
|
||||
NSString *urlString = [NSString
|
||||
stringWithFormat:urlTemplate,
|
||||
tile->z,
|
||||
@@ -192,20 +199,25 @@ void llmr::platform::request(tile *tile) {
|
||||
tile->setData((uint8_t *)[data bytes], [data length]);
|
||||
if (tile->parse()) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^ {
|
||||
((MapView *)obj)->map->tileLoaded(tile);
|
||||
view->map->tileLoaded(tile);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^ {
|
||||
((MapView *)obj)->map->tileFailed(tile);
|
||||
view->map->tileFailed(tile);
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
MapView view;
|
||||
return view.run();
|
||||
view = new MapView();
|
||||
view->init();
|
||||
int ret = view->run();
|
||||
delete view;
|
||||
return ret;
|
||||
}
|
||||
|
||||
43
src/CMakeLists.txt
Normal file
43
src/CMakeLists.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
SET(llmr_SOURCES
|
||||
geometry/linevertexbuffer.cpp
|
||||
map/map.cpp
|
||||
map/tile.cpp
|
||||
map/transform.cpp
|
||||
renderer/painter.cpp
|
||||
renderer/shader-fill.cpp
|
||||
renderer/shader-line.cpp
|
||||
renderer/shader.cpp
|
||||
shader/shaders.c
|
||||
util/mat4.c
|
||||
)
|
||||
|
||||
SET(llmr_HEADERS
|
||||
../include/llmr/geometry/linevertexbuffer.hpp
|
||||
../include/llmr/llmr.hpp
|
||||
../include/llmr/map/map.hpp
|
||||
../include/llmr/map/tile.hpp
|
||||
../include/llmr/map/transform.hpp
|
||||
../include/llmr/platform/gl.hpp
|
||||
../include/llmr/platform/platform.hpp
|
||||
../include/llmr/renderer/painter.hpp
|
||||
../include/llmr/renderer/shader-fill.hpp
|
||||
../include/llmr/renderer/shader-line.hpp
|
||||
../include/llmr/renderer/shader.hpp
|
||||
../include/llmr/util/math.hpp
|
||||
../include/llmr/util/vec2.hpp
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
../include
|
||||
)
|
||||
|
||||
ADD_LIBRARY(llmr STATIC
|
||||
${llmr_SOURCES}
|
||||
${llmr_HEADERS}
|
||||
)
|
||||
|
||||
LINK_DIRECTORIES(
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(llmr
|
||||
)
|
||||
100
src/map/map.cpp
100
src/map/map.cpp
@@ -1,31 +1,20 @@
|
||||
#include <llmr/map/map.hpp>
|
||||
#include <llmr/map/tile.hpp>
|
||||
#include <llmr/util/vec2.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
map::map(class platform *platform)
|
||||
: platform(platform),
|
||||
transform(new class transform()),
|
||||
painter(new class painter(platform, transform)) {
|
||||
|
||||
transform->setLonLat(13, 50);
|
||||
transform->setZoom(3);
|
||||
|
||||
tiles.push_back(new class tile(1, 0, 0));
|
||||
platform->request(tiles.back());
|
||||
|
||||
tiles.push_back(new class tile(1, 1, 0));
|
||||
platform->request(tiles.back());
|
||||
|
||||
tiles.push_back(new class tile(1, 0, 1));
|
||||
platform->request(tiles.back());
|
||||
|
||||
tiles.push_back(new class tile(1, 1, 1));
|
||||
platform->request(tiles.back());
|
||||
map::map()
|
||||
: transform(new class transform()),
|
||||
painter(new class painter(transform)) {
|
||||
|
||||
// transform->setLonLat(13, 50);
|
||||
// transform->setZoom(3);
|
||||
}
|
||||
|
||||
map::~map() {
|
||||
@@ -39,24 +28,83 @@ void map::setup() {
|
||||
void map::resize(uint32_t width, uint32_t height) {
|
||||
transform->width = width;
|
||||
transform->height = height;
|
||||
platform->restart();
|
||||
updateTiles();
|
||||
platform::restart(this);
|
||||
}
|
||||
|
||||
void map::moveBy(double dx, double dy) {
|
||||
transform->moveBy(dx, dy);
|
||||
platform->restart();
|
||||
updateTiles();
|
||||
platform::restart(this);
|
||||
}
|
||||
|
||||
void map::scaleBy(double ds, double cx, double cy) {
|
||||
transform->scaleBy(ds, cx, cy);
|
||||
platform->restart();
|
||||
updateTiles();
|
||||
platform::restart(this);
|
||||
}
|
||||
|
||||
void map::rotateBy(double cx, double cy, double sx, double sy, double ex, double ey) {
|
||||
transform->rotateBy(cx, cy, sx, sy, ex, ey);
|
||||
platform->restart();
|
||||
updateTiles();
|
||||
platform::restart(this);
|
||||
}
|
||||
|
||||
void map::updateTiles() {
|
||||
// Figure out what tiles we need to load
|
||||
int32_t zoom = transform->getZoom();
|
||||
int32_t max_dim = pow(2, zoom);
|
||||
|
||||
// Map four viewport corners to pixel coordinates
|
||||
box box;
|
||||
transform->mapCornersToBox(zoom, box);
|
||||
|
||||
vec2<int32_t> tl, br;
|
||||
tl.x = fmax(0, floor(fmin(box.tl.x, box.bl.x)));
|
||||
tl.y = fmax(0, floor(fmin(box.tl.y, box.tr.y)));
|
||||
br.x = fmin(max_dim, ceil(fmax(box.tr.x, box.br.x)));
|
||||
br.y = fmin(max_dim, ceil(fmax(box.bl.y, box.br.y)));
|
||||
|
||||
// TODO: Discard tiles that are outside the viewport
|
||||
std::vector<uint64_t> required;
|
||||
for (int32_t y = tl.y; y < br.y; y++) {
|
||||
for (int32_t x = tl.x; x < br.x; x++) {
|
||||
required.push_back(tile::toID(zoom, x, y));
|
||||
}
|
||||
}
|
||||
|
||||
// Add existing child/parent tiles if the actual tile is not yet loaded
|
||||
// TODO
|
||||
|
||||
|
||||
// Remove tiles that we definitely don't need, i.e. tiles that are not on
|
||||
// the required list.
|
||||
for (std::vector<tile *>::iterator it = tiles.begin(); it != tiles.end(); it++) {
|
||||
tile *tile = *it;
|
||||
uint64_t id = tile::toID(tile->z, tile->x, tile->y);
|
||||
std::vector<uint64_t>::const_iterator required_it = std::find(required.begin(), required.end(), id);
|
||||
bool retain = required_it != required.end();
|
||||
if (retain) {
|
||||
// We already have the tile; remove it from the list of required tiles.
|
||||
required.erase(required_it);
|
||||
} else {
|
||||
// We don't need this tile, so we can remove it entirely.
|
||||
std::vector<class tile *>::iterator to_remove = it - 1;
|
||||
tile->cancel();
|
||||
tiles.erase(it);
|
||||
it = to_remove;
|
||||
}
|
||||
}
|
||||
|
||||
// Required now only contains those tiles that are not yet in the list of
|
||||
// tiles, so we should add them all.
|
||||
for (int64_t id : required) {
|
||||
vec4<int32_t> tile_coord = tile::fromID(id);
|
||||
tile *tile = new class tile(tile_coord.z, tile_coord.x, tile_coord.y);
|
||||
tiles.push_back(tile);
|
||||
platform::request(this, tile);
|
||||
}
|
||||
}
|
||||
|
||||
bool map::render() {
|
||||
painter->clear();
|
||||
@@ -72,11 +120,7 @@ bool map::render() {
|
||||
}
|
||||
|
||||
void map::tileLoaded(tile *tile) {
|
||||
platform->restart();
|
||||
// fprintf(stderr, "[%8zx] tile loaded %d/%d/%d\n",
|
||||
// std::hash<std::thread::id>()(std::this_thread::get_id()),
|
||||
// tile->z, tile->x, tile->y);
|
||||
// schedule rerender
|
||||
platform::restart(this);
|
||||
}
|
||||
|
||||
void map::tileFailed(tile *tile) {
|
||||
|
||||
@@ -22,11 +22,11 @@ struct pbf {
|
||||
|
||||
inline bool next();
|
||||
template <typename T = uint32_t> inline T varint();
|
||||
inline int64_t svarint();
|
||||
template <typename T = uint32_t> inline T svarint();
|
||||
inline std::string string();
|
||||
inline float float32();
|
||||
inline double float64();
|
||||
inline int64_t int64();
|
||||
// inline int64_t int64();
|
||||
inline bool boolean();
|
||||
|
||||
template <typename T, typename... Args>
|
||||
@@ -91,10 +91,11 @@ T pbf::varint()
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t pbf::svarint()
|
||||
template <typename T>
|
||||
T pbf::svarint()
|
||||
{
|
||||
uint64_t n = varint();
|
||||
return (n >> 1) ^ -(int64_t)(n & 1);
|
||||
T n = varint<T>();
|
||||
return (n >> 1) ^ -(T)(n & 1);
|
||||
}
|
||||
|
||||
std::string pbf::string()
|
||||
@@ -112,6 +113,7 @@ float pbf::float32()
|
||||
memcpy(&result, data - 4, 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
double pbf::float64()
|
||||
{
|
||||
skipBytes(8);
|
||||
@@ -120,10 +122,10 @@ double pbf::float64()
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t pbf::int64()
|
||||
{
|
||||
return (int64_t)varint();
|
||||
}
|
||||
// int64_t pbf::int64()
|
||||
// {
|
||||
// return (int64_t)varint();
|
||||
// }
|
||||
|
||||
bool pbf::boolean()
|
||||
{
|
||||
|
||||
@@ -1,18 +1,43 @@
|
||||
#include <llmr/map/tile.hpp>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cassert>
|
||||
// #include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "pbf.hpp"
|
||||
#include <llmr/util/vec2.hpp>
|
||||
#include <cmath>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
|
||||
uint64_t tile::toID(int32_t z, int32_t x, int32_t y, int32_t w) {
|
||||
w *= 2;
|
||||
if (w < 0) w = w * -1 -1;
|
||||
int32_t dim = 1 << z;
|
||||
return ((dim * dim * w + dim * y + x) * 32) + z;
|
||||
}
|
||||
|
||||
vec4<int32_t> tile::fromID(uint64_t id) {
|
||||
vec4<int32_t> coord;
|
||||
coord.z = id % 32;
|
||||
int32_t dim = 1 << coord.z;
|
||||
int32_t xy = ((id - coord.z) / 32);
|
||||
coord.x = xy % dim;
|
||||
coord.y = ((xy - coord.x) / dim) % dim;
|
||||
coord.w = floor(xy / (dim * dim));
|
||||
if (coord.w % 2 != 0) coord.w = coord.w * -1 -1;
|
||||
coord.w /= 2;
|
||||
return coord;
|
||||
};
|
||||
|
||||
tile::tile(int32_t z, int32_t x, int32_t y)
|
||||
: z(z),
|
||||
x(x),
|
||||
y(y),
|
||||
loaded(false),
|
||||
cancelled(false),
|
||||
data(0),
|
||||
bytes(0) {
|
||||
}
|
||||
@@ -23,8 +48,26 @@ void tile::setData(uint8_t *data, uint32_t bytes) {
|
||||
memcpy(this->data, data, bytes);
|
||||
}
|
||||
|
||||
void tile::cancel()
|
||||
{
|
||||
// TODO: thread safety
|
||||
if (!cancelled) {
|
||||
cancelled = true;
|
||||
if (loaded) {
|
||||
delete this;
|
||||
}
|
||||
} else {
|
||||
assert((!"logic error? multiple cancelleations"));
|
||||
}
|
||||
}
|
||||
|
||||
bool tile::parse()
|
||||
{
|
||||
if (cancelled) {
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[%p] parsing tile...\n", this);
|
||||
|
||||
pbf tile(data, bytes);
|
||||
@@ -40,6 +83,11 @@ bool tile::parse()
|
||||
|
||||
fprintf(stderr, "[%p] parsing tile...done\n", this);
|
||||
|
||||
if (cancelled) {
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
return true;
|
||||
}
|
||||
@@ -84,7 +132,7 @@ void tile::parseFeature(const uint8_t *data, uint32_t bytes) {
|
||||
}
|
||||
|
||||
void tile::loadGeometry(const uint8_t *data, uint32_t bytes) {
|
||||
pbf geometry(data, bytes);
|
||||
pbf geometry(data, bytes);
|
||||
|
||||
uint32_t cmd = 1;
|
||||
uint32_t length = 0;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <llmr/map/transform.hpp>
|
||||
|
||||
#include <llmr/util/mat4.h>
|
||||
#include <llmr/util/vec2.hpp>
|
||||
#include <llmr/util/math.hpp>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
@@ -22,7 +23,9 @@ transform::transform()
|
||||
x(0),
|
||||
y(0),
|
||||
angle(0.0),
|
||||
scale(1.0) {
|
||||
scale(1.0),
|
||||
min_scale(pow(2, 0)),
|
||||
max_scale(pow(2, 20)) {
|
||||
setScale(scale);
|
||||
setAngle(angle);
|
||||
}
|
||||
@@ -33,6 +36,14 @@ void transform::moveBy(double dx, double dy) {
|
||||
}
|
||||
|
||||
void transform::scaleBy(double ds, double cx, double cy) {
|
||||
// clamp scale to min/max values
|
||||
const double new_scale = scale * ds;
|
||||
if (new_scale < min_scale) {
|
||||
ds = min_scale / scale;
|
||||
} else if (new_scale > max_scale) {
|
||||
ds = max_scale / scale;
|
||||
}
|
||||
|
||||
const double dx = (cx - width / 2) * (1.0 - ds);
|
||||
const double dy = (cy - height / 2) * (1.0 - ds);
|
||||
const double fx = cos(angle) * dx + sin(angle) * dy;
|
||||
@@ -41,6 +52,8 @@ void transform::scaleBy(double ds, double cx, double cy) {
|
||||
scale *= ds;
|
||||
x = (x * ds) + fx;
|
||||
y = (y * ds) + fy;
|
||||
|
||||
fprintf(stderr, "scale: %f, %f, %f\n", scale, x, y);
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +91,12 @@ void transform::setAngle(double new_angle) {
|
||||
}
|
||||
|
||||
void transform::setScale(double new_scale) {
|
||||
if (new_scale < min_scale) {
|
||||
new_scale = min_scale;
|
||||
} else if (new_scale > max_scale) {
|
||||
new_scale = max_scale;
|
||||
}
|
||||
|
||||
const double factor = new_scale / scale;
|
||||
x *= factor;
|
||||
y *= factor;
|
||||
@@ -99,7 +118,7 @@ void transform::setLonLat(double lon, double lat) {
|
||||
y = round(0.5 * Cc * log((1 + f) / (1 - f)));
|
||||
}
|
||||
|
||||
void transform::getLonLat(double& lon, double& lat) const {
|
||||
void transform::getLonLat(double &lon, double &lat) const {
|
||||
lon = -x / Bc;
|
||||
lat = R2D * (2 * atan(exp(y / Cc)) - 0.5 * M_PI);
|
||||
}
|
||||
@@ -132,7 +151,40 @@ void transform::matrixFor(float matrix[16], uint32_t tile_z, uint32_t tile_x, ui
|
||||
|
||||
// Clipping plane
|
||||
mat4_translate(matrix, matrix, 0, 0, -1);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int32_t transform::getZoom() const {
|
||||
return floor(log(scale) / M_LN2);
|
||||
}
|
||||
|
||||
|
||||
void transform::mapCornersToBox(uint32_t z, box& b) const {
|
||||
const double ref_scale = pow(2, z);
|
||||
|
||||
// Keep the map as upright as possible.
|
||||
double local_angle = angle;
|
||||
if (local_angle >= M_PI_2) local_angle -= M_PI;
|
||||
if (local_angle < -M_PI_2) local_angle += M_PI;
|
||||
|
||||
const double angle_sin = sin(-local_angle);
|
||||
const double angle_cos = cos(-local_angle);
|
||||
|
||||
const double w_2 = width / 2;
|
||||
const double h_2 = height / 2;
|
||||
const double ss_1 = ref_scale / (scale * size);
|
||||
const double ss_2 = (scale * size) / 2;
|
||||
|
||||
// Calculate the corners of the map view. The resulting coordinates will be
|
||||
// in fractional tile coordinates.
|
||||
b.tl.x = ((-w_2) * angle_cos - (-h_2) * angle_sin + ss_2 - x) * ss_1;
|
||||
b.tl.y = ((-w_2) * angle_sin + (-h_2) * angle_cos + ss_2 - y) * ss_1;
|
||||
b.tr.x = ((+w_2) * angle_cos - (-h_2) * angle_sin + ss_2 - x) * ss_1;
|
||||
b.tr.y = ((+w_2) * angle_sin + (-h_2) * angle_cos + ss_2 - y) * ss_1;
|
||||
b.bl.x = ((-w_2) * angle_cos - (+h_2) * angle_sin + ss_2 - x) * ss_1;
|
||||
b.bl.y = ((-w_2) * angle_sin + (+h_2) * angle_cos + ss_2 - y) * ss_1;
|
||||
b.br.x = ((+w_2) * angle_cos - (+h_2) * angle_sin + ss_2 - x) * ss_1;
|
||||
b.br.y = ((+w_2) * angle_sin + (+h_2) * angle_cos + ss_2 - y) * ss_1;
|
||||
|
||||
// Quick hack: use the entire non-rotated bounding box.
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,8 @@ GLfloat fill_vertices[] = {
|
||||
};
|
||||
|
||||
|
||||
painter::painter(class platform *platform, class transform *transform)
|
||||
: platform(platform),
|
||||
transform(transform),
|
||||
painter::painter(class transform *transform)
|
||||
: transform(transform),
|
||||
currentShader(NULL),
|
||||
fillShader(NULL) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user