-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhorizonator.h
208 lines (174 loc) · 7.86 KB
/
horizonator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "dem.h"
typedef struct
{
int Ntriangles;
bool render_texture, use_glut;
// meaningful only if use_glut. 0 means "invalid" or "closed"
int glut_window;
// These should be GLint, but I don't want to #include <GL.h>.
// I will static_assert() this in the .c to make sure they are compatible
int32_t uniform_aspect, uniform_az_deg0, uniform_az_deg1;
int32_t uniform_viewer_cell_i;
int32_t uniform_viewer_cell_j;
int32_t uniform_viewer_z;
int32_t uniform_viewer_lat;
int32_t uniform_cos_viewer_lat;
int32_t uniform_texturemap_lon0;
int32_t uniform_texturemap_lon1;
int32_t uniform_texturemap_dlat0;
int32_t uniform_texturemap_dlat1;
int32_t uniform_texturemap_dlat2;
int32_t uniform_znear, uniform_zfar;
int32_t uniform_znear_color, uniform_zfar_color;
uint32_t program;
float viewer_lat, viewer_lon;
horizonator_dem_context_t dems;
struct
{
bool inited;
// These should be GLuint, but I don't want to #include <GL.h>.
// I will static_assert() this in the .c to make sure they are compatible
uint32_t frameBufID;
uint32_t renderBufID;
uint32_t depthBufID;
int width, height;
} offscreen;
} horizonator_context_t;
__attribute__((unused))
static bool horizonator_context_isvalid(const horizonator_context_t* ctx)
{
return ctx->Ntriangles > 0;
}
// The main init routine. We support 3 modes:
//
// - GLUT: static window (use_glut = true, offscreen_width <= 0)
// - GLUT: offscreen render (use_glut = true, offscreen_width > 0)
// - no GLUT: higher-level application (use_glut = false)
//
// This routine loads the DEMs around the viewer (viewer is at the center of the
// DEMs). The render can then be updated by calling any of
// - horizonator_move()
// - horizonator_pan_zoom()
// - horizonator_resized()
// and then
// - horizonator_redraw()
//
// If rendering off-screen, horizonator_resized() is not allowed.
// horizonator_pan_zoom() must be called to update the azimuth extents.
// Completely arbitrarily, these are set to -45deg - 45deg initially
//
// SRTM1 selects between 1" SRTM and 3" SRTM. Currently every triangle is
// rendered, so 1" SRTM tiles can easily overload the machine. Unless you need
// the extra resolution, stick with 3" SRTM tiles for now
bool horizonator_init( // output
horizonator_context_t* ctx,
// input
float viewer_lat, float viewer_lon,
// output/input
// if viewer_z==NULL, auto-select a value; if *viewer_z >=
// 0, use that; if *viewer_z < 0, auto-select a value, and
// report it here
float* viewer_z,
int offscreen_width, int offscreen_height,
int render_radius_cells,
bool use_glut,
bool render_texture,
bool SRTM1,
const char* dir_dems,
const char* dir_tiles,
const char* tiles_name,
const char* tiles_url_fmt,
bool allow_downloads);
void horizonator_deinit( horizonator_context_t* ctx );
bool horizonator_resized(const horizonator_context_t* ctx, int width, int height);
// Must be called at least once before horizonator_redraw()
bool horizonator_pan_zoom(const horizonator_context_t* ctx,
// Bounds of the view. We expect az_deg1 > az_deg0. The azimuth
// edges lie at the edges of the image. So for an image that's
// W pixels wide, az0 is at x = -0.5 and az1 is at W-0.5. The
// elevation extents will be chosen to keep the aspect ratio
// square.
float az_deg0, float az_deg1);
// Called after horizonator_init(). Moves the viewer around in the space of
// loaded DEMs. If the viewer moves a LOT, new DEMs should be loaded, and this
// function is no longer appropriate
bool horizonator_move(horizonator_context_t* ctx,
// output/input
// if viewer_z==NULL, auto-select a value; if *viewer_z >=
// 0, use that; if *viewer_z < 0, auto-select a value, and
// report it here
float* viewer_z,
// input
float viewer_lat, float viewer_lon);
// set the position of the clipping planes. The horizontal distance from the
// viewer is compared against these positions. Only points in [znear,zfar] are
// rendered. The render is color-coded by this distance, using znear_color and
// zfar_color as the bounds for the color-coding
//
// Any value <0 is untouched by this call
bool horizonator_set_zextents(horizonator_context_t* ctx,
float znear, float zfar,
float znear_color, float zfar_color);
bool horizonator_redraw(const horizonator_context_t* ctx);
// returns true if an intersection is found
bool horizonator_pick(const horizonator_context_t* ctx,
// output
float* lat, float* lon,
// input
// pixel coordinates in the render
int x, int y );
// Renders a given scene to an RGB image and/or a range image.
// horizonator_init() must have been called first with use_glut=true and
// offscreen_width,height > 0. Then the viewer and camera must have been
// configured with horizonator_move() and horizonator_pan_zoom()
//
// Returns true on success. The image and ranges buffers must be large-enough to
// contain packed 24-bits-per-pixel BGR data and 32-bit floats respectively. The
// images are returned using the usual convention: the top row is stored first.
// This is opposite of the OpenGL convention: bottom row is first. Invisible
// points have ranges <0
bool horizonator_render_offscreen(const horizonator_context_t* ctx,
// output
// either may be NULL
char* image, float* ranges);
bool horizonator_x_from_az( // output
double* x,
double* az_ndc_per_rad,
// input
double az_rad,
double az_rad0,
double az_rad1,
int width);
bool horizonator_project( // output
double* x,
double* y,
double* range,
// input
double lat_viewer, double cos_lat_viewer,
double lon_viewer,
double ele_viewer,
double lat,
double lon,
double ele,
double az_rad0,
double az_rad1,
int width,
int height);
bool horizonator_unproject(// output
float* lat, float* lon,
// input
// pixel coordinates in the render
int x, int y,
// exactly one of these should be >0; we'll use the
// appropriate computation
double range_enh,
double range_en,
double lat_viewer, double cos_lat_viewer,
double lon_viewer,
double az_deg0,
double az_deg1,
int width,
int height);