Compare commits
28 Commits
tmp_lib_up
...
transform-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7576ad3d04 | ||
![]() |
10b24eabba | ||
![]() |
f754ce1c5e | ||
![]() |
418d931490 | ||
![]() |
a075c8a0b4 | ||
![]() |
52328be974 | ||
![]() |
ece7b7dc53 | ||
![]() |
9888e1e3d4 | ||
![]() |
d5def0bedf | ||
![]() |
723e0a5e01 | ||
![]() |
380aacb12a | ||
![]() |
90fcbde62d | ||
![]() |
077ac7b302 | ||
![]() |
87fd59406b | ||
![]() |
754eaf45ff | ||
![]() |
54327bf6f1 | ||
![]() |
74e784b3e5 | ||
![]() |
246a104dbc | ||
![]() |
c5c2c3be98 | ||
![]() |
6e8a0047d6 | ||
![]() |
a14d7f3009 | ||
![]() |
57d6983f52 | ||
![]() |
ca10cacf6c | ||
![]() |
693265e1e9 | ||
![]() |
26de2b4f9c | ||
![]() |
8d8f2e2e33 | ||
![]() |
b574bd6cf7 | ||
![]() |
91fc0c4f2a |
@@ -116,7 +116,7 @@ bool BKE_object_obdata_is_libdata(struct Object *ob);
|
||||
void BKE_object_obdata_size_init(struct Object *ob, const float scale);
|
||||
|
||||
void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]);
|
||||
void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3], bool use_drot);
|
||||
void BKE_object_rot_to_mat3(const struct Object *ob, float mat[3][3], bool use_drot);
|
||||
void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], bool use_compat);
|
||||
void BKE_object_to_mat3(struct Object *ob, float mat[3][3]);
|
||||
void BKE_object_to_mat4(struct Object *ob, float mat[4][4]);
|
||||
|
@@ -308,8 +308,8 @@ unsigned int BKE_screen_view3d_layer_all(const struct bScreen *sc) ATTR_WARN_UNU
|
||||
void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene);
|
||||
void BKE_screen_view3d_scene_sync(struct bScreen *sc);
|
||||
void BKE_screen_view3d_main_sync(ListBase *screen_lb, struct Scene *scene);
|
||||
void BKE_screen_view3d_twmode_remove(struct View3D *v3d, const int i);
|
||||
void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, struct Scene *scene, const int i);
|
||||
void BKE_screen_view3d_transform_orientation_remove(struct View3D *v3d, const int i);
|
||||
void BKE_screen_view3d_main_transform_orientation_remove(ListBase *screen_lb, struct Scene *scene, const int i);
|
||||
void BKE_screen_gpu_fx_validate(struct GPUFXSettings *fx_settings);
|
||||
|
||||
/* zoom factor conversion */
|
||||
|
@@ -451,10 +451,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
|
||||
}
|
||||
|
||||
|
||||
/* derive the rotation from the average normal:
|
||||
* - code taken from transform_manipulator.c,
|
||||
* calc_manipulator_stats, V3D_MANIP_NORMAL case
|
||||
*/
|
||||
/* derive the rotation from the average normal */
|
||||
/* we need the transpose of the inverse for a normal... */
|
||||
copy_m3_m4(imat, ob->obmat);
|
||||
|
||||
|
@@ -1483,7 +1483,7 @@ void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
|
||||
size_to_mat3(mat, vec);
|
||||
}
|
||||
|
||||
void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], bool use_drot)
|
||||
void BKE_object_rot_to_mat3(const Object *ob, float r_mat[3][3], bool use_drot)
|
||||
{
|
||||
float rmat[3][3], dmat[3][3];
|
||||
|
||||
@@ -1515,9 +1515,9 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], bool use_drot)
|
||||
|
||||
/* combine these rotations */
|
||||
if (use_drot)
|
||||
mul_m3_m3m3(mat, dmat, rmat);
|
||||
mul_m3_m3m3(r_mat, dmat, rmat);
|
||||
else
|
||||
copy_m3_m3(mat, rmat);
|
||||
copy_m3_m3(r_mat, rmat);
|
||||
}
|
||||
|
||||
void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], bool use_compat)
|
||||
|
@@ -629,18 +629,18 @@ void BKE_screen_view3d_main_sync(ListBase *screen_lb, Scene *scene)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_screen_view3d_twmode_remove(View3D *v3d, const int i)
|
||||
void BKE_screen_view3d_transform_orientation_remove(View3D *v3d, const int i)
|
||||
{
|
||||
const int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
|
||||
const int selected_index = (v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM);
|
||||
if (selected_index == i) {
|
||||
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
|
||||
v3d->transform_orientation = V3D_TRANS_ORIENTATION_GLOBAL; /* fallback to global */
|
||||
}
|
||||
else if (selected_index > i) {
|
||||
v3d->twmode--;
|
||||
v3d->transform_orientation--;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, Scene *scene, const int i)
|
||||
void BKE_screen_view3d_main_transform_orientation_remove(ListBase *screen_lb, Scene *scene, const int i)
|
||||
{
|
||||
bScreen *sc;
|
||||
|
||||
@@ -652,7 +652,7 @@ void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, Scene *scene, con
|
||||
for (sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
if (sl->spacetype == SPACE_VIEW3D) {
|
||||
View3D *v3d = (View3D *)sl;
|
||||
BKE_screen_view3d_twmode_remove(v3d, i);
|
||||
BKE_screen_view3d_transform_orientation_remove(v3d, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7109,8 +7109,8 @@ void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions)
|
||||
}
|
||||
|
||||
/* this was not initialized correct always */
|
||||
if (v3d->twtype == 0)
|
||||
v3d->twtype = V3D_MANIP_TRANSLATE;
|
||||
if (v3d->transform_manipulators_type == 0)
|
||||
v3d->transform_manipulators_type = V3D_MANIP_TRANSLATE;
|
||||
if (v3d->gridsubdiv == 0)
|
||||
v3d->gridsubdiv = 10;
|
||||
}
|
||||
|
@@ -1633,6 +1633,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* New transform manipulators */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "View3D", "char", "transform_manipulators_type")) {
|
||||
for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
/* handle pushed-back space data first */
|
||||
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
if (sl->spacetype == SPACE_VIEW3D) {
|
||||
View3D *v3d = (View3D *)sl;
|
||||
v3d->flag3 |= V3D_USE_TRANSFORM_MANIPULATORS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void do_versions_after_linking_270(Main *main)
|
||||
|
@@ -1880,8 +1880,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
|
||||
for (sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
if (sl->spacetype == SPACE_VIEW3D) {
|
||||
View3D *v3d = (View3D *) sl;
|
||||
if (v3d->twtype == 0)
|
||||
v3d->twtype = V3D_MANIP_TRANSLATE;
|
||||
if (v3d->transform_manipulators_type == 0)
|
||||
v3d->transform_manipulators_type = V3D_MANIP_TRANSLATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -43,6 +43,7 @@ set(INC
|
||||
../editors/space_view3d
|
||||
../render/extern/include
|
||||
../render/intern/include
|
||||
../windowmanager
|
||||
|
||||
../../../intern/glew-mx
|
||||
../../../intern/guardedalloc
|
||||
|
@@ -48,6 +48,9 @@
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "view3d_intern.h"
|
||||
|
||||
#include "draw_view.h"
|
||||
@@ -697,7 +700,8 @@ void DRW_draw_cursor(void)
|
||||
void DRW_draw_manipulator(void)
|
||||
{
|
||||
const bContext *C = DRW_get_context();
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
v3d->zbuf = false;
|
||||
BIF_draw_manipulator(C);
|
||||
WM_manipulatormap_draw(region->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
|
||||
}
|
||||
|
@@ -61,6 +61,20 @@ void imm_draw_lined_circle(unsigned pos, float x, float y, float radius, int nse
|
||||
|
||||
/* use this version when VertexFormat has a vec3 position */
|
||||
void imm_draw_lined_circle_3D(unsigned pos, float x, float y, float radius, int nsegments);
|
||||
void imm_draw_filled_circle_3D(unsigned pos, float x, float y, float rad, int nsegments);
|
||||
|
||||
/**
|
||||
* Draw a filled arc with the given \a radius,
|
||||
* starting at angle \a start and arcing through
|
||||
* \a angle. The arc is centered at the origin
|
||||
* and drawn in the XY plane.
|
||||
*
|
||||
* \param start The initial angle (in radians).
|
||||
* \param angle The length of the arc (in radians).
|
||||
* \param radius The arc radius.
|
||||
* \param nsegments The number of segments to use in drawing the arc.
|
||||
*/
|
||||
void imm_draw_filled_arc_3D(unsigned int pos, float start, float angle, float radius, int nsegments);
|
||||
|
||||
/**
|
||||
* Draw a filled circle with the given \a radius.
|
||||
|
@@ -102,12 +102,6 @@ enum TfmMode {
|
||||
#define CTX_PAINT_CURVE (1 << 8)
|
||||
#define CTX_GPENCIL_STROKES (1 << 9)
|
||||
|
||||
/* Standalone call to get the transformation center corresponding to the current situation
|
||||
* returns 1 if successful, 0 otherwise (usually means there's no selection)
|
||||
* (if 0 is returns, *vec is unmodified)
|
||||
* */
|
||||
bool calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
|
||||
|
||||
struct TransInfo;
|
||||
struct BaseLegacy;
|
||||
struct Scene;
|
||||
@@ -130,7 +124,15 @@ void BIF_createTransformOrientation(struct bContext *C, struct ReportList *repor
|
||||
void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
|
||||
void BIF_selectTransformOrientationValue(struct bContext *C, int orientation);
|
||||
|
||||
void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], const short around);
|
||||
void ED_getLocalTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], const short around);
|
||||
void ED_getTransformOrientationMatrix(
|
||||
const struct bContext *C, const char orientation_type, const short around,
|
||||
float r_orientation_mat[3][3]);
|
||||
/* Standalone call to get the transformation center corresponding to the current situation
|
||||
* returns 1 if successful, 0 otherwise (usually means there's no selection)
|
||||
* (if 0 is returns, *vec is unmodified)
|
||||
* */
|
||||
bool ED_calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], float cent2d[2]);
|
||||
|
||||
int BIF_countTransformOrientation(const struct bContext *C);
|
||||
|
||||
@@ -152,11 +154,6 @@ int BIF_countTransformOrientation(const struct bContext *C);
|
||||
|
||||
void Transform_Properties(struct wmOperatorType *ot, int flags);
|
||||
|
||||
/* view3d manipulators */
|
||||
|
||||
int BIF_do_manipulator(struct bContext *C, const struct wmEvent *event, struct wmOperator *op);
|
||||
void BIF_draw_manipulator(const struct bContext *C);
|
||||
|
||||
/* Snapping */
|
||||
|
||||
typedef enum SnapSelect {
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
@@ -864,9 +865,9 @@ void ui_theme_init_default(void)
|
||||
rgba_char_args_set(btheme->tui.wcol_tooltip.text, 255, 255, 255, 255);
|
||||
rgba_char_args_set_fl(btheme->tui.widget_emboss, 1.0f, 1.0f, 1.0f, 0.02f);
|
||||
|
||||
rgba_char_args_set(btheme->tui.xaxis, 220, 0, 0, 255);
|
||||
rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255);
|
||||
rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255);
|
||||
rgba_char_args_set_fl(btheme->tui.xaxis, 1.0f, 0.27f, 0.27f, 1.0f); /* red */
|
||||
rgba_char_args_set_fl(btheme->tui.yaxis, 0.27f, 1.0f, 0.27f, 1.0f); /* green */
|
||||
rgba_char_args_set_fl(btheme->tui.zaxis, 0.27f, 0.27f, 1.0f, 1.0f); /* blue */
|
||||
|
||||
btheme->tui.menu_shadow_fac = 0.5f;
|
||||
btheme->tui.menu_shadow_width = 12;
|
||||
@@ -2396,16 +2397,6 @@ void init_userdef_do_versions(void)
|
||||
rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255);
|
||||
}
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(264, 9)) {
|
||||
bTheme *btheme;
|
||||
|
||||
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
rgba_char_args_set(btheme->tui.xaxis, 220, 0, 0, 255);
|
||||
rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255);
|
||||
rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255);
|
||||
}
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(267, 0)) {
|
||||
/* Freestyle color settings */
|
||||
@@ -2857,14 +2848,6 @@ void init_userdef_do_versions(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(278, 3)) {
|
||||
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
/* Keyframe Indicators (were using wrong alpha) */
|
||||
btheme->tv3d.time_keyframe[3] = btheme->tv3d.time_gp_keyframe[3] = 255;
|
||||
btheme->ttime.time_keyframe[3] = btheme->ttime.time_gp_keyframe[3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Include next version bump.
|
||||
*
|
||||
@@ -2888,6 +2871,14 @@ void init_userdef_do_versions(void)
|
||||
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
btheme->tui.wcol_tab = wcol_tab;
|
||||
}
|
||||
|
||||
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
rgba_char_args_set_fl(btheme->tui.xaxis, 1.0f, 0.27f, 0.27f, 1.0f); /* red */
|
||||
rgba_char_args_set_fl(btheme->tui.yaxis, 0.27f, 1.0f, 0.27f, 1.0f); /* green */
|
||||
rgba_char_args_set_fl(btheme->tui.zaxis, 0.27f, 0.27f, 1.0f, 1.0f); /* blue */
|
||||
}
|
||||
/* Flag value has changed */
|
||||
U.tw_flag = V3D_USE_TRANSFORM_MANIPULATORS;
|
||||
}
|
||||
|
||||
if (U.pixelsize == 0.0f)
|
||||
|
@@ -88,7 +88,7 @@ typedef struct {
|
||||
float mcenter[2];
|
||||
BMBackup mesh_backup;
|
||||
void *draw_handle_pixel;
|
||||
short twtype;
|
||||
short transform_manipulators_type;
|
||||
short value_mode; /* Which value does mouse movement and numeric input affect? */
|
||||
float segments; /* Segments as float so smooth mouse pan works in small increments */
|
||||
} BevelData;
|
||||
@@ -176,8 +176,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
|
||||
G.moving = G_TRANSFORM_EDIT;
|
||||
|
||||
if (v3d) {
|
||||
opdata->twtype = v3d->twtype;
|
||||
v3d->twtype = 0;
|
||||
opdata->transform_manipulators_type = v3d->transform_manipulators_type;
|
||||
v3d->transform_manipulators_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op)
|
||||
EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
|
||||
ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel);
|
||||
if (v3d) {
|
||||
v3d->twtype = opdata->twtype;
|
||||
v3d->transform_manipulators_type = opdata->transform_manipulators_type;
|
||||
}
|
||||
G.moving = 0;
|
||||
}
|
||||
@@ -329,7 +329,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
opdata = op->customdata;
|
||||
|
||||
/* initialize mouse values */
|
||||
if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
|
||||
if (!ED_calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
|
||||
/* in this case the tool will likely do nothing,
|
||||
* ideally this will never happen and should be checked for above */
|
||||
opdata->mcenter[0] = opdata->mcenter[1] = 0;
|
||||
|
@@ -62,7 +62,7 @@ typedef struct {
|
||||
/* modal only */
|
||||
BMBackup mesh_backup;
|
||||
bool is_first;
|
||||
short twtype;
|
||||
short transform_manipulators_type;
|
||||
} BisectData;
|
||||
|
||||
static bool mesh_bisect_interactive_calc(
|
||||
@@ -148,8 +148,8 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
/* misc other vars */
|
||||
G.moving = G_TRANSFORM_EDIT;
|
||||
opdata->twtype = v3d->twtype;
|
||||
v3d->twtype = 0;
|
||||
opdata->transform_manipulators_type = v3d->transform_manipulators_type;
|
||||
v3d->transform_manipulators_type = 0;
|
||||
|
||||
/* initialize modal callout */
|
||||
ED_area_headerprint(CTX_wm_area(C), IFACE_("LMB: Click and drag to draw cut line"));
|
||||
@@ -161,7 +161,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
|
||||
v3d->twtype = opdata->twtype;
|
||||
v3d->transform_manipulators_type = opdata->transform_manipulators_type;
|
||||
G.moving = 0;
|
||||
}
|
||||
|
||||
|
@@ -144,8 +144,8 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
|
||||
opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL);
|
||||
G.moving = G_TRANSFORM_EDIT;
|
||||
if (v3d) {
|
||||
opdata->twtype = v3d->twtype;
|
||||
v3d->twtype = 0;
|
||||
opdata->twtype = v3d->transform_manipulators_type;
|
||||
v3d->transform_manipulators_type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ static void edbm_inset_exit(bContext *C, wmOperator *op)
|
||||
EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
|
||||
ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel);
|
||||
if (v3d) {
|
||||
v3d->twtype = opdata->twtype;
|
||||
v3d->transform_manipulators_type = opdata->twtype;
|
||||
}
|
||||
G.moving = 0;
|
||||
}
|
||||
@@ -284,7 +284,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
opdata = op->customdata;
|
||||
|
||||
/* initialize mouse values */
|
||||
if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
|
||||
if (!ED_calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, center_3d, opdata->mcenter)) {
|
||||
/* in this case the tool will likely do nothing,
|
||||
* ideally this will never happen and should be checked for above */
|
||||
opdata->mcenter[0] = opdata->mcenter[1] = 0;
|
||||
|
@@ -137,23 +137,6 @@ static void keymap_particle(wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "PARTICLE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "unselected", true);
|
||||
|
||||
/* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
|
||||
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "release_confirm", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_accurate", false);
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "release_confirm", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
|
||||
RNA_boolean_set(kmi->ptr, "use_accurate", true);
|
||||
|
||||
/* Using KM_ANY here to allow holding modifiers before starting to transform. */
|
||||
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
|
||||
RNA_boolean_set(kmi->ptr, "release_confirm", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
|
||||
RNA_boolean_set(kmi->ptr, "use_accurate", false);
|
||||
|
||||
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "PARTICLE_OT_brush_edit", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
|
||||
|
@@ -124,26 +124,46 @@ static void imm_draw_disk_partial(
|
||||
immEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacement for gluPartialDisk, (without 'loops' argument).
|
||||
*/
|
||||
void imm_draw_filled_disk_partial(
|
||||
unsigned pos, float x, float y,
|
||||
float rad_inner, float rad_outer, int nsegments, float start, float sweep)
|
||||
static void imm_draw_circle_3D(GLenum prim_type, unsigned pos, float x, float y, float rad, int nsegments)
|
||||
{
|
||||
imm_draw_disk_partial(PRIM_TRIANGLE_STRIP, pos, x, y, rad_inner, rad_outer, nsegments, start, sweep);
|
||||
immBegin(prim_type, nsegments);
|
||||
for (int i = 0; i < nsegments; ++i) {
|
||||
float angle = 2 * M_PI * ((float)i / (float)nsegments);
|
||||
immVertex3f(pos, x + rad * cosf(angle),
|
||||
y + rad * sinf(angle), 0.0f);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
||||
void imm_draw_lined_circle_3D(unsigned pos, float x, float y, float rad, int nsegments)
|
||||
{
|
||||
immBegin(PRIM_LINE_LOOP, nsegments);
|
||||
for (int i = 0; i < nsegments; ++i) {
|
||||
float angle = 2 * M_PI * ((float)i / (float)nsegments);
|
||||
immVertex3f(pos, x + rad * cosf(angle), y + rad * sinf(angle), 0.0f);
|
||||
imm_draw_circle_3D(PRIM_LINE_LOOP, pos, x, y, rad, nsegments);
|
||||
}
|
||||
|
||||
void imm_draw_filled_circle_3D(unsigned pos, float x, float y, float rad, int nsegments)
|
||||
{
|
||||
imm_draw_circle_3D(PRIM_TRIANGLE_FAN, pos, x, y, rad, nsegments);
|
||||
}
|
||||
|
||||
static void imm_draw_arc_3D(GLenum prim_type, unsigned int pos, float start, float angle, float radius, int nsegments)
|
||||
{
|
||||
immBegin(prim_type, nsegments + 1);
|
||||
|
||||
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < nsegments; i++) {
|
||||
float t = (float) i / (nsegments - 1);
|
||||
float cur = start + t * angle;
|
||||
|
||||
immVertex3f(pos, cosf(cur) * radius, sinf(cur) * radius, 0.0f);
|
||||
}
|
||||
immEnd();
|
||||
}
|
||||
|
||||
void imm_draw_filled_arc_3D(unsigned int pos, float start, float angle, float radius, int nsegments)
|
||||
{
|
||||
imm_draw_arc_3D(PRIM_TRIANGLE_FAN, pos, start, angle, radius, nsegments);
|
||||
}
|
||||
|
||||
void imm_draw_line_box(unsigned pos, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
immBegin(PRIM_LINE_LOOP, 4);
|
||||
|
@@ -65,6 +65,7 @@ set(SRC
|
||||
view3d_select.c
|
||||
view3d_snap.c
|
||||
view3d_toolbar.c
|
||||
view3d_transform_manipulators.c
|
||||
view3d_view.c
|
||||
|
||||
view3d_intern.h
|
||||
|
@@ -336,13 +336,13 @@ static SpaceLink *view3d_new(const bContext *C)
|
||||
|
||||
v3d->flag = V3D_SELECT_OUTLINE;
|
||||
v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL;
|
||||
v3d->flag3 |= (U.tw_flag & V3D_USE_TRANSFORM_MANIPULATORS);
|
||||
|
||||
v3d->lens = 35.0f;
|
||||
v3d->near = 0.01f;
|
||||
v3d->far = 1000.0f;
|
||||
|
||||
v3d->twflag |= U.tw_flag & V3D_USE_MANIPULATOR;
|
||||
v3d->twtype = V3D_MANIP_TRANSLATE;
|
||||
v3d->transform_manipulators_type = V3D_MANIP_TRANSLATE;
|
||||
v3d->around = V3D_AROUND_CENTER_MEAN;
|
||||
|
||||
v3d->bundle_size = 0.2f;
|
||||
@@ -488,6 +488,12 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar)
|
||||
ListBase *lb;
|
||||
wmKeyMap *keymap;
|
||||
|
||||
if (!ar->manipulator_map) {
|
||||
ar->manipulator_map = WM_manipulatormap_new_from_type(&(const struct wmManipulatorMapType_Params) {
|
||||
"View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW});
|
||||
}
|
||||
WM_manipulatormap_add_handlers(ar, ar->manipulator_map);
|
||||
|
||||
/* object ops. */
|
||||
|
||||
/* important to be before Pose keymap since they can both be enabled at once */
|
||||
@@ -815,7 +821,8 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
{
|
||||
Scene *scene = sc->scene;
|
||||
View3D *v3d = sa->spacedata.first;
|
||||
|
||||
wmManipulatorMap *mmap = ar->manipulator_map;
|
||||
|
||||
/* context changes */
|
||||
switch (wmn->category) {
|
||||
case NC_ANIMATION:
|
||||
@@ -841,6 +848,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
if (wmn->reference)
|
||||
view3d_recalc_used_layers(ar, wmn, wmn->reference);
|
||||
ED_region_tag_redraw(ar);
|
||||
WM_manipulatormap_tag_refresh(mmap);
|
||||
break;
|
||||
case ND_FRAME:
|
||||
case ND_TRANSFORM:
|
||||
@@ -852,6 +860,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
case ND_MARKERS:
|
||||
case ND_MODE:
|
||||
ED_region_tag_redraw(ar);
|
||||
WM_manipulatormap_tag_refresh(mmap);
|
||||
break;
|
||||
case ND_WORLD:
|
||||
/* handled by space_view3d_listener() for v3d access */
|
||||
@@ -884,6 +893,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
case ND_POINTCACHE:
|
||||
case ND_LOD:
|
||||
ED_region_tag_redraw(ar);
|
||||
WM_manipulatormap_tag_refresh(mmap);
|
||||
break;
|
||||
}
|
||||
switch (wmn->action) {
|
||||
@@ -906,6 +916,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
}
|
||||
case ND_DATA:
|
||||
case ND_VERTEX_GROUP:
|
||||
WM_manipulatormap_tag_refresh(mmap);
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
@@ -1002,6 +1013,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
|
||||
}
|
||||
ED_region_tag_redraw(ar);
|
||||
WM_manipulatormap_tag_refresh(mmap);
|
||||
}
|
||||
break;
|
||||
case NC_ID:
|
||||
@@ -1031,6 +1043,7 @@ static void view3d_main_region_listener(bScreen *sc, ScrArea *sa, ARegion *ar, w
|
||||
case NC_GPENCIL:
|
||||
if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
|
||||
ED_region_tag_redraw(ar);
|
||||
WM_manipulatormap_tag_refresh(mmap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1376,6 +1389,14 @@ static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_i
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_manipulators(void)
|
||||
{
|
||||
wmManipulatorMapType *mmaptype = WM_manipulatormaptype_ensure(&(const struct wmManipulatorMapType_Params) {
|
||||
"View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW});
|
||||
|
||||
WM_manipulatorgrouptype_append(mmaptype, VIEW3D_MGT_transform_manipulators);
|
||||
}
|
||||
|
||||
/* only called once, from space/spacetypes.c */
|
||||
void ED_spacetype_view3d(void)
|
||||
{
|
||||
@@ -1395,6 +1416,7 @@ void ED_spacetype_view3d(void)
|
||||
st->dropboxes = view3d_dropboxes;
|
||||
st->context = view3d_context;
|
||||
st->id_remap = view3d_id_remap;
|
||||
st->manipulators = view3d_manipulators;
|
||||
|
||||
/* regions: main window */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region");
|
||||
|
@@ -83,6 +83,7 @@
|
||||
#include "RE_engine.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "view3d_intern.h" /* own include */
|
||||
|
||||
@@ -2211,11 +2212,14 @@ static void view3d_draw_reference_images(const bContext *UNUSED(C))
|
||||
/**
|
||||
* 3D manipulators
|
||||
*/
|
||||
static void view3d_draw_manipulator(const bContext *C)
|
||||
static void view3d_draw_manipulators(const bContext *C, const ARegion *ar)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
v3d->zbuf = false;
|
||||
BIF_draw_manipulator(C);
|
||||
/* TODO, only draws 3D manipulators right now, need to see how 2D drawing will work in new viewport */
|
||||
|
||||
/* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
|
||||
/* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
|
||||
* later become _IN_SCENE (and draw _3D separate) */
|
||||
WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2308,7 +2312,8 @@ static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data
|
||||
view3d_draw_other_elements(C, ar);
|
||||
view3d_draw_tool_ui(C);
|
||||
view3d_draw_reference_images(C);
|
||||
view3d_draw_manipulator(C);
|
||||
view3d_draw_manipulators(C, ar);
|
||||
view3d_draw_region_info(C, ar);
|
||||
|
||||
gpuMatrixEnd();
|
||||
|
||||
|
@@ -79,6 +79,7 @@
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "BLF_api.h"
|
||||
#include "BLT_translation.h"
|
||||
@@ -1708,10 +1709,6 @@ static void view3d_draw_objects(
|
||||
view3d_draw_bgpic_test(scene, ar, v3d, true, do_camera_frame);
|
||||
}
|
||||
|
||||
if (!draw_offscreen) {
|
||||
BIF_draw_manipulator(C);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
if (v3d->zbuf) {
|
||||
v3d->zbuf = false;
|
||||
@@ -2428,6 +2425,11 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce
|
||||
/* main drawing call */
|
||||
view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
|
||||
|
||||
/* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
|
||||
/* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
|
||||
* later become _IN_SCENE (and draw _3D separate) */
|
||||
WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D);
|
||||
|
||||
/* post process */
|
||||
if (do_compositing) {
|
||||
GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
|
||||
|
@@ -623,7 +623,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
|
||||
Object *ob_act = OBACT_NEW;
|
||||
|
||||
if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
|
||||
/* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
|
||||
/* with weight-paint + pose-mode, fall through to using ED_calculateTransformCenter */
|
||||
((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0)
|
||||
{
|
||||
/* in case of sculpting use last average stroke position as a rotation
|
||||
@@ -689,7 +689,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
|
||||
}
|
||||
else {
|
||||
/* If there's no selection, lastofs is unmodified and last value since static */
|
||||
is_set = calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, lastofs, NULL);
|
||||
is_set = ED_calculateTransformCenter(C, V3D_AROUND_CENTER_MEAN, lastofs, NULL);
|
||||
}
|
||||
|
||||
copy_v3_v3(r_dyn_ofs, lastofs);
|
||||
@@ -3790,7 +3790,7 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar,
|
||||
float twmat[3][3];
|
||||
|
||||
/* same as transform manipulator when normal is set */
|
||||
ED_getTransformOrientationMatrix(C, twmat, V3D_AROUND_ACTIVE);
|
||||
ED_getLocalTransformOrientationMatrix(C, twmat, V3D_AROUND_ACTIVE);
|
||||
|
||||
mat3_to_quat(obact_quat, twmat);
|
||||
invert_qt_normalized(obact_quat);
|
||||
@@ -4748,57 +4748,18 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
|
||||
|
||||
/* ***************** manipulator op ******************* */
|
||||
|
||||
|
||||
static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
|
||||
if (!(v3d->twflag & V3D_USE_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
|
||||
if (!(v3d->twflag & V3D_DRAW_MANIPULATOR)) return OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* note; otherwise opengl won't work */
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
if (BIF_do_manipulator(C, event, op) == 0)
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void VIEW3D_OT_manipulator(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "3D Manipulator";
|
||||
ot->description = "Manipulate selected item by axis";
|
||||
ot->idname = "VIEW3D_OT_manipulator";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = manipulator_invoke;
|
||||
|
||||
ot->poll = ED_operator_view3d_active;
|
||||
|
||||
/* properties to pass to transform */
|
||||
Transform_Properties(ot, P_CONSTRAINT);
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "use_planar_constraint", false, "Planar Constraint", "Limit the transformation to the "
|
||||
"two axes that have not been clicked (translate/scale only)");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
}
|
||||
|
||||
static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
|
||||
v3d->twtype = 0;
|
||||
v3d->transform_manipulators_type = 0;
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "translate"))
|
||||
v3d->twtype |= V3D_MANIP_TRANSLATE;
|
||||
v3d->transform_manipulators_type |= V3D_MANIP_TRANSLATE;
|
||||
if (RNA_boolean_get(op->ptr, "rotate"))
|
||||
v3d->twtype |= V3D_MANIP_ROTATE;
|
||||
v3d->transform_manipulators_type |= V3D_MANIP_ROTATE;
|
||||
if (RNA_boolean_get(op->ptr, "scale"))
|
||||
v3d->twtype |= V3D_MANIP_SCALE;
|
||||
v3d->transform_manipulators_type |= V3D_MANIP_SCALE;
|
||||
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
||||
|
||||
|
@@ -367,8 +367,8 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
|
||||
/* Transform widget / manipulators */
|
||||
row = uiLayoutRow(layout, true);
|
||||
uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
||||
if (v3d->twflag & V3D_USE_MANIPULATOR) {
|
||||
uiItemR(row, &v3dptr, "transform_manipulators", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
||||
if (v3d->flag3 & V3D_USE_TRANSFORM_MANIPULATORS) {
|
||||
uiItemR(row, &v3dptr, "transform_manipulators_type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
||||
}
|
||||
uiItemR(row, &v3dptr, "transform_orientation", 0, "", ICON_NONE);
|
||||
}
|
||||
|
@@ -48,6 +48,7 @@ struct bMotionPath;
|
||||
struct bPoseChannel;
|
||||
struct Mesh;
|
||||
struct SceneLayer;
|
||||
struct wmManipulatorGroupType;
|
||||
struct wmOperatorType;
|
||||
struct wmWindowManager;
|
||||
struct wmKeyConfig;
|
||||
@@ -101,7 +102,6 @@ void VIEW3D_OT_view_orbit(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_view_roll(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_clip_border(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_manipulator(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_render_border(struct wmOperatorType *ot);
|
||||
void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
|
||||
@@ -351,4 +351,8 @@ void VP_drawrenderborder(ARegion *ar, View3D *v3d);
|
||||
void VP_view3d_draw_background_none(void);
|
||||
void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d);
|
||||
|
||||
/* manipulators */
|
||||
|
||||
void VIEW3D_MGT_transform_manipulators(struct wmManipulatorGroupType *mgt);
|
||||
|
||||
#endif /* __VIEW3D_INTERN_H__ */
|
||||
|
@@ -193,7 +193,6 @@ void view3d_operatortypes(void)
|
||||
WM_operatortype_append(VIEW3D_OT_render_border);
|
||||
WM_operatortype_append(VIEW3D_OT_clear_render_border);
|
||||
WM_operatortype_append(VIEW3D_OT_zoom_border);
|
||||
WM_operatortype_append(VIEW3D_OT_manipulator);
|
||||
WM_operatortype_append(VIEW3D_OT_enable_manipulator);
|
||||
WM_operatortype_append(VIEW3D_OT_cursor3d);
|
||||
WM_operatortype_append(VIEW3D_OT_select_lasso);
|
||||
@@ -240,23 +239,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
|
||||
/* only for region 3D window */
|
||||
keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0);
|
||||
|
||||
/* Shift+LMB behavior first, so it has priority over KM_ANY item below. */
|
||||
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "release_confirm", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_planar_constraint", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_accurate", false);
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "release_confirm", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
|
||||
RNA_boolean_set(kmi->ptr, "use_accurate", true);
|
||||
|
||||
/* Using KM_ANY here to allow holding modifiers before starting to transform. */
|
||||
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0);
|
||||
RNA_boolean_set(kmi->ptr, "release_confirm", true);
|
||||
RNA_boolean_set(kmi->ptr, "use_planar_constraint", false);
|
||||
RNA_boolean_set(kmi->ptr, "use_accurate", false);
|
||||
|
||||
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_verify_item(keymap, "VIEW3D_OT_rotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
|
||||
|
@@ -0,0 +1,794 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/space_view3d/view3d_transform_manipulators.c
|
||||
* \ingroup spview3d
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "ED_armature.h"
|
||||
#include "ED_transform.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "view3d_intern.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
|
||||
/* threshold for testing view aligned axis manipulator */
|
||||
#define TRANSFORM_MAN_AXIS_DOT_MIN 0.02f
|
||||
#define TRANSFORM_MAN_AXIS_DOT_MAX 0.1f
|
||||
|
||||
#define TRANSFORM_MAN_AXIS_LINE_WIDTH 2.0f
|
||||
|
||||
/**
|
||||
* Transform axis type that can be used as index.
|
||||
*/
|
||||
typedef enum eTransformAxisType {
|
||||
/* single axes */
|
||||
TRANSFORM_AXIS_X = 0,
|
||||
TRANSFORM_AXIS_Y = 1,
|
||||
TRANSFORM_AXIS_Z = 2,
|
||||
|
||||
/* mulitple axes */
|
||||
TRANSFORM_AXIS_VIEW = 3,
|
||||
TRANSFORM_AXIS_XY = 4,
|
||||
TRANSFORM_AXIS_YZ = 5,
|
||||
TRANSFORM_AXIS_ZX = 6,
|
||||
} eTransformAxisType;
|
||||
|
||||
/**
|
||||
* Struct for carrying data of transform manipulators as wmManipulatorGroup.customdata.
|
||||
*/
|
||||
typedef struct TransformManipulatorsInfo {
|
||||
struct TransformAxisManipulator *axes; /* Array of axes */
|
||||
|
||||
float mat[4][4]; /* Cached loc/rot matrix */
|
||||
float init_rot[3][3]; /* rotation matrix since last transform (to calculate rotation delta while dragging) */
|
||||
} TransformManipulatorsInfo;
|
||||
|
||||
/* Callback types */
|
||||
typedef wmManipulator *TransformManipulatorInitFunc(struct TransformAxisManipulator *, wmManipulatorGroup *mgroup);
|
||||
typedef void TransformManipulatorUpdateFunc(
|
||||
const bContext *, const TransformManipulatorsInfo *, const struct TransformAxisManipulator *);
|
||||
typedef int TransformManipulatorHanderFunc(bContext *, const wmEvent *, wmManipulator *, const int);
|
||||
|
||||
/**
|
||||
* Struct that allows us to store info for each transform axis manipulator in a rather generic way.
|
||||
*/
|
||||
typedef struct TransformAxisManipulator {
|
||||
/* -- initialized using static array -- */
|
||||
|
||||
eTransformAxisType type;
|
||||
int transform_type; /* View3d->twtype */
|
||||
|
||||
/* per-manipulator callbacks for initializing/updating data */
|
||||
TransformManipulatorInitFunc (*init);
|
||||
TransformManipulatorUpdateFunc (*refresh);
|
||||
TransformManipulatorUpdateFunc (*draw_prepare);
|
||||
TransformManipulatorHanderFunc (*handler);
|
||||
|
||||
const char *name;
|
||||
int constraint[3]; /* {x, y, z} */
|
||||
int protectflag; /* the protectflags this axis checks (e.g. OB_LOCK_LOCZ) */
|
||||
|
||||
/* appearance */
|
||||
float scale;
|
||||
float line_width;
|
||||
int theme_colorid;
|
||||
int manipulator_style;
|
||||
|
||||
|
||||
/* The manipulator that represents this axis */
|
||||
wmManipulator *manipulator;
|
||||
} TransformAxisManipulator;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Manipulator init/update callbacks */
|
||||
|
||||
static wmManipulator *manipulator_arrow_init(TransformAxisManipulator *axis, wmManipulatorGroup *mgroup)
|
||||
{
|
||||
return WM_arrow_manipulator_new(mgroup, axis->name, axis->manipulator_style);
|
||||
}
|
||||
|
||||
static wmManipulator *manipulator_dial_init(TransformAxisManipulator *axis, wmManipulatorGroup *mgroup)
|
||||
{
|
||||
wmManipulator *manipulator = WM_dial_manipulator_new(mgroup, axis->name, axis->manipulator_style);
|
||||
|
||||
if (axis->transform_type == V3D_MANIP_ROTATE) { /* could also be separate callback */
|
||||
WM_manipulator_set_flag(manipulator, WM_MANIPULATOR_DRAW_ACTIVE, true);
|
||||
}
|
||||
|
||||
return manipulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up \a r_start and \a r_len to define arrow line range.
|
||||
* Needed to adjust line drawing for combined manipulator axis types.
|
||||
*/
|
||||
static void manipulator_line_range(
|
||||
const TransformAxisManipulator *axis, const View3D *v3d,
|
||||
float *r_start, float *r_len)
|
||||
{
|
||||
const float ofs = 0.2f;
|
||||
|
||||
*r_start = 0.2f;
|
||||
*r_len = 1.0f;
|
||||
|
||||
switch (axis->transform_type) {
|
||||
case V3D_MANIP_TRANSLATE:
|
||||
if (v3d->transform_manipulators_type & V3D_MANIP_SCALE) {
|
||||
*r_start = *r_len - ofs + 0.075f;
|
||||
}
|
||||
if (v3d->transform_manipulators_type & V3D_MANIP_ROTATE) {
|
||||
*r_len += ofs;
|
||||
}
|
||||
break;
|
||||
case V3D_MANIP_SCALE:
|
||||
if (v3d->transform_manipulators_type & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE)) {
|
||||
*r_len -= ofs + 0.025f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*r_len -= *r_start;
|
||||
}
|
||||
|
||||
static void manipulator_arrow_update_line_range(const View3D *v3d, const TransformAxisManipulator *axis)
|
||||
{
|
||||
float start[3] = {0.0f};
|
||||
float len;
|
||||
|
||||
manipulator_line_range(axis, v3d, &start[2], &len);
|
||||
WM_manipulator_set_offset(axis->manipulator, start);
|
||||
WM_arrow_manipulator_set_length(axis->manipulator, len);
|
||||
}
|
||||
|
||||
static void manipulator_arrow_refresh(
|
||||
const bContext *C, const TransformManipulatorsInfo *UNUSED(info), const TransformAxisManipulator *axis)
|
||||
{
|
||||
manipulator_arrow_update_line_range(CTX_wm_view3d(C), axis);
|
||||
}
|
||||
|
||||
static void manipulator_dial_refresh(
|
||||
const bContext *UNUSED(C), const TransformManipulatorsInfo *info, const TransformAxisManipulator *axis)
|
||||
{
|
||||
WM_dial_manipulator_set_up_vector(axis->manipulator, info->mat[axis->type]);
|
||||
}
|
||||
|
||||
static void manipulator_arrow_draw_prepare(
|
||||
const bContext *UNUSED(C), const TransformManipulatorsInfo *info, const TransformAxisManipulator *axis)
|
||||
{
|
||||
WM_arrow_manipulator_set_direction(axis->manipulator, info->mat[axis->type]);
|
||||
}
|
||||
|
||||
static void manipulator_view_dial_draw_prepare(
|
||||
const bContext *C, const TransformManipulatorsInfo *UNUSED(info), const TransformAxisManipulator *axis)
|
||||
{
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
WM_dial_manipulator_set_up_vector(axis->manipulator, rv3d->viewinv[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom handler for transform manipulators to update them while modal transform operator runs.
|
||||
*/
|
||||
static int manipulator_axis_translate_handler(
|
||||
bContext *C, const wmEvent *UNUSED(event), wmManipulator *manipulator, const int UNUSED(flag))
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
float origin[3];
|
||||
|
||||
/* update origin */
|
||||
if (ED_calculateTransformCenter((bContext *)C, v3d->around, origin, NULL)) {
|
||||
WM_manipulator_set_origin(manipulator, origin);
|
||||
}
|
||||
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
static TransformAxisManipulator *transform_axis_manipulator_find(
|
||||
const TransformManipulatorsInfo *info, const wmManipulator *manipulator)
|
||||
{
|
||||
for (int i = 0; info->axes[i].name; i++) {
|
||||
if (info->axes[i].manipulator == manipulator) {
|
||||
return &info->axes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static float manipulator_axis_rotate_get_delta_angle(
|
||||
const RegionView3D *rv3d, const Object *ob,
|
||||
TransformManipulatorsInfo *info, eTransformAxisType axis_type)
|
||||
{
|
||||
const bool is_view_aligned = (axis_type == TRANSFORM_AXIS_VIEW);
|
||||
float rot[3][3], delta_rot[3][3];
|
||||
float axis_vec[3];
|
||||
float delta_angle;
|
||||
|
||||
/* Get updated rotation matrix */
|
||||
BKE_object_rot_to_mat3(ob, rot, true);
|
||||
|
||||
/* Calculate delta rotation */
|
||||
transpose_m3(rot);
|
||||
mul_m3_m3m3(delta_rot, info->init_rot, rot);
|
||||
|
||||
/* convert delta rotation to angle */
|
||||
mat3_to_axis_angle(axis_vec, &delta_angle, delta_rot);
|
||||
if (is_view_aligned) {
|
||||
if (dot_v3v3(axis_vec, rv3d->viewinv[2]) < 0.0f) {
|
||||
delta_angle *= -1.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(axis_type < 3);
|
||||
delta_angle *= axis_vec[axis_type];
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* TODO Would be nicer if the ghost arc to show current delta rotation value could display the whole 360 degree
|
||||
* range instead of -180 to 180. This block does this conversion, however it only works nicely when dragging in
|
||||
* one direction. Other direction will start with full 360 degree arc and substract angle from it. */
|
||||
if (delta_angle < 0.0f) {
|
||||
/* convert to pi * 2 range */
|
||||
delta_angle = (float)M_PI * 2.0f - fabs(delta_angle);
|
||||
BLI_assert(delta_angle > 0.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
return delta_angle;
|
||||
}
|
||||
|
||||
static double manipulator_axis_rotate_angle_to_value(float angle)
|
||||
{
|
||||
return (angle / (M_PI * 2.0));
|
||||
}
|
||||
|
||||
static int manipulator_axis_rotate_handler(
|
||||
bContext *C, const wmEvent *UNUSED(event), wmManipulator *manipulator, const int UNUSED(flag))
|
||||
{
|
||||
const RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
const wmManipulatorGroup *mgroup = WM_manipulator_get_parent_group(manipulator);
|
||||
TransformManipulatorsInfo *info = mgroup->customdata;
|
||||
TransformAxisManipulator *axis = transform_axis_manipulator_find(info, manipulator);
|
||||
|
||||
const float angle = manipulator_axis_rotate_get_delta_angle(rv3d, CTX_data_active_object(C), info, axis->type);
|
||||
const double value = manipulator_axis_rotate_angle_to_value(angle);
|
||||
|
||||
WM_dial_manipulator_set_value(manipulator, value);
|
||||
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* General helpers */
|
||||
|
||||
/**
|
||||
* This TransformAxisManipulator array contains all the info we need to initialize, store and identify all
|
||||
* transform manipulators. When creating a new group instance we simply create an allocated version of this.
|
||||
*
|
||||
* \note Order matches drawing order!
|
||||
*/
|
||||
static TransformAxisManipulator tman_axes[] = {
|
||||
{
|
||||
TRANSFORM_AXIS_X, V3D_MANIP_TRANSLATE,
|
||||
manipulator_arrow_init,
|
||||
manipulator_arrow_refresh,
|
||||
manipulator_arrow_draw_prepare,
|
||||
manipulator_axis_translate_handler,
|
||||
"translate_x", {1, 0, 0}, OB_LOCK_LOCX,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_X, MANIPULATOR_ARROW_STYLE_CONE,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_Y, V3D_MANIP_TRANSLATE,
|
||||
manipulator_arrow_init,
|
||||
manipulator_arrow_refresh,
|
||||
manipulator_arrow_draw_prepare,
|
||||
manipulator_axis_translate_handler,
|
||||
"translate_y", {0, 1, 0}, OB_LOCK_LOCY,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Y, MANIPULATOR_ARROW_STYLE_CONE,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_Z, V3D_MANIP_TRANSLATE,
|
||||
manipulator_arrow_init,
|
||||
manipulator_arrow_refresh,
|
||||
manipulator_arrow_draw_prepare,
|
||||
manipulator_axis_translate_handler,
|
||||
"translate_z", {0, 0, 1}, OB_LOCK_LOCZ,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Z, MANIPULATOR_ARROW_STYLE_CONE,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_VIEW, V3D_MANIP_TRANSLATE,
|
||||
manipulator_dial_init,
|
||||
manipulator_dial_refresh,
|
||||
manipulator_view_dial_draw_prepare,
|
||||
NULL,
|
||||
"translate_view", {0}, 0,
|
||||
0.2f, TRANSFORM_MAN_AXIS_LINE_WIDTH, -1, MANIPULATOR_DIAL_STYLE_RING,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_X, V3D_MANIP_ROTATE,
|
||||
manipulator_dial_init,
|
||||
manipulator_dial_refresh,
|
||||
NULL,
|
||||
manipulator_axis_rotate_handler,
|
||||
"rotate_x", {1, 0, 0}, OB_LOCK_ROTX,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, TH_AXIS_X, MANIPULATOR_DIAL_STYLE_RING_CLIPPED,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_Y, V3D_MANIP_ROTATE,
|
||||
manipulator_dial_init,
|
||||
manipulator_dial_refresh,
|
||||
NULL,
|
||||
manipulator_axis_rotate_handler,
|
||||
"rotate_y", {0, 1, 0}, OB_LOCK_ROTY,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, TH_AXIS_Y, MANIPULATOR_DIAL_STYLE_RING_CLIPPED,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_Z, V3D_MANIP_ROTATE,
|
||||
manipulator_dial_init,
|
||||
manipulator_dial_refresh,
|
||||
NULL,
|
||||
manipulator_axis_rotate_handler,
|
||||
"rotate_y", {0, 0, 1}, OB_LOCK_ROTZ,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, TH_AXIS_Z, MANIPULATOR_DIAL_STYLE_RING_CLIPPED,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_VIEW, V3D_MANIP_ROTATE,
|
||||
manipulator_dial_init,
|
||||
NULL,
|
||||
manipulator_view_dial_draw_prepare,
|
||||
manipulator_axis_rotate_handler,
|
||||
"rotate_view", {0}, OB_LOCK_ROTZ,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH + 1.0f, -1, MANIPULATOR_DIAL_STYLE_RING,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_X, V3D_MANIP_SCALE,
|
||||
manipulator_arrow_init,
|
||||
manipulator_arrow_refresh,
|
||||
manipulator_arrow_draw_prepare,
|
||||
NULL,
|
||||
"scale_x", {1, 0, 0}, OB_LOCK_SCALEX,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_X, MANIPULATOR_ARROW_STYLE_CUBE,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_Y, V3D_MANIP_SCALE,
|
||||
manipulator_arrow_init,
|
||||
manipulator_arrow_refresh,
|
||||
manipulator_arrow_draw_prepare,
|
||||
NULL,
|
||||
"scale_y", {0, 1, 0}, OB_LOCK_SCALEY,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Y, MANIPULATOR_ARROW_STYLE_CUBE,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_Z, V3D_MANIP_SCALE,
|
||||
manipulator_arrow_init,
|
||||
manipulator_arrow_refresh,
|
||||
manipulator_arrow_draw_prepare,
|
||||
NULL,
|
||||
"scale_y", {0, 0, 1}, OB_LOCK_SCALEZ,
|
||||
1.0f, TRANSFORM_MAN_AXIS_LINE_WIDTH, TH_AXIS_Z, MANIPULATOR_ARROW_STYLE_CUBE,
|
||||
},
|
||||
{
|
||||
TRANSFORM_AXIS_VIEW, V3D_MANIP_SCALE,
|
||||
manipulator_dial_init,
|
||||
manipulator_dial_refresh,
|
||||
manipulator_view_dial_draw_prepare,
|
||||
NULL,
|
||||
"scale_view", {0}, 0,
|
||||
0.2f, TRANSFORM_MAN_AXIS_LINE_WIDTH, -1, MANIPULATOR_DIAL_STYLE_RING,
|
||||
},
|
||||
{0, 0, NULL}
|
||||
};
|
||||
|
||||
static void transform_manipulators_info_init(TransformManipulatorsInfo *info)
|
||||
{
|
||||
info->axes = MEM_callocN(sizeof(tman_axes), STRINGIFY(TransformAxisManipulator));
|
||||
memcpy(info->axes, tman_axes, sizeof(tman_axes));
|
||||
}
|
||||
|
||||
static void transform_manipulators_info_free(void *customdata)
|
||||
{
|
||||
TransformManipulatorsInfo *info = customdata;
|
||||
|
||||
MEM_freeN(info->axes);
|
||||
MEM_freeN(info);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* init callback and helpers */
|
||||
|
||||
static const char *transform_axis_ot_name_get(int transform_type)
|
||||
{
|
||||
const char *name = NULL;
|
||||
|
||||
switch (transform_type) {
|
||||
case V3D_MANIP_TRANSLATE:
|
||||
name = "TRANSFORM_OT_translate";
|
||||
break;
|
||||
case V3D_MANIP_ROTATE:
|
||||
name = "TRANSFORM_OT_rotate";
|
||||
break;
|
||||
case V3D_MANIP_SCALE:
|
||||
name = "TRANSFORM_OT_resize";
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and initialize a manipulator for \a axis.
|
||||
*/
|
||||
static void transform_axis_manipulator_init(TransformAxisManipulator *axis, wmManipulatorGroup *mgroup)
|
||||
{
|
||||
axis->manipulator = axis->init(axis, mgroup);
|
||||
|
||||
const char *op_name = transform_axis_ot_name_get(axis->transform_type);
|
||||
PointerRNA *ptr = WM_manipulator_set_operator(axis->manipulator, op_name);
|
||||
|
||||
if (axis->handler) {
|
||||
WM_manipulator_set_custom_handler(axis->manipulator, axis->handler);
|
||||
}
|
||||
WM_manipulator_set_scale(axis->manipulator, axis->scale);
|
||||
WM_manipulator_set_line_width(axis->manipulator, axis->line_width);
|
||||
|
||||
if (RNA_struct_find_property(ptr, "constraint_axis")) {
|
||||
RNA_boolean_set_array(ptr, "constraint_axis", axis->constraint);
|
||||
}
|
||||
RNA_boolean_set(ptr, "release_confirm", 1);
|
||||
RNA_boolean_set(ptr, "draw_helplines", 0);
|
||||
}
|
||||
|
||||
static void transform_manipulatorgroup_init(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
|
||||
{
|
||||
TransformManipulatorsInfo *info = MEM_callocN(sizeof(*info), __func__);
|
||||
transform_manipulators_info_init(info);
|
||||
|
||||
for (int i = 0; info->axes[i].name; i++) {
|
||||
transform_axis_manipulator_init(&info->axes[i], mgroup);
|
||||
}
|
||||
|
||||
mgroup->customdata = info;
|
||||
mgroup->customdata_free = transform_manipulators_info_free;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* refresh callback and helpers */
|
||||
|
||||
static bool transform_axis_manipulator_is_visible(TransformAxisManipulator *axis, char transform_type, int protectflag)
|
||||
{
|
||||
return ((axis->transform_type & transform_type) &&
|
||||
(!axis->protectflag || (axis->protectflag & protectflag) != axis->protectflag));
|
||||
}
|
||||
|
||||
static int transform_manipulators_protectflag_posemode_get(Object *ob, View3D *v3d)
|
||||
{
|
||||
bPoseChannel *pchan;
|
||||
int protectflag = 0;
|
||||
|
||||
if ((v3d->around == V3D_AROUND_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) {
|
||||
if (pchan->bone) {
|
||||
protectflag = pchan->protectflag;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* use channels to get stats */
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
Bone *bone = pchan->bone;
|
||||
if (bone && (bone->flag & BONE_TRANSFORM)) {
|
||||
protectflag |= pchan->protectflag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return protectflag;
|
||||
}
|
||||
|
||||
static int transform_manipulators_protectflag_editmode_get(Object *obedit, View3D *v3d)
|
||||
{
|
||||
int protectflag = 0;
|
||||
|
||||
if (obedit->type == OB_ARMATURE) {
|
||||
const bArmature *arm = obedit->data;
|
||||
EditBone *ebo;
|
||||
if ((v3d->around == V3D_AROUND_ACTIVE) && (ebo = arm->act_edbone)) {
|
||||
if (ebo->flag & BONE_EDITMODE_LOCKED) {
|
||||
protectflag = (OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
|
||||
if (EBONE_VISIBLE(arm, ebo)) {
|
||||
if ((ebo->flag & BONE_SELECTED) && (ebo->flag & BONE_EDITMODE_LOCKED)) {
|
||||
protectflag = (OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return protectflag;
|
||||
}
|
||||
|
||||
static int transform_manipulators_protectflag_objectmode_get(const Scene *scene)
|
||||
{
|
||||
int protectflag = 0;
|
||||
|
||||
for (Base *base = scene->base.first; base; base = base->next) {
|
||||
if (TESTBASELIB_NEW(base)) {
|
||||
protectflag |= base->object->protectflag;
|
||||
}
|
||||
}
|
||||
|
||||
return protectflag;
|
||||
}
|
||||
|
||||
static int transform_manipulators_protectflag_get(const bContext *C, View3D *v3d)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = OBACT, *obedit = CTX_data_edit_object(C);
|
||||
bGPdata *gpd = CTX_data_gpencil_data(C);
|
||||
const bool is_gp_edit = (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE));
|
||||
int protectflag = 0;
|
||||
|
||||
if (is_gp_edit) {
|
||||
/* pass */
|
||||
}
|
||||
else if (obedit) {
|
||||
protectflag = transform_manipulators_protectflag_editmode_get(obedit, v3d);
|
||||
}
|
||||
else if (ob && (ob->mode & OB_MODE_POSE)) {
|
||||
protectflag = transform_manipulators_protectflag_posemode_get(ob, v3d);
|
||||
}
|
||||
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
protectflag = transform_manipulators_protectflag_objectmode_get(scene);
|
||||
}
|
||||
|
||||
return protectflag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get (or calculate if needed) location and rotation for the transform manipulators as
|
||||
* transformation matrix. This may iterate over entire selection so avoid as many calls as possible!
|
||||
*
|
||||
* \return If valid matrix has been created. This is not the case if no selection was found.
|
||||
*/
|
||||
static bool transform_manipulators_matrix_get(const bContext *C, const View3D *v3d,
|
||||
float r_local_rot[3][3], float r_mat[4][4])
|
||||
{
|
||||
float origin[3];
|
||||
float rot[3][3];
|
||||
|
||||
if (ED_calculateTransformCenter((bContext *)C, v3d->around, origin, NULL)) {
|
||||
ED_getTransformOrientationMatrix(C, v3d->transform_orientation, v3d->around, rot);
|
||||
if (v3d->transform_orientation == V3D_TRANS_ORIENTATION_LOCAL) {
|
||||
copy_m3_m3(r_local_rot, rot);
|
||||
}
|
||||
else {
|
||||
ED_getTransformOrientationMatrix(C, V3D_TRANS_ORIENTATION_LOCAL, v3d->around, r_local_rot);
|
||||
}
|
||||
|
||||
copy_m4_m3(r_mat, rot);
|
||||
copy_v3_v3(r_mat[3], origin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs some additional layer checks, #ED_calculateTransformCenter does the rest of them.
|
||||
*/
|
||||
static bool transform_manipulators_layer_visible(const bContext *C, const View3D *v3d)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = OBACT;
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
bGPdata *gpd = CTX_data_gpencil_data(C);
|
||||
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
|
||||
|
||||
if (is_gp_edit) {
|
||||
/* TODO */
|
||||
}
|
||||
else if (obedit) {
|
||||
return (obedit->lay & v3d->lay) != 0;
|
||||
}
|
||||
else if (ob && (ob->mode & OB_MODE_POSE)) {
|
||||
return (ob->lay & v3d->lay) != 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void transform_manipulatorgroup_refresh(const bContext *C, wmManipulatorGroup *mgroup)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
TransformManipulatorsInfo *info = mgroup->customdata;
|
||||
|
||||
float mat[4][4], local_rot[3][3];
|
||||
const bool any_visible = transform_manipulators_layer_visible(C, v3d) &&
|
||||
transform_manipulators_matrix_get(C, v3d, local_rot, mat);
|
||||
const int protectflag = transform_manipulators_protectflag_get(C, v3d);
|
||||
|
||||
copy_m4_m4(info->mat, mat);
|
||||
copy_m3_m3(info->init_rot, local_rot);
|
||||
|
||||
for (int i = 0; info->axes[i].name; i++) {
|
||||
TransformAxisManipulator *axis = &info->axes[i];
|
||||
|
||||
if (any_visible && transform_axis_manipulator_is_visible(axis, v3d->transform_manipulators_type, protectflag)) {
|
||||
WM_manipulator_set_flag(axis->manipulator, WM_MANIPULATOR_HIDDEN, false);
|
||||
}
|
||||
else {
|
||||
WM_manipulator_set_flag(axis->manipulator, WM_MANIPULATOR_HIDDEN, true);
|
||||
continue;
|
||||
}
|
||||
WM_manipulator_set_origin(axis->manipulator, mat[3]); /* Could do in callback, but we do it for all anyway */
|
||||
if (axis->refresh) {
|
||||
axis->refresh(C, info, axis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* draw_prepare callback and helpers */
|
||||
|
||||
|
||||
static float transform_axis_view_alpha_fac_get(
|
||||
const TransformAxisManipulator *axis, const RegionView3D *rv3d, const float mat[4][4])
|
||||
{
|
||||
const float dot_min = TRANSFORM_MAN_AXIS_DOT_MIN;
|
||||
const float dot_max = TRANSFORM_MAN_AXIS_DOT_MAX;
|
||||
float view_vec[3], axis_vec[3];
|
||||
float idot[3], idot_axis;
|
||||
|
||||
ED_view3d_global_to_vector(rv3d, mat[3], view_vec);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
normalize_v3_v3(axis_vec, mat[i]);
|
||||
idot[i] = 1.0f - fabsf(dot_v3v3(view_vec, axis_vec));
|
||||
}
|
||||
idot_axis = idot[axis->type];
|
||||
|
||||
return ((idot_axis > dot_max) ?
|
||||
1.0f : (idot_axis < dot_min) ?
|
||||
0.0f : ((idot_axis - dot_min) / (dot_max - dot_min)));
|
||||
}
|
||||
|
||||
static void transform_axis_manipulator_set_color(
|
||||
const TransformAxisManipulator *axis, const RegionView3D *rv3d, const float mat[4][4])
|
||||
{
|
||||
/* alpha values for normal/highlighted states */
|
||||
const float alpha = 0.6f;
|
||||
const float alpha_hi = 1.0f;
|
||||
float alpha_fac = 1.0f;
|
||||
float col[4], col_hi[4];
|
||||
|
||||
if (axis->theme_colorid == -1) {
|
||||
copy_v4_fl(col, 1.0f);
|
||||
}
|
||||
else {
|
||||
UI_GetThemeColor4fv(axis->theme_colorid, col);
|
||||
alpha_fac = transform_axis_view_alpha_fac_get(axis, rv3d, mat);
|
||||
}
|
||||
copy_v4_v4(col_hi, col);
|
||||
|
||||
col[3] = alpha * alpha_fac;
|
||||
col_hi[3] = alpha_hi * alpha_fac;
|
||||
|
||||
WM_manipulator_set_colors(axis->manipulator, col, col_hi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some transform orientation modes require updating the transform manipulators rotation matrix every redraw.
|
||||
* \return If manipulators need to update their rotation.
|
||||
*/
|
||||
static bool transform_manipulators_draw_rotmatrix_get(const bContext *C, const View3D *v3d, float r_rot[3][3])
|
||||
{
|
||||
if (v3d->transform_orientation == V3D_TRANS_ORIENTATION_VIEW) {
|
||||
ED_getTransformOrientationMatrix(C, v3d->transform_orientation, v3d->around, r_rot);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void transform_manipulatorgroup_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
TransformManipulatorsInfo *info = mgroup->customdata;
|
||||
|
||||
float rot[3][3];
|
||||
if (transform_manipulators_draw_rotmatrix_get(C, v3d, rot)) {
|
||||
copy_m4_m3(info->mat, rot);
|
||||
}
|
||||
|
||||
for (int i = 0; info->axes[i].name; i++) {
|
||||
if (info->axes[i].draw_prepare) {
|
||||
info->axes[i].draw_prepare(C, info, &info->axes[i]);
|
||||
}
|
||||
transform_axis_manipulator_set_color(&info->axes[i], rv3d, info->mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static bool transform_manipulatorgroup_poll(const bContext *C, wmManipulatorGroupType *UNUSED(mgt))
|
||||
{
|
||||
const View3D *v3d = CTX_wm_view3d(C);
|
||||
const Object *ob = CTX_data_active_object(C);
|
||||
const Object *editob = CTX_data_edit_object(C);
|
||||
|
||||
BLI_assert(v3d != NULL);
|
||||
|
||||
/* avoiding complex stuff here (like checking for selected vertices),
|
||||
* this poll check runs on every redraw (and more) */
|
||||
return (((v3d->flag3 & V3D_USE_TRANSFORM_MANIPULATORS) != 0) &&
|
||||
((v3d->transform_manipulators_type & (V3D_MANIP_TRANSLATE | V3D_MANIP_ROTATE | V3D_MANIP_SCALE)) != 0) &&
|
||||
(ob || editob));
|
||||
}
|
||||
|
||||
void VIEW3D_MGT_transform_manipulators(wmManipulatorGroupType *mgt)
|
||||
{
|
||||
mgt->name = "Transform Manipulators";
|
||||
|
||||
mgt->poll = transform_manipulatorgroup_poll;
|
||||
mgt->init = transform_manipulatorgroup_init;
|
||||
mgt->refresh = transform_manipulatorgroup_refresh;
|
||||
mgt->draw_prepare = transform_manipulatorgroup_draw_prepare;
|
||||
|
||||
mgt->flag = (WM_MANIPULATORGROUPTYPE_IS_3D | WM_MANIPULATORGROUPTYPE_SCALE_3D);
|
||||
}
|
@@ -45,7 +45,6 @@ set(SRC
|
||||
transform_conversions.c
|
||||
transform_generics.c
|
||||
transform_input.c
|
||||
transform_manipulator.c
|
||||
transform_ops.c
|
||||
transform_orientations.c
|
||||
transform_snap.c
|
||||
|
@@ -928,17 +928,17 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
|
||||
stopConstraint(t);
|
||||
}
|
||||
else {
|
||||
setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg1);
|
||||
setUserConstraint(t, V3D_TRANS_ORIENTATION_GLOBAL, constraint_axis, msg1);
|
||||
}
|
||||
}
|
||||
else if (!edit_2d) {
|
||||
if (cmode == axis) {
|
||||
if (t->con.orientation != V3D_MANIP_GLOBAL) {
|
||||
if (t->con.orientation != V3D_TRANS_ORIENTATION_GLOBAL) {
|
||||
stopConstraint(t);
|
||||
}
|
||||
else {
|
||||
short orientation = (t->current_orientation != V3D_MANIP_GLOBAL ?
|
||||
t->current_orientation : V3D_MANIP_LOCAL);
|
||||
short orientation = (t->current_orientation != V3D_TRANS_ORIENTATION_GLOBAL ?
|
||||
t->current_orientation : V3D_TRANS_ORIENTATION_LOCAL);
|
||||
if (!(t->modifiers & MOD_CONSTRAINT_PLANE))
|
||||
setUserConstraint(t, orientation, constraint_axis, msg2);
|
||||
else if (t->modifiers & MOD_CONSTRAINT_PLANE)
|
||||
@@ -947,9 +947,9 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
|
||||
}
|
||||
else {
|
||||
if (!(t->modifiers & MOD_CONSTRAINT_PLANE))
|
||||
setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg2);
|
||||
setUserConstraint(t, V3D_TRANS_ORIENTATION_GLOBAL, constraint_axis, msg2);
|
||||
else if (t->modifiers & MOD_CONSTRAINT_PLANE)
|
||||
setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_plane, msg3);
|
||||
setUserConstraint(t, V3D_TRANS_ORIENTATION_GLOBAL, constraint_plane, msg3);
|
||||
}
|
||||
}
|
||||
t->redraw |= TREDRAW_HARD;
|
||||
@@ -1082,7 +1082,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
|
||||
if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
|
||||
|
||||
/* Scale isn't normally very useful after extrude along normals, see T39756 */
|
||||
if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_MANIP_NORMAL)) {
|
||||
if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_TRANS_ORIENTATION_NORMAL)) {
|
||||
stopConstraint(t);
|
||||
}
|
||||
|
||||
@@ -1544,7 +1544,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
|
||||
bool ED_calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float cent2d[2])
|
||||
{
|
||||
TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
|
||||
bool success;
|
||||
@@ -1701,7 +1701,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata)
|
||||
{
|
||||
TransInfo *t = (TransInfo *)customdata;
|
||||
|
||||
if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR)) {
|
||||
if (t->helpline != HLP_NONE && (t->flag & T_DRAW_HELPLINES)) {
|
||||
float vecrot[3], cent[2];
|
||||
float mval[3] = { x, y, 0.0f };
|
||||
|
||||
@@ -1999,7 +1999,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
|
||||
{
|
||||
View3D *v3d = t->view;
|
||||
|
||||
v3d->twmode = t->current_orientation;
|
||||
v3d->transform_orientation = t->current_orientation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3422,7 +3422,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
|
||||
constraintTransLim(t, td);
|
||||
}
|
||||
|
||||
static void applyResize(TransInfo *t, const int mval[2])
|
||||
static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
|
||||
{
|
||||
TransData *td;
|
||||
float mat[3][3];
|
||||
@@ -3433,17 +3433,7 @@ static void applyResize(TransInfo *t, const int mval[2])
|
||||
copy_v3_v3(t->values, t->auto_values);
|
||||
}
|
||||
else {
|
||||
float ratio;
|
||||
|
||||
/* for manipulator, center handle, the scaling can't be done relative to center */
|
||||
if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
|
||||
ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
|
||||
}
|
||||
else {
|
||||
ratio = t->values[0];
|
||||
}
|
||||
|
||||
copy_v3_fl(t->values, ratio);
|
||||
copy_v3_fl(t->values, t->values[0]);
|
||||
|
||||
snapGridIncrement(t, t->values);
|
||||
|
||||
@@ -3460,8 +3450,6 @@ static void applyResize(TransInfo *t, const int mval[2])
|
||||
t->con.applySize(t, NULL, mat);
|
||||
}
|
||||
|
||||
copy_m3_m3(t->mat, mat); // used in manipulator
|
||||
|
||||
headerResize(t, t->values, str);
|
||||
|
||||
for (i = 0, td = t->data; i < t->total; i++, td++) {
|
||||
@@ -5265,24 +5253,14 @@ static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
|
||||
td->loc[1] = oldy;
|
||||
}
|
||||
|
||||
static void applyBoneSize(TransInfo *t, const int mval[2])
|
||||
static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
|
||||
{
|
||||
TransData *td = t->data;
|
||||
float size[3], mat[3][3];
|
||||
float ratio;
|
||||
int i;
|
||||
char str[UI_MAX_DRAW_STR];
|
||||
|
||||
// TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
|
||||
/* for manipulator, center handle, the scaling can't be done relative to center */
|
||||
if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
|
||||
ratio = 1.0f - ((t->mouse.imval[0] - mval[0]) + (t->mouse.imval[1] - mval[1])) / 100.0f;
|
||||
}
|
||||
else {
|
||||
ratio = t->values[0];
|
||||
}
|
||||
|
||||
copy_v3_fl(size, ratio);
|
||||
copy_v3_fl(size, t->values[0]);
|
||||
|
||||
snapGridIncrement(t, size);
|
||||
|
||||
@@ -5298,8 +5276,6 @@ static void applyBoneSize(TransInfo *t, const int mval[2])
|
||||
t->con.applySize(t, NULL, mat);
|
||||
}
|
||||
|
||||
copy_m3_m3(t->mat, mat); // used in manipulator
|
||||
|
||||
headerBoneSize(t, size, str);
|
||||
|
||||
for (i = 0; i < t->total; i++, td++) {
|
||||
@@ -8332,9 +8308,7 @@ static void applyTimeTranslate(TransInfo *t, const int mval[2])
|
||||
}
|
||||
|
||||
/* handle numeric-input stuff */
|
||||
t->vec[0] = t->values[0];
|
||||
applyNumInput(&t->num, &t->vec[0]);
|
||||
t->values[0] = t->vec[0];
|
||||
applyNumInput(&t->num, t->values);
|
||||
headerTimeTranslate(t, str);
|
||||
|
||||
applyTimeTranslateValue(t);
|
||||
@@ -8499,9 +8473,9 @@ static void applyTimeSlide(TransInfo *t, const int mval[2])
|
||||
/* t->values[0] = cval[0]; */ /* UNUSED (reset again later). */
|
||||
|
||||
/* handle numeric-input stuff */
|
||||
t->vec[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
|
||||
applyNumInput(&t->num, &t->vec[0]);
|
||||
t->values[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0];
|
||||
t->values[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
|
||||
applyNumInput(&t->num, t->values);
|
||||
t->values[0] = (maxx - minx) * t->values[0] / 2.0f + sval[0];
|
||||
|
||||
headerTimeSlide(t, sval[0], str);
|
||||
applyTimeSlideValue(t, sval[0]);
|
||||
@@ -8615,11 +8589,9 @@ static void applyTimeScaleValue(TransInfo *t)
|
||||
static void applyTimeScale(TransInfo *t, const int UNUSED(mval[2]))
|
||||
{
|
||||
char str[UI_MAX_DRAW_STR];
|
||||
|
||||
|
||||
/* handle numeric-input stuff */
|
||||
t->vec[0] = t->values[0];
|
||||
applyNumInput(&t->num, &t->vec[0]);
|
||||
t->values[0] = t->vec[0];
|
||||
applyNumInput(&t->num, t->values);
|
||||
headerTimeScale(t, str);
|
||||
|
||||
applyTimeScaleValue(t);
|
||||
|
@@ -418,9 +418,6 @@ typedef struct TransInfo {
|
||||
char spacetype; /* spacetype where transforming is */
|
||||
char helpline; /* helpline modes (not to be confused with hotline) */
|
||||
|
||||
float vec[3]; /* translation, to show for widget */
|
||||
float mat[3][3]; /* rot/rescale, to show for widget */
|
||||
|
||||
float spacemtx[3][3]; /* orientation matrix of the current space */
|
||||
char spacename[64]; /* name of the current space, MAX_NAME */
|
||||
|
||||
@@ -498,8 +495,8 @@ typedef struct TransInfo {
|
||||
#define T_CAMERA (1 << 4)
|
||||
// trans on points, having no rotation/scale
|
||||
#define T_POINTS (1 << 6)
|
||||
// for manipulator exceptions, like scaling using center point, drawing help lines
|
||||
#define T_USES_MANIPULATOR (1 << 7)
|
||||
/* Draw helplines (includes constraint lines) */
|
||||
#define T_DRAW_HELPLINES (1 << 7)
|
||||
|
||||
/* restrictions flags */
|
||||
#define T_ALL_RESTRICTIONS ((1 << 8)|(1 << 9)|(1 << 10))
|
||||
@@ -636,9 +633,6 @@ void flushTransMasking(TransInfo *t);
|
||||
void flushTransPaintCurve(TransInfo *t);
|
||||
void restoreBones(TransInfo *t);
|
||||
|
||||
/*********************** exported from transform_manipulator.c ********** */
|
||||
bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
|
||||
|
||||
/*********************** TransData Creation and General Handling *********** */
|
||||
void createTransData(struct bContext *C, TransInfo *t);
|
||||
void sort_trans_data_dist(TransInfo *t);
|
||||
@@ -794,8 +788,8 @@ bool applyTransformOrientation(const struct bContext *C, float mat[3][3], char r
|
||||
#define ORIENTATION_EDGE 3
|
||||
#define ORIENTATION_FACE 4
|
||||
|
||||
int getTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around);
|
||||
int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3]);
|
||||
int getLocalTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around);
|
||||
int getLocalTransformOrientation(const struct bContext *C, float normal[3], float plane[3]);
|
||||
|
||||
void freeEdgeSlideTempFaces(EdgeSlideData *sld);
|
||||
void freeEdgeSlideVerts(TransInfo *t, TransCustomData *custom_data);
|
||||
|
@@ -656,7 +656,7 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
|
||||
char text[40];
|
||||
|
||||
switch (orientation) {
|
||||
case V3D_MANIP_GLOBAL:
|
||||
case V3D_TRANS_ORIENTATION_GLOBAL:
|
||||
{
|
||||
float mtx[3][3];
|
||||
BLI_snprintf(text, sizeof(text), ftext, IFACE_("global"));
|
||||
@@ -664,11 +664,11 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
|
||||
setConstraint(t, mtx, mode, text);
|
||||
break;
|
||||
}
|
||||
case V3D_MANIP_LOCAL:
|
||||
case V3D_TRANS_ORIENTATION_LOCAL:
|
||||
BLI_snprintf(text, sizeof(text), ftext, IFACE_("local"));
|
||||
setLocalConstraint(t, mode, text);
|
||||
break;
|
||||
case V3D_MANIP_NORMAL:
|
||||
case V3D_TRANS_ORIENTATION_NORMAL:
|
||||
BLI_snprintf(text, sizeof(text), ftext, IFACE_("normal"));
|
||||
if (checkUseAxisMatrix(t)) {
|
||||
setAxisMatrixConstraint(t, mode, text);
|
||||
@@ -677,11 +677,11 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
|
||||
setConstraint(t, t->spacemtx, mode, text);
|
||||
}
|
||||
break;
|
||||
case V3D_MANIP_VIEW:
|
||||
case V3D_TRANS_ORIENTATION_VIEW:
|
||||
BLI_snprintf(text, sizeof(text), ftext, IFACE_("view"));
|
||||
setConstraint(t, t->spacemtx, mode, text);
|
||||
break;
|
||||
case V3D_MANIP_GIMBAL:
|
||||
case V3D_TRANS_ORIENTATION_GIMBAL:
|
||||
BLI_snprintf(text, sizeof(text), ftext, IFACE_("gimbal"));
|
||||
setConstraint(t, t->spacemtx, mode, text);
|
||||
break;
|
||||
@@ -706,7 +706,7 @@ void drawConstraint(TransInfo *t)
|
||||
return;
|
||||
if (!(tc->mode & CON_APPLY))
|
||||
return;
|
||||
if (t->flag & T_USES_MANIPULATOR)
|
||||
if (!(t->flag & T_DRAW_HELPLINES))
|
||||
return;
|
||||
if (t->flag & T_NO_CONSTRAINT)
|
||||
return;
|
||||
|
@@ -1163,12 +1163,9 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
|
||||
t->val = 0.0f;
|
||||
|
||||
zero_v3(t->vec);
|
||||
zero_v3(t->center);
|
||||
zero_v3(t->center_global);
|
||||
|
||||
unit_m3(t->mat);
|
||||
|
||||
/* if there's an event, we're modal */
|
||||
if (event) {
|
||||
t->flag |= T_MODAL;
|
||||
@@ -1230,8 +1227,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
/* turn manipulator off during transform */
|
||||
// FIXME: but don't do this when USING the manipulator...
|
||||
if (t->flag & T_MODAL) {
|
||||
t->twtype = v3d->twtype;
|
||||
v3d->twtype = 0;
|
||||
t->twtype = v3d->transform_manipulators_type;
|
||||
v3d->transform_manipulators_type = 0;
|
||||
}
|
||||
|
||||
if (v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN;
|
||||
@@ -1242,7 +1239,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
t->around = V3D_AROUND_CURSOR;
|
||||
}
|
||||
|
||||
t->current_orientation = v3d->twmode;
|
||||
t->current_orientation = v3d->transform_orientation;
|
||||
|
||||
/* exceptional case */
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
@@ -1335,8 +1332,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
{
|
||||
t->current_orientation = RNA_property_enum_get(op->ptr, prop);
|
||||
|
||||
if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C)) {
|
||||
t->current_orientation = V3D_MANIP_GLOBAL;
|
||||
if (t->current_orientation >= V3D_TRANS_ORIENTATION_CUSTOM + BIF_countTransformOrientation(C)) {
|
||||
t->current_orientation = V3D_TRANS_ORIENTATION_GLOBAL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1434,7 +1431,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
else { /* add not pet option to context when not available */
|
||||
t->options |= CTX_NO_PET;
|
||||
}
|
||||
|
||||
|
||||
if (op && (prop = RNA_struct_find_property(op->ptr, "draw_helplines"))) {
|
||||
if (RNA_property_boolean_get(op->ptr, prop)) {
|
||||
t->flag |= T_DRAW_HELPLINES;
|
||||
}
|
||||
}
|
||||
|
||||
// Mirror is not supported with PET, turn it off.
|
||||
#if 0
|
||||
if (t->flag & T_PROP_EDIT) {
|
||||
@@ -1516,7 +1519,7 @@ void postTrans(bContext *C, TransInfo *t)
|
||||
View3D *v3d = t->sa->spacedata.first;
|
||||
/* restore manipulator */
|
||||
if (t->flag & T_MODAL) {
|
||||
v3d->twtype = t->twtype;
|
||||
v3d->transform_manipulators_type = t->twtype;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1598,8 +1601,6 @@ void restoreTransObjects(TransInfo *t)
|
||||
}
|
||||
}
|
||||
|
||||
unit_m3(t->mat);
|
||||
|
||||
recalcData(t);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -206,7 +206,7 @@ static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot)
|
||||
static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
|
||||
int selected_index = (v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM);
|
||||
|
||||
BIF_removeTransformOrientationIndex(C, selected_index);
|
||||
|
||||
@@ -231,7 +231,7 @@ static int delete_orientation_poll(bContext *C)
|
||||
|
||||
|
||||
if (v3d) {
|
||||
selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
|
||||
selected_index = (v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM);
|
||||
}
|
||||
|
||||
return selected_index >= 0;
|
||||
@@ -573,6 +573,9 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
|
||||
prop = RNA_def_boolean(ot->srna, "use_accurate", 0, "Accurate", "Use accurate transformation");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
}
|
||||
|
||||
prop = RNA_def_boolean(ot->srna, "draw_helplines", 1, "Draw Helplines", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
}
|
||||
|
||||
static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
|
||||
|
@@ -69,8 +69,8 @@ void BIF_clearTransformOrientation(bContext *C)
|
||||
BLI_freelistN(transform_spaces);
|
||||
|
||||
// Need to loop over all view3d
|
||||
if (v3d && v3d->twmode >= V3D_MANIP_CUSTOM) {
|
||||
v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */
|
||||
if (v3d && v3d->transform_orientation >= V3D_TRANS_ORIENTATION_CUSTOM) {
|
||||
v3d->transform_orientation = V3D_TRANS_ORIENTATION_GLOBAL; /* fallback to global */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports,
|
||||
float mat[3][3];
|
||||
float normal[3], plane[3];
|
||||
|
||||
getTransformOrientation(C, normal, plane);
|
||||
getLocalTransformOrientation(C, normal, plane);
|
||||
|
||||
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
|
||||
BKE_reports_prepend(reports, "Cannot use zero-length bone");
|
||||
@@ -165,7 +165,7 @@ static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports,
|
||||
float mat[3][3];
|
||||
float normal[3], plane[3];
|
||||
|
||||
getTransformOrientation(C, normal, plane);
|
||||
getLocalTransformOrientation(C, normal, plane);
|
||||
|
||||
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
|
||||
BKE_reports_prepend(reports, "Cannot use zero-length curve");
|
||||
@@ -187,7 +187,7 @@ static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports,
|
||||
float normal[3], plane[3];
|
||||
int type;
|
||||
|
||||
type = getTransformOrientation(C, normal, plane);
|
||||
type = getLocalTransformOrientation(C, normal, plane);
|
||||
|
||||
switch (type) {
|
||||
case ORIENTATION_VERT:
|
||||
@@ -352,7 +352,7 @@ void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target)
|
||||
|
||||
if (i != -1) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
BKE_screen_view3d_main_twmode_remove(&bmain->screen, scene, i);
|
||||
BKE_screen_view3d_main_transform_orientation_remove(&bmain->screen, scene, i);
|
||||
BLI_freelinkN(transform_spaces, target);
|
||||
}
|
||||
}
|
||||
@@ -374,7 +374,7 @@ void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target)
|
||||
|
||||
if (i != -1) {
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
v3d->twmode = V3D_MANIP_CUSTOM + i;
|
||||
v3d->transform_orientation = V3D_TRANS_ORIENTATION_CUSTOM + i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +382,7 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation)
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
if (v3d) /* currently using generic poll */
|
||||
v3d->twmode = orientation;
|
||||
v3d->transform_orientation = orientation;
|
||||
}
|
||||
|
||||
int BIF_countTransformOrientation(const bContext *C)
|
||||
@@ -438,32 +438,134 @@ static int count_bone_select(bArmature *arm, ListBase *lb, const bool do_it)
|
||||
return total;
|
||||
}
|
||||
|
||||
/* could move into BLI_math however this is only useful for display/editing purposes */
|
||||
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
|
||||
{
|
||||
/* X/Y are arbitrary axies, most importantly Z is the axis of rotation */
|
||||
|
||||
float cross_vec[3];
|
||||
float quat[4];
|
||||
|
||||
/* this is an un-scientific method to get a vector to cross with
|
||||
* XYZ intentionally YZX */
|
||||
cross_vec[0] = axis[1];
|
||||
cross_vec[1] = axis[2];
|
||||
cross_vec[2] = axis[0];
|
||||
|
||||
/* X-axis */
|
||||
cross_v3_v3v3(gmat[0], cross_vec, axis);
|
||||
normalize_v3(gmat[0]);
|
||||
axis_angle_to_quat(quat, axis, angle);
|
||||
mul_qt_v3(quat, gmat[0]);
|
||||
|
||||
/* Y-axis */
|
||||
axis_angle_to_quat(quat, axis, M_PI_2);
|
||||
copy_v3_v3(gmat[1], gmat[0]);
|
||||
mul_qt_v3(quat, gmat[1]);
|
||||
|
||||
/* Z-axis */
|
||||
copy_v3_v3(gmat[2], axis);
|
||||
|
||||
normalize_m3(gmat);
|
||||
}
|
||||
|
||||
static int test_rotmode_euler(short rotmode)
|
||||
{
|
||||
return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1;
|
||||
}
|
||||
|
||||
static bool gimbal_axis(Object *ob, float gmat[3][3])
|
||||
{
|
||||
if (ob) {
|
||||
if (ob->mode & OB_MODE_POSE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_active(ob);
|
||||
|
||||
if (pchan) {
|
||||
float mat[3][3], tmat[3][3], obmat[3][3];
|
||||
if (test_rotmode_euler(pchan->rotmode)) {
|
||||
eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
|
||||
}
|
||||
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
|
||||
axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
|
||||
}
|
||||
else { /* quat */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* apply bone transformation */
|
||||
mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
|
||||
|
||||
if (pchan->parent) {
|
||||
float parent_mat[3][3];
|
||||
|
||||
copy_m3_m4(parent_mat, pchan->parent->pose_mat);
|
||||
mul_m3_m3m3(mat, parent_mat, tmat);
|
||||
|
||||
/* needed if object transformation isn't identity */
|
||||
copy_m3_m4(obmat, ob->obmat);
|
||||
mul_m3_m3m3(gmat, obmat, mat);
|
||||
}
|
||||
else {
|
||||
/* needed if object transformation isn't identity */
|
||||
copy_m3_m4(obmat, ob->obmat);
|
||||
mul_m3_m3m3(gmat, obmat, tmat);
|
||||
}
|
||||
|
||||
normalize_m3(gmat);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (test_rotmode_euler(ob->rotmode)) {
|
||||
eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
|
||||
}
|
||||
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
||||
axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
|
||||
}
|
||||
else { /* quat */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ob->parent) {
|
||||
float parent_mat[3][3];
|
||||
copy_m3_m4(parent_mat, ob->parent->obmat);
|
||||
normalize_m3(parent_mat);
|
||||
mul_m3_m3m3(gmat, parent_mat, gmat);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initTransformOrientation(bContext *C, TransInfo *t)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Object *obedit = CTX_data_active_object(C);
|
||||
|
||||
switch (t->current_orientation) {
|
||||
case V3D_MANIP_GLOBAL:
|
||||
case V3D_TRANS_ORIENTATION_GLOBAL:
|
||||
unit_m3(t->spacemtx);
|
||||
BLI_strncpy(t->spacename, IFACE_("global"), sizeof(t->spacename));
|
||||
break;
|
||||
|
||||
case V3D_MANIP_GIMBAL:
|
||||
case V3D_TRANS_ORIENTATION_GIMBAL:
|
||||
unit_m3(t->spacemtx);
|
||||
if (gimbal_axis(ob, t->spacemtx)) {
|
||||
BLI_strncpy(t->spacename, IFACE_("gimbal"), sizeof(t->spacename));
|
||||
break;
|
||||
}
|
||||
/* fall-through */ /* no gimbal fallthrough to normal */
|
||||
case V3D_MANIP_NORMAL:
|
||||
case V3D_TRANS_ORIENTATION_NORMAL:
|
||||
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
|
||||
BLI_strncpy(t->spacename, IFACE_("normal"), sizeof(t->spacename));
|
||||
ED_getTransformOrientationMatrix(C, t->spacemtx, t->around);
|
||||
ED_getLocalTransformOrientationMatrix(C, t->spacemtx, t->around);
|
||||
break;
|
||||
}
|
||||
/* fall-through */ /* we define 'normal' as 'local' in Object mode */
|
||||
case V3D_MANIP_LOCAL:
|
||||
case V3D_TRANS_ORIENTATION_LOCAL:
|
||||
BLI_strncpy(t->spacename, IFACE_("local"), sizeof(t->spacename));
|
||||
|
||||
if (ob) {
|
||||
@@ -476,7 +578,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
|
||||
|
||||
break;
|
||||
|
||||
case V3D_MANIP_VIEW:
|
||||
case V3D_TRANS_ORIENTATION_VIEW:
|
||||
if ((t->spacetype == SPACE_VIEW3D) &&
|
||||
(t->ar->regiontype == RGN_TYPE_WINDOW))
|
||||
{
|
||||
@@ -493,7 +595,7 @@ void initTransformOrientation(bContext *C, TransInfo *t)
|
||||
}
|
||||
break;
|
||||
default: /* V3D_MANIP_CUSTOM */
|
||||
if (applyTransformOrientation(C, t->spacemtx, t->spacename, t->current_orientation - V3D_MANIP_CUSTOM)) {
|
||||
if (applyTransformOrientation(C, t->spacemtx, t->spacename, t->current_orientation - V3D_TRANS_ORIENTATION_CUSTOM)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
@@ -584,7 +686,7 @@ static unsigned int bm_mesh_faces_select_get_n(BMesh *bm, BMVert **elems, const
|
||||
}
|
||||
#endif
|
||||
|
||||
int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
|
||||
int getLocalTransformOrientation_ex(const bContext *C, float normal[3], float plane[3], const short around)
|
||||
{
|
||||
SceneLayer *sl = CTX_data_scene_layer(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
@@ -1042,22 +1144,22 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
|
||||
return result;
|
||||
}
|
||||
|
||||
int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
|
||||
int getLocalTransformOrientation(const bContext *C, float normal[3], float plane[3])
|
||||
{
|
||||
/* dummy value, not V3D_AROUND_ACTIVE and not V3D_AROUND_LOCAL_ORIGINS */
|
||||
short around = V3D_AROUND_CENTER_BOUNDS;
|
||||
|
||||
return getTransformOrientation_ex(C, normal, plane, around);
|
||||
return getLocalTransformOrientation_ex(C, normal, plane, around);
|
||||
}
|
||||
|
||||
void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], const short around)
|
||||
void ED_getLocalTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], const short around)
|
||||
{
|
||||
float normal[3] = {0.0, 0.0, 0.0};
|
||||
float plane[3] = {0.0, 0.0, 0.0};
|
||||
|
||||
int type;
|
||||
|
||||
type = getTransformOrientation_ex(C, normal, plane, around);
|
||||
type = getLocalTransformOrientation_ex(C, normal, plane, around);
|
||||
|
||||
switch (type) {
|
||||
case ORIENTATION_NORMAL:
|
||||
@@ -1086,3 +1188,63 @@ void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3
|
||||
unit_m3(orientation_mat);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get (or calculate if needed) the rotation matrix for \a orientation_type.
|
||||
*/
|
||||
void ED_getTransformOrientationMatrix(
|
||||
const bContext *C, const char orientation_type, const short around,
|
||||
float r_orientation_mat[3][3])
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Object *obedit = CTX_data_active_object(C);
|
||||
float mat[3][3];
|
||||
|
||||
BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
|
||||
CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW);
|
||||
|
||||
unit_m3(mat);
|
||||
|
||||
switch (orientation_type) {
|
||||
case V3D_TRANS_ORIENTATION_GLOBAL:
|
||||
/* use unit matrix */
|
||||
break;
|
||||
case V3D_TRANS_ORIENTATION_GIMBAL:
|
||||
if (gimbal_axis(ob, mat)) {
|
||||
break;
|
||||
}
|
||||
/* No break, fall-through here! If not gimbal, fall through to normal. */
|
||||
case V3D_TRANS_ORIENTATION_NORMAL:
|
||||
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
|
||||
ED_getLocalTransformOrientationMatrix(C, mat, around);
|
||||
break;
|
||||
}
|
||||
/* No break, fall-trough here! We define 'normal' as 'local' in Object mode. */
|
||||
case V3D_TRANS_ORIENTATION_LOCAL:
|
||||
if (ob && ob->mode & OB_MODE_POSE) {
|
||||
/* each bone moves on its own local axis, but to avoid confusion,
|
||||
* use the active pones axis for display [#33575], this works as expected on a single bone
|
||||
* and users who select many bones will understand whats going on and what local means
|
||||
* when they start transforming */
|
||||
ED_getLocalTransformOrientationMatrix(C, mat, around);
|
||||
break;
|
||||
}
|
||||
else if (ob) {
|
||||
copy_m3_m4(mat, ob->obmat);
|
||||
normalize_m3(mat);
|
||||
}
|
||||
break;
|
||||
case V3D_TRANS_ORIENTATION_VIEW:
|
||||
{
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
copy_m3_m4(mat, rv3d->viewinv);
|
||||
normalize_m3(mat);
|
||||
break;
|
||||
}
|
||||
default: /* custom (V3D_MANIP_CUSTOM and higher) */
|
||||
applyTransformOrientation(C, mat, NULL, orientation_type - V3D_TRANS_ORIENTATION_CUSTOM);
|
||||
break;
|
||||
}
|
||||
|
||||
copy_m3_m3(r_orientation_mat, mat);
|
||||
}
|
||||
|
@@ -148,6 +148,7 @@ data_to_c_simple(shaders/gpu_shader_3D_flat_color_vert.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_vert.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_3D_passthrough_vert.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_3D_clipped_uniform_color_vert.glsl SRC)
|
||||
|
||||
data_to_c_simple(shaders/gpu_shader_instance_vert.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl SRC)
|
||||
|
@@ -121,6 +121,7 @@ typedef enum GPUBuiltinShader {
|
||||
GPU_SHADER_3D_FLAT_COLOR,
|
||||
GPU_SHADER_3D_SMOOTH_COLOR,
|
||||
GPU_SHADER_3D_DEPTH_ONLY,
|
||||
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
|
||||
/* basic image drawing */
|
||||
GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
|
||||
GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR,
|
||||
|
@@ -74,6 +74,7 @@ extern char datatoc_gpu_shader_3D_flat_color_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_passthrough_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl[];
|
||||
|
||||
extern char datatoc_gpu_shader_instance_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[];
|
||||
@@ -724,6 +725,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
|
||||
[GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_passthrough_vert_glsl,
|
||||
datatoc_gpu_shader_uniform_color_frag_glsl,
|
||||
datatoc_gpu_shader_3D_groundline_geom_glsl },
|
||||
[GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_clipped_uniform_color_vert_glsl,
|
||||
datatoc_gpu_shader_uniform_color_frag_glsl },
|
||||
|
||||
[GPU_SHADER_2D_LINE_DASHED_COLOR] = { datatoc_gpu_shader_2D_line_dashed_vert_glsl,
|
||||
datatoc_gpu_shader_2D_line_dashed_frag_glsl },
|
||||
|
@@ -0,0 +1,16 @@
|
||||
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform vec4 ClipPlane;
|
||||
|
||||
#if __VERSION__ == 120
|
||||
attribute vec3 pos;
|
||||
#else
|
||||
in vec3 pos;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
gl_ClipDistance[0] = dot(ModelMatrix * vec4(pos, 1.0), ClipPlane);
|
||||
}
|
@@ -1636,8 +1636,6 @@ typedef struct Scene {
|
||||
struct Object *obedit; /* name replaces old G.obedit */
|
||||
|
||||
float cursor[3]; /* 3d cursor location */
|
||||
float twcent[3]; /* center for transform widget */
|
||||
float twmin[3], twmax[3]; /* boundbox of selection for transform widget */
|
||||
|
||||
unsigned int lay; /* bitflags for layer visibility */
|
||||
int layact; /* active layer */
|
||||
@@ -1646,7 +1644,7 @@ typedef struct Scene {
|
||||
short flag; /* various settings */
|
||||
|
||||
char use_nodes;
|
||||
char pad[1];
|
||||
char pad[5];
|
||||
|
||||
struct bNodeTree *nodetree;
|
||||
|
||||
|
@@ -91,7 +91,6 @@ typedef struct BGpic {
|
||||
/* ********************************* */
|
||||
|
||||
typedef struct RegionView3D {
|
||||
|
||||
float winmat[4][4]; /* GL_PROJECTION matrix */
|
||||
float viewmat[4][4]; /* GL_MODELVIEW matrix */
|
||||
float viewinv[4][4]; /* inverse of viewmat */
|
||||
@@ -113,14 +112,12 @@ typedef struct RegionView3D {
|
||||
struct ViewDepths *depths;
|
||||
void *gpuoffscreen;
|
||||
|
||||
|
||||
/* animated smooth view */
|
||||
struct SmoothView3DStore *sms;
|
||||
struct wmTimer *smooth_timer;
|
||||
|
||||
|
||||
/* transform manipulator matrix */
|
||||
float twmat[4][4];
|
||||
|
||||
float viewquat[4]; /* view rotation, must be kept normalized */
|
||||
float dist; /* distance from 'ofs' along -viewinv[2] vector, where result is negative as is 'ofs' */
|
||||
float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */
|
||||
@@ -137,8 +134,7 @@ typedef struct RegionView3D {
|
||||
char pad[3];
|
||||
float ofs_lock[2]; /* normalized offset for locked view: (-1, -1) bottom left, (1, 1) upper right */
|
||||
|
||||
short twdrawflag;
|
||||
short rflag;
|
||||
short rflag, pad2[3];
|
||||
|
||||
|
||||
/* last view (use when switching out of camera view) */
|
||||
@@ -146,7 +142,6 @@ typedef struct RegionView3D {
|
||||
short lpersp, lview; /* lpersp can never be set to 'RV3D_CAMOB' */
|
||||
|
||||
float gridview;
|
||||
float tw_idot[3]; /* manipulator runtime: (1 - dot) product with view vector (used to check view alignment) */
|
||||
|
||||
|
||||
/* active rotation from NDOF or elsewhere */
|
||||
@@ -210,11 +205,13 @@ typedef struct View3D {
|
||||
short gridsubdiv; /* Number of subdivisions in the grid between each highlighted grid line */
|
||||
char gridflag;
|
||||
|
||||
/* transform manipulator info */
|
||||
char twtype, twmode, twflag;
|
||||
|
||||
/* transform manipulators info */
|
||||
char transform_manipulators_type;
|
||||
char transform_orientation;
|
||||
char pad5;
|
||||
|
||||
short flag3;
|
||||
|
||||
|
||||
/* afterdraw, for xray & transparent */
|
||||
struct ListBase afterdraw_transp;
|
||||
struct ListBase afterdraw_xray;
|
||||
@@ -330,7 +327,10 @@ typedef struct View3D {
|
||||
|
||||
|
||||
/* View3d->flag3 (short) */
|
||||
#define V3D_SHOW_WORLD (1 << 0)
|
||||
enum {
|
||||
V3D_SHOW_WORLD = (1 << 0),
|
||||
V3D_USE_TRANSFORM_MANIPULATORS = (1 << 1),
|
||||
};
|
||||
|
||||
/* View3d->tmp_compat_flag */
|
||||
enum {
|
||||
@@ -376,24 +376,23 @@ enum {
|
||||
#define V3D_SHOW_Y 4
|
||||
#define V3D_SHOW_Z 8
|
||||
|
||||
/* View3d->twtype (bits, we can combine them) */
|
||||
#define V3D_MANIP_TRANSLATE 1
|
||||
#define V3D_MANIP_ROTATE 2
|
||||
#define V3D_MANIP_SCALE 4
|
||||
/* View3d->transform_manipulators_type (bits, we can combine them) */
|
||||
enum {
|
||||
V3D_MANIP_TRANSLATE = (1 << 0),
|
||||
V3D_MANIP_ROTATE = (1 << 1),
|
||||
V3D_MANIP_SCALE = (1 << 2),
|
||||
};
|
||||
|
||||
/* View3d->twmode */
|
||||
#define V3D_MANIP_GLOBAL 0
|
||||
#define V3D_MANIP_LOCAL 1
|
||||
#define V3D_MANIP_NORMAL 2
|
||||
#define V3D_MANIP_VIEW 3
|
||||
#define V3D_MANIP_GIMBAL 4
|
||||
#define V3D_MANIP_CUSTOM 5 /* anything of value 5 or higher is custom */
|
||||
|
||||
/* View3d->twflag */
|
||||
/* USE = user setting, DRAW = based on selection */
|
||||
#define V3D_USE_MANIPULATOR 1
|
||||
#define V3D_DRAW_MANIPULATOR 2
|
||||
/* #define V3D_CALC_MANIPULATOR 4 */ /*UNUSED*/
|
||||
/* View3d->transform_orientation */
|
||||
enum {
|
||||
V3D_TRANS_ORIENTATION_GLOBAL = 0,
|
||||
V3D_TRANS_ORIENTATION_LOCAL = 1,
|
||||
V3D_TRANS_ORIENTATION_NORMAL = 2,
|
||||
V3D_TRANS_ORIENTATION_VIEW = 3,
|
||||
V3D_TRANS_ORIENTATION_GIMBAL = 4,
|
||||
V3D_TRANS_ORIENTATION_CUSTOM = 5,
|
||||
/* anything of value 5 or higher is custom */
|
||||
};
|
||||
|
||||
/* BGPic->flag */
|
||||
/* may want to use 1 for select ? */
|
||||
|
@@ -149,13 +149,15 @@ static EnumPropertyItem draw_channels_items[] = {
|
||||
};
|
||||
|
||||
static EnumPropertyItem transform_orientation_items[] = {
|
||||
{V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", "Align the transformation axes to world space"},
|
||||
{V3D_MANIP_LOCAL, "LOCAL", 0, "Local", "Align the transformation axes to the selected objects' local space"},
|
||||
{V3D_MANIP_NORMAL, "NORMAL", 0, "Normal",
|
||||
{V3D_TRANS_ORIENTATION_GLOBAL, "GLOBAL", 0, "Global", "Align the transformation axes to world space"},
|
||||
{V3D_TRANS_ORIENTATION_LOCAL, "LOCAL", 0, "Local",
|
||||
"Align the transformation axes to the selected objects' local space"},
|
||||
{V3D_TRANS_ORIENTATION_NORMAL, "NORMAL", 0, "Normal",
|
||||
"Align the transformation axes to average normal of selected elements "
|
||||
"(bone Y axis for pose mode)"},
|
||||
{V3D_MANIP_GIMBAL, "GIMBAL", 0, "Gimbal", "Align each axis to the Euler rotation axis as used for input"},
|
||||
{V3D_MANIP_VIEW, "VIEW", 0, "View", "Align the transformation axes to the window"},
|
||||
{V3D_TRANS_ORIENTATION_GIMBAL, "GIMBAL", 0, "Gimbal",
|
||||
"Align each axis to the Euler rotation axis as used for input"},
|
||||
{V3D_TRANS_ORIENTATION_VIEW, "VIEW", 0, "View", "Align the transformation axes to the window"},
|
||||
// {V3D_MANIP_CUSTOM, "CUSTOM", 0, "Custom", "Use a custom transform orientation"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
@@ -410,11 +412,13 @@ static PointerRNA rna_CurrentOrientation_get(PointerRNA *ptr)
|
||||
Scene *scene = ((bScreen *)ptr->id.data)->scene;
|
||||
View3D *v3d = (View3D *)ptr->data;
|
||||
|
||||
if (v3d->twmode < V3D_MANIP_CUSTOM)
|
||||
if (v3d->transform_orientation < V3D_TRANS_ORIENTATION_CUSTOM)
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_TransformOrientation, NULL);
|
||||
else
|
||||
else {
|
||||
const int ts_idx = v3d->transform_orientation - V3D_TRANS_ORIENTATION_CUSTOM;
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_TransformOrientation,
|
||||
BLI_findlink(&scene->transform_spaces, v3d->twmode - V3D_MANIP_CUSTOM));
|
||||
BLI_findlink(&scene->transform_spaces, ts_idx));
|
||||
}
|
||||
}
|
||||
|
||||
EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
|
||||
@@ -424,7 +428,7 @@ EnumPropertyItem *rna_TransformOrientation_itemf(bContext *C, PointerRNA *ptr, P
|
||||
TransformOrientation *ts = NULL;
|
||||
EnumPropertyItem tmp = {0, "", 0, "", ""};
|
||||
EnumPropertyItem *item = NULL;
|
||||
int i = V3D_MANIP_CUSTOM, totitem = 0;
|
||||
int i = V3D_TRANS_ORIENTATION_CUSTOM, totitem = 0;
|
||||
|
||||
RNA_enum_items_add(&item, &totitem, transform_orientation_items);
|
||||
|
||||
@@ -2649,20 +2653,19 @@ static void rna_def_space_view3d(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_pivot_update");
|
||||
|
||||
prop = RNA_def_property(srna, "show_manipulator", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "twflag", V3D_USE_MANIPULATOR);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_USE_TRANSFORM_MANIPULATORS);
|
||||
RNA_def_property_ui_text(prop, "Manipulator", "Use a 3D manipulator widget for controlling transforms");
|
||||
RNA_def_property_ui_icon(prop, ICON_MANIPUL, 0);
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "transform_manipulators", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "twtype");
|
||||
prop = RNA_def_property(srna, "transform_manipulators_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, manipulators_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_ui_text(prop, "Transform Manipulators", "Transformation manipulators");
|
||||
RNA_def_property_ui_text(prop, "Transform Manipulators", "Type of transformation the transform "
|
||||
"manipulators will represent");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
|
||||
prop = RNA_def_property(srna, "transform_orientation", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "twmode");
|
||||
RNA_def_property_enum_items(prop, transform_orientation_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_TransformOrientation_itemf");
|
||||
RNA_def_property_ui_text(prop, "Transform Orientation", "Transformation orientation");
|
||||
|
@@ -175,10 +175,10 @@ static void rna_userdef_show_manipulator_update(Main *bmain, Scene *scene, Point
|
||||
for (sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
if (sl->spacetype == SPACE_VIEW3D) {
|
||||
View3D *v3d = (View3D *)sl;
|
||||
if (userdef->tw_flag & V3D_USE_MANIPULATOR)
|
||||
v3d->twflag |= V3D_USE_MANIPULATOR;
|
||||
if (userdef->tw_flag & V3D_USE_TRANSFORM_MANIPULATORS)
|
||||
v3d->flag3 |= V3D_USE_TRANSFORM_MANIPULATORS;
|
||||
else
|
||||
v3d->twflag &= ~V3D_USE_MANIPULATOR;
|
||||
v3d->flag3 &= ~V3D_USE_TRANSFORM_MANIPULATORS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3499,7 +3499,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
|
||||
|
||||
/* 3D transform widget */
|
||||
prop = RNA_def_property(srna, "show_manipulator", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "tw_flag", V3D_USE_MANIPULATOR);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "tw_flag", V3D_USE_TRANSFORM_MANIPULATORS);
|
||||
RNA_def_property_ui_text(prop, "Manipulator", "Use 3D transform manipulator");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_show_manipulator_update");
|
||||
|
||||
|
@@ -73,6 +73,10 @@ set(SRC
|
||||
manipulators/intern/wm_manipulator.c
|
||||
manipulators/intern/wm_manipulatorgroup.c
|
||||
manipulators/intern/wm_manipulatormap.c
|
||||
manipulators/intern/manipulator_library/arrow_manipulator.c
|
||||
manipulators/intern/manipulator_library/dial_manipulator.c
|
||||
manipulators/intern/manipulator_library/geom_cone.c
|
||||
manipulators/intern/manipulator_library/geom_cube.c
|
||||
manipulators/intern/manipulator_library/manipulator_library_utils.c
|
||||
|
||||
WM_api.h
|
||||
@@ -87,9 +91,11 @@ set(SRC
|
||||
wm_subwindow.h
|
||||
wm_window.h
|
||||
manipulators/WM_manipulator_api.h
|
||||
manipulators/WM_manipulator_library.h
|
||||
manipulators/WM_manipulator_types.h
|
||||
manipulators/wm_manipulator_wmapi.h
|
||||
manipulators/intern/wm_manipulator_intern.h
|
||||
manipulators/intern/manipulator_library/manipulator_geometry.h
|
||||
manipulators/intern/manipulator_library/manipulator_library_intern.h
|
||||
)
|
||||
|
||||
|
@@ -44,6 +44,7 @@
|
||||
|
||||
/* Include external manipulator API's */
|
||||
#include "manipulators/WM_manipulator_api.h"
|
||||
#include "manipulators/WM_manipulator_library.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@@ -2138,7 +2138,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
|
||||
/* handle user configurable manipulator-map keymap */
|
||||
else if (manipulator) {
|
||||
/* get user customized keymap from default one */
|
||||
const wmManipulatorGroup *highlightgroup = wm_manipulator_get_parent_group(manipulator);
|
||||
const wmManipulatorGroup *highlightgroup = WM_manipulator_get_parent_group(manipulator);
|
||||
const wmKeyMap *keymap = WM_keymap_active(wm, highlightgroup->type->keymap);
|
||||
wmKeyMapItem *kmi;
|
||||
|
||||
|
@@ -58,6 +58,9 @@ void WM_manipulator_delete(
|
||||
|
||||
void WM_manipulator_set_property(struct wmManipulator *, int slot, struct PointerRNA *ptr, const char *propname);
|
||||
struct PointerRNA *WM_manipulator_set_operator(struct wmManipulator *, const char *opname);
|
||||
void WM_manipulator_set_custom_handler(
|
||||
struct wmManipulator *manipulator,
|
||||
int (*handler)(struct bContext *, const struct wmEvent *, struct wmManipulator *, const int));
|
||||
void WM_manipulator_set_func_select(
|
||||
struct wmManipulator *manipulator,
|
||||
void (*select)(struct bContext *, struct wmManipulator *, const int action)); /* wmManipulatorSelectFunc */
|
||||
@@ -67,6 +70,7 @@ void WM_manipulator_set_flag(struct wmManipulator *manipulator, const int flag,
|
||||
void WM_manipulator_set_scale(struct wmManipulator *manipulator, float scale);
|
||||
void WM_manipulator_set_line_width(struct wmManipulator *manipulator, const float line_width);
|
||||
void WM_manipulator_set_colors(struct wmManipulator *manipulator, const float col[4], const float col_hi[4]);
|
||||
struct wmManipulatorGroup *WM_manipulator_get_parent_group(const struct wmManipulator *manipulator);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/windowmanager/manipulators/WM_manipulator_library.h
|
||||
* \ingroup wm
|
||||
*
|
||||
* \name Generic Manipulator Library
|
||||
*
|
||||
* Only included in WM_api.h and lower level files.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __WM_MANIPULATOR_LIBRARY_H__
|
||||
#define __WM_MANIPULATOR_LIBRARY_H__
|
||||
|
||||
struct wmManipulator;
|
||||
struct wmManipulatorGroup;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* 3D Arrow Manipulator */
|
||||
|
||||
enum ArrowManipulatorStyle {
|
||||
MANIPULATOR_ARROW_STYLE_CONE = 0,
|
||||
MANIPULATOR_ARROW_STYLE_CUBE = 1,
|
||||
};
|
||||
|
||||
struct wmManipulator *WM_arrow_manipulator_new(
|
||||
struct wmManipulatorGroup *mgroup, const char *name, const enum ArrowManipulatorStyle style);
|
||||
void WM_arrow_manipulator_set_direction(struct wmManipulator *manipulator, const float direction[3]);
|
||||
void WM_arrow_manipulator_set_length(struct wmManipulator *manipulator, const float length);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Dial Manipulator */
|
||||
|
||||
enum {
|
||||
MANIPULATOR_DIAL_STYLE_RING = 0,
|
||||
MANIPULATOR_DIAL_STYLE_RING_CLIPPED = 1,
|
||||
MANIPULATOR_DIAL_STYLE_RING_FILLED = 2,
|
||||
};
|
||||
|
||||
struct wmManipulator *WM_dial_manipulator_new(struct wmManipulatorGroup *mgroup, const char *name, const int style);
|
||||
void WM_dial_manipulator_set_up_vector(struct wmManipulator *manipulator, const float direction[3]);
|
||||
void WM_dial_manipulator_set_value(struct wmManipulator *manipulator, const double value);
|
||||
|
||||
#endif /* __WM_MANIPULATOR_LIBRARY_H__ */
|
||||
|
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
|
||||
struct bContext;
|
||||
struct wmManipulatorGroupType;
|
||||
struct wmManipulatorGroup;
|
||||
struct wmKeyConfig;
|
||||
|
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/windowmanager/manipulators/intern/manipulator_library/arrow_manipulator.c
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
#include "BIF_gl.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_select.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "manipulator_geometry.h"
|
||||
#include "manipulator_library_intern.h"
|
||||
#include "WM_manipulator_types.h"
|
||||
#include "wm_manipulator_wmapi.h"
|
||||
#include "wm_manipulator_intern.h"
|
||||
#include "WM_manipulator_library.h"
|
||||
|
||||
typedef struct ArrowManipulator {
|
||||
wmManipulator manipulator;
|
||||
|
||||
int style;
|
||||
|
||||
float direction[3];
|
||||
float length;
|
||||
} ArrowManipulator;
|
||||
|
||||
|
||||
static void arrow_draw_line(const ArrowManipulator *arrow, const float col[4], const float len)
|
||||
{
|
||||
VertexFormat *format = immVertexFormat();
|
||||
unsigned int pos = add_attrib(format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(col);
|
||||
|
||||
glLineWidth(arrow->manipulator.line_width);
|
||||
|
||||
immBegin(GL_LINES, 2);
|
||||
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
|
||||
immVertex3f(pos, 0.0f, 0.0f, len);
|
||||
immEnd();
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void arrow_draw_head_cone(const float col[4], const bool select)
|
||||
{
|
||||
const ManipulatorGeometryInfo cone_geo = {
|
||||
_MANIPULATOR_nverts_cone,
|
||||
_MANIPULATOR_ntris_cone,
|
||||
_MANIPULATOR_verts_cone,
|
||||
_MANIPULATOR_normals_cone,
|
||||
_MANIPULATOR_indices_cone,
|
||||
true,
|
||||
};
|
||||
const float scale = 0.25f;
|
||||
|
||||
glColor4fv(col);
|
||||
glScalef(scale, scale, scale);
|
||||
wm_manipulator_geometryinfo_draw(&cone_geo, select);
|
||||
}
|
||||
|
||||
static void arrow_draw_head_cube(const float col[4], const bool select)
|
||||
{
|
||||
const ManipulatorGeometryInfo cone_geo = {
|
||||
_MANIPULATOR_nverts_cube,
|
||||
_MANIPULATOR_ntris_cube,
|
||||
_MANIPULATOR_verts_cube,
|
||||
_MANIPULATOR_normals_cube,
|
||||
_MANIPULATOR_indices_cube,
|
||||
true,
|
||||
};
|
||||
const float scale = 0.05f;
|
||||
|
||||
glColor4fv(col);
|
||||
glScalef(scale, scale, scale);
|
||||
glTranslatef(0.0f, 0.0f, 1.0f); /* Cube origin is at its center, needs this offset to not overlap with line. */
|
||||
wm_manipulator_geometryinfo_draw(&cone_geo, select);
|
||||
}
|
||||
|
||||
static void arrow_draw_head(const ArrowManipulator *arrow, const float col[4], const bool select)
|
||||
{
|
||||
switch (arrow->style) {
|
||||
case MANIPULATOR_ARROW_STYLE_CONE:
|
||||
arrow_draw_head_cone(col, select);
|
||||
break;
|
||||
case MANIPULATOR_ARROW_STYLE_CUBE:
|
||||
arrow_draw_head_cube(col, select);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void arrow_draw_geom(const ArrowManipulator *arrow, const float col[4], const bool select)
|
||||
{
|
||||
const float len = arrow->length;
|
||||
const bool use_lighting = /*select == false && ((U.manipulator_flag & V3D_SHADED_MANIPULATORS) != 0)*/ false;
|
||||
|
||||
glTranslatef(UNPACK3(arrow->manipulator.offset));
|
||||
|
||||
arrow_draw_line(arrow, col, len);
|
||||
|
||||
/* *** draw arrow head *** */
|
||||
|
||||
/* translate to line end */
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0f, 0.0f, len);
|
||||
|
||||
if (use_lighting) {
|
||||
glShadeModel(GL_SMOOTH);
|
||||
}
|
||||
|
||||
arrow_draw_head(arrow, col, select);
|
||||
|
||||
if (use_lighting) {
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void arrow_get_matrix(const ArrowManipulator *arrow, float r_rot[3][3], float r_mat[4][4])
|
||||
{
|
||||
const float up[3] = {0.0f, 0.0f, 1.0f};
|
||||
|
||||
rotation_between_vecs_to_mat3(r_rot, up, arrow->direction);
|
||||
|
||||
copy_m4_m3(r_mat, r_rot);
|
||||
copy_v3_v3(r_mat[3], arrow->manipulator.origin);
|
||||
mul_mat3_m4_fl(r_mat, arrow->manipulator.scale);
|
||||
}
|
||||
|
||||
static void arrow_draw_intern(const ArrowManipulator *arrow, const bool select, const bool highlight)
|
||||
{
|
||||
float col[4];
|
||||
float rot[3][3];
|
||||
float mat[4][4];
|
||||
|
||||
manipulator_color_get(&arrow->manipulator, highlight, col);
|
||||
arrow_get_matrix(arrow, rot, mat);
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf((float *)mat);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
arrow_draw_geom(arrow, col, select);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if (arrow->manipulator.interaction_data) {
|
||||
ManipulatorInteraction *inter = arrow->manipulator.interaction_data;
|
||||
const float ghost_col[] = {0.5f, 0.5f, 0.5f, 0.5f};
|
||||
|
||||
copy_m4_m3(mat, rot);
|
||||
copy_v3_v3(mat[3], inter->init_origin);
|
||||
mul_mat3_m4_fl(mat, inter->init_scale);
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf((float *)mat);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
arrow_draw_geom(arrow, ghost_col, select);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
static void arrow_manipulator_render_3d_intersect(
|
||||
const bContext *UNUSED(C), wmManipulator *manipulator,
|
||||
int selectionbase)
|
||||
{
|
||||
GPU_select_load_id(selectionbase);
|
||||
arrow_draw_intern((ArrowManipulator *)manipulator, true, false);
|
||||
}
|
||||
|
||||
static void arrow_manipulator_draw(const bContext *UNUSED(C), wmManipulator *manipulator)
|
||||
{
|
||||
arrow_draw_intern((ArrowManipulator *)manipulator, false, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0);
|
||||
}
|
||||
|
||||
static int manipulator_arrow_invoke(bContext *UNUSED(C), const wmEvent *UNUSED(event), wmManipulator *manipulator)
|
||||
{
|
||||
ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
|
||||
|
||||
inter->init_scale = manipulator->scale;
|
||||
// manipulator_arrow_get_final_pos(manipulator, inter->init_origin);
|
||||
copy_v3_v3(inter->init_origin, manipulator->origin);
|
||||
|
||||
manipulator->interaction_data = inter;
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Arrow Manipulator API
|
||||
*
|
||||
* \{ */
|
||||
|
||||
wmManipulator *WM_arrow_manipulator_new(
|
||||
wmManipulatorGroup *mgroup, const char *idname, const enum ArrowManipulatorStyle style)
|
||||
{
|
||||
ArrowManipulator *arrow = MEM_callocN(sizeof(*arrow), __func__);
|
||||
|
||||
arrow->manipulator.draw = arrow_manipulator_draw;
|
||||
arrow->manipulator.render_3d_intersection = arrow_manipulator_render_3d_intersect;
|
||||
arrow->manipulator.invoke = manipulator_arrow_invoke;
|
||||
arrow->manipulator.flag |= WM_MANIPULATOR_DRAW_ACTIVE;
|
||||
|
||||
arrow->style = style;
|
||||
arrow->length = 1.0f;
|
||||
|
||||
wm_manipulator_register(mgroup, &arrow->manipulator, idname);
|
||||
|
||||
return &arrow->manipulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define direction the arrow will point towards
|
||||
*/
|
||||
void WM_arrow_manipulator_set_direction(wmManipulator *manipulator, const float direction[3])
|
||||
{
|
||||
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
|
||||
|
||||
copy_v3_v3(arrow->direction, direction);
|
||||
normalize_v3(arrow->direction);
|
||||
}
|
||||
|
||||
void WM_arrow_manipulator_set_length(wmManipulator *manipulator, const float length)
|
||||
{
|
||||
ArrowManipulator *arrow = (ArrowManipulator *)manipulator;
|
||||
|
||||
arrow->length = length;
|
||||
}
|
||||
|
||||
/** \} */ /* Arrow Manipulator API */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void fix_linking_manipulator_arrow(void)
|
||||
{
|
||||
(void)0;
|
||||
}
|
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2014 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): Blender Foundation
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/windowmanager/manipulators/intern/manipulator_library/dial_manipulator.c
|
||||
* \ingroup wm
|
||||
*
|
||||
* \name Dial Manipulator
|
||||
*
|
||||
* 3D Manipulator
|
||||
*
|
||||
* \brief Circle shaped manipulator for circular interaction.
|
||||
* Currently no own handling, use with operator only.
|
||||
*/
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_matrix.h"
|
||||
#include "GPU_select.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
/* own includes */
|
||||
#include "WM_manipulator_types.h"
|
||||
#include "WM_manipulator_library.h"
|
||||
#include "wm_manipulator_wmapi.h"
|
||||
#include "wm_manipulator_intern.h"
|
||||
#include "manipulator_geometry.h"
|
||||
#include "manipulator_library_intern.h"
|
||||
|
||||
|
||||
typedef struct DialManipulator {
|
||||
wmManipulator manipulator;
|
||||
int style;
|
||||
float direction[3];
|
||||
/* will later be converted into angle */
|
||||
double value;
|
||||
} DialManipulator;
|
||||
|
||||
typedef struct DialInteraction {
|
||||
float value_indicator_offset;
|
||||
} DialInteraction;
|
||||
|
||||
#define DIAL_WIDTH 1.0f
|
||||
#define DIAL_RESOLUTION 32
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static void dial_geom_draw(
|
||||
const DialManipulator *dial, const float mat[4][4], const float clipping_plane[4], const float col[4])
|
||||
{
|
||||
const bool is_active = (dial->manipulator.interaction_data != NULL);
|
||||
const bool use_clipping = (dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) && !is_active;
|
||||
const bool filled = (dial->style == MANIPULATOR_DIAL_STYLE_RING_FILLED);
|
||||
const unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
|
||||
|
||||
glLineWidth(dial->manipulator.line_width);
|
||||
|
||||
immBindBuiltinProgram(use_clipping ? GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR : GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(col);
|
||||
|
||||
if (use_clipping) {
|
||||
glEnable(GL_CLIP_DISTANCE0);
|
||||
immUniform4fv("ClipPlane", clipping_plane);
|
||||
immUniformMatrix4fv("ModelMatrix", mat);
|
||||
}
|
||||
|
||||
if (filled) {
|
||||
imm_draw_filled_circle_3D(pos, 0.0f, 0.0f, DIAL_WIDTH, DIAL_RESOLUTION);
|
||||
}
|
||||
else {
|
||||
imm_draw_lined_circle_3D(pos, 0.0f, 0.0f, DIAL_WIDTH, DIAL_RESOLUTION);
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
|
||||
static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float col[4])
|
||||
{
|
||||
const unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(col);
|
||||
|
||||
gpuPushMatrix();
|
||||
gpuRotateAxis(-RAD2DEGF(angle), 'Z');
|
||||
|
||||
immBegin(GL_LINE_STRIP, 2);
|
||||
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
|
||||
immVertex3fv(pos, co_outer);
|
||||
immEnd();
|
||||
|
||||
gpuPopMatrix();
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void dial_ghostarc_draw_inner(const float init_angle_offset, const float angle, const float col[4])
|
||||
{
|
||||
const unsigned int pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 3, KEEP_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4fv(col);
|
||||
/* not entirely sure why the 90 degree offset is needed here and why values have to be negative */
|
||||
imm_draw_filled_arc_3D(pos, -init_angle_offset + (float)M_PI_2, -angle, DIAL_WIDTH, DIAL_RESOLUTION);
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static float manipulator_value_to_angle(const double value)
|
||||
{
|
||||
return (float)(value * M_PI * 2.0);
|
||||
}
|
||||
|
||||
static void dial_geom_value_indicator_draw(
|
||||
const DialManipulator *dial, DialInteraction *inter,
|
||||
const float col_outer[4], const float col_inner[4])
|
||||
{
|
||||
const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */
|
||||
const float angle = manipulator_value_to_angle(dial->value);
|
||||
|
||||
dial_ghostarc_draw_helpline(inter->value_indicator_offset, co_outer, col_outer);
|
||||
dial_ghostarc_draw_helpline(inter->value_indicator_offset + angle, co_outer, col_outer);
|
||||
dial_ghostarc_draw_inner(inter->value_indicator_offset, angle, col_inner);
|
||||
}
|
||||
|
||||
static void dial_clipping_plane_get(DialManipulator *dial, RegionView3D *rv3d, float r_clipping_plane[4])
|
||||
{
|
||||
copy_v3_v3(r_clipping_plane, rv3d->viewinv[2]);
|
||||
r_clipping_plane[3] = -dot_v3v3(rv3d->viewinv[2], dial->manipulator.origin);
|
||||
}
|
||||
|
||||
static void dial_matrix_get(const DialManipulator *dial, float r_mat[4][4])
|
||||
{
|
||||
const float up[3] = {0.0f, 0.0f, 1.0f};
|
||||
float rot[3][3];
|
||||
|
||||
rotation_between_vecs_to_mat3(rot, up, dial->direction);
|
||||
copy_m4_m3(r_mat, rot);
|
||||
copy_v3_v3(r_mat[3], dial->manipulator.origin);
|
||||
mul_mat3_m4_fl(r_mat, dial->manipulator.scale);
|
||||
}
|
||||
|
||||
static void dial_draw_intern(const bContext *C, DialManipulator *dial, const bool highlight)
|
||||
{
|
||||
DialInteraction *inter = dial->manipulator.interaction_data;
|
||||
const bool is_active = (inter != NULL);
|
||||
const bool use_value_indicator = is_active && (dial->manipulator.flag & WM_MANIPULATOR_DRAW_ACTIVE);
|
||||
const bool use_clipping = (dial->style == MANIPULATOR_DIAL_STYLE_RING_CLIPPED) && !is_active;
|
||||
float clipping_plane[4];
|
||||
float mat[4][4];
|
||||
float col[4];
|
||||
|
||||
BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
|
||||
|
||||
/* get all data we need */
|
||||
manipulator_color_get(&dial->manipulator, highlight, col);
|
||||
dial_matrix_get(dial, mat);
|
||||
if (use_clipping) {
|
||||
dial_clipping_plane_get(dial, CTX_wm_region_view3d(C), clipping_plane);
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf((float *)mat);
|
||||
|
||||
if (use_value_indicator) {
|
||||
const float col_inner[] = {0.8f, 0.8f, 0.8f, 0.4f};
|
||||
/* draw rotation indicator arc first */
|
||||
dial_geom_value_indicator_draw(dial, inter, col, col_inner);
|
||||
}
|
||||
/* draw actual dial manipulator */
|
||||
dial_geom_draw(dial, mat, clipping_plane, col);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void manipulator_dial_render_3d_intersect(const bContext *C, wmManipulator *manipulator, int selectionbase)
|
||||
{
|
||||
DialManipulator *dial = (DialManipulator *)manipulator;
|
||||
|
||||
GPU_select_load_id(selectionbase);
|
||||
dial_draw_intern(C, dial, false);
|
||||
}
|
||||
|
||||
static void manipulator_dial_draw(const bContext *C, wmManipulator *manipulator)
|
||||
{
|
||||
DialManipulator *dial = (DialManipulator *)manipulator;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
dial_draw_intern(C, dial, (manipulator->state & WM_MANIPULATOR_HIGHLIGHT) != 0);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function calculates the angle between the current mouse coordinate \a mval and the default
|
||||
* starting coordinate of the value indicator arc (projected onto the 2d viewing plane). The resulting
|
||||
* angle is used to offset the value indicator arc so that it starts where the user starts dragging.
|
||||
*
|
||||
* Not sure yet if this is only useful for rotation manipulators or for other dial manipulators
|
||||
* as well. Might consider moving it to view3d_transform_manipulators.c if not.
|
||||
*/
|
||||
static float manipulator_init_angle_offset_get(
|
||||
const DialManipulator *dial, const ARegion *ar,
|
||||
const float mat[4][4], const float mval[2])
|
||||
{
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
/* model-space coordinate at which the arc drawing will be started (converted to world-space later) */
|
||||
float co_outer[3] = {0.0f, DIAL_WIDTH, 0.0f};
|
||||
float origin_2d[2], co_outer_2d[2], rel_mval[2], rel_co_outer_2d[2];
|
||||
bool inv = false;
|
||||
|
||||
/* we might need to invert the direction of the angles */
|
||||
float view_vec[3], axis_vec[3];
|
||||
ED_view3d_global_to_vector(rv3d, mat[3], view_vec);
|
||||
normalize_v3_v3(axis_vec, dial->direction);
|
||||
if (dot_v3v3(view_vec, axis_vec) < 0.0f) {
|
||||
inv = true;
|
||||
}
|
||||
|
||||
/* convert to world-space */
|
||||
mul_m4_v3(mat, co_outer);
|
||||
|
||||
/* project origin and starting coordinate of arc onto 2D view plane */
|
||||
ED_view3d_project_float_global(ar, mat[3], origin_2d, V3D_PROJ_TEST_NOP);
|
||||
ED_view3d_project_float_global(ar, co_outer, co_outer_2d, V3D_PROJ_TEST_NOP);
|
||||
|
||||
/* convert to origin relative space */
|
||||
sub_v2_v2v2(rel_mval, mval, origin_2d);
|
||||
sub_v2_v2v2(rel_co_outer_2d, co_outer_2d, origin_2d);
|
||||
|
||||
/* return angle between co_outer_2d and mval around origin */
|
||||
return angle_signed_v2v2(rel_co_outer_2d, rel_mval) * (inv ? -1 : 1);
|
||||
}
|
||||
|
||||
static int manipulator_dial_invoke(bContext *C, const wmEvent *event, wmManipulator *manipulator)
|
||||
{
|
||||
if (manipulator->flag & WM_MANIPULATOR_DRAW_ACTIVE) {
|
||||
const ARegion *ar = CTX_wm_region(C);
|
||||
const DialManipulator *dial = (DialManipulator *)manipulator;
|
||||
const float mval[2] = {event->mval[0], event->mval[1]};
|
||||
DialInteraction *inter = MEM_callocN(sizeof(DialInteraction), __func__);
|
||||
float mat[4][4];
|
||||
|
||||
dial_matrix_get(dial, mat);
|
||||
inter->value_indicator_offset = manipulator_init_angle_offset_get(dial, ar, mat, mval);
|
||||
|
||||
manipulator->interaction_data = inter;
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Dial Manipulator API
|
||||
*
|
||||
* \{ */
|
||||
|
||||
wmManipulator *WM_dial_manipulator_new(wmManipulatorGroup *mgroup, const char *name, const int style)
|
||||
{
|
||||
DialManipulator *dial = MEM_callocN(sizeof(DialManipulator), name);
|
||||
const float dir_default[3] = {0.0f, 0.0f, 1.0f};
|
||||
|
||||
dial->manipulator.draw = manipulator_dial_draw;
|
||||
dial->manipulator.render_3d_intersection = manipulator_dial_render_3d_intersect;
|
||||
dial->manipulator.invoke = manipulator_dial_invoke;
|
||||
|
||||
dial->style = style;
|
||||
|
||||
/* defaults */
|
||||
copy_v3_v3(dial->direction, dir_default);
|
||||
|
||||
wm_manipulator_register(mgroup, &dial->manipulator, name);
|
||||
|
||||
return (wmManipulator *)dial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define up-direction of the dial manipulator
|
||||
*/
|
||||
void WM_dial_manipulator_set_up_vector(wmManipulator *manipulator, const float direction[3])
|
||||
{
|
||||
DialManipulator *dial = (DialManipulator *)manipulator;
|
||||
|
||||
copy_v3_v3(dial->direction, direction);
|
||||
normalize_v3(dial->direction);
|
||||
}
|
||||
|
||||
void WM_dial_manipulator_set_value(wmManipulator *manipulator, const double value)
|
||||
{
|
||||
DialManipulator *dial = (DialManipulator *)manipulator;
|
||||
dial->value = value;
|
||||
}
|
||||
|
||||
/** \} */ // Dial Manipulator API
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void fix_linking_manipulator_dial(void)
|
||||
{
|
||||
(void)0;
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_cone.c
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
int _MANIPULATOR_nverts_cone = 10;
|
||||
int _MANIPULATOR_ntris_cone = 16;
|
||||
|
||||
float _MANIPULATOR_verts_cone[][3] = {
|
||||
{0.000000, 0.000000, 0.000000},
|
||||
{0.000000, 0.000000, 1.000000},
|
||||
{0.000000, 0.270000, 0.000000},
|
||||
{0.190919, 0.190919, 0.000000},
|
||||
{0.270000, -0.000000, 0.000000},
|
||||
{0.190919, -0.190919, 0.000000},
|
||||
{-0.000000, -0.270000, 0.000000},
|
||||
{-0.190919, -0.190919, 0.000000},
|
||||
{-0.270000, 0.000000, 0.000000},
|
||||
{-0.190919, 0.190919, 0.000000},
|
||||
};
|
||||
|
||||
float _MANIPULATOR_normals_cone[][3] = {
|
||||
{0.000000, 0.000000, -1.000000},
|
||||
{0.000000, 0.000000, 0.999969},
|
||||
{0.000000, 0.848567, -0.529069},
|
||||
{0.600024, 0.600024, -0.529069},
|
||||
{0.848567, 0.000000, -0.529069},
|
||||
{0.600024, -0.600024, -0.529069},
|
||||
{0.000000, -0.848567, -0.529069},
|
||||
{-0.600024, -0.600024, -0.529069},
|
||||
{-0.848567, 0.000000, -0.529069},
|
||||
{-0.600024, 0.600024, -0.529069},
|
||||
};
|
||||
|
||||
unsigned short _MANIPULATOR_indices_cone[] = {
|
||||
0, 2, 3,
|
||||
2, 1, 3,
|
||||
0, 3, 4,
|
||||
3, 1, 4,
|
||||
0, 4, 5,
|
||||
4, 1, 5,
|
||||
0, 5, 6,
|
||||
5, 1, 6,
|
||||
0, 6, 7,
|
||||
6, 1, 7,
|
||||
0, 7, 8,
|
||||
7, 1, 8,
|
||||
0, 8, 9,
|
||||
8, 1, 9,
|
||||
0, 9, 2,
|
||||
9, 1, 2,
|
||||
};
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/windowmanager/manipulators/intern/manipulator_library/geom_cube.c
|
||||
* \ingroup wm
|
||||
*/
|
||||
|
||||
int _MANIPULATOR_nverts_cube = 8;
|
||||
int _MANIPULATOR_ntris_cube = 12;
|
||||
|
||||
float _MANIPULATOR_verts_cube[][3] = {
|
||||
{1.000000, 1.000000, -1.000000},
|
||||
{1.000000, -1.000000, -1.000000},
|
||||
{-1.000000, -1.000000, -1.000000},
|
||||
{-1.000000, 1.000000, -1.000000},
|
||||
{1.000000, 1.000000, 1.000000},
|
||||
{0.999999, -1.000001, 1.000000},
|
||||
{-1.000000, -1.000000, 1.000000},
|
||||
{-1.000000, 1.000000, 1.000000},
|
||||
};
|
||||
|
||||
float _MANIPULATOR_normals_cube[][3] = {
|
||||
{0.577349, 0.577349, -0.577349},
|
||||
{0.577349, -0.577349, -0.577349},
|
||||
{-0.577349, -0.577349, -0.577349},
|
||||
{-0.577349, 0.577349, -0.577349},
|
||||
{0.577349, 0.577349, 0.577349},
|
||||
{0.577349, -0.577349, 0.577349},
|
||||
{-0.577349, -0.577349, 0.577349},
|
||||
{-0.577349, 0.577349, 0.577349},
|
||||
};
|
||||
|
||||
unsigned short _MANIPULATOR_indices_cube[] = {
|
||||
1, 2, 3,
|
||||
7, 6, 5,
|
||||
4, 5, 1,
|
||||
5, 6, 2,
|
||||
2, 6, 7,
|
||||
0, 3, 7,
|
||||
0, 1, 3,
|
||||
4, 7, 5,
|
||||
0, 4, 1,
|
||||
1, 5, 2,
|
||||
3, 2, 7,
|
||||
4, 0, 7,
|
||||
};
|
||||
|
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2016 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/windowmanager/manipulators/intern/manipulator_library/manipulator_geometry.h
|
||||
* \ingroup wm
|
||||
*
|
||||
* \name Manipulator Geometry
|
||||
*
|
||||
* \brief Prototypes for arrays defining the manipulator geometry. The actual definitions can be found in files usually
|
||||
* called geom_xxx.c
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __MANIPULATOR_GEOMETRY_H__
|
||||
#define __MANIPULATOR_GEOMETRY_H__
|
||||
|
||||
|
||||
/* cone */
|
||||
|
||||
extern int _MANIPULATOR_nverts_cone;
|
||||
extern int _MANIPULATOR_ntris_cone;
|
||||
|
||||
extern float _MANIPULATOR_verts_cone[][3];
|
||||
extern float _MANIPULATOR_normals_cone[][3];
|
||||
extern unsigned short _MANIPULATOR_indices_cone[];
|
||||
|
||||
|
||||
/* cube */
|
||||
|
||||
extern int _MANIPULATOR_nverts_cube;
|
||||
extern int _MANIPULATOR_ntris_cube;
|
||||
|
||||
extern float _MANIPULATOR_verts_cube[][3];
|
||||
extern float _MANIPULATOR_normals_cube[][3];
|
||||
extern unsigned short _MANIPULATOR_indices_cube[];
|
||||
|
||||
#endif /* __MANIPULATOR_GEOMETRY_H__ */
|
||||
|
@@ -31,6 +31,25 @@
|
||||
#ifndef __MANIPULATOR_LIBRARY_INTERN_H__
|
||||
#define __MANIPULATOR_LIBRARY_INTERN_H__
|
||||
|
||||
struct wmManipulator;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Manipulator drawing */
|
||||
|
||||
typedef struct ManipulatorGeometryInfo {
|
||||
int nverts;
|
||||
int ntris;
|
||||
float (*verts)[3];
|
||||
float (*normals)[3];
|
||||
unsigned short *indices;
|
||||
bool init;
|
||||
} ManipulatorGeometryInfo;
|
||||
|
||||
void wm_manipulator_geometryinfo_draw(const ManipulatorGeometryInfo *info, const bool select);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Manipulator handling */
|
||||
|
||||
/* distance around which manipulators respond to input (and get highlighted) */
|
||||
#define MANIPULATOR_HOTSPOT 14.0f
|
||||
|
||||
@@ -77,23 +96,23 @@ float manipulator_value_from_offset(
|
||||
const bool constrained, const bool inverted, const bool use_precision);
|
||||
|
||||
void manipulator_property_data_update(
|
||||
wmManipulator *manipulator, ManipulatorCommonData *data, const int slot,
|
||||
struct wmManipulator *manipulator, ManipulatorCommonData *data, const int slot,
|
||||
const bool constrained, const bool inverted);
|
||||
|
||||
void manipulator_property_value_set(
|
||||
bContext *C, const wmManipulator *manipulator,
|
||||
bContext *C, const struct wmManipulator *manipulator,
|
||||
const int slot, const float value);
|
||||
float manipulator_property_value_get(
|
||||
const wmManipulator *manipulator, const int slot);
|
||||
const struct wmManipulator *manipulator, const int slot);
|
||||
void manipulator_property_value_reset(
|
||||
bContext *C, const wmManipulator *manipulator, ManipulatorInteraction *inter,
|
||||
bContext *C, const struct wmManipulator *manipulator, ManipulatorInteraction *inter,
|
||||
const int slot);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void manipulator_color_get(
|
||||
const wmManipulator *manipulator, const bool highlight,
|
||||
const struct wmManipulator *manipulator, const bool highlight,
|
||||
float r_col[]);
|
||||
|
||||
#endif /* __MANIPULATOR_LIBRARY_INTERN_H__ */
|
||||
|
@@ -31,6 +31,8 @@
|
||||
* \brief This file contains functions for common behaviors of manipulators.
|
||||
*/
|
||||
|
||||
#include "BIF_gl.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
@@ -48,6 +50,49 @@
|
||||
/* factor for precision tweaking */
|
||||
#define MANIPULATOR_PRECISION_FAC 0.05f
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Manipulator drawing */
|
||||
|
||||
/**
|
||||
* Main draw call for ManipulatorGeometryInfo data.
|
||||
*/
|
||||
void wm_manipulator_geometryinfo_draw(const ManipulatorGeometryInfo *info, const bool UNUSED(select))
|
||||
{
|
||||
GLuint buf[2];
|
||||
|
||||
glGenBuffers(2, buf);
|
||||
|
||||
/* vertex buffer */
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buf[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * info->nverts, info->verts, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||
|
||||
/* normal buffer */
|
||||
/* TODO normal buffer for lighting (if we need this?) */
|
||||
|
||||
/* index buffer */
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * (3 * info->ntris), info->indices, GL_STATIC_DRAW);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
// glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, info->ntris * 3, GL_UNSIGNED_SHORT, NULL);
|
||||
|
||||
// glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDeleteBuffers(2, buf);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Manipulator handling */
|
||||
|
||||
BLI_INLINE float manipulator_offset_from_value_constr(
|
||||
const float range_fac, const float min, const float range, const float value,
|
||||
|
@@ -66,10 +66,10 @@ wmManipulator *WM_manipulator_new(
|
||||
manipulator->render_3d_intersection = render_3d_intersection;
|
||||
|
||||
/* XXX */
|
||||
// fix_linking_manipulator_arrow();
|
||||
fix_linking_manipulator_arrow();
|
||||
// fix_linking_manipulator_arrow2d();
|
||||
// fix_linking_manipulator_cage();
|
||||
// fix_linking_manipulator_dial();
|
||||
fix_linking_manipulator_dial();
|
||||
// fix_linking_manipulator_facemap();
|
||||
// fix_linking_manipulator_primitive();
|
||||
|
||||
@@ -157,7 +157,7 @@ void WM_manipulator_delete(ListBase *manipulatorlist, wmManipulatorMap *mmap, wm
|
||||
MEM_freeN(manipulator);
|
||||
}
|
||||
|
||||
wmManipulatorGroup *wm_manipulator_get_parent_group(const wmManipulator *manipulator)
|
||||
wmManipulatorGroup *WM_manipulator_get_parent_group(const wmManipulator *manipulator)
|
||||
{
|
||||
return manipulator->mgroup;
|
||||
}
|
||||
@@ -207,6 +207,13 @@ PointerRNA *WM_manipulator_set_operator(wmManipulator *manipulator, const char *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void WM_manipulator_set_custom_handler(
|
||||
wmManipulator *manipulator,
|
||||
int (*handler)(bContext *, const wmEvent *, wmManipulator *, const int))
|
||||
{
|
||||
manipulator->handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set manipulator select callback.
|
||||
*
|
||||
|
@@ -128,10 +128,10 @@ enum {
|
||||
void wm_manipulator_register(struct wmManipulatorGroup *mgroup, struct wmManipulator *manipulator, const char *name);
|
||||
|
||||
bool wm_manipulator_deselect(struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
|
||||
bool wm_manipulator_select(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
|
||||
bool wm_manipulator_select(struct bContext *C, struct wmManipulatorMap *mmap, struct wmManipulator *manipulator);
|
||||
|
||||
void wm_manipulator_calculate_scale(struct wmManipulator *manipulator, const bContext *C);
|
||||
void wm_manipulator_update(struct wmManipulator *manipulator, const bContext *C, const bool refresh_map);
|
||||
void wm_manipulator_calculate_scale(struct wmManipulator *manipulator, const struct bContext *C);
|
||||
void wm_manipulator_update(struct wmManipulator *manipulator, const struct bContext *C, const bool refresh_map);
|
||||
bool wm_manipulator_is_visible(struct wmManipulator *manipulator);
|
||||
|
||||
void fix_linking_manipulator_arrow(void);
|
||||
@@ -153,7 +153,7 @@ enum {
|
||||
};
|
||||
|
||||
struct wmManipulatorGroup *wm_manipulatorgroup_new_from_type(struct wmManipulatorGroupType *mgrouptype);
|
||||
void wm_manipulatorgroup_free(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulatorGroup *mgroup);
|
||||
void wm_manipulatorgroup_free(struct bContext *C, struct wmManipulatorMap *mmap, struct wmManipulatorGroup *mgroup);
|
||||
void wm_manipulatorgroup_manipulator_register(struct wmManipulatorGroup *mgroup, wmManipulator *manipulator);
|
||||
wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
|
||||
const struct wmManipulatorGroup *mgroup, struct bContext *C, const struct wmEvent *event,
|
||||
@@ -213,18 +213,5 @@ struct wmManipulatorMapType {
|
||||
void wm_manipulatormap_selected_delete(wmManipulatorMap *mmap);
|
||||
bool wm_manipulatormap_deselect_all(struct wmManipulatorMap *mmap, wmManipulator ***sel);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Manipulator drawing */
|
||||
|
||||
typedef struct ManipulatorGeometryInfo {
|
||||
int nverts;
|
||||
int ntris;
|
||||
float (*verts)[3];
|
||||
float (*normals)[3];
|
||||
unsigned short *indices;
|
||||
bool init;
|
||||
} ManipulatorGeometryInfo;
|
||||
|
||||
#endif /* __WM_MANIPULATOR_INTERN_H__ */
|
||||
|
||||
|
@@ -628,7 +628,7 @@ void wm_manipulatormap_set_active_manipulator(
|
||||
|
||||
if (ot) {
|
||||
/* first activate the manipulator itself */
|
||||
if (manipulator->invoke && manipulator->handler) {
|
||||
if (manipulator->invoke) {
|
||||
manipulator->invoke(C, event, manipulator);
|
||||
}
|
||||
|
||||
@@ -652,7 +652,7 @@ void wm_manipulatormap_set_active_manipulator(
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (manipulator->invoke && manipulator->handler) {
|
||||
if (manipulator->invoke) {
|
||||
manipulator->invoke(C, event, manipulator);
|
||||
}
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#ifndef __WM_MANIPULATOR_WMAPI_H__
|
||||
#define __WM_MANIPULATOR_WMAPI_H__
|
||||
|
||||
struct wmEvent;
|
||||
struct wmEventHandler;
|
||||
struct wmManipulatorMap;
|
||||
struct wmOperatorType;
|
||||
@@ -49,8 +50,6 @@ struct wmOperator;
|
||||
|
||||
typedef void (*wmManipulatorSelectFunc)(struct bContext *, struct wmManipulator *, const int);
|
||||
|
||||
struct wmManipulatorGroup *wm_manipulator_get_parent_group(const struct wmManipulator *manipulator);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* wmManipulatorGroup */
|
||||
|
||||
@@ -70,19 +69,19 @@ void wm_manipulatormaptypes_free(void);
|
||||
void wm_manipulators_keymap(struct wmKeyConfig *keyconf);
|
||||
|
||||
void wm_manipulatormaps_handled_modal_update(
|
||||
bContext *C, struct wmEvent *event, struct wmEventHandler *handler,
|
||||
struct bContext *C, struct wmEvent *event, struct wmEventHandler *handler,
|
||||
const struct wmOperatorType *ot);
|
||||
void wm_manipulatormap_handler_context(bContext *C, struct wmEventHandler *handler);
|
||||
void wm_manipulatormap_handler_context(struct bContext *C, struct wmEventHandler *handler);
|
||||
|
||||
struct wmManipulator *wm_manipulatormap_find_highlighted_manipulator(
|
||||
struct wmManipulatorMap *mmap, bContext *C,
|
||||
struct wmManipulatorMap *mmap, struct bContext *C,
|
||||
const struct wmEvent *event, unsigned char *part);
|
||||
void wm_manipulatormap_set_highlighted_manipulator(
|
||||
struct wmManipulatorMap *mmap, const bContext *C,
|
||||
struct wmManipulatorMap *mmap, const struct bContext *C,
|
||||
struct wmManipulator *manipulator, unsigned char part);
|
||||
struct wmManipulator *wm_manipulatormap_get_highlighted_manipulator(struct wmManipulatorMap *mmap);
|
||||
void wm_manipulatormap_set_active_manipulator(
|
||||
struct wmManipulatorMap *mmap, bContext *C,
|
||||
struct wmManipulatorMap *mmap, struct bContext *C,
|
||||
const struct wmEvent *event, struct wmManipulator *manipulator);
|
||||
struct wmManipulator *wm_manipulatormap_get_active_manipulator(struct wmManipulatorMap *mmap);
|
||||
|
||||
|
@@ -736,6 +736,7 @@ int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title,
|
||||
|
||||
/* RNA COLLADA dependency */
|
||||
int collada_export(struct Scene *sce,
|
||||
struct SceneLayer *scene_layer,
|
||||
const char *filepath,
|
||||
int apply_modifiers,
|
||||
BC_export_mesh_type export_mesh_type,
|
||||
|
Reference in New Issue
Block a user