10 printf(
"error %d: %s\n", error, str);
15 const unsigned int& num_grays)
18 ,m_num_grays(num_grays)
22 std::locale::global(std::locale(
"en_US.utf8"));
23 std::wcout.imbue(std::locale());
60 m_colors =
static_cast<float**
>( malloc( m_ascii_width *
sizeof(
float*) ) );
99 RTCDevice device = rtcNewDevice(
NULL);
103 std::cerr <<
"error " << rtcGetDeviceError(
NULL) <<
": cannot create device" << std::endl;
114 RTCScene scene = rtcNewScene(device);
115 RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE);
117 auto lvr_vertices = mesh->getVertices();
118 int num_vertices = mesh->numVertices();
120 auto lvr_indices = mesh->getFaceIndices();
121 int num_faces = mesh->numFaces();
123 float* embree_vertices = (
float*) rtcSetNewGeometryBuffer(geom,
124 RTC_BUFFER_TYPE_VERTEX,
130 unsigned* embree_indices = (
unsigned*) rtcSetNewGeometryBuffer(geom,
131 RTC_BUFFER_TYPE_INDEX,
137 if (embree_vertices && embree_indices)
140 const float* lvr_vertices_begin = lvr_vertices.get();
141 const float* lvr_vertices_end = lvr_vertices_begin + num_vertices * 3;
142 std::copy(lvr_vertices_begin, lvr_vertices_end, embree_vertices);
144 const unsigned int* lvr_indices_begin = lvr_indices.get();
145 const unsigned int* lvr_indices_end = lvr_indices_begin + num_faces * 3;
146 std::copy(lvr_indices_begin, lvr_indices_end, embree_indices);
149 rtcCommitGeometry(geom);
150 rtcAttachGeometry(scene, geom);
151 rtcReleaseGeometry(geom);
152 rtcCommitScene(scene);
165 unsigned int x_outer = x / 2;
166 unsigned int x_inner = x % 2;
168 unsigned int y_outer = y / 4;
169 unsigned int y_inner = y % 4;
171 m_chars[x_outer][y_outer].
set(x_inner, y_inner);
176 unsigned int x_outer = x / 2;
177 unsigned int x_inner = x % 2;
179 unsigned int y_outer = y / 4;
180 unsigned int y_inner = y % 4;
202 double c_u = image_width / 2;
203 double c_v = image_height / 2;
205 float focal_length = 700.0;
207 double fx = focal_length;
208 double fy = focal_length;
214 #pragma omp parallel for 215 for(
int u = 0; u < image_width; u++)
217 for(
int v = 0; v < image_height; v++)
220 rayhit.ray.org_x = origin.coeff(0);
221 rayhit.ray.org_y = origin.coeff(1);
222 rayhit.ray.org_z = origin.coeff(2);
223 rayhit.ray.tnear = 0;
224 rayhit.ray.tfar = INFINITY;
226 rayhit.ray.flags = 0;
227 rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
228 rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
230 Vector3d dir(1.0, -(static_cast<double>(u) - c_u ) / fx, -(static_cast<double>(v) - c_v) / fy);
236 rayhit.ray.dir_x = dir.coeff(0);
237 rayhit.ray.dir_y = dir.coeff(1);
238 rayhit.ray.dir_z = dir.coeff(2);
243 if(rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID)
245 float norm_normal = sqrt( pow(rayhit.hit.Ng_x, 2.0)
246 + pow(rayhit.hit.Ng_y,2.0)
247 + pow(rayhit.hit.Ng_z,2.0));
249 rayhit.hit.Ng_x /= norm_normal;
250 rayhit.hit.Ng_y /= norm_normal;
251 rayhit.hit.Ng_z /= norm_normal;
253 float scalar = rayhit.ray.dir_x * rayhit.hit.Ng_x
254 + rayhit.ray.dir_y * rayhit.hit.Ng_y
255 + rayhit.ray.dir_z * rayhit.hit.Ng_z;
257 unsigned int ascii_x = u / 2;
258 unsigned int ascii_y = v / 4;
259 m_colors[ascii_x][ascii_y] += std::max(0.1f, fabs(scalar)) / 8.0;
274 }
else if( key ==
'A') {
276 }
else if( key ==
'w') {
279 }
else if( key ==
'W') {
282 }
else if( key ==
's') {
285 }
else if( key ==
'S') {
288 }
else if( key ==
'd') {
291 }
else if( key ==
'D') {
293 }
else if( key ==
'q' ) {
295 m_camera.rotate(Eigen::AngleAxisd(roll, Eigen::Vector3d::UnitX()));
296 }
else if( key ==
'Q' ) {
298 m_camera.rotate(Eigen::AngleAxisd(roll *
m_boost, Eigen::Vector3d::UnitX()));
299 }
else if( key ==
'e' ) {
301 m_camera.rotate(Eigen::AngleAxisd(roll, Eigen::Vector3d::UnitX()));
302 }
else if( key ==
'E' ) {
304 m_camera.rotate(Eigen::AngleAxisd(roll *
m_boost, Eigen::Vector3d::UnitX()));
305 }
else if( key == KEY_LEFT ) {
308 m_camera.rotate(Eigen::AngleAxisd(yaw, Eigen::Vector3d::UnitZ()));
309 }
else if( key == KEY_RIGHT ) {
312 m_camera.rotate(Eigen::AngleAxisd(yaw, Eigen::Vector3d::UnitZ()));
313 }
else if( key == KEY_UP ) {
315 m_camera.rotate(Eigen::AngleAxisd(pitch, Eigen::Vector3d::UnitY()));
316 }
else if( key == KEY_DOWN ) {
318 m_camera.rotate(Eigen::AngleAxisd(pitch, Eigen::Vector3d::UnitY()));
319 }
else if( key ==
' ') {
321 }
else if( key == KEY_MOUSE ) {
325 if(getmouse(&event) == OK)
328 if(event.bstate & BUTTON1_PRESSED)
337 double mouse_x =
static_cast<double>(
event.x);
338 double mouse_y =
static_cast<double>(
event.y);
345 Eigen::AngleAxisd(-delta_y *
m_vrot, Eigen::Vector3d::UnitY())
346 * Eigen::AngleAxisd(delta_x * m_vrot, Eigen::Vector3d::UnitZ())
353 m_mouse_x =
static_cast<double>(
event.x);
354 m_mouse_y =
static_cast<double>(
event.y);
356 }
else if(key == KEY_RESIZE) {
358 }
else if(key ==
'i') {
360 }
else if(key ==
'k') {
362 }
else if(key ==
'h') {
371 auto start = std::chrono::steady_clock::now();
379 for(
unsigned int y=0; y< H; y++)
381 for(
unsigned int x=0; x< W; x++)
387 auto end = std::chrono::steady_clock::now();
388 double ms = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() / 1000.0;
391 double fps = 1000.0 / 0.001;
400 mvprintw(0, 0,
"%4d fps",
int(
m_avg_fps) );
419 addstr(message.c_str());
432 mvprintw(H-8, 0,
"CONTROLLS (H)");
433 mvprintw(H-7, 0,
"Translate: W A S D Scroll");
434 mvprintw(H-6, 0,
"Rotate: ← ↑ → ↓ q e");
435 mvprintw(H-5, 0,
"Mouse control:");
436 mvprintw(H-4, 0,
" - ON: Space, Left Click");
437 mvprintw(H-3, 0,
" - OFF: Space, Other Click");
438 mvprintw(H-2, 0,
"Speed inc/dec: i k");
439 mvprintw(H-1, 0,
"Exit: Esc");
441 mvprintw(H-1, 0,
"CONTROLLS (H)");
void set(const unsigned int &i, const unsigned int &j)
static void console_print_grayscale(int y, int x, wchar_t sign, short gray)
void consoleReleaseMessages()
std::shared_ptr< MeshBuffer > MeshBufferPtr
RTCDevice initializeDevice()
AsciiRenderer(MeshBufferPtr mesh, const unsigned int &num_grays=200)
static mmask_t MOUSE_SCROLL_UP
static mmask_t MOUSE_MOVE
unsigned int m_ascii_width
void AsciiRendererErrorFunc(void *userPtr, enum RTCError error, const char *str)
void consolePrintMessage(std::string message)
Eigen::Vector3d Vector3d
Eigen 3D vector, double precision.
static void init_curses(unsigned int num_grayscale)
RTCIntersectContext m_context
static void destroy_curses()
unsigned int m_ascii_height
static int curses_width()
void initEmbree(MeshBufferPtr mesh)
static int curses_height()
KF_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func="")
Error handler. All GPU functions from this subsystem call the function to report an error...
RTCScene initializeScene(RTCDevice device, const MeshBufferPtr mesh)
void set(const unsigned int &i, const unsigned int &j)
std::vector< std::string > m_messages
void clear(const unsigned int &i, const unsigned int &j)