1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup edgizmolib
19  *
20  * \name Gizmo Lib Presets
21  *
22  * \brief Preset shapes that can be drawn from any gizmo type.
23  */
24 
25 #include "MEM_guardedalloc.h"
26 
27 #include "BLI_math.h"
28 
29 #include "DNA_object_types.h"
30 #include "DNA_view3d_types.h"
31 
32 #include "BKE_context.h"
33 
34 #include "GPU_matrix.h"
35 #include "GPU_select.h"
36 
37 #include "DEG_depsgraph.h"
38 
39 #include "RNA_access.h"
40 
41 #include "WM_api.h"
42 #include "WM_types.h"
43 
44 #include "ED_screen.h"
45 #include "ED_view3d.h"
46 
47 /* own includes */
48 #include "ED_gizmo_library.h"     /* own include */
49 #include "gizmo_library_intern.h" /* own include */
50 
51 /* TODO, this is to be used by RNA. might move to ED_gizmo_library */
52 
53 /**
54  * Given a single axis, orient the matrix to a different direction.
55  */
single_axis_convert(int src_axis,const float src_mat[4][4],int dst_axis,float dst_mat[4][4])56 static void single_axis_convert(int src_axis,
57                                 const float src_mat[4][4],
58                                 int dst_axis,
59                                 float dst_mat[4][4])
60 {
61   copy_m4_m4(dst_mat, src_mat);
62   if (src_axis == dst_axis) {
63     return;
64   }
65 
66   float rotmat[3][3];
67   mat3_from_axis_conversion_single(src_axis, dst_axis, rotmat);
68   transpose_m3(rotmat);
69   mul_m4_m4m3(dst_mat, src_mat, rotmat);
70 }
71 
72 /**
73  * Use for all geometry.
74  */
ed_gizmo_draw_preset_geometry(const struct wmGizmo * gz,const float mat[4][4],int select_id,const GizmoGeomInfo * info)75 static void ed_gizmo_draw_preset_geometry(const struct wmGizmo *gz,
76                                           const float mat[4][4],
77                                           int select_id,
78                                           const GizmoGeomInfo *info)
79 {
80   const bool is_select = (select_id != -1);
81   const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
82 
83   float color[4];
84   gizmo_color_get(gz, is_highlight, color);
85 
86   if (is_select) {
87     GPU_select_load_id(select_id);
88   }
89 
90   GPU_matrix_push();
91   GPU_matrix_mul(mat);
92   wm_gizmo_geometryinfo_draw(info, is_select, color);
93   GPU_matrix_pop();
94 
95   if (is_select) {
96     GPU_select_load_id(-1);
97   }
98 }
99 
ED_gizmo_draw_preset_box(const struct wmGizmo * gz,float mat[4][4],int select_id)100 void ED_gizmo_draw_preset_box(const struct wmGizmo *gz, float mat[4][4], int select_id)
101 {
102   ed_gizmo_draw_preset_geometry(gz, mat, select_id, &wm_gizmo_geom_data_cube);
103 }
104 
ED_gizmo_draw_preset_arrow(const struct wmGizmo * gz,float mat[4][4],int axis,int select_id)105 void ED_gizmo_draw_preset_arrow(const struct wmGizmo *gz, float mat[4][4], int axis, int select_id)
106 {
107   float mat_rotate[4][4];
108   single_axis_convert(OB_POSZ, mat, axis, mat_rotate);
109   ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_arrow);
110 }
111 
ED_gizmo_draw_preset_circle(const struct wmGizmo * gz,float mat[4][4],int axis,int select_id)112 void ED_gizmo_draw_preset_circle(const struct wmGizmo *gz,
113                                  float mat[4][4],
114                                  int axis,
115                                  int select_id)
116 {
117   float mat_rotate[4][4];
118   single_axis_convert(OB_POSZ, mat, axis, mat_rotate);
119   ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_dial);
120 }
121 
ED_gizmo_draw_preset_facemap(const bContext * C,const struct wmGizmo * gz,Object * ob,const int facemap,int select_id)122 void ED_gizmo_draw_preset_facemap(
123     const bContext *C, const struct wmGizmo *gz, Object *ob, const int facemap, int select_id)
124 {
125   /* Dependency graph is supposed to be evaluated prior to draw. */
126   Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
127   const bool is_select = (select_id != -1);
128   const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
129 
130   float color[4];
131   gizmo_color_get(gz, is_highlight, color);
132 
133   if (is_select) {
134     GPU_select_load_id(select_id);
135   }
136 
137   GPU_matrix_push();
138   GPU_matrix_mul(ob->obmat);
139   ED_draw_object_facemap(depsgraph, ob, color, facemap);
140   GPU_matrix_pop();
141 
142   if (is_select) {
143     GPU_select_load_id(-1);
144   }
145 }
146