1111
1212#define FMT_FLOAT (x ) (int)(x), (int)(abs((int)(fabsf((x) * 100)) % 100))
1313
14- /*
15- To add :
16-
17- automatic moving camera with mode
18- add more info to debug mode
19-
20- */
21-
2214const char eadk_app_name [] __attribute__((section (".rodata.eadk_app_name" ))) = "3DView" ;
2315const uint32_t eadk_api_level __attribute__((section (".rodata.eadk_api_level" ))) = 0 ;
2416
2517typedef struct {
2618 float x , y , z ;
2719} Vec3 ;
2820
29- Vec3 * points = NULL ;
30- int (* edges )[2 ] = NULL ;
3121int NB_POINTS = 0 ;
3222int NB_EDGES = 0 ;
3323
34- void load_external_data () {
35- const unsigned char * data = (const unsigned char * )eadk_external_data ;
36- int offset = 0 ;
37- int32_t nb_points = 0 , nb_edges = 0 ;
38- memcpy (& nb_points , data + offset , 4 ); offset += 4 ;
39- memcpy (& nb_edges , data + offset , 4 ); offset += 4 ;
40- NB_POINTS = nb_points ;
41- NB_EDGES = nb_edges ;
42-
43- points = malloc (NB_POINTS * sizeof (Vec3 ));
44- edges = malloc (NB_EDGES * sizeof (int [2 ]));
45-
46- memcpy (points , data + offset , NB_POINTS * sizeof (Vec3 ));
47- offset += NB_POINTS * sizeof (Vec3 );
48- memcpy (edges , data + offset , NB_EDGES * sizeof (int [2 ]));
49- }
50-
51- void free_external_data () {
52- free (points );
53- free (edges );
54- }
55-
5624void project (Vec3 point , int * x , int * y , float scale ) {
5725 float factor = FOV / (FOV + point .z );
5826 * x = (int )(point .x * factor * scale + WIDTH / 2 );
@@ -116,76 +84,196 @@ void draw_line(int x0, int y0, int x1, int y1, eadk_color_t color) {
11684 }
11785}
11886
119- void screen (float cam_theta , float cam_phi , float cam_dist , float scale , float cx , float cy , float cz ) {
120- eadk_display_push_rect_uniform (eadk_screen_rect , eadk_color_white );
87+ void screen_batch (
88+ Vec3 * points , int nb_points ,
89+ int (* edges )[2 ], int nb_edges ,
90+ float cam_theta , float cam_phi , float cam_dist , float scale , float cx , float cy , float cz ,
91+ int point_offset
92+ ) {
93+ Vec3 * transformed = malloc (nb_points * sizeof (Vec3 ));
94+ int (* projected )[2 ] = malloc (nb_points * sizeof (int [2 ]));
95+ if (!transformed || !projected ) {
96+ eadk_display_draw_string ("Erreur alloc batch" , (eadk_point_t ){10 , 50 }, false, eadk_color_red , eadk_color_white );
97+ while (1 );
98+ }
12199
122- Vec3 transformed [NB_POINTS ];
123- int projected [NB_POINTS ][2 ];
124- for (int i = 0 ; i < NB_POINTS ; i ++ ) {
125- Vec3 v = camera_transform (points [i ], cam_theta , cam_phi , cam_dist , cx , cy , cz );
126- transformed [i ] = v ;
127- project (transformed [i ], & projected [i ][0 ], & projected [i ][1 ], scale );
128- }
100+ for (int i = 0 ; i < nb_points ; i ++ ) {
101+ Vec3 v = camera_transform (points [i ], cam_theta , cam_phi , cam_dist , cx , cy , cz );
102+ transformed [i ] = v ;
103+ project (transformed [i ], & projected [i ][0 ], & projected [i ][1 ], scale );
104+ }
129105
130- for (int i = 0 ; i < NB_EDGES ; i ++ ) {
131- int a = edges [i ][0 ], b = edges [i ][1 ];
106+ for (int i = 0 ; i < nb_edges ; i ++ ) {
107+ int a = edges [i ][0 ] - point_offset ;
108+ int b = edges [i ][1 ] - point_offset ;
109+ if (a >= 0 && a < nb_points && b >= 0 && b < nb_points ) {
132110 draw_line (projected [a ][0 ], projected [a ][1 ],
133111 projected [b ][0 ], projected [b ][1 ],
134112 eadk_color_black );
135113 }
114+ }
115+
116+ free (transformed );
117+ free (projected );
118+ }
119+
120+ void screen_batches_dynamic (
121+ const unsigned char * data , int32_t nb_points , int32_t nb_edges ,
122+ float cam_theta , float cam_phi , float cam_dist , float scale , float cx , float cy , float cz
123+ ) {
124+ int offset_points = 8 ;
125+ int offset_edges = 8 + nb_points * sizeof (Vec3 );
126+
127+ int points_done = 0 ;
128+ const int BATCH_POINTS = 1500 ;
129+
130+ Vec3 * points = malloc (BATCH_POINTS * sizeof (Vec3 ));
131+ int (* edges_batch )[2 ] = malloc (BATCH_POINTS * 8 * sizeof (int [2 ]));
132+ if (!points || !edges_batch ) {
133+ eadk_display_draw_string ("Erreur alloc batch" , (eadk_point_t ){10 , 50 }, false, eadk_color_red , eadk_color_white );
134+ while (1 );
135+ }
136+
137+ while (points_done < nb_points ) {
138+ int batch_points = (points_done + BATCH_POINTS < nb_points ) ? BATCH_POINTS : (nb_points - points_done );
139+ memcpy (points , data + offset_points + points_done * sizeof (Vec3 ), batch_points * sizeof (Vec3 ));
140+
141+ int nb_edges_batch = 0 ;
142+ for (int i = 0 ; i < nb_edges ; i ++ ) {
143+ int a , b ;
144+ memcpy (& a , data + offset_edges + i * sizeof (int [2 ]), sizeof (int ));
145+ memcpy (& b , data + offset_edges + i * sizeof (int [2 ]) + sizeof (int ), sizeof (int ));
146+ if (a >= points_done && a < points_done + batch_points &&
147+ b >= points_done && b < points_done + batch_points ) {
148+ if (nb_edges_batch < BATCH_POINTS * 8 ) {
149+ edges_batch [nb_edges_batch ][0 ] = a ;
150+ edges_batch [nb_edges_batch ][1 ] = b ;
151+ nb_edges_batch ++ ;
152+ }
153+ }
154+ }
155+
156+ screen_batch (points , batch_points , edges_batch , nb_edges_batch ,
157+ cam_theta , cam_phi , cam_dist , scale , cx , cy , cz , points_done );
158+
159+ points_done += batch_points ;
160+ }
161+
162+ free (points );
163+ free (edges_batch );
136164}
137165
138166int main () {
139167 eadk_display_push_rect_uniform (eadk_screen_rect , eadk_color_white );
140168 eadk_backlight_set_brightness (255 );
141169 eadk_display_draw_string ("Loading..." , (eadk_point_t ){10 , 10 }, false, eadk_color_black , eadk_color_white );
142170
143- load_external_data () ;
144-
145- char buf [ 64 ] ;
146- snprintf ( buf , sizeof ( buf ), "Points: %d, Edges: %d" , NB_POINTS , NB_EDGES );
147- eadk_display_draw_string ( buf , ( eadk_point_t ){ 10 , 30 }, false, eadk_color_black , eadk_color_white ) ;
148- eadk_timing_msleep ( 1000 ) ;
171+ const unsigned char * data = ( const unsigned char * ) eadk_external_data ;
172+ int32_t nb_points = 0 , nb_edges = 0 ;
173+ memcpy ( & nb_points , data , 4 ) ;
174+ memcpy ( & nb_edges , data + 4 , 4 );
175+ NB_POINTS = nb_points ;
176+ NB_EDGES = nb_edges ;
149177
150178 float cam_theta = 0.0f ;
151179 float cam_phi = 0.0f ;
152180 float cam_dist = 10.0f ;
153181 float scale = 50.0f ;
154182 float center_x = 0.0f , center_y = 0.0f , center_z = 0.0f ;
155183
156- screen (cam_theta , cam_phi , cam_dist , scale , center_x , center_y , center_z );
184+ char buf [64 ];
185+ snprintf (buf , sizeof (buf ), "Points: %d, Edges: %d" , NB_POINTS , NB_EDGES );
186+ eadk_display_draw_string (buf , (eadk_point_t ){10 , 30 }, false, eadk_color_black , eadk_color_white );
187+ eadk_display_draw_string ("Press shift to change camera distance" , (eadk_point_t ){10 , 50 }, false, eadk_color_black , eadk_color_white );
188+ for (int i = 0 ; i < 10 ; i ++ ) {
189+ char buf [32 ];
190+ snprintf (buf , "%d ms" , 1000 - 100 * i );
191+ eadk_display_draw_string (buf , (eadk_point_t ){10 , 200 }, false, eadk_color_black , eadk_color_white );
192+ eadk_timing_msleep (100 );
193+ eadk_keyboard_state_t keys = eadk_keyboard_scan ();
194+ if (eadk_keyboard_key_down (keys , eadk_key_shift )) {
195+ eadk_display_push_rect_uniform (eadk_screen_rect , eadk_color_white );
196+ eadk_display_draw_string ("Chooce camera distance " , (eadk_point_t ){10 , 10 }, false, eadk_color_black , eadk_color_white );
197+ eadk_display_draw_string ("If the camera is in the model" , (eadk_point_t ){10 , 30 }, false, eadk_color_black , eadk_color_white );
198+ eadk_display_draw_string ("Right/left arrow to increase/decrease" , (eadk_point_t ){10 , 50 }, false, eadk_color_black , eadk_color_white );
199+ eadk_display_draw_string ("or up/down to increase/decrease * 10" , (eadk_point_t ){10 , 70 }, false, eadk_color_black , eadk_color_white );
200+ eadk_display_draw_string ("Press ok to continue" , (eadk_point_t ){10 , 90 }, false, eadk_color_black , eadk_color_white );
201+ snprintf (buf , sizeof (buf ), "Camera distance: %d.%02d" , (int )cam_dist , (int )(fabsf (cam_dist * 100 )) % 100 );
202+ eadk_display_draw_string (buf , (eadk_point_t ){10 , 130 }, false, eadk_color_black , eadk_color_white );
203+ while (1 ){
204+ eadk_keyboard_state_t keys = eadk_keyboard_scan ();
205+ if (eadk_keyboard_key_down (keys , eadk_key_home )) {
206+ return 0 ;
207+ }
208+ if (eadk_keyboard_key_down (keys , eadk_key_right )) {
209+ cam_dist += 0.5f ;
210+ snprintf (buf , sizeof (buf ), "Camera distance: %d.%02d" , (int )cam_dist , (int )(fabsf (cam_dist * 100 )) % 100 );
211+ eadk_display_draw_string (buf , (eadk_point_t ){10 , 130 }, false, eadk_color_black , eadk_color_white );
212+ eadk_timing_msleep (50 );
213+ }
214+ if (eadk_keyboard_key_down (keys , eadk_key_left )) {
215+ cam_dist -= 0.5f ;
216+ if (cam_dist < 0.5f ) cam_dist = 0.5f ;
217+ snprintf (buf , sizeof (buf ), "Camera distance: %d.%02d" , (int )cam_dist , (int )(fabsf (cam_dist * 100 )) % 100 );
218+ eadk_display_draw_string (buf , (eadk_point_t ){10 , 130 }, false, eadk_color_black , eadk_color_white );
219+ eadk_timing_msleep (50 );
220+ }
221+ if (eadk_keyboard_key_down (keys , eadk_key_up )) {
222+ cam_dist += 5.0f ;
223+ snprintf (buf , sizeof (buf ), "Camera distance: %d.%02d" , (int )cam_dist , (int )(fabsf (cam_dist * 100 )) % 100 );
224+ eadk_display_draw_string (buf , (eadk_point_t ){10 , 130 }, false, eadk_color_black , eadk_color_white );
225+ eadk_timing_msleep (50 );
226+ }
227+ if (eadk_keyboard_key_down (keys , eadk_key_down )) {
228+ cam_dist -= 5.0f ;
229+ if (cam_dist < 0.5f ) cam_dist = 0.5f ;
230+ snprintf (buf , sizeof (buf ), "Camera distance: %d.%02d" , (int )cam_dist , (int )(fabsf (cam_dist * 100 )) % 100 );
231+ eadk_display_draw_string (buf , (eadk_point_t ){10 , 130 }, false, eadk_color_black , eadk_color_white );
232+ eadk_timing_msleep (50 );
233+ }
234+ if (eadk_keyboard_key_down (keys , eadk_key_ok )) {
235+ break ;
236+ }
237+ }
238+ }
239+ }
240+
241+ eadk_display_push_rect_uniform (eadk_screen_rect , eadk_color_white );
242+ screen_batches_dynamic (data , NB_POINTS , NB_EDGES , cam_theta , cam_phi , cam_dist , scale , center_x , center_y , center_z );
157243
158244 bool is_debug = false;
159245 bool is_cam_mode = false;
160246
161- uint32_t elapsed ;
247+ uint32_t elapsed = 0 ;
162248
163249 while (true) {
164250 bool redraw = false;
165251
166252 eadk_keyboard_state_t keys = eadk_keyboard_scan ();
167253
254+ float cam_speed = 0.02f * ((float )elapsed / 60.0f );
255+ float move_speed = 0.05f * ((float )elapsed / 60.0f );
256+
168257 if (!is_cam_mode ) {
169258 if (eadk_keyboard_key_down (keys , eadk_key_imaginary )) {
170- cam_theta += 0.05f ;
259+ cam_theta += cam_speed ;
171260 redraw = true;
172261 }
173262 if (eadk_keyboard_key_down (keys , eadk_key_power )) {
174- cam_theta -= 0.05f ;
263+ cam_theta -= cam_speed ;
175264 redraw = true;
176265 }
177266 if (eadk_keyboard_key_down (keys , eadk_key_toolbox )) {
178- cam_phi += 0.05f ;
267+ cam_phi += cam_speed ;
179268 if (cam_phi > 1.5f ) cam_phi = 1.5f ;
180269 redraw = true;
181270 }
182271 if (eadk_keyboard_key_down (keys , eadk_key_sqrt )) {
183- cam_phi -= 0.05f ;
272+ cam_phi -= cam_speed ;
184273 if (cam_phi < -1.5f ) cam_phi = -1.5f ;
185274 redraw = true;
186275 }
187276
188- float move_speed = 0.2f ;
189277 float forward [3 ], right [3 ], up [3 ];
190278 camera_axes (cam_theta , cam_phi , forward , right , up );
191279
@@ -225,7 +313,7 @@ int main() {
225313 }
226314
227315 if (eadk_keyboard_key_down (keys , eadk_key_home )) {
228- break ;
316+ return 0 ;
229317 }
230318
231319 if (eadk_keyboard_key_down (keys , eadk_key_shift )) {
@@ -243,35 +331,47 @@ int main() {
243331 if (!is_cam_mode ){
244332 if (redraw ) {
245333 uint32_t start = (uint32_t )eadk_timing_millis ();
246- screen (cam_theta , cam_phi , cam_dist , scale , center_x , center_y , center_z );
334+ eadk_display_push_rect_uniform (eadk_screen_rect , eadk_color_white );
335+ screen_batches_dynamic (data , NB_POINTS , NB_EDGES , cam_theta , cam_phi , cam_dist , scale , center_x , center_y , center_z );
247336 uint32_t end = (uint32_t )eadk_timing_millis ();
248337 elapsed = end - start ;
249338 }
250339 }
251340 else {
252341 uint32_t start = (uint32_t )eadk_timing_millis ();
253342
254- cam_theta += 0.02f ;
343+ cam_theta -= cam_speed ;
255344
256- screen (cam_theta , cam_phi , cam_dist , scale , center_x , center_y , center_z );
345+ eadk_display_push_rect_uniform (eadk_screen_rect , eadk_color_white );
346+ screen_batches_dynamic (data , NB_POINTS , NB_EDGES , cam_theta , cam_phi , cam_dist , scale , center_x , center_y , center_z );
257347 eadk_display_draw_string ("Camera Mode... Press 0 to quit" , (eadk_point_t ){0 , 225 }, false, eadk_color_black , eadk_color_white );
258348
259349 uint32_t end = (uint32_t )eadk_timing_millis ();
260350 elapsed = end - start ;
261351 }
262352
263353 if (is_debug ) {
264- char buf [128 ];
354+ char buf [192 ];
265355 snprintf (buf , sizeof (buf ),
266- "Cam: theta=%d.%02d, phi=%d.%02d, scale=%d.%02d\nCenter: (%d.%02d, %d.%02d, %d.%02d)\nFramerate: %u ms" ,
356+ "Cam: theta=%d.%02d, phi=%d.%02d, scale=%d.%02d\n"
357+ "Center: (%d.%02d, %d.%02d, %d.%02d)\n"
358+ "Cam_speed: %d.%02d, Move_speed: %d.%02d\n"
359+ "Framerate: %u ms\n"
360+ "Sleep: %u ms" ,
267361 FMT_FLOAT (cam_theta ), FMT_FLOAT (cam_phi ), FMT_FLOAT (scale ),
268- FMT_FLOAT (center_x ), FMT_FLOAT (center_y ), FMT_FLOAT (center_z ), elapsed );
362+ FMT_FLOAT (center_x ), FMT_FLOAT (center_y ), FMT_FLOAT (center_z ),
363+ FMT_FLOAT (cam_speed ), FMT_FLOAT (move_speed ),
364+ elapsed ,
365+ elapsed < 60 ? 60 - elapsed : 0
366+ );
269367 eadk_display_draw_string (buf , (eadk_point_t ){0 , 0 }, false, eadk_color_black , eadk_color_white );
270368 }
271369
272- eadk_timing_msleep (30 );
370+
371+ if (elapsed < 60 ) {
372+ eadk_timing_msleep (60 - elapsed );
373+ }
273374 }
274375
275- free_external_data ();
276376 return 0 ;
277377}
0 commit comments