1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2015 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
21 * Oussama Sboui <oussama.sboui@synchrotron-soleil.fr>
23 #include <gtk/gtkgl.h>
28 #include "hkl/ccan/compiler/compiler.h"
30 #include "hkl-gui-macros.h"
31 #include "hkl-gui-3d.h"
32 #include "hkl-gui-3d-gl.h"
35 * updates glarea widget (redraw)
37 static void glarea_update(GtkWidget
*glarea
)
39 gtk_widget_queue_draw_area(glarea
,
41 glarea
->allocation
.width
,
42 glarea
->allocation
.height
);
47 HKL_GUI_3D_COL_NAME
= 0,
50 HKL_GUI_3D_COL_OBJECT
,
51 HKL_GUI_3D_COL_NUM_COLS
63 /* Keep a pointer to the properties definition */
64 static GParamSpec
*obj_properties
[N_PROPERTIES
] = { NULL
, };
72 static NEEDED guint signals
[N_SIGNALS
] = { 0 };
76 GObject parent_instance
;
79 HklGui3DPrivate
* priv
;
82 struct _HklGui3DClass
{
83 GObjectClass parent_class
;
87 struct _HklGui3DPrivate
{
90 HklGeometry
*geometry
;
97 GtkTreeView
*treeview1
;
98 GtkToolButton
*toolbutton1
;
99 GtkToolButton
*toolbutton2
;
100 GtkToolButton
*toolbutton3
;
101 GtkFileChooserDialog
*filechooserdialog1
;
104 GtkTreeStore
*treestore1
;
105 GtkDrawingArea
*drawingarea1
;
109 /* opengl connected to the drawingarea1 */
110 G3DGLRenderOptions renderoptions
;
118 G_DEFINE_TYPE (HklGui3D
, hkl_gui_3d
, G_TYPE_OBJECT
);
120 #define HKL_GUI_3D_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HKL_GUI_TYPE_3D, HklGui3DPrivate))
123 static void hkl_gui_3d_update_hkl3d_objects_TreeStore(HklGui3D
*self
)
125 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
129 gtk_tree_store_clear(priv
->treestore1
);
131 for(i
=0; i
<priv
->hkl3d
->config
->len
; ++i
){
132 GtkTreeIter iter
= {0};
134 gtk_tree_store_append(priv
->treestore1
, &iter
, NULL
);
135 gtk_tree_store_set(priv
->treestore1
, &iter
,
136 HKL_GUI_3D_COL_NAME
, priv
->hkl3d
->config
->models
[i
]->filename
,
137 HKL_GUI_3D_COL_MODEL
, priv
->hkl3d
->config
->models
[i
],
138 HKL_GUI_3D_COL_OBJECT
, NULL
,
141 for(j
=0; j
<priv
->hkl3d
->config
->models
[i
]->len
; ++j
){
142 GtkTreeIter citer
= {0};
144 gtk_tree_store_append(priv
->treestore1
, &citer
, &iter
);
145 gtk_tree_store_set(priv
->treestore1
, &citer
,
146 HKL_GUI_3D_COL_NAME
, priv
->hkl3d
->config
->models
[i
]->objects
[j
]->axis_name
,
147 HKL_GUI_3D_COL_HIDE
, priv
->hkl3d
->config
->models
[i
]->objects
[j
]->hide
,
148 HKL_GUI_3D_COL_MODEL
, priv
->hkl3d
->config
->models
[i
],
149 HKL_GUI_3D_COL_OBJECT
, priv
->hkl3d
->config
->models
[i
]->objects
[j
],
158 hkl_gui_3d_get_filename(HklGui3D
*self
)
160 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
162 return priv
->filename
;
166 hkl_gui_3d_get_geometry(HklGui3D
*self
)
168 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
170 return priv
->geometry
;
173 void _filename_and_geometry(HklGui3D
*self
)
175 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
176 if(priv
->filename
&& priv
->geometry
){
178 hkl3d_free(priv
->hkl3d
);
179 priv
->hkl3d
= hkl3d_new(priv
->filename
, priv
->geometry
);
181 /* priv->scene = hkl_gui_3d_scene_new(priv->hkl3d, FALSE, FALSE, FALSE, FALSE); */
183 hkl_gui_3d_update_hkl3d_objects_TreeStore(self
);
184 /* gtk_box_pack_start(GTK_BOX(priv->vbox1), */
185 /* GTK_WIDGET(priv->scene), */
186 /* TRUE, TRUE, 0); */
187 /* gtk_widget_show_all(GTK_WIDGET(priv->vbox1)); */
193 hkl_gui_3d_set_filename(HklGui3D
*self
, const char *filename
)
195 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
198 g_free(priv
->filename
);
199 priv
->filename
= g_strdup(filename
);
201 _filename_and_geometry(self
);
205 hkl_gui_3d_set_geometry(HklGui3D
*self
, HklGeometry
*geometry
)
207 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
209 priv
->geometry
= geometry
;
210 _filename_and_geometry(self
);
214 set_property (GObject
*object
, guint prop_id
,
215 const GValue
*value
, GParamSpec
*pspec
)
217 HklGui3D
*self
= HKL_GUI_3D (object
);
221 hkl_gui_3d_set_filename(self
, g_value_get_string (value
));
224 hkl_gui_3d_set_geometry(self
, g_value_get_pointer (value
));
227 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
233 get_property (GObject
*object
, guint prop_id
,
234 GValue
*value
, GParamSpec
*pspec
)
236 HklGui3D
*self
= HKL_GUI_3D (object
);
241 g_value_set_string (value
, hkl_gui_3d_get_filename (self
));
244 g_value_set_pointer (value
, hkl_gui_3d_get_geometry (self
));
247 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
253 finalize (GObject
* object
)
255 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(object
);
258 g_free(priv
->filename
);
260 g_object_unref(priv
->builder
);
262 hkl3d_free(priv
->hkl3d
);
264 G_OBJECT_CLASS (hkl_gui_3d_parent_class
)->finalize (object
);
268 hkl_gui_3d_new (const char *filename
, HklGeometry
*geometry
)
270 return g_object_new (HKL_GUI_TYPE_3D
,
271 "filename", filename
,
272 "geometry", geometry
,
276 GtkFrame
*hkl_gui_3d_frame_get(HklGui3D
*self
)
278 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
283 void hkl_gui_3d_is_colliding(HklGui3D
*self
)
285 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
288 hkl3d_is_colliding(priv
->hkl3d
);
291 void hkl_gui_3d_invalidate(HklGui3D
*self
)
293 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
295 priv
->renderoptions
.updated
= TRUE
;
296 glarea_update(GTK_WIDGET(priv
->drawingarea1
));
303 void hkl_gui_3d_cellrenderertext2_toggled_cb(GtkCellRendererToggle
* renderer
,
304 const gchar
* path
, gpointer user_data
)
306 HklGui3D
*self
= HKL_GUI_3D(user_data
);
307 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
310 GtkTreeIter iter
= {0};
313 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv
->treestore1
),
315 gtk_tree_model_get (GTK_TREE_MODEL(priv
->treestore1
),
317 HKL_GUI_3D_COL_OBJECT
, &object
,
320 hide
= !gtk_cell_renderer_toggle_get_active(renderer
);
323 hkl3d_hide_object(priv
->hkl3d
, object
, hide
);
324 gtk_tree_store_set (priv
->treestore1
,
326 HKL_GUI_3D_COL_HIDE
, hide
,
328 hkl_gui_3d_is_colliding(self
);
329 hkl_gui_3d_invalidate(self
);
333 gtk_tree_model_get (GTK_TREE_MODEL(priv
->treestore1
),
335 HKL_GUI_3D_COL_MODEL
, &model
,
338 GtkTreeIter children
= {0};
342 gtk_tree_store_set (priv
->treestore1
,
344 HKL_GUI_3D_COL_HIDE
, hide
,
347 /* set all the children rows */
348 valid
= gtk_tree_model_iter_children(GTK_TREE_MODEL(priv
->treestore1
),
351 hkl3d_hide_object(priv
->hkl3d
, model
->objects
[i
++], hide
);
352 gtk_tree_store_set (priv
->treestore1
,
354 HKL_GUI_3D_COL_HIDE
, hide
,
357 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(priv
->treestore1
), &children
);
359 hkl_gui_3d_is_colliding(self
);
360 hkl_gui_3d_invalidate(self
);
365 void hkl_gui_3d_treeview1_cursor_changed_cb(GtkTreeView
*tree_view
,
370 HklGui3D
*self
= user_data
;
371 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
372 GtkTreeIter iter
= {0};
375 GtkTreeViewColumn
* column
;
377 gtk_tree_view_get_cursor(priv
->treeview1
, &path
, &column
);
378 gtk_tree_model_get_iter(GTK_TREE_MODEL(priv
->treestore1
), &iter
, path
);
379 gtk_tree_path_free(path
);
381 /* need to unselect of objects of all 3d models */
382 for(i
=0; i
<priv
->hkl3d
->config
->len
; ++i
)
383 for(j
=0; j
<priv
->hkl3d
->config
->models
[i
]->len
; ++j
)
384 priv
->hkl3d
->config
->models
[i
]->objects
[j
]->selected
= FALSE
;
386 /* now select the right object */
387 gtk_tree_model_get (GTK_TREE_MODEL(priv
->treestore1
),
389 HKL_GUI_3D_COL_OBJECT
, &object
,
392 object
->selected
= TRUE
;
394 hkl_gui_3d_invalidate(self
);
397 void hkl_gui_3d_toolbutton1_clicked_cb(GtkToolButton
*toolbutton
,
400 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
402 gtk_widget_show(GTK_WIDGET(priv
->filechooserdialog1
));
405 /* remove an object from the model */
406 void hkl_gui_3d_toolbutton2_clicked_cb(GtkToolButton
*toolbutton
,
409 HklGui3D
*self
= user_data
;
410 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
411 GtkTreeIter iter
= {0};
413 GtkTreeViewColumn
* column
;
416 gtk_tree_view_get_cursor(priv
->treeview1
, &path
, &column
);
417 gtk_tree_model_get_iter(GTK_TREE_MODEL(priv
->treestore1
), &iter
, path
);
418 gtk_tree_path_free(path
);
420 gtk_tree_model_get (GTK_TREE_MODEL(priv
->treestore1
),
422 HKL_GUI_3D_COL_OBJECT
, &object
,
425 hkl3d_remove_object(priv
->hkl3d
, object
);
426 hkl_gui_3d_update_hkl3d_objects_TreeStore(self
);
427 hkl_gui_3d_invalidate(self
);
432 reset_3d(G3DGLRenderOptions
*renderoptions
)
435 renderoptions
->updated
= TRUE
;
436 renderoptions
->initialized
= FALSE
;
437 renderoptions
->zoom
= 7;
438 renderoptions
->bgcolor
[0] = 0.9;
439 renderoptions
->bgcolor
[1] = 0.8;
440 renderoptions
->bgcolor
[2] = 0.6;
441 renderoptions
->bgcolor
[3] = 1.0;
442 renderoptions
->glflags
=
443 // G3D_FLAG_GL_ISOMETRIC |
444 G3D_FLAG_GL_SPECULAR
|
445 G3D_FLAG_GL_SHININESS
|
446 G3D_FLAG_GL_TEXTURES
|
448 G3D_FLAG_GL_COORD_AXES
;
450 g3d_quat_trackball(renderoptions
->quat
, 0.0, 0.0, 0.0, 0.0, 0.8);
452 /* rotate a little bit */
454 gfloat a1
[3] = { 0.0, 1.0, 0.0 }, a2
[3] = {1.0, 0.0, 1.0};
456 g3d_quat_rotate(q1
, a1
, - 45.0 * G_PI
/ 180.0);
457 g3d_quat_rotate(q2
, a2
, - 45.0 * G_PI
/ 180.0);
458 g3d_quat_add(renderoptions
->quat
, q1
, q2
);
461 /* re-initialize the 3d view */
462 void hkl_gui_3d_toolbutton3_clicked_cb(GtkToolButton
*toolbutton
,
465 HklGui3D
*self
= user_data
;
466 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
468 reset_3d(&priv
->renderoptions
);
469 hkl_gui_3d_invalidate(self
);
472 void hkl_gui_3d_toolbutton4_toggled_cb(GtkToggleToolButton
*toggle_tool_button
,
475 HklGui3D
*self
= user_data
;
476 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
478 priv
->aabb
= gtk_toggle_tool_button_get_active(toggle_tool_button
);
479 hkl_gui_3d_invalidate(self
);
482 void hkl_gui_3d_button1_clicked_cb(GtkButton
*button
,
485 HklGui3D
*self
= user_data
;
486 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
490 filenames
= gtk_file_chooser_get_files(GTK_FILE_CHOOSER(priv
->filechooserdialog1
));
491 filename
= filenames
;
493 GFile
*file
= filename
->data
;
494 GFile
*directory
= g_file_get_parent(file
);
495 char *basename
= g_file_get_basename(file
);
496 char *path
= g_file_get_path(directory
);
498 hkl3d_add_model_from_file(priv
->hkl3d
, basename
, path
);
499 hkl3d_connect_all_axes(priv
->hkl3d
);
503 g_object_unref(G_OBJECT(directory
));
504 g_object_unref(G_OBJECT(file
));
505 filename
= g_slist_next(filename
);
508 hkl_gui_3d_update_hkl3d_objects_TreeStore(self
);
509 gtk_widget_hide(GTK_WIDGET(priv
->filechooserdialog1
));
510 g_slist_free(filenames
);
513 void hkl_gui_3d_button2_clicked_cb(GtkButton
*button
,
516 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
518 gtk_widget_hide(GTK_WIDGET(priv
->filechooserdialog1
));
533 static void hkl_gui_3d_draw_g3dmodel(HklGui3D
*self
)
537 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
539 /* set the alpha canal to 0.5 if there is a collision */
540 for(i
=0; i
<priv
->hkl3d
->config
->len
; i
++)
541 for(j
=0; j
<priv
->hkl3d
->config
->models
[i
]->len
; j
++){
546 if(priv
->hkl3d
->config
->models
[i
]->objects
[j
]->is_colliding
)
551 faces
= priv
->hkl3d
->config
->models
[i
]->objects
[j
]->g3d
->faces
;
553 face
= (G3DFace
*)(faces
->data
);
554 face
->material
->a
= alpha
;
555 faces
= g_slist_next(faces
);
559 /* draw the G3DObjects */
560 gl_draw(&priv
->renderoptions
, priv
->hkl3d
->model
);
563 static void draw_g3dObject(G3DObject
*object
)
568 faces
= object
->faces
;
569 vertex
= object
->vertex_data
;
573 /* apply the transformation of the object */
574 if(object
->transformation
)
575 glMultMatrixf(object
->transformation
->matrix
);
577 /* draw all faces with the current stencil */
581 face
= (G3DFace
*)faces
->data
;
582 glBegin(GL_TRIANGLES
);
583 glVertex3d(vertex
[3*(face
->vertex_indices
[0])],
584 vertex
[3*(face
->vertex_indices
[0])+1],
585 vertex
[3*(face
->vertex_indices
[0])+2]);
586 glVertex3d(vertex
[3*(face
->vertex_indices
[1])],
587 vertex
[3*(face
->vertex_indices
[1])+1],
588 vertex
[3*(face
->vertex_indices
[1])+2]);
589 glVertex3d(vertex
[3*(face
->vertex_indices
[2])],
590 vertex
[3*(face
->vertex_indices
[2])+1],
591 vertex
[3*(face
->vertex_indices
[2])+2]);
593 faces
= g_slist_next(faces
);
599 void hkl_gui_3d_draw_selected(HklGui3D
*self
)
603 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
605 /* glDisable(GL_LIGHTING); */
607 for(i
=0; i
<priv
->hkl3d
->config
->len
; i
++)
608 for(j
=0; j
<priv
->hkl3d
->config
->models
[i
]->len
; j
++){
609 if(priv
->hkl3d
->config
->models
[i
]->objects
[j
]->selected
610 && !priv
->hkl3d
->config
->models
[i
]->objects
[j
]->hide
){
611 // Push the GL attribute bits so that we don't wreck any settings
612 glPushAttrib( GL_ALL_ATTRIB_BITS
);
614 // Enable polygon offsets, and offset filled polygons forward by 2.5
615 glEnable( GL_POLYGON_OFFSET_FILL
);
616 glPolygonOffset( -2.5, -2.5);
618 // Set the render mode to be line rendering with a thick line width
619 glPolygonMode( GL_FRONT_AND_BACK
, GL_LINE
);
621 // Set the colour to be pink
622 glColor3f( 1.f
, .0f
, 1.f
);
624 draw_g3dObject(priv
->hkl3d
->config
->models
[i
]->objects
[j
]->g3d
);
625 // Set the polygon mode to be filled triangles
627 glPolygonMode( GL_FRONT_AND_BACK
, GL_FILL
);
628 // Set the colour to the background
629 glCullFace(GL_FRONT
);
630 glColor3f( 0.0f
, 0.0f
, 0.0f
);
632 draw_g3dObject(priv
->hkl3d
->config
->models
[i
]->objects
[j
]->g3d
);
634 // Pop the state changes off the attribute
635 // to set things back how they were
639 /* glEnable(GL_LIGHTING); */
642 static void draw_sphere(float radius
, int lats
, int longs
)
645 for(i
=0;i
<=lats
;i
++){
646 float lat0
= M_PI
* (-0.5 + (float) (i
- 1) / lats
);
647 float z0
= radius
* sin(lat0
);
648 float zr0
= radius
* cos(lat0
);
650 float lat1
= M_PI
* (-0.5 + (float) i
/ lats
);
651 float z1
= radius
* sin(lat1
);
652 float zr1
= radius
* cos(lat1
);
654 glBegin(GL_QUAD_STRIP
);
655 for(j
=0;j
<=longs
;j
++) {
656 float lng
= 2 * M_PI
* (float) (j
- 1) / longs
;
660 glNormal3f(x
* zr1
, y
* zr1
, z1
);
661 glVertex3f(x
* zr1
, y
* zr1
, z1
);
662 glNormal3f(x
* zr0
, y
* zr0
, z0
);
663 glVertex3f(x
* zr0
, y
* zr0
, z0
);
669 void hkl_gui_3d_draw_collisions(HklGui3D
*self
)
673 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
675 /* glDisable(GL_LIGHTING); */
676 ///one way to draw all the contact points is iterating over contact manifolds / points:
677 numManifolds
= hkl3d_get_nb_manifolds(priv
->hkl3d
);
678 for (i
=0; i
<numManifolds
; i
++){
682 // now draw the manifolds / points
683 numContacts
= hkl3d_get_nb_contacts(priv
->hkl3d
, i
);
684 for (j
=0; j
<numContacts
; j
++){
688 hkl3d_get_collision_coordinates(priv
->hkl3d
, i
, j
,
689 &xa
, &ya
, &za
, &xb
, &yb
, &zb
);
691 glDisable(GL_DEPTH_TEST
);
693 glColor4f(0, 0, 0, 1);
694 glVertex3d(xa
, ya
, za
);
695 glVertex3d(xb
, yb
, zb
);
697 glColor4f(1, 0, 0, 1);
699 glTranslatef (xb
, yb
, zb
);
700 glScaled(0.05,0.05,0.05);
702 draw_sphere(1, 10, 10);
705 glColor4f(1, 1, 0, 1);
707 glTranslatef (xa
, ya
, za
);
708 glScaled(0.05,0.05,0.05);
710 draw_sphere(1, 10, 10);
713 glEnable(GL_DEPTH_TEST
);
719 static void draw_line(const float from
[3], const float to
[3],
720 const float fromColor
[3], const float toColor
[3])
723 glColor3f(fromColor
[0], fromColor
[1], fromColor
[2]);
724 glVertex3d(from
[0], from
[1], from
[2]);
725 glColor3f(toColor
[0], toColor
[1], toColor
[2]);
726 glVertex3d(to
[0], to
[1], to
[2]);
730 static void draw_aabb(const float from
[3], const float to
[3], const float color
[3])
732 float halfExtents
[3] = {
733 (to
[0] - from
[0]) * .5,
734 (to
[1] - from
[1]) * .5,
735 (to
[2] - from
[2]) * .5
738 (to
[0] + from
[0]) * .5,
739 (to
[1] + from
[1]) * .5,
740 (to
[2] + from
[2]) * .5
744 float edgecoord
[3] = {1., 1., 1.};
749 edgecoord
[0] * halfExtents
[0] + center
[0],
750 edgecoord
[1] * halfExtents
[1] + center
[1],
751 edgecoord
[2] * halfExtents
[2] + center
[2]
754 int othercoord
= j
% 3;
755 edgecoord
[othercoord
] *= -1.f
;
758 edgecoord
[0] * halfExtents
[0] + center
[0],
759 edgecoord
[1] * halfExtents
[1] + center
[1],
760 edgecoord
[2] * halfExtents
[2] + center
[2]
762 draw_line(pa
, pb
, color
, color
);
773 hkl_gui_3d_draw_aabb_object(const Hkl3DObject
*self
)
777 GLfloat color
[3] = {1, 0, 0};
782 hkl3d_object_aabb_get(self
, from
, to
);
783 draw_aabb(from
, to
, color
);
787 hkl_gui_3d_draw_aabb(const HklGui3D
*self
)
791 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
793 for(i
=0; i
<priv
->hkl3d
->config
->len
; i
++)
794 for(j
=0; j
<priv
->hkl3d
->config
->models
[i
]->len
; j
++)
795 hkl_gui_3d_draw_aabb_object(priv
->hkl3d
->config
->models
[i
]->objects
[j
]);
800 /* void hkl_gui_3d_draw_bullet_object(const Hkl3DObject *self) */
804 /* btScalar m[16]; */
805 /* btVector3 worldBoundsMin; */
806 /* btVector3 worldBoundsMax; */
807 /* btVector3 aabbMin,aabbMax; */
809 /* /\* get the bounding box from bullet *\/ */
810 /* hkl3d_get_bounding_boxes(_hkl3d, &worldBoundsMin, &worldBoundsMax); */
812 /* object = _hkl3d->config->models[i]->objects[j]; */
813 /* if(!object->hide){ */
814 /* btCollisionObject *btObject; */
816 /* btObject = object->btObject; */
817 /* btObject->getWorldTransform().getOpenGLMatrix( m ); */
818 /* m_shapeDrawer.drawOpenGL(m, */
819 /* btObject->getCollisionShape(), */
820 /* *object->color, */
821 /* 0, /\* debug mode *\/ */
822 /* worldBoundsMin, */
823 /* worldBoundsMax); */
829 /* hkl_gui_3d_draw_bullet(const HklGui3D *self) */
833 /* HklGui3DPrivate *priv = HKL_GUI_3D_GET_PRIVATE(self); */
835 /* for(i=0; i<priv->hkl3d->config->len; i++) */
836 /* for(j=0; j<priv->hkl3d->config->models[i]->len; j++) */
837 /* hkl_gui_3d_draw_bullet_object(priv->hkl3d->config->models[i]->objects[j]); */
842 hkl_gui_3d_drawingarea1_expose_cb(GtkWidget
*drawing_area
, GdkEventExpose
*event
, gpointer user_data
)
845 HklGui3D
*self
= HKL_GUI_3D(user_data
);
846 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
847 GdkGLContext
*gl_context
= gtk_widget_get_gl_context(drawing_area
);
848 GdkGLDrawable
*gl_drawable
= gtk_widget_get_gl_drawable(drawing_area
);
850 /* Delimits the begining of the OpenGL execution. */
851 if (!gdk_gl_drawable_gl_begin(gl_drawable
, gl_context
))
852 g_assert_not_reached();
854 gtk_widget_get_allocation(drawing_area
, &alloc
);
855 glViewport(0,0, alloc
.width
, alloc
.height
);
856 priv
->renderoptions
.aspect
= (gfloat
)alloc
.width
/ (gfloat
)alloc
.height
;
858 hkl_gui_3d_draw_g3dmodel(self
);
859 hkl_gui_3d_draw_selected(self
);
860 hkl_gui_3d_draw_collisions(self
);
862 hkl_gui_3d_draw_aabb(self
);
863 /* hkl_gui_3d_draw_bullet(self); */
865 /* swap buffer if we're using double-buffering */
866 if (gdk_gl_drawable_is_double_buffered(gl_drawable
))
867 gdk_gl_drawable_swap_buffers(gl_drawable
);
872 /* Delimits the end of the OpenGL execution. */
873 gdk_gl_drawable_gl_end(gl_drawable
);
879 hkl_gui_3d_drawingarea1_configure_event_cb(GtkWidget
*drawing_area
,
880 GdkEventConfigure
*event
,
884 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
885 GdkGLContext
*gl_context
= gtk_widget_get_gl_context(drawing_area
);
886 GdkGLDrawable
*gl_drawable
= gtk_widget_get_gl_drawable(drawing_area
);
888 /* Delimits the begining of the OpenGL execution. */
889 if (!gdk_gl_drawable_gl_begin(gl_drawable
, gl_context
))
890 g_assert_not_reached();
892 gtk_widget_get_allocation(drawing_area
, &alloc
);
893 glViewport(0,0, alloc
.width
, alloc
.height
);
894 priv
->renderoptions
.aspect
= (gfloat
)alloc
.width
/ (gfloat
)alloc
.height
;
896 /* Delimits the end of the OpenGL execution. */
897 gdk_gl_drawable_gl_end(gl_drawable
);
903 hkl_gui_3d_idle_cb(gpointer user_data
)
905 /* update control data/params in this function if needed */
906 GtkWidget
*drawing_area
= GTK_WIDGET(user_data
);
908 glarea_update(drawing_area
);
914 hkl_gui_3d_drawingarea1_button_press_event_cb(GtkWidget
*drawing_area
,
915 GdkEventButton
* event
,
918 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
920 /* left mouse buttom: rotate object */
921 if(event
->button
== 1)
923 priv
->mouse
.beginx
= event
->x
;
924 priv
->mouse
.beginy
= event
->y
;
933 hkl_gui_3d_drawingarea1_scroll_event_cb(GtkWidget
*drawing_area
,
934 GdkEventScroll
*event
,
938 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
940 gtk_widget_get_allocation(drawing_area
, &alloc
);
943 if(event
->direction
== GDK_SCROLL_DOWN
)
944 priv
->renderoptions
.zoom
+= ZOOM_BY
;
946 priv
->renderoptions
.zoom
-= ZOOM_BY
;
949 if(priv
->renderoptions
.zoom
< 1)
950 priv
->renderoptions
.zoom
= 1;
951 if(priv
->renderoptions
.zoom
> 120)
952 priv
->renderoptions
.zoom
= 120;
954 glarea_update(drawing_area
);
960 hkl_gui_3d_drawingarea1_motion_notify_event_cb(GtkWidget
*drawing_area
,
961 GdkEventMotion
* event
,
964 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(user_data
);
967 GdkModifierType state
;
969 gtk_widget_get_allocation(drawing_area
, &alloc
);
972 gdk_window_get_pointer(event
->window
, &x
, &y
, &state
);
977 state
= event
->state
;
980 /* left button pressed */
981 if(state
& GDK_BUTTON1_MASK
)
983 if(state
& GDK_SHIFT_MASK
)
985 /* shift pressed, translate view */
986 priv
->renderoptions
.offx
+= (float)(x
- priv
->mouse
.beginx
) / alloc
.width
/ priv
->renderoptions
.zoom
;
987 priv
->renderoptions
.offy
-= (float)(y
- priv
->mouse
.beginy
) / alloc
.height
/ priv
->renderoptions
.zoom
;
993 g3d_quat_trackball(spin_quat
,
994 (2.0 * priv
->mouse
.beginx
- alloc
.width
) / alloc
.width
,
995 (alloc
.height
- 2.0 * priv
->mouse
.beginy
) / alloc
.height
,
996 (2.0 * x
- alloc
.width
) / alloc
.width
,
997 (alloc
.height
- 2.0 * y
) / alloc
.height
,
998 0.8 /* trackball radius */);
999 g3d_quat_add(priv
->renderoptions
.quat
,
1000 spin_quat
, priv
->renderoptions
.quat
);
1001 /* normalize quat some times */
1002 priv
->renderoptions
.norm_count
++;
1003 if(priv
->renderoptions
.norm_count
> 97) {
1004 priv
->renderoptions
.norm_count
= 0;
1005 g3d_quat_normalize(priv
->renderoptions
.quat
);
1008 /* g3d_quat_to_rotation_xyz(priv->renderoptions.quat, */
1009 /* &rx, &ry, &rz); */
1010 /* text = g_strdup_printf("%-.2f°, %-.2f°, %-.2f°", */
1011 /* rx * 180.0 / G_PI, ry * 180.0 / G_PI, rz * 180.0 / G_PI); */
1012 /* gui_glade_status(priv, text); */
1016 glarea_update(GTK_WIDGET(priv
->drawingarea1
));
1019 /* middle mouse button */
1020 if(state
& GDK_BUTTON2_MASK
)
1022 priv
->renderoptions
.zoom
+=
1023 ((y
- priv
->mouse
.beginy
) / (gfloat
)alloc
.height
) * 40;
1024 if(priv
->renderoptions
.zoom
< 1)
1025 priv
->renderoptions
.zoom
= 1;
1026 if(priv
->renderoptions
.zoom
> 120)
1027 priv
->renderoptions
.zoom
= 120;
1029 glarea_update(GTK_WIDGET(priv
->drawingarea1
));
1031 priv
->mouse
.beginx
= x
;
1032 priv
->mouse
.beginy
= y
;
1037 /*********************************************/
1038 /* HklGui3D and HklGui3DClass initialization */
1039 /*********************************************/
1042 hkl_gui_3d_class_init (HklGui3DClass
*class)
1044 GObjectClass
*gobject_class
= G_OBJECT_CLASS (class);
1046 g_type_class_add_private (class, sizeof (HklGui3DPrivate
));
1048 /* virtual method */
1049 gobject_class
->finalize
= finalize
;
1050 gobject_class
->set_property
= set_property
;
1051 gobject_class
->get_property
= get_property
;
1054 obj_properties
[PROP_FILENAME
] =
1055 g_param_spec_string ("filename",
1057 "The confuration filename",
1059 G_PARAM_CONSTRUCT_ONLY
|
1061 G_PARAM_STATIC_STRINGS
);
1063 obj_properties
[PROP_GEOMETRY
] =
1064 g_param_spec_pointer ("geometry",
1066 "The Hkl Geometry used underneath",
1067 G_PARAM_CONSTRUCT_ONLY
|
1069 G_PARAM_STATIC_STRINGS
);
1071 g_object_class_install_properties (gobject_class
,
1077 static void hkl_gui_3d_init (HklGui3D
* self
)
1079 HklGui3DPrivate
*priv
= HKL_GUI_3D_GET_PRIVATE(self
);
1080 GtkBuilder
*builder
;
1083 priv
->filename
= NULL
;
1084 priv
->geometry
= NULL
;
1086 priv
->builder
= builder
= gtk_builder_new ();
1088 get_ui(builder
, "3d.ui");
1091 get_object(builder
, GTK_FRAME
, priv
, frame1
);
1092 get_object(builder
, GTK_VBOX
, priv
, vbox1
);
1093 get_object(builder
, GTK_TREE_VIEW
, priv
, treeview1
);
1094 get_object(builder
, GTK_TOOL_BUTTON
, priv
, toolbutton1
);
1095 get_object(builder
, GTK_TOOL_BUTTON
, priv
, toolbutton2
);
1096 get_object(builder
, GTK_TOOL_BUTTON
, priv
, toolbutton3
);
1097 get_object(builder
, GTK_FILE_CHOOSER_DIALOG
, priv
, filechooserdialog1
);
1098 get_object(builder
, GTK_BUTTON
, priv
, button1
);
1099 get_object(builder
, GTK_BUTTON
, priv
, button2
);
1100 get_object(builder
, GTK_TREE_STORE
, priv
, treestore1
);
1101 get_object(builder
, GTK_DRAWING_AREA
, priv
, drawingarea1
);
1103 gtk_builder_connect_signals (builder
, self
);
1108 reset_3d(&priv
->renderoptions
);
1111 /* attache GL capability to drawingarea1 */
1112 GdkGLConfig
*gl_config
= gdk_gl_config_new_by_mode(GDK_GL_MODE_RGBA
|
1114 GDK_GL_MODE_DOUBLE
);
1116 g_assert_not_reached();
1117 if (!gtk_widget_set_gl_capability(GTK_WIDGET(priv
->drawingarea1
), gl_config
, NULL
, TRUE
,
1119 g_assert_not_reached();
1121 gtk_widget_set_can_focus(GTK_WIDGET(priv
->drawingarea1
), TRUE
);
1122 gtk_widget_add_events(GTK_WIDGET(priv
->drawingarea1
),
1123 GDK_BUTTON1_MOTION_MASK
|
1124 GDK_BUTTON2_MOTION_MASK
|
1125 GDK_BUTTON_PRESS_MASK
|
1126 GDK_VISIBILITY_NOTIFY_MASK
);
1128 /* connect the GL callbacks */
1129 const gdouble TIMEOUT_PERIOD
= 1000 / 60;
1130 g_timeout_add(TIMEOUT_PERIOD
, hkl_gui_3d_idle_cb
, priv
->drawingarea1
);
1131 g_signal_connect(priv
->drawingarea1
, "expose-event",
1132 G_CALLBACK(hkl_gui_3d_drawingarea1_expose_cb
), self
);
1133 g_signal_connect(priv
->drawingarea1
, "button-press-event",
1134 G_CALLBACK(hkl_gui_3d_drawingarea1_button_press_event_cb
), self
);
1135 g_signal_connect(priv
->drawingarea1
, "motion-notify-event",
1136 G_CALLBACK(hkl_gui_3d_drawingarea1_motion_notify_event_cb
), self
);