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 }
|