rayzor

annotate src/modeller.cc @ 22:5380ff64e83f

minor changes from dos, and line endings cleanup
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 02 May 2014 14:32:58 +0300
parents 79609d482762
children
rev   line source
nuclear@12 1 #include <stdio.h>
nuclear@9 2 #include <string.h>
nuclear@9 3 #include <assert.h>
nuclear@9 4 #include "modeller.h"
nuclear@9 5 #include "min3d.h"
nuclear@9 6 #include "rayzor.h"
nuclear@9 7 #include "scene.h"
nuclear@12 8 #include "keyb.h"
nuclear@14 9 #include "scrman.h"
nuclear@14 10 #include "logger.h"
nuclear@22 11 #include "timer.h"
nuclear@9 12
nuclear@9 13 struct ModellerImpl {
nuclear@9 14 int mx, my;
nuclear@17 15 float cam_theta, cam_phi, cam_dist, cam_fov;
nuclear@15 16 Camera *viewport_cam;
nuclear@9 17
nuclear@9 18 struct m3d_image rbuf;
nuclear@9 19
nuclear@9 20 bool bnstate[8];
nuclear@9 21 int prev_x, prev_y;
nuclear@22 22
nuclear@22 23 float orig_theta;
nuclear@22 24 bool screensaver;
nuclear@9 25 };
nuclear@9 26
nuclear@9 27 static void draw_grid(float size, float spacing);
nuclear@9 28
nuclear@9 29 Modeller::Modeller()
nuclear@9 30 {
nuclear@9 31 set_name("modeller");
nuclear@9 32 }
nuclear@9 33
nuclear@9 34 Modeller::~Modeller()
nuclear@9 35 {
nuclear@9 36 shutdown();
nuclear@9 37 }
nuclear@9 38
nuclear@9 39 bool Modeller::init()
nuclear@9 40 {
nuclear@9 41 mod = new ModellerImpl;
nuclear@9 42 memset(mod, 0, sizeof *mod);
nuclear@9 43
nuclear@15 44 mod->viewport_cam = new Camera;
nuclear@15 45
nuclear@9 46 mod->cam_phi = 25;
nuclear@9 47 mod->cam_dist = 5;
nuclear@17 48 mod->cam_fov = 50.0;
nuclear@9 49
nuclear@9 50 m3d_init();
nuclear@9 51 mod->rbuf.pixels = fb_pixels;
nuclear@9 52 mod->rbuf.xsz = fb_width;
nuclear@9 53 mod->rbuf.ysz = fb_height;
nuclear@9 54 m3d_set_buffers(&mod->rbuf, 0);
nuclear@9 55
nuclear@9 56 m3d_matrix_mode(M3D_PROJECTION);
nuclear@9 57 m3d_load_identity();
nuclear@17 58 m3d_perspective(mod->cam_fov, (float)fb_width / (float)fb_height, 0.5, 500.0);
nuclear@9 59
nuclear@9 60 m3d_enable(M3D_CULL_FACE);
nuclear@9 61 return true;
nuclear@9 62 }
nuclear@9 63
nuclear@9 64 void Modeller::shutdown()
nuclear@9 65 {
nuclear@9 66 if(mod) {
nuclear@9 67 m3d_shutdown();
nuclear@9 68
nuclear@9 69 delete mod;
nuclear@9 70 mod = 0;
nuclear@9 71 }
nuclear@9 72 }
nuclear@9 73
nuclear@9 74 void Modeller::draw() const
nuclear@9 75 {
nuclear@22 76 if(mod->screensaver) {
nuclear@22 77 mod->cam_theta = get_msec() / 100.0f;
nuclear@22 78 }
nuclear@22 79
nuclear@9 80 m3d_clear(M3D_COLOR_BUFFER_BIT);
nuclear@9 81
nuclear@9 82 m3d_matrix_mode(M3D_MODELVIEW);
nuclear@9 83 m3d_load_identity();
nuclear@9 84 m3d_translate(0, 0, -mod->cam_dist);
nuclear@9 85 m3d_rotate(mod->cam_phi, 1, 0, 0);
nuclear@9 86 m3d_rotate(mod->cam_theta, 0, 1, 0);
nuclear@9 87
nuclear@9 88 draw_grid(10.0, 1.0);
nuclear@9 89
nuclear@9 90 scene->draw();
nuclear@9 91 }
nuclear@9 92
nuclear@9 93
nuclear@9 94 static void draw_grid(float size, float spacing)
nuclear@9 95 {
nuclear@9 96 int num_lines = size / spacing;
nuclear@9 97 float dist = size / 2.0;
nuclear@9 98
nuclear@9 99 m3d_disable(M3D_LIGHTING);
nuclear@9 100
nuclear@9 101 m3d_begin(M3D_LINES);
nuclear@9 102 m3d_color(0.4, 0.4, 0.4);
nuclear@9 103
nuclear@9 104 float x = -dist;
nuclear@9 105 for(int i=0; i<=num_lines; i++) {
nuclear@9 106 if(i != num_lines / 2) {
nuclear@9 107 m3d_vertex(-dist, 0, x);
nuclear@9 108 m3d_vertex(dist, 0, x);
nuclear@9 109 m3d_vertex(x, 0, -dist);
nuclear@9 110 m3d_vertex(x, 0, dist);
nuclear@9 111 }
nuclear@9 112 x += spacing;
nuclear@9 113 }
nuclear@9 114 m3d_end();
nuclear@9 115
nuclear@9 116 m3d_begin(M3D_LINES);
nuclear@14 117 m3d_color(0.8, 0, 0);
nuclear@9 118 m3d_vertex(-dist, 0, 0);
nuclear@9 119 m3d_vertex(dist, 0, 0);
nuclear@14 120 m3d_color(0.1, 0.3, 0.8);
nuclear@9 121 m3d_vertex(0, 0, -dist);
nuclear@9 122 m3d_vertex(0, 0, dist);
nuclear@9 123 m3d_end();
nuclear@9 124 }
nuclear@9 125
nuclear@9 126
nuclear@9 127 void Modeller::handle_keyboard(int key, bool press)
nuclear@9 128 {
nuclear@9 129 if(press) {
nuclear@9 130 switch(key) {
nuclear@12 131 case 'q':
nuclear@12 132 quit_app();
nuclear@12 133 break;
nuclear@12 134
nuclear@9 135 case 27:
nuclear@12 136 scene->clear_selection();
nuclear@12 137 break;
nuclear@12 138
nuclear@12 139 case '\t':
nuclear@12 140 {
nuclear@12 141 int s = scene->get_selection();
nuclear@12 142 if(s >= 0) {
nuclear@12 143 s = (s + 1) % scene->get_node_count();
nuclear@12 144 scene->clear_selection();
nuclear@12 145 } else {
nuclear@12 146 s = 0;
nuclear@12 147 }
nuclear@12 148 scene->select(s);
nuclear@12 149 }
nuclear@9 150 break;
nuclear@9 151
nuclear@14 152 case 'r':
nuclear@15 153 case 'p':
nuclear@14 154 if(kb_isdown(KB_ALT) || kb_isdown(KB_CTRL)) {
nuclear@15 155 case KB_F5:
nuclear@15 156 case KB_F6:
nuclear@14 157 Screen *rs = get_screen("renderer");
nuclear@14 158 if(rs) {
nuclear@14 159 activate_screen(rs);
nuclear@15 160
nuclear@15 161 if(key == 'r' || key == KB_F5) {
nuclear@15 162 // start a rendering, and make sure there is a camera
nuclear@15 163 if(!scene->get_active_camera()) {
nuclear@15 164 scene->set_active_camera(mod->viewport_cam);
nuclear@15 165 }
nuclear@15 166 Vector3 dir;
nuclear@17 167 float theta = -DEG2RAD(mod->cam_theta);
nuclear@17 168 float phi = DEG2RAD(mod->cam_phi);
nuclear@17 169 dir.x = sin(theta) * cos(phi) * mod->cam_dist;
nuclear@17 170 dir.y = sin(phi) * mod->cam_dist;
nuclear@17 171 dir.z = cos(theta) * cos(phi) * mod->cam_dist;
nuclear@15 172 mod->viewport_cam->set_position(dir);
nuclear@15 173 mod->viewport_cam->set_target(Vector3(0, 0, 0));
nuclear@17 174 mod->viewport_cam->set_fov(DEG2RAD(mod->cam_fov));
nuclear@15 175
nuclear@15 176 rs->message(message_atom("start"));
nuclear@15 177 }
nuclear@14 178 } else {
nuclear@14 179 printlog("failed to find renderer screen!\n");
nuclear@14 180 }
nuclear@14 181 }
nuclear@14 182 break;
nuclear@14 183
nuclear@22 184 case KB_F1:
nuclear@22 185 mod->screensaver = !mod->screensaver;
nuclear@22 186 if(mod->screensaver) {
nuclear@22 187 mod->orig_theta = mod->cam_theta;
nuclear@22 188 } else {
nuclear@22 189 mod->cam_theta = mod->orig_theta;
nuclear@22 190 }
nuclear@22 191 break;
nuclear@22 192
nuclear@9 193 default:
nuclear@9 194 break;
nuclear@9 195 }
nuclear@9 196 }
nuclear@9 197 }
nuclear@9 198
nuclear@9 199 void Modeller::handle_mbutton(int bn, bool press, int x, int y)
nuclear@9 200 {
nuclear@9 201 mod->bnstate[bn] = press;
nuclear@9 202 mod->prev_x = x;
nuclear@9 203 mod->prev_y = y;
nuclear@9 204 }
nuclear@9 205
nuclear@9 206 void Modeller::handle_mmotion(int x, int y)
nuclear@9 207 {
nuclear@9 208 int dx = x - mod->prev_x;
nuclear@9 209 int dy = y - mod->prev_y;
nuclear@9 210 mod->prev_x = x;
nuclear@9 211 mod->prev_y = y;
nuclear@9 212
nuclear@12 213 if(kb_isdown(KB_ALT) || kb_isdown(KB_CTRL)) {
nuclear@12 214 if(mod->bnstate[0]) {
nuclear@12 215 mod->cam_theta += dx * 0.5;
nuclear@12 216 mod->cam_phi += dy * 0.5;
nuclear@9 217
nuclear@12 218 if(mod->cam_phi < -90) mod->cam_phi = -90;
nuclear@12 219 if(mod->cam_phi > 90) mod->cam_phi = 90;
nuclear@12 220 }
nuclear@12 221 if(mod->bnstate[1]) {
nuclear@12 222 mod->cam_dist += dy * 0.1;
nuclear@12 223 if(mod->cam_dist < 0) mod->cam_dist = 0;
nuclear@12 224 }
nuclear@9 225 }
nuclear@9 226 }