forked from bartvdbraak/blender
== Radial Control ==
* Generalized the interactive brush property control from sculpt mode into a simple API * Modified sculpt mode to take advantage of this (even fixes some minor bugs!) * Added shortcuts in particle edit to set brush size/strength (FKEY/shift+FKEY) Still todo are the other modes that have brushes...
This commit is contained in:
parent
f41c3340be
commit
c6118036bc
@ -31,30 +31,11 @@
|
||||
#define BKE_SCULPT_H
|
||||
|
||||
struct NumInput;
|
||||
struct RadialControl;
|
||||
struct Scene;
|
||||
struct SculptData;
|
||||
struct SculptSession;
|
||||
|
||||
typedef enum PropsetMode {
|
||||
PropsetNone = 0,
|
||||
PropsetSize,
|
||||
PropsetStrength,
|
||||
PropsetTexRot
|
||||
} PropsetMode;
|
||||
|
||||
typedef struct PropsetData {
|
||||
PropsetMode mode;
|
||||
unsigned int tex;
|
||||
short origloc[2];
|
||||
float *texdata;
|
||||
|
||||
short origsize;
|
||||
char origstrength;
|
||||
float origtexrot;
|
||||
|
||||
struct NumInput *num;
|
||||
} PropsetData;
|
||||
|
||||
typedef struct SculptSession {
|
||||
struct ProjVert *projverts;
|
||||
|
||||
@ -76,7 +57,7 @@ typedef struct SculptSession {
|
||||
/* Used to cache the render of the active texture */
|
||||
unsigned int texcache_w, texcache_h, *texcache;
|
||||
|
||||
struct PropsetData *propset;
|
||||
struct RadialControl *radialcontrol;
|
||||
|
||||
/* For rotating around a pivot point */
|
||||
vec3f pivot;
|
||||
|
@ -661,13 +661,8 @@ void sculptsession_free(Scene *sce)
|
||||
if(ss->mats)
|
||||
MEM_freeN(ss->mats);
|
||||
|
||||
if(ss->propset) {
|
||||
if(ss->propset->texdata)
|
||||
MEM_freeN(ss->propset->texdata);
|
||||
if(ss->propset->num)
|
||||
MEM_freeN(ss->propset->num);
|
||||
MEM_freeN(ss->propset);
|
||||
}
|
||||
if(ss->radialcontrol)
|
||||
MEM_freeN(ss->radialcontrol);
|
||||
|
||||
sculpt_vertexusers_free(ss);
|
||||
if(ss->texcache)
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_vec_types.h"
|
||||
#include "BKE_sculpt.h"
|
||||
#include "transform.h"
|
||||
|
||||
struct uiBlock;
|
||||
struct BrushData;
|
||||
@ -59,15 +58,13 @@ void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, un
|
||||
void sculptmode_draw_interface_brush(struct uiBlock *block,unsigned short cx, unsigned short cy);
|
||||
void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx, unsigned short cy);
|
||||
void sculptmode_rem_tex(void*,void*);
|
||||
void sculptmode_propset_init(PropsetMode mode);
|
||||
void sculptmode_propset(const unsigned short event);
|
||||
void sculptmode_selectbrush_menu(void);
|
||||
void sculptmode_draw_mesh(int);
|
||||
void sculpt_paint_brush(char clear);
|
||||
void sculpt_stroke_draw();
|
||||
void sculpt_radialcontrol_start(int mode);
|
||||
|
||||
struct BrushData *sculptmode_brush(void);
|
||||
float tex_angle(void);
|
||||
void do_symmetrical_brush_actions(struct EditData *e, short *, short *);
|
||||
|
||||
void sculptmode_update_tex(void);
|
||||
|
@ -38,6 +38,7 @@
|
||||
struct Object;
|
||||
struct ParticleSystem;
|
||||
struct ParticleEditSettings;
|
||||
struct RadialControl;
|
||||
|
||||
/* particle edit mode */
|
||||
void PE_set_particle_edit(void);
|
||||
@ -53,6 +54,7 @@ short PE_get_current_num(struct Object *ob);
|
||||
int PE_minmax(float *min, float *max);
|
||||
void PE_get_colors(char sel[4], char nosel[4]);
|
||||
struct ParticleEditSettings *PE_settings(void);
|
||||
struct RadialControl **PE_radialcontrol();
|
||||
|
||||
/* update calls */
|
||||
void PE_hide_keys_time(struct ParticleSystem *psys, float cfra);
|
||||
@ -83,6 +85,7 @@ void PE_remove_doubles(void);
|
||||
void PE_mirror_x(int tagged);
|
||||
void PE_selectbrush_menu(void);
|
||||
void PE_remove_doubles(void);
|
||||
void PE_radialcontrol_start(const int mode);
|
||||
|
||||
/* undo */
|
||||
void PE_undo_push(char *str);
|
||||
|
62
source/blender/include/BIF_radialcontrol.h
Normal file
62
source/blender/include/BIF_radialcontrol.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* $Id: multires.h 13015 2007-12-27 07:27:03Z nicholasbishop $
|
||||
*
|
||||
* ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008 by Nicholas Bishop
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef RADIALCONTROL_H
|
||||
#define RADIALCONTROL_H
|
||||
|
||||
struct NumInput;
|
||||
|
||||
#define RADIALCONTROL_NONE 0
|
||||
#define RADIALCONTROL_SIZE 1
|
||||
#define RADIALCONTROL_STRENGTH 2
|
||||
#define RADIALCONTROL_ROTATION 3
|
||||
|
||||
typedef void (*RadialControlCallback)(const int, const int);
|
||||
|
||||
typedef struct RadialControl {
|
||||
int mode;
|
||||
short origloc[2];
|
||||
|
||||
unsigned int tex;
|
||||
|
||||
int new_value;
|
||||
int original_value;
|
||||
int max_value;
|
||||
RadialControlCallback callback;
|
||||
|
||||
struct NumInput *num;
|
||||
} RadialControl;
|
||||
|
||||
RadialControl *radialcontrol_start(const int mode, RadialControlCallback callback,
|
||||
const int original_value, const int max_value,
|
||||
const unsigned int tex);
|
||||
void radialcontrol_do_events(RadialControl *rc, const unsigned short event);
|
||||
void radialcontrol_draw(RadialControl *rc);
|
||||
|
||||
#endif
|
@ -125,6 +125,7 @@
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_previewrender.h"
|
||||
#include "BIF_radialcontrol.h"
|
||||
#include "BIF_resources.h"
|
||||
#include "BIF_retopo.h"
|
||||
#include "BIF_screen.h"
|
||||
@ -3061,68 +3062,13 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
|
||||
|
||||
/* Draw Sculpt Mode brush */
|
||||
if(!G.obedit && (G.f & G_SCULPTMODE) && area_is_active_area(v3d->area) && sculpt_session()) {
|
||||
PropsetData *pd= sculpt_session()->propset;
|
||||
short r1=100, r2=100, r3=100;
|
||||
short mouse[2];
|
||||
RadialControl *rc= sculpt_session()->radialcontrol;
|
||||
|
||||
if(sculpt_data()->flags & SCULPT_INPUT_SMOOTH)
|
||||
sculpt_stroke_draw();
|
||||
|
||||
if(pd) {
|
||||
if(pd->mode == PropsetSize) {
|
||||
r1= sculptmode_brush()->size;
|
||||
r2= pd->origsize;
|
||||
r3= r1;
|
||||
} else if(pd->mode == PropsetStrength) {
|
||||
r1= 200 - sculptmode_brush()->strength * 2;
|
||||
r2= 200;
|
||||
r3= 200;
|
||||
} else if(pd->mode == PropsetTexRot) {
|
||||
r1= r2= 200;
|
||||
r3= 200;
|
||||
}
|
||||
|
||||
/* Draw brush with texture */
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, pd->tex);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(pd->origloc[0], pd->origloc[1], 0);
|
||||
glRotatef(tex_angle(), 0, 0, 1);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(0,0,0,1);
|
||||
glTexCoord2f(0,0);
|
||||
glVertex2f(-r3, -r3);
|
||||
glTexCoord2f(1,0);
|
||||
glVertex2f(r3, -r3);
|
||||
glTexCoord2f(1,1);
|
||||
glVertex2f(r3, r3);
|
||||
glTexCoord2f(0,1);
|
||||
glVertex2f(-r3, r3);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if(r1 != r2)
|
||||
fdrawXORcirc(pd->origloc[0], pd->origloc[1], r1);
|
||||
fdrawXORcirc(pd->origloc[0], pd->origloc[1], r2);
|
||||
|
||||
if(pd->mode == PropsetTexRot) {
|
||||
const float ang= pd->origtexrot * (M_PI/180.0f);
|
||||
getmouseco_areawin(mouse);
|
||||
sdrawXORline(pd->origloc[0], pd->origloc[1],
|
||||
pd->origloc[0]+200*cos(ang), pd->origloc[1]+200*sin(ang));
|
||||
sdrawXORline(pd->origloc[0], pd->origloc[1], mouse[0], mouse[1]);
|
||||
}
|
||||
}
|
||||
if(rc)
|
||||
radialcontrol_draw(rc);
|
||||
else if(sculpt_data()->flags & SCULPT_DRAW_BRUSH) {
|
||||
short csc[2], car[2];
|
||||
getmouseco_sc(csc);
|
||||
@ -3143,7 +3089,9 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
|
||||
ParticleEditSettings *pset = PE_settings();
|
||||
|
||||
short c[2];
|
||||
if(psys && psys->edit && pset->brushtype>=0){
|
||||
if(*PE_radialcontrol())
|
||||
radialcontrol_draw(*PE_radialcontrol());
|
||||
else if(psys && psys->edit && pset->brushtype>=0) {
|
||||
getmouseco_areawin(c);
|
||||
fdrawXORcirc((float)c[0], (float)c[1], (float)pset->brush[pset->brushtype].size);
|
||||
}
|
||||
|
@ -80,6 +80,7 @@
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_meshtools.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_radialcontrol.h"
|
||||
#include "BIF_resources.h"
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
@ -1989,6 +1990,46 @@ void PE_remove_doubles(void)
|
||||
BIF_undo_push("Remove double particles");
|
||||
}
|
||||
|
||||
static void PE_radialcontrol_callback(const int mode, const int val)
|
||||
{
|
||||
ParticleEditSettings *pset = PE_settings();
|
||||
|
||||
if(pset->brushtype>=0) {
|
||||
ParticleBrushData *brush= &pset->brush[pset->brushtype];
|
||||
|
||||
if(mode == RADIALCONTROL_SIZE)
|
||||
brush->size = val;
|
||||
else if(mode == RADIALCONTROL_STRENGTH)
|
||||
brush->strength = val;
|
||||
}
|
||||
|
||||
(*PE_radialcontrol()) = NULL;
|
||||
}
|
||||
|
||||
RadialControl **PE_radialcontrol()
|
||||
{
|
||||
static RadialControl *rc = NULL;
|
||||
return &rc;
|
||||
}
|
||||
|
||||
void PE_radialcontrol_start(const int mode)
|
||||
{
|
||||
ParticleEditSettings *pset = PE_settings();
|
||||
int orig;
|
||||
|
||||
if(pset->brushtype>=0) {
|
||||
ParticleBrushData *brush= &pset->brush[pset->brushtype];
|
||||
|
||||
if(mode == RADIALCONTROL_SIZE)
|
||||
orig = brush->size;
|
||||
else if(mode == RADIALCONTROL_STRENGTH)
|
||||
orig = brush->strength;
|
||||
|
||||
if(mode != RADIALCONTROL_NONE)
|
||||
(*PE_radialcontrol())= radialcontrol_start(mode, PE_radialcontrol_callback, orig, 100, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Edit Brushes */
|
||||
/************************************************/
|
||||
|
@ -113,6 +113,7 @@
|
||||
#include "BIF_meshtools.h"
|
||||
#include "BIF_poselib.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_radialcontrol.h"
|
||||
#include "BIF_renderwin.h"
|
||||
#include "BIF_resources.h"
|
||||
#include "BIF_retopo.h"
|
||||
@ -4402,6 +4403,7 @@ void do_view3d_sculptmenu(void *arg, int event)
|
||||
{
|
||||
SculptData *sd= &G.scene->sculptdata;
|
||||
BrushData *br= sculptmode_brush();
|
||||
|
||||
switch(event) {
|
||||
case 0:
|
||||
case 1:
|
||||
@ -4445,13 +4447,13 @@ void do_view3d_sculptmenu(void *arg, int event)
|
||||
add_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_UNSTOW);
|
||||
break;
|
||||
case 15:
|
||||
sculptmode_propset_init(PropsetTexRot);
|
||||
sculpt_radialcontrol_start(RADIALCONTROL_ROTATION);
|
||||
break;
|
||||
case 16:
|
||||
sculptmode_propset_init(PropsetStrength);
|
||||
sculpt_radialcontrol_start(RADIALCONTROL_STRENGTH);
|
||||
break;
|
||||
case 17:
|
||||
sculptmode_propset_init(PropsetSize);
|
||||
sculpt_radialcontrol_start(RADIALCONTROL_SIZE);
|
||||
break;
|
||||
case 18:
|
||||
br->dir= br->dir==1 ? 2 : 1;
|
||||
|
266
source/blender/src/radialcontrol.c
Normal file
266
source/blender/src/radialcontrol.c
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* $Id: multires.c 13015 2007-12-27 07:27:03Z nicholasbishop $
|
||||
*
|
||||
* ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2006 by Nicholas Bishop
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
* Implements the multiresolution modeling tools.
|
||||
*
|
||||
* multires.h
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
#include "BIF_radialcontrol.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
|
||||
#include "mydevice.h"
|
||||
#include "transform.h"
|
||||
|
||||
#include "math.h"
|
||||
|
||||
/* Prints the value being edited in the view header */
|
||||
static void radialcontrol_header(const RadialControl *rc)
|
||||
{
|
||||
if(rc) {
|
||||
char str[512];
|
||||
const char *name= "";
|
||||
|
||||
if(rc->mode == RADIALCONTROL_SIZE)
|
||||
name= "Size";
|
||||
else if(rc->mode == RADIALCONTROL_STRENGTH)
|
||||
name= "Strength";
|
||||
else if(rc->mode == RADIALCONTROL_ROTATION)
|
||||
name= "Angle";
|
||||
|
||||
sprintf(str, "%s: %d", name, (int)(rc->new_value));
|
||||
headerprint(str);
|
||||
}
|
||||
}
|
||||
|
||||
/* Creates, initializes, and returns the control */
|
||||
RadialControl *radialcontrol_start(const int mode, RadialControlCallback callback,
|
||||
const int original_value, const int max_value,
|
||||
const unsigned int tex)
|
||||
{
|
||||
RadialControl *rc= MEM_callocN(sizeof(RadialControl), "radial control");
|
||||
short mouse[2];
|
||||
|
||||
getmouseco_areawin(mouse);
|
||||
rc->origloc[0]= mouse[0];
|
||||
rc->origloc[1]= mouse[1];
|
||||
|
||||
if(mode == RADIALCONTROL_SIZE)
|
||||
rc->origloc[0]-= original_value;
|
||||
else if(mode == RADIALCONTROL_STRENGTH)
|
||||
rc->origloc[0]-= 200 - 2*original_value;
|
||||
else if(mode == RADIALCONTROL_ROTATION) {
|
||||
rc->origloc[0]-= 200 * cos(original_value * M_PI / 180.0);
|
||||
rc->origloc[1]-= 200 * sin(original_value * M_PI / 180.0);
|
||||
}
|
||||
|
||||
rc->callback = callback;
|
||||
rc->original_value = original_value;
|
||||
rc->max_value = max_value;
|
||||
|
||||
rc->tex = tex;
|
||||
|
||||
/* NumInput is used for keyboard input */
|
||||
rc->num = MEM_callocN(sizeof(NumInput), "radialcontrol numinput");
|
||||
rc->num->idx_max= 0;
|
||||
|
||||
rc->mode= mode;
|
||||
radialcontrol_header(rc);
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static void radialcontrol_end(RadialControl *rc)
|
||||
{
|
||||
if(rc) {
|
||||
rc->callback(rc->mode, rc->new_value);
|
||||
BIF_undo_push("Brush property set");
|
||||
|
||||
/* Free everything */
|
||||
glDeleteTextures(1, (GLuint*)(&rc->tex));
|
||||
MEM_freeN(rc->num);
|
||||
MEM_freeN(rc);
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
allqueue(REDRAWHEADERS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void radialcontrol_do_events(RadialControl *rc, unsigned short event)
|
||||
{
|
||||
short mouse[2];
|
||||
short tmp[2];
|
||||
float dist;
|
||||
char valset= 0;
|
||||
|
||||
if(!rc)
|
||||
return;
|
||||
|
||||
handleNumInput(rc->num, event);
|
||||
|
||||
if(hasNumInput(rc->num)) {
|
||||
float val;
|
||||
applyNumInput(rc->num, &val);
|
||||
rc->new_value = val;
|
||||
valset= 1;
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
switch(event) {
|
||||
case MOUSEX:
|
||||
case MOUSEY:
|
||||
if(!hasNumInput(rc->num)) {
|
||||
char ctrl= G.qual & LR_CTRLKEY;
|
||||
getmouseco_areawin(mouse);
|
||||
tmp[0]= rc->origloc[0]-mouse[0];
|
||||
tmp[1]= rc->origloc[1]-mouse[1];
|
||||
dist= sqrt(tmp[0]*tmp[0]+tmp[1]*tmp[1]);
|
||||
if(rc->mode == RADIALCONTROL_SIZE)
|
||||
rc->new_value = dist;
|
||||
else if(rc->mode == RADIALCONTROL_STRENGTH) {
|
||||
float fin= (200.0f - dist) * 0.5f;
|
||||
rc->new_value= fin>=0 ? fin : 0;
|
||||
} else if(rc->mode == RADIALCONTROL_ROTATION)
|
||||
rc->new_value= ((int)(atan2(tmp[1], tmp[0]) * (180.0 / M_PI)) + 180);
|
||||
|
||||
if(ctrl)
|
||||
rc->new_value= (rc->new_value + 5) / 10*10;
|
||||
|
||||
valset= 1;
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
break;
|
||||
case ESCKEY:
|
||||
case RIGHTMOUSE:
|
||||
rc->new_value = rc->original_value;
|
||||
case LEFTMOUSE:
|
||||
while(get_mbut()==L_MOUSE);
|
||||
case RETKEY:
|
||||
case PADENTER:
|
||||
radialcontrol_end(rc);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if(valset) {
|
||||
if(rc->new_value > rc->max_value)
|
||||
rc->new_value = rc->max_value;
|
||||
}
|
||||
|
||||
radialcontrol_header(rc);
|
||||
}
|
||||
|
||||
static void rot_line(const short o[2], const float ang)
|
||||
{
|
||||
sdrawXORline(o[0], o[1], o[0] + 200*cos(ang), o[1] + 200*sin(ang));
|
||||
}
|
||||
|
||||
void radialcontrol_draw(RadialControl *rc)
|
||||
{
|
||||
short r1, r2, r3;
|
||||
float angle = 0;
|
||||
|
||||
if(rc && rc->mode) {
|
||||
if(rc->mode == RADIALCONTROL_SIZE) {
|
||||
r1= rc->new_value;
|
||||
r2= rc->original_value;
|
||||
r3= r1;
|
||||
} else if(rc->mode == RADIALCONTROL_STRENGTH) {
|
||||
r1= 200 - rc->new_value * 2;
|
||||
r2= 200;
|
||||
r3= 200;
|
||||
} else if(rc->mode == RADIALCONTROL_ROTATION) {
|
||||
r1= r2= 200;
|
||||
r3= 200;
|
||||
angle = rc->new_value;
|
||||
}
|
||||
|
||||
/* Draw brush with texture */
|
||||
glPushMatrix();
|
||||
glTranslatef(rc->origloc[0], rc->origloc[1], 0);
|
||||
glRotatef(angle, 0, 0, 1);
|
||||
|
||||
if(rc->tex) {
|
||||
const float str = rc->mode == RADIALCONTROL_STRENGTH ? (rc->new_value / 200.0 + 0.5) : 1;
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, rc->tex);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(0,0,0, str);
|
||||
glTexCoord2f(0,0);
|
||||
glVertex2f(-r3, -r3);
|
||||
glTexCoord2f(1,0);
|
||||
glVertex2f(r3, -r3);
|
||||
glTexCoord2f(1,1);
|
||||
glVertex2f(r3, r3);
|
||||
glTexCoord2f(0,1);
|
||||
glVertex2f(-r3, r3);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if(r1 != r2)
|
||||
fdrawXORcirc(rc->origloc[0], rc->origloc[1], r1);
|
||||
fdrawXORcirc(rc->origloc[0], rc->origloc[1], r2);
|
||||
|
||||
if(rc->mode == RADIALCONTROL_ROTATION) {
|
||||
float ang1= rc->original_value * (M_PI/180.0f);
|
||||
float ang2= rc->new_value * (M_PI/180.0f);
|
||||
|
||||
if(rc->new_value > 359)
|
||||
ang2 = 0;
|
||||
|
||||
rot_line(rc->origloc, ang1);
|
||||
if(ang1 != ang2)
|
||||
rot_line(rc->origloc, ang2);
|
||||
}
|
||||
}
|
||||
}
|
@ -76,6 +76,7 @@
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_radialcontrol.h"
|
||||
#include "BIF_resources.h"
|
||||
#include "BIF_screen.h"
|
||||
#include "BIF_space.h"
|
||||
@ -672,7 +673,7 @@ void flip_coord(float co[3], const char symm)
|
||||
}
|
||||
|
||||
/* Use the warpfac field in MTex to store a rotation value for sculpt textures. Value is in degrees */
|
||||
float tex_angle(void)
|
||||
float sculpt_tex_angle(void)
|
||||
{
|
||||
SculptData *sd= sculpt_data();
|
||||
if(sd->texact!=-1 && sd->mtex[sd->texact])
|
||||
@ -737,7 +738,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
|
||||
else if(ss->texcache) {
|
||||
const short bsize= sculptmode_brush()->size * 2;
|
||||
const short half= sculptmode_brush()->size;
|
||||
const float rot= to_rad(tex_angle());
|
||||
const float rot= to_rad(sculpt_tex_angle());
|
||||
const unsigned tcw = ss->texcache_w, tch = ss->texcache_h;
|
||||
int px, py;
|
||||
unsigned i, *p;
|
||||
@ -1224,147 +1225,85 @@ void sculptmode_set_strength(const int delta)
|
||||
sculptmode_brush()->strength= val;
|
||||
}
|
||||
|
||||
void sculptmode_propset_calctex()
|
||||
static void sculpt_radialcontrol_callback(const int mode, const int val)
|
||||
{
|
||||
SculptSession *ss = sculpt_session();
|
||||
BrushData *br = sculptmode_brush();
|
||||
|
||||
if(mode == RADIALCONTROL_SIZE)
|
||||
br->size = val;
|
||||
else if(mode == RADIALCONTROL_STRENGTH)
|
||||
br->strength = val;
|
||||
else if(mode == RADIALCONTROL_ROTATION)
|
||||
set_tex_angle(val);
|
||||
|
||||
ss->radialcontrol = NULL;
|
||||
}
|
||||
|
||||
/* Returns GL handle to brush texture */
|
||||
static GLuint sculpt_radialcontrol_calctex()
|
||||
{
|
||||
SculptData *sd= sculpt_data();
|
||||
SculptSession *ss= sculpt_session();
|
||||
PropsetData *pd= sculpt_session()->propset;
|
||||
if(pd) {
|
||||
int i, j;
|
||||
const int tsz = 128;
|
||||
float *d;
|
||||
if(!pd->texdata) {
|
||||
pd->texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
|
||||
if(sd->texrept!=SCULPTREPT_3D)
|
||||
sculptmode_update_tex();
|
||||
for(i=0; i<tsz; ++i)
|
||||
for(j=0; j<tsz; ++j) {
|
||||
float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
|
||||
if(sd->texfade)
|
||||
pd->texdata[i*tsz+j]= curve_strength(magn,tsz/2);
|
||||
else
|
||||
pd->texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
|
||||
}
|
||||
if(sd->texact != -1 && ss->texcache) {
|
||||
for(i=0; i<tsz; ++i)
|
||||
for(j=0; j<tsz; ++j) {
|
||||
const int col= ss->texcache[i*tsz+j];
|
||||
pd->texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
|
||||
}
|
||||
}
|
||||
int i, j;
|
||||
const int tsz = 128;
|
||||
float *texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview");
|
||||
GLuint tex;
|
||||
|
||||
if(sd->texrept!=SCULPTREPT_3D)
|
||||
sculptmode_update_tex();
|
||||
for(i=0; i<tsz; ++i)
|
||||
for(j=0; j<tsz; ++j) {
|
||||
float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
|
||||
if(sd->texfade)
|
||||
texdata[i*tsz+j]= curve_strength(magn,tsz/2);
|
||||
else
|
||||
texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Adjust alpha with brush strength */
|
||||
d= MEM_dupallocN(pd->texdata);
|
||||
if(sd->texact != -1 && ss->texcache) {
|
||||
for(i=0; i<tsz; ++i)
|
||||
for(j=0; j<tsz; ++j)
|
||||
d[i*tsz+j]*= sculptmode_brush()->strength/200.0f+0.5f;
|
||||
|
||||
|
||||
if(!pd->tex)
|
||||
glGenTextures(1, (GLuint *)&pd->tex);
|
||||
glBindTexture(GL_TEXTURE_2D, pd->tex);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, d);
|
||||
MEM_freeN(d);
|
||||
for(j=0; j<tsz; ++j) {
|
||||
const int col= ss->texcache[i*tsz+j];
|
||||
texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, texdata);
|
||||
MEM_freeN(texdata);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void sculptmode_propset_header()
|
||||
void sculpt_radialcontrol_start(int mode)
|
||||
{
|
||||
SculptSession *ss= sculpt_session();
|
||||
PropsetData *pd= ss ? ss->propset : NULL;
|
||||
if(pd) {
|
||||
char str[512];
|
||||
const char *name= "";
|
||||
int val= 0;
|
||||
if(pd->mode == PropsetSize) {
|
||||
name= "Size";
|
||||
val= sculptmode_brush()->size;
|
||||
}
|
||||
else if(pd->mode == PropsetStrength) {
|
||||
name= "Strength";
|
||||
val= sculptmode_brush()->strength;
|
||||
}
|
||||
else if(pd->mode == PropsetTexRot) {
|
||||
name= "Texture Angle";
|
||||
val= tex_angle();
|
||||
}
|
||||
sprintf(str, "Brush %s: %d", name, val);
|
||||
headerprint(str);
|
||||
SculptData *sd = sculpt_data();
|
||||
SculptSession *ss = sculpt_session();
|
||||
BrushData *br = sculptmode_brush();
|
||||
int orig, max;
|
||||
|
||||
if(mode == RADIALCONTROL_SIZE) {
|
||||
orig = br->size;
|
||||
max = 200;
|
||||
}
|
||||
}
|
||||
|
||||
void sculptmode_propset_end(SculptSession *ss, int cancel)
|
||||
{
|
||||
if(ss && ss->propset) {
|
||||
PropsetData *pd= ss->propset;
|
||||
|
||||
if(cancel) {
|
||||
sculptmode_brush()->size= pd->origsize;
|
||||
sculptmode_brush()->strength= pd->origstrength;
|
||||
set_tex_angle(pd->origtexrot);
|
||||
} else {
|
||||
if(pd->mode != PropsetSize)
|
||||
sculptmode_brush()->size= pd->origsize;
|
||||
if(pd->mode != PropsetStrength)
|
||||
sculptmode_brush()->strength= pd->origstrength;
|
||||
if(pd->mode != PropsetTexRot)
|
||||
set_tex_angle(pd->origtexrot);
|
||||
|
||||
BIF_undo_push("Brush property set");
|
||||
}
|
||||
glDeleteTextures(1, &pd->tex);
|
||||
MEM_freeN(pd->num);
|
||||
MEM_freeN(pd->texdata);
|
||||
MEM_freeN(pd);
|
||||
ss->propset= NULL;
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
allqueue(REDRAWHEADERS, 0);
|
||||
else if(mode == RADIALCONTROL_STRENGTH) {
|
||||
orig = br->strength;
|
||||
max = 100;
|
||||
}
|
||||
}
|
||||
|
||||
void sculptmode_propset_init(PropsetMode mode)
|
||||
{
|
||||
SculptSession *ss= sculpt_session();
|
||||
PropsetData *pd= ss->propset;
|
||||
const float ang= tex_angle();
|
||||
|
||||
if(!pd) {
|
||||
short mouse[2];
|
||||
|
||||
pd= MEM_callocN(sizeof(PropsetData),"PropsetSize");
|
||||
ss->propset= pd;
|
||||
|
||||
getmouseco_areawin(mouse);
|
||||
pd->origloc[0]= mouse[0];
|
||||
pd->origloc[1]= mouse[1];
|
||||
|
||||
if(mode == PropsetSize)
|
||||
pd->origloc[0]-= sculptmode_brush()->size;
|
||||
else if(mode == PropsetStrength)
|
||||
pd->origloc[0]-= 200 - 2*sculptmode_brush()->strength;
|
||||
else if(mode == PropsetTexRot) {
|
||||
pd->origloc[0]-= 200 * cos(to_rad(ang));
|
||||
pd->origloc[1]-= 200 * sin(to_rad(ang));
|
||||
else if(mode == RADIALCONTROL_ROTATION) {
|
||||
if(sd->texact!=-1 && sd->mtex[sd->texact]) {
|
||||
orig = sculpt_tex_angle();
|
||||
max = 360;
|
||||
}
|
||||
|
||||
pd->origsize= sculptmode_brush()->size;
|
||||
pd->origstrength= sculptmode_brush()->strength;
|
||||
pd->origtexrot= ang;
|
||||
|
||||
sculptmode_propset_calctex();
|
||||
|
||||
if(!pd->num)
|
||||
pd->num = MEM_callocN(sizeof(NumInput), "propset numinput");
|
||||
pd->num->idx_max= 0;
|
||||
else
|
||||
mode = RADIALCONTROL_NONE;
|
||||
}
|
||||
|
||||
pd->mode= mode;
|
||||
sculptmode_propset_header();
|
||||
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
if(mode != RADIALCONTROL_NONE) {
|
||||
ss->radialcontrol= radialcontrol_start(mode, sculpt_radialcontrol_callback, orig, max,
|
||||
sculpt_radialcontrol_calctex());
|
||||
}
|
||||
}
|
||||
|
||||
void sculpt_paint_brush(char clear)
|
||||
@ -1387,90 +1326,6 @@ void sculpt_paint_brush(char clear)
|
||||
}
|
||||
}
|
||||
|
||||
void sculptmode_propset(unsigned short event)
|
||||
{
|
||||
PropsetData *pd= sculpt_session()->propset;
|
||||
short mouse[2];
|
||||
short tmp[2];
|
||||
float dist;
|
||||
BrushData *brush= sculptmode_brush();
|
||||
char valset= 0;
|
||||
|
||||
handleNumInput(pd->num, event);
|
||||
|
||||
if(hasNumInput(pd->num)) {
|
||||
float val;
|
||||
applyNumInput(pd->num, &val);
|
||||
if(pd->mode==PropsetSize)
|
||||
brush->size= val;
|
||||
else if(pd->mode==PropsetStrength)
|
||||
brush->strength= val;
|
||||
else if(pd->mode==PropsetTexRot)
|
||||
set_tex_angle(val);
|
||||
valset= 1;
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
|
||||
switch(event) {
|
||||
case MOUSEX:
|
||||
case MOUSEY:
|
||||
if(!hasNumInput(pd->num)) {
|
||||
char ctrl= G.qual & LR_CTRLKEY;
|
||||
getmouseco_areawin(mouse);
|
||||
tmp[0]= pd->origloc[0]-mouse[0];
|
||||
tmp[1]= pd->origloc[1]-mouse[1];
|
||||
dist= sqrt(tmp[0]*tmp[0]+tmp[1]*tmp[1]);
|
||||
if(pd->mode == PropsetSize) {
|
||||
brush->size= dist;
|
||||
if(ctrl) brush->size= (brush->size+5)/10*10;
|
||||
} else if(pd->mode == PropsetStrength) {
|
||||
float fin= (200.0f - dist) * 0.5f;
|
||||
brush->strength= fin>=0 ? fin : 0;
|
||||
if(ctrl) brush->strength= (brush->strength+5)/10*10;
|
||||
} else if(pd->mode == PropsetTexRot) {
|
||||
set_tex_angle((int)to_deg(atan2(tmp[1], tmp[0])) + 180);
|
||||
if(ctrl)
|
||||
set_tex_angle(((int)(tex_angle())+5)/10*10);
|
||||
}
|
||||
valset= 1;
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
break;
|
||||
case ESCKEY:
|
||||
case RIGHTMOUSE:
|
||||
brush->size= pd->origsize;
|
||||
brush->strength= pd->origstrength;
|
||||
set_tex_angle(pd->origtexrot);
|
||||
case LEFTMOUSE:
|
||||
while(get_mbut()==L_MOUSE);
|
||||
case RETKEY:
|
||||
case PADENTER:
|
||||
sculptmode_propset_end(sculpt_session(), 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if(valset) {
|
||||
if(pd->mode == PropsetSize) {
|
||||
if(brush->size<1) brush->size= 1;
|
||||
if(brush->size>200) brush->size= 200;
|
||||
}
|
||||
else if(pd->mode == PropsetStrength) {
|
||||
if(brush->strength > 100) brush->strength= 100;
|
||||
sculptmode_propset_calctex();
|
||||
}
|
||||
else if(pd->mode == PropsetTexRot) {
|
||||
if(tex_angle() < 0)
|
||||
set_tex_angle(0);
|
||||
else if(tex_angle() > 360)
|
||||
set_tex_angle(360);
|
||||
}
|
||||
}
|
||||
|
||||
sculptmode_propset_header();
|
||||
}
|
||||
|
||||
void sculptmode_selectbrush_menu(void)
|
||||
{
|
||||
SculptData *sd= sculpt_data();
|
||||
@ -1699,7 +1554,7 @@ void sculpt(void)
|
||||
glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
|
||||
|
||||
/* For raking, get the original angle*/
|
||||
offsetRot=tex_angle();
|
||||
offsetRot=sculpt_tex_angle();
|
||||
|
||||
while (get_mbut() & mousebut) {
|
||||
getmouseco_areawin(mouse);
|
||||
|
@ -129,6 +129,7 @@
|
||||
#include "BIF_poselib.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_outliner.h"
|
||||
#include "BIF_radialcontrol.h"
|
||||
#include "BIF_resources.h"
|
||||
#include "BIF_retopo.h"
|
||||
#include "BIF_screen.h"
|
||||
@ -1199,8 +1200,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
if(!mouse_in_header(sa)) {
|
||||
if(!G.obedit && (G.f & G_SCULPTMODE)) {
|
||||
SculptSession *ss= sculpt_session();
|
||||
if(ss && ss->propset) {
|
||||
sculptmode_propset(event);
|
||||
if(ss && ss->radialcontrol) {
|
||||
radialcontrol_do_events(ss->radialcontrol, event);
|
||||
return;
|
||||
}
|
||||
else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
|
||||
@ -1211,6 +1212,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
else if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT){
|
||||
ParticleSystem *psys=PE_get_current(OBACT);
|
||||
ParticleEditSettings *pset=PE_settings();
|
||||
if(*PE_radialcontrol()) {
|
||||
radialcontrol_do_events(*PE_radialcontrol(), event);
|
||||
return;
|
||||
}
|
||||
if(psys && psys->edit){
|
||||
if(pset->brushtype>=0 &&
|
||||
event!=LEFTMOUSE && event!=RIGHTMOUSE && event!=MIDDLEMOUSE &&
|
||||
@ -1366,7 +1371,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
case LEFTMOUSE:
|
||||
if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
|
||||
sculptmode_pmv(0);
|
||||
else if(!(ss && ss->propset))
|
||||
else if(!(ss && ss->radialcontrol))
|
||||
sculpt();
|
||||
break;
|
||||
/* View */
|
||||
@ -1444,12 +1449,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
br->airbrush= !br->airbrush;
|
||||
update_prop= 1; break;
|
||||
case FKEY:
|
||||
if(G.qual==0)
|
||||
sculptmode_propset_init(PropsetSize);
|
||||
if(G.qual==LR_SHIFTKEY)
|
||||
sculptmode_propset_init(PropsetStrength);
|
||||
if(G.qual==LR_CTRLKEY)
|
||||
sculptmode_propset_init(PropsetTexRot);
|
||||
if(ss) {
|
||||
sculpt_radialcontrol_start(G.qual == 0 ? RADIALCONTROL_SIZE :
|
||||
G.qual == LR_SHIFTKEY ? RADIALCONTROL_STRENGTH :
|
||||
G.qual == LR_CTRLKEY ? RADIALCONTROL_ROTATION :
|
||||
RADIALCONTROL_NONE);
|
||||
}
|
||||
break;
|
||||
case VKEY:
|
||||
br->dir= br->dir==1 ? 2 : 1;
|
||||
@ -1914,6 +1919,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
pose_activate_flipped_bone();
|
||||
else if(G.f & G_WEIGHTPAINT)
|
||||
pose_activate_flipped_bone();
|
||||
else if(G.f & G_PARTICLEEDIT)
|
||||
PE_radialcontrol_start(RADIALCONTROL_STRENGTH);
|
||||
else
|
||||
fly();
|
||||
}
|
||||
@ -1922,6 +1929,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
G.f ^= G_FACESELECT;
|
||||
allqueue(REDRAWVIEW3D, 1);
|
||||
}
|
||||
else if(G.f & G_PARTICLEEDIT)
|
||||
PE_radialcontrol_start(RADIALCONTROL_SIZE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user