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