2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2008-12-20 13:29:35 +00:00
|
|
|
* ***** 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2008-12-20 13:29:35 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_view3d/drawarmature.c
|
|
|
|
|
* \ingroup spview3d
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
2009-06-25 10:52:09 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2008-12-20 13:29:35 +00:00
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
|
#include "DNA_constraint_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
|
#include "DNA_view3d_types.h"
|
2010-08-04 04:01:27 +00:00
|
|
|
#include "DNA_object_types.h"
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2009-07-18 07:11:37 +00:00
|
|
|
#include "BLI_dlrbTree.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-06-25 10:52:09 +00:00
|
|
|
#include "BKE_animsys.h"
|
2008-12-20 13:29:35 +00:00
|
|
|
#include "BKE_action.h"
|
|
|
|
|
#include "BKE_armature.h"
|
|
|
|
|
#include "BKE_global.h"
|
2009-01-10 14:19:14 +00:00
|
|
|
#include "BKE_modifier.h"
|
2009-06-25 10:52:09 +00:00
|
|
|
#include "BKE_nla.h"
|
2011-01-07 19:18:31 +00:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
|
#include "BIF_glutil.h"
|
|
|
|
|
|
2009-01-05 15:19:31 +00:00
|
|
|
#include "ED_armature.h"
|
2008-12-22 08:13:25 +00:00
|
|
|
#include "ED_keyframes_draw.h"
|
|
|
|
|
|
2015-12-05 22:11:31 +01:00
|
|
|
#include "GPU_basic_shader.h"
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
#include "UI_resources.h"
|
|
|
|
|
|
|
|
|
|
#include "view3d_intern.h"
|
|
|
|
|
|
2014-07-23 15:24:07 +02:00
|
|
|
#include "GPU_select.h"
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* *************** Armature Drawing - Coloring API ***************************** */
|
|
|
|
|
|
|
|
|
|
/* global here is reset before drawing each bone */
|
2012-03-25 23:54:33 +00:00
|
|
|
static ThemeWireColor *bcolor = NULL;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* values of colCode for set_pchan_glcolor */
|
|
|
|
|
enum {
|
2012-03-25 23:54:33 +00:00
|
|
|
PCHAN_COLOR_NORMAL = 0, /* normal drawing */
|
|
|
|
|
PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */
|
|
|
|
|
PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */
|
|
|
|
|
|
|
|
|
|
PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */
|
|
|
|
|
PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */
|
|
|
|
|
PCHAN_COLOR_LINEBONE /* for the middle of line-bones */
|
2011-09-10 12:07:16 +00:00
|
|
|
};
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* This function sets the color-set for coloring a certain bone */
|
2012-03-25 23:54:33 +00:00
|
|
|
static void set_pchan_colorset(Object *ob, bPoseChannel *pchan)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
bPose *pose = (ob) ? ob->pose : NULL;
|
|
|
|
|
bArmature *arm = (ob) ? ob->data : NULL;
|
|
|
|
|
bActionGroup *grp = NULL;
|
|
|
|
|
short color_index = 0;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* sanity check */
|
2014-07-20 01:30:29 +10:00
|
|
|
if (ELEM(NULL, ob, arm, pose, pchan)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
bcolor = NULL;
|
2008-12-20 13:29:35 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* only try to set custom color if enabled for armature */
|
2012-10-21 05:46:41 +00:00
|
|
|
if (arm->flag & ARM_COL_CUSTOM) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* currently, a bone can only use a custom color set if it's group (if it has one),
|
|
|
|
|
* has been set to use one
|
|
|
|
|
*/
|
|
|
|
|
if (pchan->agrp_index) {
|
2012-03-25 23:54:33 +00:00
|
|
|
grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
|
2008-12-20 13:29:35 +00:00
|
|
|
if (grp)
|
2012-03-25 23:54:33 +00:00
|
|
|
color_index = grp->customCol;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* bcolor is a pointer to the color set to use. If NULL, then the default
|
|
|
|
|
* color set (based on the theme colors for 3d-view) is used.
|
|
|
|
|
*/
|
|
|
|
|
if (color_index > 0) {
|
2012-03-25 23:54:33 +00:00
|
|
|
bTheme *btheme = UI_GetTheme();
|
|
|
|
|
bcolor = &btheme->tarm[(color_index - 1)];
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else if (color_index == -1) {
|
|
|
|
|
/* use the group's own custom color set */
|
2012-03-25 23:54:33 +00:00
|
|
|
bcolor = (grp) ? &grp->cs : NULL;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
bcolor = NULL;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This function is for brightening/darkening a given color (like UI_ThemeColorShade()) */
|
2012-03-25 23:54:33 +00:00
|
|
|
static void cp_shade_color3ub(unsigned char cp[3], const int offset)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
|
|
|
|
int r, g, b;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
r = offset + (int) cp[0];
|
2008-12-20 13:29:35 +00:00
|
|
|
CLAMP(r, 0, 255);
|
2012-03-25 23:54:33 +00:00
|
|
|
g = offset + (int) cp[1];
|
2008-12-20 13:29:35 +00:00
|
|
|
CLAMP(g, 0, 255);
|
2012-03-25 23:54:33 +00:00
|
|
|
b = offset + (int) cp[2];
|
2008-12-20 13:29:35 +00:00
|
|
|
CLAMP(b, 0, 255);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
cp[0] = r;
|
|
|
|
|
cp[1] = g;
|
|
|
|
|
cp[2] = b;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This function sets the gl-color for coloring a certain bone (based on bcolor) */
|
2013-03-20 23:14:18 +00:00
|
|
|
static bool set_pchan_glColor(short colCode, int boneflag, short constflag)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
|
|
|
|
switch (colCode) {
|
2012-03-25 23:54:33 +00:00
|
|
|
case PCHAN_COLOR_NORMAL:
|
|
|
|
|
{
|
|
|
|
|
if (bcolor) {
|
|
|
|
|
unsigned char cp[3];
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (boneflag & BONE_DRAW_ACTIVE) {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->active);
|
|
|
|
|
if (!(boneflag & BONE_SELECTED)) {
|
|
|
|
|
cp_shade_color3ub(cp, -80);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (boneflag & BONE_SELECTED) {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->select);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* a bit darker than solid */
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->solid);
|
|
|
|
|
cp_shade_color3ub(cp, -50);
|
2010-12-08 03:05:46 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
glColor3ubv(cp);
|
2012-03-10 22:00:55 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
|
2012-07-26 10:53:59 +00:00
|
|
|
UI_ThemeColor(TH_BONE_POSE_ACTIVE);
|
2012-03-25 23:54:33 +00:00
|
|
|
}
|
|
|
|
|
else if (boneflag & BONE_DRAW_ACTIVE) {
|
|
|
|
|
UI_ThemeColorBlend(TH_WIRE, TH_BONE_POSE, 0.15f); /* unselected active */
|
|
|
|
|
}
|
|
|
|
|
else if (boneflag & BONE_SELECTED) {
|
|
|
|
|
UI_ThemeColor(TH_BONE_POSE);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
UI_ThemeColor(TH_WIRE);
|
|
|
|
|
}
|
2012-03-10 22:00:55 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
case PCHAN_COLOR_SOLID:
|
|
|
|
|
{
|
|
|
|
|
if (bcolor) {
|
|
|
|
|
glColor3ubv((unsigned char *)bcolor->solid);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
case PCHAN_COLOR_CONSTS:
|
|
|
|
|
{
|
|
|
|
|
if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) {
|
|
|
|
|
if (constflag & PCHAN_HAS_TARGET) glColor4ub(255, 150, 0, 80);
|
|
|
|
|
else if (constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 80);
|
|
|
|
|
else if (constflag & PCHAN_HAS_SPLINEIK) glColor4ub(200, 255, 0, 80);
|
|
|
|
|
else if (constflag & PCHAN_HAS_CONST) glColor4ub(0, 255, 120, 80);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2013-07-19 15:23:42 +00:00
|
|
|
return false;
|
2012-03-25 23:54:33 +00:00
|
|
|
}
|
|
|
|
|
case PCHAN_COLOR_SPHEREBONE_BASE:
|
|
|
|
|
{
|
|
|
|
|
if (bcolor) {
|
|
|
|
|
unsigned char cp[3];
|
|
|
|
|
|
|
|
|
|
if (boneflag & BONE_DRAW_ACTIVE) {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->active);
|
|
|
|
|
}
|
|
|
|
|
else if (boneflag & BONE_SELECTED) {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->select);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->solid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glColor3ubv(cp);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40);
|
|
|
|
|
else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE);
|
|
|
|
|
else UI_ThemeColor(TH_BONE_SOLID);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
case PCHAN_COLOR_SPHEREBONE_END:
|
|
|
|
|
{
|
|
|
|
|
if (bcolor) {
|
|
|
|
|
unsigned char cp[3];
|
|
|
|
|
|
|
|
|
|
if (boneflag & BONE_DRAW_ACTIVE) {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->active);
|
|
|
|
|
cp_shade_color3ub(cp, 10);
|
|
|
|
|
}
|
|
|
|
|
else if (boneflag & BONE_SELECTED) {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->select);
|
|
|
|
|
cp_shade_color3ub(cp, -30);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v3_v3_char((char *)cp, bcolor->solid);
|
|
|
|
|
cp_shade_color3ub(cp, -30);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
glColor3ubv(cp);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 10);
|
|
|
|
|
else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, -30);
|
|
|
|
|
else UI_ThemeColorShade(TH_BONE_SOLID, -30);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2013-07-19 15:23:42 +00:00
|
|
|
break;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
case PCHAN_COLOR_LINEBONE:
|
|
|
|
|
{
|
|
|
|
|
/* inner part in background color or constraint */
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (constflag & PCHAN_HAS_TARGET) glColor3ub(255, 150, 0);
|
|
|
|
|
else if (constflag & PCHAN_HAS_IK) glColor3ub(255, 255, 0);
|
|
|
|
|
else if (constflag & PCHAN_HAS_SPLINEIK) glColor3ub(200, 255, 0);
|
|
|
|
|
else if (constflag & PCHAN_HAS_CONST) glColor3ub(0, 255, 120);
|
|
|
|
|
else if (constflag) UI_ThemeColor(TH_BONE_POSE); /* PCHAN_HAS_ACTION */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (bcolor) {
|
2014-04-27 00:22:49 +10:00
|
|
|
const char *cp = bcolor->solid;
|
2012-03-25 23:54:33 +00:00
|
|
|
glColor4ub(cp[0], cp[1], cp[2], 204);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
UI_ThemeColorShade(TH_BACK, -30);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2012-03-25 23:54:33 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return false;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2010-12-08 03:05:46 +00:00
|
|
|
static void set_ebone_glColor(const unsigned int boneflag)
|
|
|
|
|
{
|
2012-03-10 22:00:55 +00:00
|
|
|
if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) {
|
|
|
|
|
UI_ThemeColor(TH_EDGE_SELECT);
|
|
|
|
|
}
|
|
|
|
|
else if (boneflag & BONE_DRAW_ACTIVE) {
|
2013-06-08 21:58:00 +00:00
|
|
|
UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f); /* unselected active */
|
2012-03-10 22:00:55 +00:00
|
|
|
}
|
|
|
|
|
else if (boneflag & BONE_SELECTED) {
|
|
|
|
|
UI_ThemeColorShade(TH_EDGE_SELECT, -20);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-06-08 21:58:00 +00:00
|
|
|
UI_ThemeColor(TH_WIRE_EDIT);
|
2012-03-10 22:00:55 +00:00
|
|
|
}
|
2010-12-08 03:05:46 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* *************** Armature drawing, helper calls for parts ******************* */
|
|
|
|
|
|
|
|
|
|
/* half the cube, in Y */
|
2013-10-10 20:22:17 +00:00
|
|
|
static const float cube[8][3] = {
|
2012-03-25 23:54:33 +00:00
|
|
|
{-1.0, 0.0, -1.0},
|
|
|
|
|
{-1.0, 0.0, 1.0},
|
|
|
|
|
{-1.0, 1.0, 1.0},
|
|
|
|
|
{-1.0, 1.0, -1.0},
|
|
|
|
|
{ 1.0, 0.0, -1.0},
|
|
|
|
|
{ 1.0, 0.0, 1.0},
|
|
|
|
|
{ 1.0, 1.0, 1.0},
|
|
|
|
|
{ 1.0, 1.0, -1.0},
|
2008-12-20 13:29:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void drawsolidcube_size(float xsize, float ysize, float zsize)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLuint displist = 0;
|
|
|
|
|
float n[3] = {0.0f};
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glScalef(xsize, ysize, zsize);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (displist == 0) {
|
|
|
|
|
displist = glGenLists(1);
|
2010-09-15 13:07:36 +00:00
|
|
|
glNewList(displist, GL_COMPILE);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
2012-03-25 23:54:33 +00:00
|
|
|
n[0] = -1.0;
|
2008-12-20 13:29:35 +00:00
|
|
|
glNormal3fv(n);
|
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
2012-03-25 23:54:33 +00:00
|
|
|
n[0] = 0;
|
|
|
|
|
n[1] = -1.0;
|
2008-12-20 13:29:35 +00:00
|
|
|
glNormal3fv(n);
|
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
|
2012-03-25 23:54:33 +00:00
|
|
|
n[1] = 0;
|
|
|
|
|
n[0] = 1.0;
|
2008-12-20 13:29:35 +00:00
|
|
|
glNormal3fv(n);
|
|
|
|
|
glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
|
2012-03-25 23:54:33 +00:00
|
|
|
n[0] = 0;
|
|
|
|
|
n[1] = 1.0;
|
2008-12-20 13:29:35 +00:00
|
|
|
glNormal3fv(n);
|
|
|
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
2012-03-25 23:54:33 +00:00
|
|
|
n[1] = 0;
|
|
|
|
|
n[2] = 1.0;
|
2008-12-20 13:29:35 +00:00
|
|
|
glNormal3fv(n);
|
|
|
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
|
2012-03-25 23:54:33 +00:00
|
|
|
n[2] = -1.0;
|
2008-12-20 13:29:35 +00:00
|
|
|
glNormal3fv(n);
|
|
|
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glEndList();
|
|
|
|
|
}
|
2010-09-15 13:07:36 +00:00
|
|
|
|
|
|
|
|
glCallList(displist);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void drawcube_size(float xsize, float ysize, float zsize)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLuint displist = 0;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (displist == 0) {
|
2012-03-25 23:54:33 +00:00
|
|
|
displist = glGenLists(1);
|
2010-09-15 13:07:36 +00:00
|
|
|
glNewList(displist, GL_COMPILE);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2012-03-25 23:54:33 +00:00
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[6]);
|
2008-12-20 13:29:35 +00:00
|
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]);
|
|
|
|
|
glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
|
|
|
|
glVertex3fv(cube[3]); glVertex3fv(cube[7]);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glEndList();
|
|
|
|
|
}
|
2010-09-15 13:07:36 +00:00
|
|
|
|
|
|
|
|
glScalef(xsize, ysize, zsize);
|
|
|
|
|
glCallList(displist);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void draw_bonevert(void)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLuint displist = 0;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (displist == 0) {
|
2012-03-25 23:54:33 +00:00
|
|
|
GLUquadricObj *qobj;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
displist = glGenLists(1);
|
2010-09-15 13:07:36 +00:00
|
|
|
glNewList(displist, GL_COMPILE);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
qobj = gluNewQuadric();
|
2008-12-20 13:29:35 +00:00
|
|
|
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
|
|
|
|
|
gluDisk(qobj, 0.0, 0.05, 16, 1);
|
|
|
|
|
|
|
|
|
|
glRotatef(90, 0, 1, 0);
|
|
|
|
|
gluDisk(qobj, 0.0, 0.05, 16, 1);
|
|
|
|
|
|
|
|
|
|
glRotatef(90, 1, 0, 0);
|
|
|
|
|
gluDisk(qobj, 0.0, 0.05, 16, 1);
|
|
|
|
|
|
|
|
|
|
gluDeleteQuadric(qobj);
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
glEndList();
|
|
|
|
|
}
|
2010-09-15 13:07:36 +00:00
|
|
|
|
|
|
|
|
glCallList(displist);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void draw_bonevert_solid(void)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLuint displist = 0;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (displist == 0) {
|
2012-03-25 23:54:33 +00:00
|
|
|
GLUquadricObj *qobj;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
displist = glGenLists(1);
|
2010-09-15 13:07:36 +00:00
|
|
|
glNewList(displist, GL_COMPILE);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
qobj = gluNewQuadric();
|
2008-12-20 13:29:35 +00:00
|
|
|
gluQuadricDrawStyle(qobj, GLU_FILL);
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
2009-02-10 09:18:04 +00:00
|
|
|
gluSphere(qobj, 0.05, 8, 5);
|
2008-12-20 13:29:35 +00:00
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
|
gluDeleteQuadric(qobj);
|
|
|
|
|
|
|
|
|
|
glEndList();
|
|
|
|
|
}
|
2010-09-15 13:07:36 +00:00
|
|
|
|
|
|
|
|
glCallList(displist);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-10 20:22:17 +00:00
|
|
|
static const float bone_octahedral_verts[6][3] = {
|
2011-10-06 22:04:01 +00:00
|
|
|
{ 0.0f, 0.0f, 0.0f},
|
|
|
|
|
{ 0.1f, 0.1f, 0.1f},
|
|
|
|
|
{ 0.1f, 0.1f, -0.1f},
|
|
|
|
|
{-0.1f, 0.1f, -0.1f},
|
|
|
|
|
{-0.1f, 0.1f, 0.1f},
|
|
|
|
|
{ 0.0f, 1.0f, 0.0f}
|
2011-09-10 12:07:16 +00:00
|
|
|
};
|
|
|
|
|
|
2013-10-10 20:22:17 +00:00
|
|
|
static const unsigned int bone_octahedral_wire_sides[8] = {0, 1, 5, 3, 0, 4, 5, 2};
|
|
|
|
|
static const unsigned int bone_octahedral_wire_square[8] = {1, 2, 3, 4, 1};
|
2011-09-10 12:07:16 +00:00
|
|
|
|
2013-10-10 20:22:17 +00:00
|
|
|
static const unsigned int bone_octahedral_solid_tris[8][3] = {
|
2011-10-06 22:04:01 +00:00
|
|
|
{2, 1, 0}, /* bottom */
|
|
|
|
|
{3, 2, 0},
|
|
|
|
|
{4, 3, 0},
|
|
|
|
|
{1, 4, 0},
|
|
|
|
|
|
|
|
|
|
{5, 1, 2}, /* top */
|
|
|
|
|
{5, 2, 3},
|
|
|
|
|
{5, 3, 4},
|
|
|
|
|
{5, 4, 1}
|
2011-09-10 12:07:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* aligned with bone_octahedral_solid_tris */
|
2013-10-10 20:22:17 +00:00
|
|
|
static const float bone_octahedral_solid_normals[8][3] = {
|
2014-08-12 15:58:53 +10:00
|
|
|
{ M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
|
|
|
|
|
{-0.00000000f, -M_SQRT1_2, -M_SQRT1_2},
|
|
|
|
|
{-M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
|
|
|
|
|
{ 0.00000000f, -M_SQRT1_2, M_SQRT1_2},
|
2011-10-06 22:04:01 +00:00
|
|
|
{ 0.99388373f, 0.11043154f, -0.00000000f},
|
|
|
|
|
{ 0.00000000f, 0.11043154f, -0.99388373f},
|
|
|
|
|
{-0.99388373f, 0.11043154f, 0.00000000f},
|
|
|
|
|
{ 0.00000000f, 0.11043154f, 0.99388373f}
|
2011-09-10 12:07:16 +00:00
|
|
|
};
|
|
|
|
|
|
2010-12-03 12:30:59 +00:00
|
|
|
static void draw_bone_octahedral(void)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLuint displist = 0;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (displist == 0) {
|
2012-03-25 23:54:33 +00:00
|
|
|
displist = glGenLists(1);
|
2010-09-15 13:07:36 +00:00
|
|
|
glNewList(displist, GL_COMPILE);
|
2011-09-10 12:07:16 +00:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* Section 1, sides */
|
2011-09-10 12:07:16 +00:00
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts);
|
|
|
|
|
glDrawElements(GL_LINE_LOOP,
|
2012-03-25 23:54:33 +00:00
|
|
|
sizeof(bone_octahedral_wire_sides) / sizeof(*bone_octahedral_wire_sides),
|
2011-09-10 12:07:16 +00:00
|
|
|
GL_UNSIGNED_INT,
|
|
|
|
|
bone_octahedral_wire_sides);
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* Section 1, square */
|
2011-09-10 12:07:16 +00:00
|
|
|
glDrawElements(GL_LINE_LOOP,
|
2012-03-25 23:54:33 +00:00
|
|
|
sizeof(bone_octahedral_wire_square) / sizeof(*bone_octahedral_wire_square),
|
2011-09-10 12:07:16 +00:00
|
|
|
GL_UNSIGNED_INT,
|
|
|
|
|
bone_octahedral_wire_square);
|
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glEndList();
|
|
|
|
|
}
|
2010-09-15 13:07:36 +00:00
|
|
|
|
|
|
|
|
glCallList(displist);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void draw_bone_solid_octahedral(void)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLuint displist = 0;
|
2011-09-10 12:07:16 +00:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
if (displist == 0) {
|
2011-09-10 12:07:16 +00:00
|
|
|
int i;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
displist = glGenLists(1);
|
2010-09-15 13:07:36 +00:00
|
|
|
glNewList(displist, GL_COMPILE);
|
2011-09-10 12:07:16 +00:00
|
|
|
|
|
|
|
|
#if 1
|
2008-12-20 13:29:35 +00:00
|
|
|
glBegin(GL_TRIANGLES);
|
2012-03-25 23:54:33 +00:00
|
|
|
for (i = 0; i < 8; i++) {
|
2011-09-10 12:07:16 +00:00
|
|
|
glNormal3fv(bone_octahedral_solid_normals[i]);
|
|
|
|
|
glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][0]]);
|
|
|
|
|
glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][1]]);
|
|
|
|
|
glVertex3fv(bone_octahedral_verts[bone_octahedral_solid_tris[i][2]]);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
glEnd();
|
2011-09-10 12:07:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
#else /* not working because each vert needs a different normal */
|
2011-09-10 12:07:16 +00:00
|
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
|
glNormalPointer(GL_FLOAT, 0, bone_octahedral_solid_normals);
|
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, bone_octahedral_verts);
|
2012-03-25 23:54:33 +00:00
|
|
|
glDrawElements(GL_TRIANGLES, sizeof(bone_octahedral_solid_tris) / sizeof(unsigned int),
|
2012-01-19 16:04:44 +00:00
|
|
|
GL_UNSIGNED_INT, bone_octahedral_solid_tris);
|
2011-09-10 12:07:16 +00:00
|
|
|
glDisableClientState(GL_NORMAL_ARRAY);
|
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
|
|
#endif
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
glEndList();
|
|
|
|
|
}
|
2010-09-15 13:07:36 +00:00
|
|
|
|
|
|
|
|
glCallList(displist);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* *************** Armature drawing, bones ******************* */
|
|
|
|
|
|
|
|
|
|
|
2012-06-10 10:15:49 +00:00
|
|
|
static void draw_bone_points(const short dt, int armflag, unsigned int boneflag, int id)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
|
|
|
|
/* Draw root point if we are not connected */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((boneflag & BONE_CONNECTED) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_ROOT);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (dt <= OB_WIRE) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColor(TH_VERTEX);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0);
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
|
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dt > OB_WIRE)
|
|
|
|
|
draw_bonevert_solid();
|
|
|
|
|
else
|
|
|
|
|
draw_bonevert();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw tip point */
|
|
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_TIP);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (dt <= OB_WIRE) {
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColor(TH_VERTEX);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, 0);
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
|
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-10 09:18:04 +00:00
|
|
|
glTranslatef(0.0f, 1.0f, 0.0f);
|
2008-12-20 13:29:35 +00:00
|
|
|
if (dt > OB_WIRE)
|
|
|
|
|
draw_bonevert_solid();
|
|
|
|
|
else
|
|
|
|
|
draw_bonevert();
|
2009-02-10 09:18:04 +00:00
|
|
|
glTranslatef(0.0f, -1.0f, 0.0f);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 16 values of sin function (still same result!) */
|
2013-10-10 20:22:17 +00:00
|
|
|
static const float si[16] = {
|
2009-02-10 09:18:04 +00:00
|
|
|
0.00000000f,
|
|
|
|
|
0.20129852f, 0.39435585f,
|
|
|
|
|
0.57126821f, 0.72479278f,
|
|
|
|
|
0.84864425f, 0.93775213f,
|
|
|
|
|
0.98846832f, 0.99871650f,
|
|
|
|
|
0.96807711f, 0.89780453f,
|
|
|
|
|
0.79077573f, 0.65137248f,
|
|
|
|
|
0.48530196f, 0.29936312f,
|
|
|
|
|
0.10116832f
|
2008-12-20 13:29:35 +00:00
|
|
|
};
|
|
|
|
|
/* 16 values of cos function (still same result!) */
|
2013-10-10 20:22:17 +00:00
|
|
|
static const float co[16] = {
|
2009-02-10 09:18:04 +00:00
|
|
|
1.00000000f,
|
|
|
|
|
0.97952994f, 0.91895781f,
|
|
|
|
|
0.82076344f, 0.68896691f,
|
|
|
|
|
0.52896401f, 0.34730525f,
|
|
|
|
|
0.15142777f, -0.05064916f,
|
|
|
|
|
-0.25065253f, -0.44039415f,
|
|
|
|
|
-0.61210598f, -0.75875812f,
|
|
|
|
|
-0.87434661f, -0.95413925f,
|
|
|
|
|
-0.99486932f
|
2008-12-20 13:29:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* smat, imat = mat & imat to draw screenaligned */
|
2012-12-11 14:29:01 +00:00
|
|
|
static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChannel *pchan, EditBone *ebone)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2011-01-12 03:41:12 +00:00
|
|
|
float head, tail, dist /*, length*/;
|
2008-12-20 13:29:35 +00:00
|
|
|
float *headvec, *tailvec, dirvec[3];
|
|
|
|
|
|
|
|
|
|
/* figure out the sizes of spheres */
|
|
|
|
|
if (ebone) {
|
2009-09-19 18:45:31 +00:00
|
|
|
/* this routine doesn't call get_matrix_editbone() that calculates it */
|
2009-11-10 20:43:45 +00:00
|
|
|
ebone->length = len_v3v3(ebone->head, ebone->tail);
|
2011-01-12 03:41:12 +00:00
|
|
|
|
2012-10-26 04:14:10 +00:00
|
|
|
/*length = ebone->length;*/ /*UNUSED*/
|
2012-03-25 23:54:33 +00:00
|
|
|
tail = ebone->rad_tail;
|
|
|
|
|
dist = ebone->dist;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (ebone->parent && (ebone->flag & BONE_CONNECTED))
|
2012-03-25 23:54:33 +00:00
|
|
|
head = ebone->parent->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
head = ebone->rad_head;
|
|
|
|
|
headvec = ebone->head;
|
|
|
|
|
tailvec = ebone->tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-10-26 04:14:10 +00:00
|
|
|
/*length = pchan->bone->length;*/ /*UNUSED*/
|
2012-03-25 23:54:33 +00:00
|
|
|
tail = pchan->bone->rad_tail;
|
|
|
|
|
dist = pchan->bone->dist;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED))
|
2012-03-25 23:54:33 +00:00
|
|
|
head = pchan->parent->bone->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
head = pchan->bone->rad_head;
|
|
|
|
|
headvec = pchan->pose_head;
|
|
|
|
|
tailvec = pchan->pose_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ***** draw it ***** */
|
|
|
|
|
|
|
|
|
|
/* move vector to viewspace */
|
2009-11-10 20:43:45 +00:00
|
|
|
sub_v3_v3v3(dirvec, tailvec, headvec);
|
|
|
|
|
mul_mat3_m4_v3(smat, dirvec);
|
2008-12-20 13:29:35 +00:00
|
|
|
/* clear zcomp */
|
2012-03-25 23:54:33 +00:00
|
|
|
dirvec[2] = 0.0f;
|
2010-09-16 06:04:47 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (head != tail) {
|
2012-03-25 23:54:33 +00:00
|
|
|
/* correction when viewing along the bones axis
|
|
|
|
|
* it pops in and out but better then artifacts, [#23841] */
|
|
|
|
|
float view_dist = len_v2(dirvec);
|
2010-09-16 06:04:47 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (head - view_dist > tail) {
|
2012-03-25 23:54:33 +00:00
|
|
|
tailvec = headvec;
|
2010-09-16 06:04:47 +00:00
|
|
|
tail = head;
|
|
|
|
|
zero_v3(dirvec);
|
2012-07-08 20:36:00 +00:00
|
|
|
dirvec[0] = 0.00001; /* XXX. weak but ok */
|
2010-09-16 06:04:47 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (tail - view_dist > head) {
|
2012-03-25 23:54:33 +00:00
|
|
|
headvec = tailvec;
|
2010-09-16 06:04:47 +00:00
|
|
|
head = tail;
|
|
|
|
|
zero_v3(dirvec);
|
2012-07-08 20:36:00 +00:00
|
|
|
dirvec[0] = 0.00001; /* XXX. weak but ok */
|
2010-09-16 06:04:47 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* move vector back */
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_mat3_m4_v3(imat, dirvec);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
if (0.0f != normalize_v3(dirvec)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
float norvec[3], vec1[3], vec2[3], vec[3];
|
|
|
|
|
int a;
|
|
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
//mul_v3_fl(dirvec, head);
|
|
|
|
|
cross_v3_v3v3(norvec, dirvec, imat[2]);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (a = 0; a < 16; a++) {
|
2012-07-04 20:47:12 +00:00
|
|
|
vec[0] = -si[a] * dirvec[0] + co[a] * norvec[0];
|
|
|
|
|
vec[1] = -si[a] * dirvec[1] + co[a] * norvec[1];
|
|
|
|
|
vec[2] = -si[a] * dirvec[2] + co[a] * norvec[2];
|
2011-09-25 05:48:16 +00:00
|
|
|
|
|
|
|
|
madd_v3_v3v3fl(vec1, headvec, vec, head);
|
|
|
|
|
madd_v3_v3v3fl(vec2, headvec, vec, head + dist);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glColor4ub(255, 255, 255, 50);
|
|
|
|
|
glVertex3fv(vec1);
|
|
|
|
|
//glColor4ub(255, 255, 255, 0);
|
|
|
|
|
glVertex3fv(vec2);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (a = 15; a >= 0; a--) {
|
2012-07-04 20:47:12 +00:00
|
|
|
vec[0] = si[a] * dirvec[0] + co[a] * norvec[0];
|
|
|
|
|
vec[1] = si[a] * dirvec[1] + co[a] * norvec[1];
|
|
|
|
|
vec[2] = si[a] * dirvec[2] + co[a] * norvec[2];
|
2011-09-25 05:48:16 +00:00
|
|
|
|
|
|
|
|
madd_v3_v3v3fl(vec1, tailvec, vec, tail);
|
|
|
|
|
madd_v3_v3v3fl(vec2, tailvec, vec, tail + dist);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
//glColor4ub(255, 255, 255, 50);
|
|
|
|
|
glVertex3fv(vec1);
|
|
|
|
|
//glColor4ub(255, 255, 255, 0);
|
|
|
|
|
glVertex3fv(vec2);
|
|
|
|
|
}
|
|
|
|
|
/* make it cyclic... */
|
|
|
|
|
|
2012-07-04 20:47:12 +00:00
|
|
|
vec[0] = -si[0] * dirvec[0] + co[0] * norvec[0];
|
|
|
|
|
vec[1] = -si[0] * dirvec[1] + co[0] * norvec[1];
|
|
|
|
|
vec[2] = -si[0] * dirvec[2] + co[0] * norvec[2];
|
2011-09-25 05:48:16 +00:00
|
|
|
|
|
|
|
|
madd_v3_v3v3fl(vec1, headvec, vec, head);
|
|
|
|
|
madd_v3_v3v3fl(vec2, headvec, vec, head + dist);
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
//glColor4ub(255, 255, 255, 50);
|
|
|
|
|
glVertex3fv(vec1);
|
|
|
|
|
//glColor4ub(255, 255, 255, 0);
|
|
|
|
|
glVertex3fv(vec2);
|
|
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* smat, imat = mat & imat to draw screenaligned */
|
2012-12-11 14:29:01 +00:00
|
|
|
static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
|
2012-01-19 16:04:44 +00:00
|
|
|
int armflag, int boneflag, short constflag, unsigned int id,
|
|
|
|
|
bPoseChannel *pchan, EditBone *ebone)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2011-01-13 04:53:55 +00:00
|
|
|
float head, tail /*, length*/;
|
2008-12-20 13:29:35 +00:00
|
|
|
float *headvec, *tailvec, dirvec[3];
|
|
|
|
|
|
|
|
|
|
/* figure out the sizes of spheres */
|
|
|
|
|
if (ebone) {
|
2009-09-19 18:45:31 +00:00
|
|
|
/* this routine doesn't call get_matrix_editbone() that calculates it */
|
2009-11-10 20:43:45 +00:00
|
|
|
ebone->length = len_v3v3(ebone->head, ebone->tail);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-10-26 04:14:10 +00:00
|
|
|
/*length = ebone->length;*/ /*UNUSED*/
|
2012-03-25 23:54:33 +00:00
|
|
|
tail = ebone->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (ebone->parent && (boneflag & BONE_CONNECTED))
|
2012-03-25 23:54:33 +00:00
|
|
|
head = ebone->parent->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
head = ebone->rad_head;
|
|
|
|
|
headvec = ebone->head;
|
|
|
|
|
tailvec = ebone->tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-10-26 04:14:10 +00:00
|
|
|
/*length = pchan->bone->length;*/ /*UNUSED*/
|
2012-03-25 23:54:33 +00:00
|
|
|
tail = pchan->bone->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
if ((pchan->parent) && (boneflag & BONE_CONNECTED))
|
2012-03-25 23:54:33 +00:00
|
|
|
head = pchan->parent->bone->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
head = pchan->bone->rad_head;
|
|
|
|
|
headvec = pchan->pose_head;
|
|
|
|
|
tailvec = pchan->pose_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* sphere root color */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColor(TH_VERTEX);
|
|
|
|
|
}
|
|
|
|
|
else if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* Draw root point if we are not connected */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((boneflag & BONE_CONNECTED) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_ROOT);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
drawcircball(GL_LINE_LOOP, headvec, head, imat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw tip point */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColor(TH_VERTEX);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_TIP);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
|
|
|
|
|
|
|
|
|
|
/* base */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT);
|
2013-06-08 21:58:00 +00:00
|
|
|
else UI_ThemeColor(TH_WIRE_EDIT);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
sub_v3_v3v3(dirvec, tailvec, headvec);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* move vector to viewspace */
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_mat3_m4_v3(smat, dirvec);
|
2008-12-20 13:29:35 +00:00
|
|
|
/* clear zcomp */
|
2012-03-25 23:54:33 +00:00
|
|
|
dirvec[2] = 0.0f;
|
2008-12-20 13:29:35 +00:00
|
|
|
/* move vector back */
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_mat3_m4_v3(imat, dirvec);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
if (0.0f != normalize_v3(dirvec)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
float norvech[3], norvect[3], vec[3];
|
|
|
|
|
|
2011-09-11 02:50:01 +00:00
|
|
|
copy_v3_v3(vec, dirvec);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_v3_fl(dirvec, head);
|
|
|
|
|
cross_v3_v3v3(norvech, dirvec, imat[2]);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_v3_fl(vec, tail);
|
|
|
|
|
cross_v3_v3v3(norvect, vec, imat[2]);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_BONE);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
2011-09-25 05:48:16 +00:00
|
|
|
|
|
|
|
|
add_v3_v3v3(vec, headvec, norvech);
|
2008-12-20 13:29:35 +00:00
|
|
|
glVertex3fv(vec);
|
2011-09-25 05:48:16 +00:00
|
|
|
|
|
|
|
|
add_v3_v3v3(vec, tailvec, norvect);
|
2008-12-20 13:29:35 +00:00
|
|
|
glVertex3fv(vec);
|
2011-09-25 05:48:16 +00:00
|
|
|
|
|
|
|
|
sub_v3_v3v3(vec, headvec, norvech);
|
2008-12-20 13:29:35 +00:00
|
|
|
glVertex3fv(vec);
|
2011-09-25 05:48:16 +00:00
|
|
|
|
|
|
|
|
sub_v3_v3v3(vec, tailvec, norvect);
|
2008-12-20 13:29:35 +00:00
|
|
|
glVertex3fv(vec);
|
|
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* does wire only for outline selecting */
|
2012-06-10 10:15:49 +00:00
|
|
|
static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
|
2012-01-19 16:04:44 +00:00
|
|
|
bPoseChannel *pchan, EditBone *ebone)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
GLUquadricObj *qobj;
|
2008-12-20 13:29:35 +00:00
|
|
|
float head, tail, length;
|
|
|
|
|
float fac1, fac2;
|
|
|
|
|
|
|
|
|
|
glPushMatrix();
|
2012-03-25 23:54:33 +00:00
|
|
|
qobj = gluNewQuadric();
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* figure out the sizes of spheres */
|
|
|
|
|
if (ebone) {
|
2012-03-25 23:54:33 +00:00
|
|
|
length = ebone->length;
|
|
|
|
|
tail = ebone->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (ebone->parent && (boneflag & BONE_CONNECTED))
|
2012-03-25 23:54:33 +00:00
|
|
|
head = ebone->parent->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
head = ebone->rad_head;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
length = pchan->bone->length;
|
|
|
|
|
tail = pchan->bone->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (pchan->parent && (boneflag & BONE_CONNECTED))
|
2012-03-25 23:54:33 +00:00
|
|
|
head = pchan->parent->bone->rad_tail;
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
head = pchan->bone->rad_head;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* move to z-axis space */
|
|
|
|
|
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (dt == OB_SOLID) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* set up solid drawing */
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
gluQuadricDrawStyle(qobj, GLU_FILL);
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* sphere root color */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColorShade(TH_BONE_SOLID, -30);
|
|
|
|
|
}
|
|
|
|
|
else if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag);
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (dt == OB_SOLID)
|
2008-12-20 13:29:35 +00:00
|
|
|
UI_ThemeColorShade(TH_BONE_SOLID, -30);
|
|
|
|
|
|
|
|
|
|
/* Draw root point if we are not connected */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((boneflag & BONE_CONNECTED) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_ROOT);
|
2008-12-20 13:29:35 +00:00
|
|
|
gluSphere(qobj, head, 16, 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw tip point */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColorShade(TH_BONE_SOLID, -30);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_TIP);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-02-10 09:18:04 +00:00
|
|
|
glTranslatef(0.0f, 0.0f, length);
|
2008-12-20 13:29:35 +00:00
|
|
|
gluSphere(qobj, tail, 16, 10);
|
2009-02-10 09:18:04 +00:00
|
|
|
glTranslatef(0.0f, 0.0f, -length);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* base */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_SELECT);
|
|
|
|
|
else UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
}
|
|
|
|
|
else if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
else if (dt == OB_SOLID)
|
|
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
fac1 = (length - head) / length;
|
|
|
|
|
fac2 = (length - tail) / length;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (length > (head + tail)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_BONE);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
2009-02-10 09:18:04 +00:00
|
|
|
glPolygonOffset(-1.0f, -1.0f);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glTranslatef(0.0f, 0.0f, head);
|
2012-03-25 23:54:33 +00:00
|
|
|
gluCylinder(qobj, fac1 * head + (1.0f - fac1) * tail, fac2 * tail + (1.0f - fac2) * head, length - head - tail, 16, 1);
|
2008-12-20 13:29:35 +00:00
|
|
|
glTranslatef(0.0f, 0.0f, -head);
|
|
|
|
|
|
|
|
|
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
|
|
|
|
|
|
|
|
|
/* draw sphere on extrema */
|
2012-03-25 23:54:33 +00:00
|
|
|
glTranslatef(0.0f, 0.0f, length - tail);
|
|
|
|
|
gluSphere(qobj, fac2 * tail + (1.0f - fac2) * head, 16, 10);
|
|
|
|
|
glTranslatef(0.0f, 0.0f, -length + tail);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glTranslatef(0.0f, 0.0f, head);
|
2012-03-25 23:54:33 +00:00
|
|
|
gluSphere(qobj, fac1 * head + (1.0f - fac1) * tail, 16, 10);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
else {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* 1 sphere in center */
|
2012-03-25 23:54:33 +00:00
|
|
|
glTranslatef(0.0f, 0.0f, (head + length - tail) / 2.0f);
|
|
|
|
|
gluSphere(qobj, fac1 * head + (1.0f - fac1) * tail, 16, 10);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* restore */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (dt == OB_SOLID) {
|
2008-12-20 13:29:35 +00:00
|
|
|
glShadeModel(GL_FLAT);
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
gluDeleteQuadric(qobj);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLubyte bm_dot6[] = {0x0, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x0};
|
|
|
|
|
static GLubyte bm_dot8[] = {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C};
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
static GLubyte bm_dot5[] = {0x0, 0x0, 0x10, 0x38, 0x7c, 0x38, 0x10, 0x0};
|
|
|
|
|
static GLubyte bm_dot7[] = {0x0, 0x38, 0x7C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38};
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned int id,
|
|
|
|
|
bPoseChannel *pchan, EditBone *ebone)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
|
|
|
|
float length;
|
|
|
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
|
|
|
|
|
|
if (pchan)
|
2012-03-25 23:54:33 +00:00
|
|
|
length = pchan->bone->length;
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
length = ebone->length;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
glScalef(length, length, length);
|
|
|
|
|
|
|
|
|
|
/* this chunk not in object mode */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) {
|
2009-02-10 09:18:04 +00:00
|
|
|
glLineWidth(4.0f);
|
2008-12-20 13:29:35 +00:00
|
|
|
if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
else if (armflag & ARM_EDITMODE) {
|
2013-06-08 21:58:00 +00:00
|
|
|
UI_ThemeColor(TH_WIRE_EDIT);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw root point if we are not connected */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((boneflag & BONE_CONNECTED) == 0) {
|
2012-07-08 20:36:00 +00:00
|
|
|
if (G.f & G_PICKSEL) { /* no bitmap in selection mode, crashes 3d cards... */
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_ROOT);
|
2008-12-20 13:29:35 +00:00
|
|
|
glBegin(GL_POINTS);
|
|
|
|
|
glVertex3f(0.0f, 0.0f, 0.0f);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
glRasterPos3f(0.0f, 0.0f, 0.0f);
|
|
|
|
|
glBitmap(8, 8, 4, 4, 0, 0, bm_dot8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id((GLuint) id | BONESEL_BONE);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3f(0.0f, 0.0f, 0.0f);
|
|
|
|
|
glVertex3f(0.0f, 1.0f, 0.0f);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
/* tip */
|
2012-10-21 05:46:41 +00:00
|
|
|
if (G.f & G_PICKSEL) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* no bitmap in selection mode, crashes 3d cards... */
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id | BONESEL_TIP);
|
2008-12-20 13:29:35 +00:00
|
|
|
glBegin(GL_POINTS);
|
|
|
|
|
glVertex3f(0.0f, 1.0f, 0.0f);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
glRasterPos3f(0.0f, 1.0f, 0.0f);
|
|
|
|
|
glBitmap(8, 8, 4, 4, 0, 0, bm_dot7);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* further we send no names */
|
|
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_LINEBONE, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glLineWidth(2.0);
|
|
|
|
|
|
|
|
|
|
/*Draw root point if we are not connected */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((boneflag & BONE_CONNECTED) == 0) {
|
|
|
|
|
if ((G.f & G_PICKSEL) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* no bitmap in selection mode, crashes 3d cards... */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_ROOTSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColor(TH_VERTEX);
|
|
|
|
|
}
|
|
|
|
|
glRasterPos3f(0.0f, 0.0f, 0.0f);
|
|
|
|
|
glBitmap(8, 8, 4, 4, 0, 0, bm_dot6);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_EDGE_SELECT);
|
|
|
|
|
else UI_ThemeColorShade(TH_BACK, -30);
|
|
|
|
|
}
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3f(0.0f, 0.0f, 0.0f);
|
|
|
|
|
glVertex3f(0.0f, 1.0f, 0.0f);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
/* tip */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((G.f & G_PICKSEL) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* no bitmap in selection mode, crashes 3d cards... */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
if (boneflag & BONE_TIPSEL) UI_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
|
else UI_ThemeColor(TH_VERTEX);
|
|
|
|
|
}
|
|
|
|
|
glRasterPos3f(0.0f, 1.0f, 0.0f);
|
|
|
|
|
glBitmap(8, 8, 4, 4, 0, 0, bm_dot5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glLineWidth(1.0);
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-10 10:15:49 +00:00
|
|
|
static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, float xwidth, float length, float zwidth)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
int segments = 0;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (pchan)
|
2012-03-25 23:54:33 +00:00
|
|
|
segments = pchan->bone->segments;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if ((segments > 1) && (pchan)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
float dlen = length / (float)segments;
|
2013-07-15 18:46:19 +00:00
|
|
|
Mat4 bbone[MAX_BBONE_SUBDIV];
|
2008-12-20 13:29:35 +00:00
|
|
|
int a;
|
2013-07-15 18:46:19 +00:00
|
|
|
|
|
|
|
|
b_bone_spline_setup(pchan, 0, bbone);
|
|
|
|
|
|
|
|
|
|
for (a = 0; a < segments; a++) {
|
2008-12-20 13:29:35 +00:00
|
|
|
glPushMatrix();
|
2013-07-15 18:46:19 +00:00
|
|
|
glMultMatrixf(bbone[a].mat);
|
2012-03-25 23:54:33 +00:00
|
|
|
if (dt == OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth);
|
2008-12-20 13:29:35 +00:00
|
|
|
else drawcube_size(xwidth, dlen, zwidth);
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
glPushMatrix();
|
2012-03-25 23:54:33 +00:00
|
|
|
if (dt == OB_SOLID) drawsolidcube_size(xwidth, length, zwidth);
|
2008-12-20 13:29:35 +00:00
|
|
|
else drawcube_size(xwidth, length, zwidth);
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-10 10:15:49 +00:00
|
|
|
static void draw_b_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
|
2012-01-19 16:04:44 +00:00
|
|
|
bPoseChannel *pchan, EditBone *ebone)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
|
|
|
|
float xwidth, length, zwidth;
|
|
|
|
|
|
|
|
|
|
if (pchan) {
|
2012-03-25 23:54:33 +00:00
|
|
|
xwidth = pchan->bone->xwidth;
|
|
|
|
|
length = pchan->bone->length;
|
|
|
|
|
zwidth = pchan->bone->zwidth;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
xwidth = ebone->xwidth;
|
|
|
|
|
length = ebone->length;
|
|
|
|
|
zwidth = ebone->zwidth;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* draw points only if... */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
/* move to unitspace */
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
glScalef(length, length, length);
|
|
|
|
|
draw_bone_points(dt, armflag, boneflag, id);
|
|
|
|
|
glPopMatrix();
|
2012-07-08 20:36:00 +00:00
|
|
|
length *= 0.95f; /* make vertices visible */
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* colors for modes */
|
|
|
|
|
if (armflag & ARM_POSEMODE) {
|
|
|
|
|
if (dt <= OB_WIRE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else if (armflag & ARM_EDITMODE) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (dt == OB_WIRE) {
|
2010-12-08 03:05:46 +00:00
|
|
|
set_ebone_glColor(boneflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (id != -1) {
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id((GLuint) id | BONESEL_BONE);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set up solid drawing */
|
|
|
|
|
if (dt > OB_WIRE) {
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
|
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
|
|
|
|
|
draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
|
|
|
|
|
|
|
|
|
|
/* disable solid drawing */
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
else {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* wire */
|
|
|
|
|
if (armflag & ARM_POSEMODE) {
|
|
|
|
|
if (constflag) {
|
|
|
|
|
/* set constraint colors */
|
2010-10-14 01:22:14 +00:00
|
|
|
if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
|
|
|
|
|
draw_b_bone_boxes(OB_SOLID, pchan, xwidth, length, zwidth);
|
|
|
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* restore colors */
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
draw_b_bone_boxes(OB_WIRE, pchan, xwidth, length, zwidth);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-26 12:34:53 +00:00
|
|
|
static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float length, int segments)
|
|
|
|
|
{
|
|
|
|
|
if ((segments > 1) && (pchan)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
float dlen = length / (float)segments;
|
2011-05-26 12:34:53 +00:00
|
|
|
Mat4 *bbone = bbones;
|
|
|
|
|
int a;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (a = 0; a < segments; a++, bbone++) {
|
2011-05-26 12:34:53 +00:00
|
|
|
glPushMatrix();
|
|
|
|
|
glMultMatrixf(bbone->mat);
|
|
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3f(0.0f, 0.0f, 0.0f);
|
|
|
|
|
glVertex3f(0.0f, dlen, 0.0f);
|
2012-07-08 20:36:00 +00:00
|
|
|
glEnd(); /* GL_LINES */
|
2011-05-26 12:34:53 +00:00
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3f(0.0f, 0.0f, 0.0f);
|
|
|
|
|
glVertex3f(0.0f, length, 0.0f);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-10 10:15:49 +00:00
|
|
|
static void draw_wire_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
|
2012-01-19 16:04:44 +00:00
|
|
|
bPoseChannel *pchan, EditBone *ebone)
|
2011-05-26 12:34:53 +00:00
|
|
|
{
|
2013-07-15 18:46:19 +00:00
|
|
|
Mat4 bbones_array[MAX_BBONE_SUBDIV];
|
2011-05-26 12:34:53 +00:00
|
|
|
Mat4 *bbones = NULL;
|
|
|
|
|
int segments = 0;
|
|
|
|
|
float length;
|
|
|
|
|
|
|
|
|
|
if (pchan) {
|
2012-03-25 23:54:33 +00:00
|
|
|
segments = pchan->bone->segments;
|
|
|
|
|
length = pchan->bone->length;
|
2011-05-26 12:34:53 +00:00
|
|
|
|
2013-07-15 18:46:19 +00:00
|
|
|
if (segments > 1) {
|
|
|
|
|
b_bone_spline_setup(pchan, 0, bbones_array);
|
|
|
|
|
bbones = bbones_array;
|
|
|
|
|
}
|
2011-05-26 12:34:53 +00:00
|
|
|
}
|
|
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
length = ebone->length;
|
2011-05-26 12:34:53 +00:00
|
|
|
|
|
|
|
|
/* draw points only if... */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
|
|
|
|
/* move to unitspace */
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
glScalef(length, length, length);
|
|
|
|
|
draw_bone_points(dt, armflag, boneflag, id);
|
|
|
|
|
glPopMatrix();
|
2012-07-08 20:36:00 +00:00
|
|
|
length *= 0.95f; /* make vertices visible */
|
2011-05-26 12:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* this chunk not in object mode */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) {
|
2011-05-26 12:34:53 +00:00
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id((GLuint) id | BONESEL_BONE);
|
2011-05-26 12:34:53 +00:00
|
|
|
|
|
|
|
|
draw_wire_bone_segments(pchan, bbones, length, segments);
|
|
|
|
|
|
|
|
|
|
/* further we send no names */
|
|
|
|
|
if (id != -1)
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */
|
2011-05-26 12:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* colors for modes */
|
|
|
|
|
if (armflag & ARM_POSEMODE) {
|
|
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
|
|
|
|
|
}
|
|
|
|
|
else if (armflag & ARM_EDITMODE) {
|
|
|
|
|
set_ebone_glColor(boneflag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* draw normal */
|
|
|
|
|
draw_wire_bone_segments(pchan, bbones, length, segments);
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-10 10:15:49 +00:00
|
|
|
static void draw_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, float length)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
|
|
|
|
|
2012-03-03 16:31:46 +00:00
|
|
|
/* Draw a 3d octahedral bone, we use normalized space based on length,
|
2012-05-04 11:50:11 +00:00
|
|
|
* for display-lists */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glScalef(length, length, length);
|
|
|
|
|
|
|
|
|
|
/* set up solid drawing */
|
|
|
|
|
if (dt > OB_WIRE) {
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR);
|
2008-12-20 13:29:35 +00:00
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* colors for posemode */
|
|
|
|
|
if (armflag & ARM_POSEMODE) {
|
|
|
|
|
if (dt <= OB_WIRE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
draw_bone_points(dt, armflag, boneflag, id);
|
|
|
|
|
|
|
|
|
|
/* now draw the bone itself */
|
|
|
|
|
if (id != -1) {
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id((GLuint) id | BONESEL_BONE);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* wire? */
|
|
|
|
|
if (dt <= OB_WIRE) {
|
|
|
|
|
/* colors */
|
|
|
|
|
if (armflag & ARM_EDITMODE) {
|
2010-12-08 03:05:46 +00:00
|
|
|
set_ebone_glColor(boneflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else if (armflag & ARM_POSEMODE) {
|
|
|
|
|
if (constflag) {
|
|
|
|
|
/* draw constraint colors */
|
2012-10-21 05:46:41 +00:00
|
|
|
if (set_pchan_glColor(PCHAN_COLOR_CONSTS, boneflag, constflag)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
|
|
|
|
|
draw_bone_solid_octahedral();
|
|
|
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* restore colors */
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_bone_octahedral();
|
|
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
else {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* solid */
|
|
|
|
|
if (armflag & ARM_POSEMODE)
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_SOLID, boneflag, constflag);
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
|
|
|
|
UI_ThemeColor(TH_BONE_SOLID);
|
|
|
|
|
draw_bone_solid_octahedral();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* disable solid drawing */
|
|
|
|
|
if (dt > OB_WIRE) {
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
|
2012-06-10 10:15:49 +00:00
|
|
|
const short dt, int armflag, int boneflag, unsigned int id, float length)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ob == NULL) return;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glScalef(length, length, length);
|
|
|
|
|
|
|
|
|
|
/* colors for posemode */
|
|
|
|
|
if (armflag & ARM_POSEMODE) {
|
2010-10-14 01:22:14 +00:00
|
|
|
set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, 0);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (id != -1) {
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id((GLuint) id | BONESEL_BONE);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2.5
View3D has been split now in a local part (RegionView3D) and a
per-area part (old View3D). Currently local is:
- view transform
- camera zoom/offset
- gpencil (todo)
- custom clipping planes
Rest is in Area still, like active camera, draw type, layers,
localview, custom centers, around-settings, transform widget,
gridlines, and so on (mostly stuff as available in header).
To see it work; also added new feature for region split,
press SHIFT+ALT+CTRL+S for four-split.
The idea is to make a preset 4-split, configured to stick
to top/right/front views for three views.
Another cool idea to explore is to then box-clip all drawing
based on these 3 views.
Note about the code:
- currently view3d still stores some depricated settings, to
convert from older files. Not all settings are copied over
though, like custom clip planes or the 'lock view to object'.
- since some view3d ops are now on area level, the operators
for it should keep track of that.
Bugfix in transform: quat initialize in operator-invoke missed
one zero.
Als brought back GE to compile for missing Ipos and channels.
2009-01-19 16:54:41 +00:00
|
|
|
draw_object_instance(scene, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp)
|
|
|
|
|
{
|
|
|
|
|
bConstraint *con;
|
|
|
|
|
bPoseChannel *parchan;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (con = pchan->constraints.first; con; con = con->next) {
|
2009-11-01 11:29:40 +00:00
|
|
|
if (con->enforce == 0.0f)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
switch (con->type) {
|
|
|
|
|
case CONSTRAINT_TYPE_KINEMATIC:
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
bKinematicConstraint *data = (bKinematicConstraint *)con->data;
|
|
|
|
|
int segcount = 0;
|
2009-11-01 11:29:40 +00:00
|
|
|
|
|
|
|
|
/* if only_temp, only draw if it is a temporary ik-chain */
|
|
|
|
|
if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
setlinestyle(3);
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
|
|
|
|
|
/* exclude tip from chain? */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((data->flag & CONSTRAINT_IK_TIP) == 0)
|
|
|
|
|
parchan = pchan->parent;
|
2009-11-01 11:29:40 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
parchan = pchan;
|
2009-11-01 11:29:40 +00:00
|
|
|
|
|
|
|
|
glVertex3fv(parchan->pose_tail);
|
|
|
|
|
|
|
|
|
|
/* Find the chain's root */
|
|
|
|
|
while (parchan->parent) {
|
|
|
|
|
segcount++;
|
2012-07-08 20:36:00 +00:00
|
|
|
if (segcount == data->rootbone || segcount > 255) {
|
|
|
|
|
break; /* 255 is weak */
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
parchan = parchan->parent;
|
2009-11-01 11:29:40 +00:00
|
|
|
}
|
|
|
|
|
if (parchan)
|
|
|
|
|
glVertex3fv(parchan->pose_head);
|
|
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
setlinestyle(0);
|
2013-07-19 15:23:42 +00:00
|
|
|
break;
|
2009-11-01 11:29:40 +00:00
|
|
|
}
|
|
|
|
|
case CONSTRAINT_TYPE_SPLINEIK:
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
|
|
|
|
|
int segcount = 0;
|
2009-11-01 11:29:40 +00:00
|
|
|
|
|
|
|
|
setlinestyle(3);
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
parchan = pchan;
|
2009-11-01 11:29:40 +00:00
|
|
|
glVertex3fv(parchan->pose_tail);
|
|
|
|
|
|
|
|
|
|
/* Find the chain's root */
|
|
|
|
|
while (parchan->parent) {
|
|
|
|
|
segcount++;
|
2012-07-08 20:36:00 +00:00
|
|
|
/* FIXME: revise the breaking conditions */
|
|
|
|
|
if (segcount == data->chainlen || segcount > 255) break; /* 255 is weak */
|
2012-03-25 23:54:33 +00:00
|
|
|
parchan = parchan->parent;
|
2009-11-01 11:29:40 +00:00
|
|
|
}
|
2012-07-08 20:36:00 +00:00
|
|
|
if (parchan) /* XXX revise the breaking conditions to only stop at the tail? */
|
2009-11-01 11:29:40 +00:00
|
|
|
glVertex3fv(parchan->pose_head);
|
2012-07-08 20:36:00 +00:00
|
|
|
|
2009-11-01 11:29:40 +00:00
|
|
|
glEnd();
|
|
|
|
|
setlinestyle(0);
|
2013-07-19 15:23:42 +00:00
|
|
|
break;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void bgl_sphere_project(float ax, float az)
|
|
|
|
|
{
|
|
|
|
|
float dir[3], sine, q3;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
sine = 1.0f - ax * ax - az * az;
|
2014-03-28 14:53:37 +11:00
|
|
|
q3 = (sine < 0.0f) ? 0.0f : (2.0f * sqrtf(sine));
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
dir[0] = -az * q3;
|
|
|
|
|
dir[1] = 1.0f - 2.0f * sine;
|
|
|
|
|
dir[2] = ax * q3;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glVertex3fv(dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void draw_dof_ellipse(float ax, float az)
|
|
|
|
|
{
|
2014-04-27 07:50:08 +10:00
|
|
|
const float staticSine[16] = {
|
2009-02-10 09:18:04 +00:00
|
|
|
0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f,
|
|
|
|
|
0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f,
|
|
|
|
|
0.743144825477f, 0.809016994375f, 0.866025403784f,
|
|
|
|
|
0.913545457643f, 0.951056516295f, 0.978147600734f,
|
|
|
|
|
0.994521895368f, 1.0f
|
2008-12-20 13:29:35 +00:00
|
|
|
};
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
int i, j, n = 16;
|
2008-12-20 13:29:35 +00:00
|
|
|
float x, z, px, pz;
|
|
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
glDepthMask(0);
|
|
|
|
|
|
|
|
|
|
glColor4ub(70, 70, 70, 50);
|
|
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
2012-03-25 23:54:33 +00:00
|
|
|
pz = 0.0f;
|
|
|
|
|
for (i = 1; i < n; i++) {
|
|
|
|
|
z = staticSine[i];
|
2009-02-10 09:18:04 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
px = 0.0f;
|
2013-08-11 05:40:35 +00:00
|
|
|
for (j = 1; j <= (n - i); j++) {
|
2008-12-20 13:29:35 +00:00
|
|
|
x = staticSine[j];
|
2009-02-10 09:18:04 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (j == n - i) {
|
2008-12-20 13:29:35 +00:00
|
|
|
glEnd();
|
|
|
|
|
glBegin(GL_TRIANGLES);
|
2012-03-25 23:54:33 +00:00
|
|
|
bgl_sphere_project(ax * px, az * z);
|
|
|
|
|
bgl_sphere_project(ax * px, az * pz);
|
|
|
|
|
bgl_sphere_project(ax * x, az * pz);
|
2008-12-20 13:29:35 +00:00
|
|
|
glEnd();
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
bgl_sphere_project(ax * x, az * z);
|
|
|
|
|
bgl_sphere_project(ax * x, az * pz);
|
|
|
|
|
bgl_sphere_project(ax * px, az * pz);
|
|
|
|
|
bgl_sphere_project(ax * px, az * z);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2009-02-10 09:18:04 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
px = x;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
pz = z;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
glDepthMask(1);
|
|
|
|
|
|
|
|
|
|
glColor3ub(0, 0, 0);
|
|
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2012-03-25 23:54:33 +00:00
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
|
bgl_sphere_project(staticSine[n - i - 1] * ax, staticSine[i] * az);
|
2008-12-20 13:29:35 +00:00
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void draw_pose_dofs(Object *ob)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
bArmature *arm = ob->data;
|
2008-12-20 13:29:35 +00:00
|
|
|
bPoseChannel *pchan;
|
|
|
|
|
Bone *bone;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
bone = pchan->bone;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((bone != NULL) && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (bone->flag & BONE_SELECTED) {
|
|
|
|
|
if (bone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (pchan->ikflag & (BONE_IK_XLIMIT | BONE_IK_ZLIMIT)) {
|
2013-09-13 03:03:46 +00:00
|
|
|
if (BKE_pose_channel_in_IK_chain(ob, pchan)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
float corner[4][3], posetrans[3], mat[4][4];
|
2012-03-25 23:54:33 +00:00
|
|
|
float phi = 0.0f, theta = 0.0f, scale;
|
2008-12-20 13:29:35 +00:00
|
|
|
int a, i;
|
|
|
|
|
|
|
|
|
|
/* in parent-bone pose, but own restspace */
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
|
2011-09-11 02:50:01 +00:00
|
|
|
copy_v3_v3(posetrans, pchan->pose_mat[3]);
|
2015-09-20 18:11:25 +02:00
|
|
|
glTranslate3fv(posetrans);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (pchan->parent) {
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m4_m4(mat, pchan->parent->pose_mat);
|
2012-03-25 23:54:33 +00:00
|
|
|
mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
|
2008-12-20 13:29:35 +00:00
|
|
|
glMultMatrixf(mat);
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m4_m3(mat, pchan->bone->bone_mat);
|
2008-12-20 13:29:35 +00:00
|
|
|
glMultMatrixf(mat);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
scale = bone->length * pchan->size[1];
|
2008-12-20 13:29:35 +00:00
|
|
|
glScalef(scale, scale, scale);
|
|
|
|
|
|
|
|
|
|
if (pchan->ikflag & BONE_IK_XLIMIT) {
|
|
|
|
|
if (pchan->ikflag & BONE_IK_ZLIMIT) {
|
|
|
|
|
float amin[3], amax[3];
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (i = 0; i < 3; i++) {
|
2010-02-07 04:38:45 +00:00
|
|
|
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
|
2013-04-04 04:22:38 +00:00
|
|
|
amin[i] = sinf(pchan->limitmin[i] * 0.5f);
|
|
|
|
|
amax[i] = sinf(pchan->limitmax[i] * 0.5f);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-10 09:18:04 +00:00
|
|
|
glScalef(1.0f, -1.0f, 1.0f);
|
|
|
|
|
if ((amin[0] != 0.0f) && (amin[2] != 0.0f))
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_dof_ellipse(amin[0], amin[2]);
|
2009-02-10 09:18:04 +00:00
|
|
|
if ((amin[0] != 0.0f) && (amax[2] != 0.0f))
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_dof_ellipse(amin[0], amax[2]);
|
2009-02-10 09:18:04 +00:00
|
|
|
if ((amax[0] != 0.0f) && (amin[2] != 0.0f))
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_dof_ellipse(amax[0], amin[2]);
|
2009-02-10 09:18:04 +00:00
|
|
|
if ((amax[0] != 0.0f) && (amax[2] != 0.0f))
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_dof_ellipse(amax[0], amax[2]);
|
2009-02-10 09:18:04 +00:00
|
|
|
glScalef(1.0f, -1.0f, 1.0f);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* arcs */
|
|
|
|
|
if (pchan->ikflag & BONE_IK_ZLIMIT) {
|
2010-02-07 04:38:45 +00:00
|
|
|
/* OpenGL requires rotations in degrees; so we're taking the average angle here */
|
2012-03-25 23:54:33 +00:00
|
|
|
theta = RAD2DEGF(0.5f * (pchan->limitmin[2] + pchan->limitmax[2]));
|
2008-12-20 13:29:35 +00:00
|
|
|
glRotatef(theta, 0.0f, 0.0f, 1.0f);
|
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
glColor3ub(50, 50, 255); /* blue, Z axis limit */
|
2008-12-20 13:29:35 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
2012-03-25 23:54:33 +00:00
|
|
|
for (a = -16; a <= 16; a++) {
|
2012-01-19 16:04:44 +00:00
|
|
|
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
|
2012-03-25 23:54:33 +00:00
|
|
|
float fac = ((float)a) / 16.0f * 0.5f;
|
2009-02-10 09:18:04 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
phi = fac * (pchan->limitmax[2] - pchan->limitmin[2]);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
i = (a == -16) ? 0 : 1;
|
2013-04-04 04:22:38 +00:00
|
|
|
corner[i][0] = sinf(phi);
|
|
|
|
|
corner[i][1] = cosf(phi);
|
2012-03-25 23:54:33 +00:00
|
|
|
corner[i][2] = 0.0f;
|
2008-12-20 13:29:35 +00:00
|
|
|
glVertex3fv(corner[i]);
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glRotatef(-theta, 0.0f, 0.0f, 1.0f);
|
2012-07-08 20:36:00 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (pchan->ikflag & BONE_IK_XLIMIT) {
|
2011-04-28 09:46:53 +00:00
|
|
|
/* OpenGL requires rotations in degrees; so we're taking the average angle here */
|
2012-03-25 23:54:33 +00:00
|
|
|
theta = RAD2DEGF(0.5f * (pchan->limitmin[0] + pchan->limitmax[0]));
|
2008-12-20 13:29:35 +00:00
|
|
|
glRotatef(theta, 1.0f, 0.0f, 0.0f);
|
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
glColor3ub(255, 50, 50); /* Red, X axis limit */
|
2008-12-20 13:29:35 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
2012-03-25 23:54:33 +00:00
|
|
|
for (a = -16; a <= 16; a++) {
|
2012-01-19 16:04:44 +00:00
|
|
|
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
|
2012-03-25 23:54:33 +00:00
|
|
|
float fac = ((float)a) / 16.0f * 0.5f;
|
2015-01-31 17:23:30 +11:00
|
|
|
phi = (float)M_PI_2 + fac * (pchan->limitmax[0] - pchan->limitmin[0]);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
i = (a == -16) ? 2 : 3;
|
|
|
|
|
corner[i][0] = 0.0f;
|
2013-04-04 04:22:38 +00:00
|
|
|
corner[i][1] = sinf(phi);
|
|
|
|
|
corner[i][2] = cosf(phi);
|
2008-12-20 13:29:35 +00:00
|
|
|
glVertex3fv(corner[i]);
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glRotatef(-theta, 1.0f, 0.0f, 0.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* out of cone, out of bone */
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-11 14:29:01 +00:00
|
|
|
static void bone_matrix_translate_y(float mat[4][4], float y)
|
2009-09-19 18:45:31 +00:00
|
|
|
{
|
|
|
|
|
float trans[3];
|
|
|
|
|
|
2011-09-11 02:50:01 +00:00
|
|
|
copy_v3_v3(trans, mat[1]);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_v3_fl(trans, y);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(mat[3], trans);
|
2009-09-19 18:45:31 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* assumes object is Armature with pose */
|
2012-06-06 18:00:08 +00:00
|
|
|
static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
|
2012-06-10 10:15:49 +00:00
|
|
|
const short dt, const unsigned char ob_wire_col[4],
|
2013-03-20 23:14:18 +00:00
|
|
|
const bool do_const_color, const bool is_outline)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
|
|
|
|
Object *ob = base->object;
|
|
|
|
|
bArmature *arm = ob->data;
|
2008-12-20 13:29:35 +00:00
|
|
|
bPoseChannel *pchan;
|
|
|
|
|
Bone *bone;
|
|
|
|
|
GLfloat tmp;
|
2009-09-19 18:45:31 +00:00
|
|
|
float smat[4][4], imat[4][4], bmat[4][4];
|
2012-03-25 23:54:33 +00:00
|
|
|
int index = -1;
|
2013-03-20 23:14:18 +00:00
|
|
|
short do_dashed = 3;
|
|
|
|
|
bool draw_wire = false;
|
2011-09-25 04:55:04 +00:00
|
|
|
int flag;
|
2014-03-11 13:08:43 +06:00
|
|
|
bool is_cull_enabled;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2010-12-12 18:16:54 +00:00
|
|
|
/* being set below */
|
2012-03-25 23:54:33 +00:00
|
|
|
arm->layer_used = 0;
|
2010-12-12 18:16:54 +00:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* hacky... prevent outline select from drawing dashed helplines */
|
|
|
|
|
glGetFloatv(GL_LINE_WIDTH, &tmp);
|
2011-03-27 14:59:55 +00:00
|
|
|
if (tmp > 1.1f) do_dashed &= ~1;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (v3d->flag & V3D_HIDE_HELPLINES) do_dashed &= ~2;
|
|
|
|
|
|
|
|
|
|
/* precalc inverse matrix for drawing screen aligned */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (arm->drawtype == ARM_ENVELOPE) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* precalc inverse matrix for drawing screen aligned */
|
2010-02-01 15:32:55 +00:00
|
|
|
copy_m4_m4(smat, rv3d->viewmatob);
|
2012-03-25 23:54:33 +00:00
|
|
|
mul_mat3_m4_fl(smat, 1.0f / len_v3(ob->obmat[0]));
|
2009-11-10 20:43:45 +00:00
|
|
|
invert_m4_m4(imat, smat);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* and draw blended distances */
|
|
|
|
|
if (arm->flag & ARM_POSEMODE) {
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
//glShadeModel(GL_SMOOTH);
|
|
|
|
|
|
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
bone = pchan->bone;
|
2011-04-28 09:46:53 +00:00
|
|
|
if (bone) {
|
|
|
|
|
/* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194]
|
2012-05-25 09:51:53 +00:00
|
|
|
* NOTE: this is the only case with (NO_DEFORM == 0) flag, as this is for envelope influence drawing
|
2011-04-28 09:46:53 +00:00
|
|
|
*/
|
2012-09-09 00:00:21 +00:00
|
|
|
if (((bone->flag & (BONE_HIDDEN_P | BONE_NO_DEFORM | BONE_HIDDEN_PG)) == 0) &&
|
|
|
|
|
((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0))
|
2011-04-28 09:46:53 +00:00
|
|
|
{
|
|
|
|
|
if (bone->flag & (BONE_SELECTED)) {
|
|
|
|
|
if (bone->layer & arm->layer)
|
|
|
|
|
draw_sphere_bone_dist(smat, imat, pchan, NULL);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
//glShadeModel(GL_FLAT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* little speedup, also make sure transparent only draws once */
|
2014-03-11 13:08:43 +06:00
|
|
|
glCullFace(GL_BACK);
|
|
|
|
|
if (v3d->flag2 & V3D_BACKFACE_CULLING) {
|
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
|
is_cull_enabled = true;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
is_cull_enabled = false;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* if solid we draw that first, with selection codes, but without names, axes etc */
|
|
|
|
|
if (dt > OB_WIRE) {
|
|
|
|
|
if (arm->flag & ARM_POSEMODE)
|
2012-03-25 23:54:33 +00:00
|
|
|
index = base->selcol;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
bone = pchan->bone;
|
2010-12-12 18:16:54 +00:00
|
|
|
arm->layer_used |= bone->layer;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2011-04-28 09:46:53 +00:00
|
|
|
/* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */
|
2012-09-09 00:00:21 +00:00
|
|
|
if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) &&
|
|
|
|
|
((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0))
|
2011-04-28 09:46:53 +00:00
|
|
|
{
|
2008-12-20 13:29:35 +00:00
|
|
|
if (bone->layer & arm->layer) {
|
2013-03-22 04:40:45 +00:00
|
|
|
const bool use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM);
|
2008-12-20 13:29:35 +00:00
|
|
|
glPushMatrix();
|
2011-04-28 09:46:53 +00:00
|
|
|
|
2011-05-26 12:34:53 +00:00
|
|
|
if (use_custom && pchan->custom_tx) {
|
2010-01-05 11:47:43 +00:00
|
|
|
glMultMatrixf(pchan->custom_tx->pose_mat);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2011-04-28 09:46:53 +00:00
|
|
|
else {
|
2010-01-05 11:47:43 +00:00
|
|
|
glMultMatrixf(pchan->pose_mat);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* catch exception for bone with hidden parent */
|
2012-03-25 23:54:33 +00:00
|
|
|
flag = bone->flag;
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) {
|
2008-12-20 13:29:35 +00:00
|
|
|
flag &= ~BONE_CONNECTED;
|
2012-09-09 00:00:21 +00:00
|
|
|
}
|
2009-11-09 23:41:48 +00:00
|
|
|
|
2010-02-05 11:39:58 +00:00
|
|
|
/* set temporary flag for drawing bone as active, but only if selected */
|
2010-12-08 03:05:46 +00:00
|
|
|
if (bone == arm->act_bone)
|
2009-11-09 21:03:54 +00:00
|
|
|
flag |= BONE_DRAW_ACTIVE;
|
2009-11-09 23:41:48 +00:00
|
|
|
|
2012-06-07 09:04:45 +00:00
|
|
|
if (do_const_color) {
|
|
|
|
|
/* keep color */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* set color-set to use */
|
|
|
|
|
set_pchan_colorset(ob, pchan);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2010-01-05 11:47:43 +00:00
|
|
|
if (use_custom) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* if drawwire, don't try to draw in solid */
|
2012-01-19 16:04:44 +00:00
|
|
|
if (pchan->bone->flag & BONE_DRAWWIRE) {
|
2013-03-20 23:14:18 +00:00
|
|
|
draw_wire = true;
|
2012-01-19 16:04:44 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2014-03-11 13:08:43 +06:00
|
|
|
if (is_cull_enabled && (v3d->flag2 & V3D_BACKFACE_CULLING) == 0) {
|
|
|
|
|
is_cull_enabled = false;
|
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
draw_custom_bone(scene, v3d, rv3d, pchan->custom,
|
2015-09-21 23:49:58 +10:00
|
|
|
OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
|
2012-01-19 16:04:44 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-03-10 22:00:55 +00:00
|
|
|
else {
|
2014-03-11 13:08:43 +06:00
|
|
|
if (is_cull_enabled == false) {
|
|
|
|
|
is_cull_enabled = true;
|
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (arm->drawtype == ARM_LINE) {
|
|
|
|
|
/* nothing in solid */
|
|
|
|
|
}
|
|
|
|
|
else if (arm->drawtype == ARM_WIRE) {
|
|
|
|
|
/* nothing in solid */
|
|
|
|
|
}
|
|
|
|
|
else if (arm->drawtype == ARM_ENVELOPE) {
|
|
|
|
|
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (arm->drawtype == ARM_B_BONE) {
|
|
|
|
|
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length);
|
|
|
|
|
}
|
2012-03-10 22:00:55 +00:00
|
|
|
}
|
2014-03-11 13:08:43 +06:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (index != -1)
|
2012-07-08 20:36:00 +00:00
|
|
|
index += 0x10000; /* pose bones count in higher 2 bytes only */
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-23 15:24:07 +02:00
|
|
|
/* very very confusing... but in object mode, solid draw, we cannot do GPU_select_load_id yet,
|
2008-12-20 13:29:35 +00:00
|
|
|
* stick bones and/or wire custom-shapes are drawn in next loop
|
|
|
|
|
*/
|
2014-07-21 15:49:16 +02:00
|
|
|
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && (draw_wire == false) && index != -1) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* object tag, for bordersel optim */
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(index & 0xFFFF);
|
2012-03-25 23:54:33 +00:00
|
|
|
index = -1;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* draw custom bone shapes as wireframes */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (!(arm->flag & ARM_NO_CUSTOM) &&
|
2013-03-20 23:14:18 +00:00
|
|
|
(draw_wire || (dt <= OB_WIRE)) )
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
|
|
|
|
if (arm->flag & ARM_POSEMODE)
|
2012-03-25 23:54:33 +00:00
|
|
|
index = base->selcol;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* only draw custom bone shapes that need to be drawn as wires */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
bone = pchan->bone;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2011-04-28 09:46:53 +00:00
|
|
|
/* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */
|
2012-09-09 00:00:21 +00:00
|
|
|
if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) &&
|
|
|
|
|
((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0) )
|
2011-04-28 09:46:53 +00:00
|
|
|
{
|
2008-12-20 13:29:35 +00:00
|
|
|
if (bone->layer & arm->layer) {
|
|
|
|
|
if (pchan->custom) {
|
|
|
|
|
if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) {
|
|
|
|
|
glPushMatrix();
|
2011-04-28 09:46:53 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (pchan->custom_tx) {
|
2010-01-05 11:47:43 +00:00
|
|
|
glMultMatrixf(pchan->custom_tx->pose_mat);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2011-04-28 09:46:53 +00:00
|
|
|
else {
|
2010-01-05 11:47:43 +00:00
|
|
|
glMultMatrixf(pchan->pose_mat);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* prepare colors */
|
2012-06-07 08:02:48 +00:00
|
|
|
if (do_const_color) {
|
2010-10-14 00:33:39 +00:00
|
|
|
/* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */
|
|
|
|
|
}
|
2012-06-07 08:02:48 +00:00
|
|
|
else if (arm->flag & ARM_POSEMODE)
|
2008-12-20 13:29:35 +00:00
|
|
|
set_pchan_colorset(ob, pchan);
|
|
|
|
|
else {
|
2012-06-06 18:00:08 +00:00
|
|
|
glColor3ubv(ob_wire_col);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* catch exception for bone with hidden parent */
|
2012-03-25 23:54:33 +00:00
|
|
|
flag = bone->flag;
|
|
|
|
|
if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)))
|
2008-12-20 13:29:35 +00:00
|
|
|
flag &= ~BONE_CONNECTED;
|
2009-11-09 23:41:48 +00:00
|
|
|
|
2010-02-05 11:39:58 +00:00
|
|
|
/* set temporary flag for drawing bone as active, but only if selected */
|
2010-12-08 03:05:46 +00:00
|
|
|
if (bone == arm->act_bone)
|
2009-11-09 23:41:48 +00:00
|
|
|
flag |= BONE_DRAW_ACTIVE;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-01-19 16:04:44 +00:00
|
|
|
draw_custom_bone(scene, v3d, rv3d, pchan->custom,
|
2015-09-21 23:49:58 +10:00
|
|
|
OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (index != -1)
|
2012-07-08 20:36:00 +00:00
|
|
|
index += 0x10000; /* pose bones count in higher 2 bytes only */
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-03-18 07:38:51 +00:00
|
|
|
/* stick or wire bones have not been drawn yet so don't clear object selection in this case */
|
2014-07-21 15:49:16 +02:00
|
|
|
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && draw_wire && index != -1) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* object tag, for bordersel optim */
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(index & 0xFFFF);
|
2012-03-25 23:54:33 +00:00
|
|
|
index = -1;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* wire draw over solid only in posemode */
|
2011-10-19 00:41:48 +00:00
|
|
|
if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* draw line check first. we do selection indices */
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (arm->flag & ARM_POSEMODE)
|
2012-03-25 23:54:33 +00:00
|
|
|
index = base->selcol;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
/* if solid && posemode, we draw again with polygonoffset */
|
|
|
|
|
else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) {
|
2013-12-09 20:59:29 +11:00
|
|
|
ED_view3d_polygon_offset(rv3d, 1.0);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* and we use selection indices if not done yet */
|
|
|
|
|
if (arm->flag & ARM_POSEMODE)
|
2012-03-25 23:54:33 +00:00
|
|
|
index = base->selcol;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2014-03-11 13:08:43 +06:00
|
|
|
|
|
|
|
|
if (is_cull_enabled == false) {
|
|
|
|
|
is_cull_enabled = true;
|
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
bone = pchan->bone;
|
2010-12-12 18:16:54 +00:00
|
|
|
arm->layer_used |= bone->layer;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2011-04-28 09:46:53 +00:00
|
|
|
/* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */
|
2012-09-09 00:00:21 +00:00
|
|
|
if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) &&
|
|
|
|
|
((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0))
|
2011-04-28 09:46:53 +00:00
|
|
|
{
|
2008-12-20 13:29:35 +00:00
|
|
|
if (bone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
const short constflag = pchan->constflag;
|
2010-11-15 11:45:54 +00:00
|
|
|
if ((do_dashed & 1) && (pchan->parent)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* Draw a line from our root to the parent's tip
|
2012-07-08 20:36:00 +00:00
|
|
|
* - only if V3D_HIDE_HELPLINES is enabled...
|
2008-12-20 13:29:35 +00:00
|
|
|
*/
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((do_dashed & 2) && ((bone->flag & BONE_CONNECTED) == 0)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (arm->flag & ARM_POSEMODE) {
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(index & 0xFFFF); /* object tag, for bordersel optim */
|
2008-12-20 13:29:35 +00:00
|
|
|
UI_ThemeColor(TH_WIRE);
|
|
|
|
|
}
|
|
|
|
|
setlinestyle(3);
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3fv(pchan->pose_head);
|
|
|
|
|
glVertex3fv(pchan->parent->pose_tail);
|
|
|
|
|
glEnd();
|
|
|
|
|
setlinestyle(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw a line to IK root bone
|
2012-03-25 23:54:33 +00:00
|
|
|
* - only if temporary chain (i.e. "autoik")
|
2008-12-20 13:29:35 +00:00
|
|
|
*/
|
|
|
|
|
if (arm->flag & ARM_POSEMODE) {
|
2011-09-25 04:55:04 +00:00
|
|
|
if (constflag & PCHAN_HAS_IK) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (bone->flag & BONE_SELECTED) {
|
2011-09-25 04:55:04 +00:00
|
|
|
if (constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0);
|
2012-07-08 20:36:00 +00:00
|
|
|
else glColor3ub(200, 200, 50); /* add theme! */
|
|
|
|
|
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(index & 0xFFFF);
|
2008-12-20 13:29:35 +00:00
|
|
|
pchan_draw_IK_root_lines(pchan, !(do_dashed & 2));
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-09-25 04:55:04 +00:00
|
|
|
else if (constflag & PCHAN_HAS_SPLINEIK) {
|
2009-11-01 11:29:40 +00:00
|
|
|
if (bone->flag & BONE_SELECTED) {
|
2012-07-08 20:36:00 +00:00
|
|
|
glColor3ub(150, 200, 50); /* add theme! */
|
2009-11-01 11:29:40 +00:00
|
|
|
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(index & 0xFFFF);
|
2009-11-01 11:29:40 +00:00
|
|
|
pchan_draw_IK_root_lines(pchan, !(do_dashed & 2));
|
|
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
if (arm->drawtype != ARM_ENVELOPE)
|
|
|
|
|
glMultMatrixf(pchan->pose_mat);
|
|
|
|
|
|
|
|
|
|
/* catch exception for bone with hidden parent */
|
2012-03-25 23:54:33 +00:00
|
|
|
flag = bone->flag;
|
|
|
|
|
if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)))
|
2008-12-20 13:29:35 +00:00
|
|
|
flag &= ~BONE_CONNECTED;
|
|
|
|
|
|
2010-02-05 11:39:58 +00:00
|
|
|
/* set temporary flag for drawing bone as active, but only if selected */
|
2010-12-08 03:05:46 +00:00
|
|
|
if (bone == arm->act_bone)
|
2009-11-09 23:41:48 +00:00
|
|
|
flag |= BONE_DRAW_ACTIVE;
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* extra draw service for pose mode */
|
2011-07-05 09:35:38 +00:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* set color-set to use */
|
2012-06-07 09:04:45 +00:00
|
|
|
if (do_const_color) {
|
|
|
|
|
/* keep color */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
set_pchan_colorset(ob, pchan);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-10 22:00:55 +00:00
|
|
|
if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
|
|
|
|
|
/* custom bone shapes should not be drawn here! */
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (arm->drawtype == ARM_ENVELOPE) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (dt < OB_SOLID)
|
|
|
|
|
draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL);
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (arm->drawtype == ARM_LINE)
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (arm->drawtype == ARM_WIRE)
|
2011-05-26 12:34:53 +00:00
|
|
|
draw_wire_bone(dt, arm->flag, flag, constflag, index, pchan, NULL);
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (arm->drawtype == ARM_B_BONE)
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
|
|
|
|
|
else
|
|
|
|
|
draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length);
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* pose bones count in higher 2 bytes only */
|
|
|
|
|
if (index != -1)
|
2012-03-25 23:54:33 +00:00
|
|
|
index += 0x10000;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
/* restore things */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (!ELEM(arm->drawtype, ARM_WIRE, ARM_LINE) && (dt > OB_WIRE) && (arm->flag & ARM_POSEMODE))
|
2013-12-09 20:59:29 +11:00
|
|
|
ED_view3d_polygon_offset(rv3d, 0.0);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* restore */
|
2014-03-11 13:08:43 +06:00
|
|
|
if (is_cull_enabled) {
|
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* draw DoFs */
|
2012-06-07 08:20:10 +00:00
|
|
|
if (arm->flag & ARM_POSEMODE) {
|
2014-07-30 12:00:11 +02:00
|
|
|
if (((base->flag & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) {
|
2012-06-07 08:20:10 +00:00
|
|
|
draw_pose_dofs(ob);
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* finally names and axes */
|
2012-06-07 08:20:10 +00:00
|
|
|
if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) &&
|
|
|
|
|
(is_outline == 0) &&
|
|
|
|
|
((base->flag & OB_FROMDUPLI) == 0))
|
|
|
|
|
{
|
2012-05-04 11:50:11 +00:00
|
|
|
/* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */
|
2008-12-20 13:29:35 +00:00
|
|
|
if ((G.f & G_PICKSEL) == 0) {
|
|
|
|
|
float vec[3];
|
2012-06-07 08:02:48 +00:00
|
|
|
|
2010-12-20 03:59:22 +00:00
|
|
|
unsigned char col[4];
|
2012-06-07 08:02:48 +00:00
|
|
|
if (do_const_color) {
|
|
|
|
|
/* so we can draw bone names in current const color */
|
|
|
|
|
float tcol[4];
|
|
|
|
|
glGetFloatv(GL_CURRENT_COLOR, tcol);
|
|
|
|
|
rgb_float_to_uchar(col, tcol);
|
|
|
|
|
col[3] = 255;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
col[0] = ob_wire_col[0];
|
|
|
|
|
col[1] = ob_wire_col[1];
|
|
|
|
|
col[2] = ob_wire_col[2];
|
|
|
|
|
col[3] = 255;
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
|
|
|
|
if ((pchan->bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (pchan->bone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (arm->flag & (ARM_EDITMODE | ARM_POSEMODE)) {
|
|
|
|
|
bone = pchan->bone;
|
2010-12-20 03:59:22 +00:00
|
|
|
UI_GetThemeColor3ubv((bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2010-12-20 03:59:22 +00:00
|
|
|
else if (dt > OB_WIRE) {
|
|
|
|
|
UI_GetThemeColor3ubv(TH_TEXT, col);
|
|
|
|
|
}
|
2011-04-28 09:46:53 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
/* Draw names of bone */
|
2008-12-20 13:29:35 +00:00
|
|
|
if (arm->flag & ARM_DRAWNAMES) {
|
2009-11-10 20:43:45 +00:00
|
|
|
mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail);
|
2014-04-17 15:14:07 +10:00
|
|
|
view3d_cached_text_draw_add(vec, pchan->name, strlen(pchan->name), 10, 0, col);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* Draw additional axes on the bone tail */
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
glPushMatrix();
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m4_m4(bmat, pchan->pose_mat);
|
2009-09-19 18:45:31 +00:00
|
|
|
bone_matrix_translate_y(bmat, pchan->bone->length);
|
|
|
|
|
glMultMatrixf(bmat);
|
2011-04-28 09:46:53 +00:00
|
|
|
|
2010-12-20 03:59:22 +00:00
|
|
|
glColor3ubv(col);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawaxes(pchan->bone->length * 0.25f, OB_ARROWS);
|
2011-04-28 09:46:53 +00:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-10-17 16:48:09 +02:00
|
|
|
|
|
|
|
|
if (index != -1) {
|
|
|
|
|
GPU_select_load_id(-1);
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* in editmode, we don't store the bone matrix... */
|
2013-07-25 12:07:55 +00:00
|
|
|
static void get_matrix_editbone(EditBone *ebone, float bmat[4][4])
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2013-07-25 12:07:55 +00:00
|
|
|
ebone->length = len_v3v3(ebone->tail, ebone->head);
|
|
|
|
|
ED_armature_ebone_to_mat4(ebone, bmat);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-10 10:15:49 +00:00
|
|
|
static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
RegionView3D *rv3d = ar->regiondata;
|
2008-12-20 13:29:35 +00:00
|
|
|
EditBone *eBone;
|
2012-03-25 23:54:33 +00:00
|
|
|
bArmature *arm = ob->data;
|
2009-09-19 18:45:31 +00:00
|
|
|
float smat[4][4], imat[4][4], bmat[4][4];
|
2008-12-20 13:29:35 +00:00
|
|
|
unsigned int index;
|
|
|
|
|
int flag;
|
|
|
|
|
|
2010-12-12 18:16:54 +00:00
|
|
|
/* being set in code below */
|
2012-03-25 23:54:33 +00:00
|
|
|
arm->layer_used = 0;
|
2013-05-08 13:00:52 +00:00
|
|
|
|
|
|
|
|
ED_view3d_check_mats_rv3d(rv3d);
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* envelope (deform distance) */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (arm->drawtype == ARM_ENVELOPE) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* precalc inverse matrix for drawing screen aligned */
|
2010-02-01 15:32:55 +00:00
|
|
|
copy_m4_m4(smat, rv3d->viewmatob);
|
2012-03-25 23:54:33 +00:00
|
|
|
mul_mat3_m4_fl(smat, 1.0f / len_v3(ob->obmat[0]));
|
2009-11-10 20:43:45 +00:00
|
|
|
invert_m4_m4(imat, smat);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* and draw blended distances */
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
//glShadeModel(GL_SMOOTH);
|
|
|
|
|
|
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (eBone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((eBone->flag & (BONE_HIDDEN_A | BONE_NO_DEFORM)) == 0) {
|
|
|
|
|
if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL))
|
2010-10-14 01:22:14 +00:00
|
|
|
draw_sphere_bone_dist(smat, imat, NULL, eBone);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
//glShadeModel(GL_FLAT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if solid we draw it first */
|
2011-05-26 12:34:53 +00:00
|
|
|
if ((dt > OB_WIRE) && (arm->drawtype != ARM_LINE)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (eBone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
glPushMatrix();
|
2009-09-19 18:45:31 +00:00
|
|
|
get_matrix_editbone(eBone, bmat);
|
|
|
|
|
glMultMatrixf(bmat);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* catch exception for bone with hidden parent */
|
2012-03-25 23:54:33 +00:00
|
|
|
flag = eBone->flag;
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
flag &= ~BONE_CONNECTED;
|
2012-09-09 00:00:21 +00:00
|
|
|
}
|
2009-11-09 23:41:48 +00:00
|
|
|
|
2010-02-05 11:39:58 +00:00
|
|
|
/* set temporary flag for drawing bone as active, but only if selected */
|
2010-12-08 03:05:46 +00:00
|
|
|
if (eBone == arm->act_edbone)
|
2009-11-09 23:41:48 +00:00
|
|
|
flag |= BONE_DRAW_ACTIVE;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (arm->drawtype == ARM_ENVELOPE)
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (arm->drawtype == ARM_B_BONE)
|
2008-12-20 13:29:35 +00:00
|
|
|
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (arm->drawtype == ARM_WIRE)
|
2011-05-26 12:34:53 +00:00
|
|
|
draw_wire_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
|
2008-12-20 13:29:35 +00:00
|
|
|
else {
|
|
|
|
|
draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if wire over solid, set offset */
|
2012-03-25 23:54:33 +00:00
|
|
|
index = -1;
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(-1);
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (G.f & G_PICKSEL)
|
2012-03-25 23:54:33 +00:00
|
|
|
index = 0;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else if (dt > OB_WIRE)
|
2013-12-09 20:59:29 +11:00
|
|
|
ED_view3d_polygon_offset(rv3d, 1.0);
|
2008-12-20 13:29:35 +00:00
|
|
|
else if (arm->flag & ARM_EDITMODE)
|
2012-03-25 23:54:33 +00:00
|
|
|
index = 0; /* do selection codes */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
|
2010-12-12 18:16:54 +00:00
|
|
|
arm->layer_used |= eBone->layer;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (eBone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* catch exception for bone with hidden parent */
|
2012-03-25 23:54:33 +00:00
|
|
|
flag = eBone->flag;
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) {
|
2008-12-20 13:29:35 +00:00
|
|
|
flag &= ~BONE_CONNECTED;
|
2012-09-09 00:00:21 +00:00
|
|
|
}
|
2009-11-09 23:41:48 +00:00
|
|
|
|
2010-02-05 11:39:58 +00:00
|
|
|
/* set temporary flag for drawing bone as active, but only if selected */
|
2010-12-08 03:05:46 +00:00
|
|
|
if (eBone == arm->act_edbone)
|
2009-11-09 23:41:48 +00:00
|
|
|
flag |= BONE_DRAW_ACTIVE;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (arm->drawtype == ARM_ENVELOPE) {
|
|
|
|
|
if (dt < OB_SOLID)
|
|
|
|
|
draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
glPushMatrix();
|
2009-09-19 18:45:31 +00:00
|
|
|
get_matrix_editbone(eBone, bmat);
|
|
|
|
|
glMultMatrixf(bmat);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (arm->drawtype == ARM_LINE)
|
|
|
|
|
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (arm->drawtype == ARM_WIRE)
|
2011-05-26 12:34:53 +00:00
|
|
|
draw_wire_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
|
2008-12-20 13:29:35 +00:00
|
|
|
else if (arm->drawtype == ARM_B_BONE)
|
|
|
|
|
draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
|
|
|
|
|
else
|
|
|
|
|
draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length);
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* offset to parent */
|
|
|
|
|
if (eBone->parent) {
|
2013-06-08 21:58:00 +00:00
|
|
|
UI_ThemeColor(TH_WIRE_EDIT);
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(-1); /* -1 here is OK! */
|
2008-12-20 13:29:35 +00:00
|
|
|
setlinestyle(3);
|
|
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3fv(eBone->parent->tail);
|
|
|
|
|
glVertex3fv(eBone->head);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
setlinestyle(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
if (index != -1) index++;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* restore */
|
2012-10-07 09:48:59 +00:00
|
|
|
if (index != -1) {
|
2014-07-23 15:24:07 +02:00
|
|
|
GPU_select_load_id(-1);
|
2012-10-07 09:48:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
|
|
|
|
|
/* pass */
|
|
|
|
|
}
|
|
|
|
|
else if (dt > OB_WIRE) {
|
2013-12-09 20:59:29 +11:00
|
|
|
ED_view3d_polygon_offset(rv3d, 0.0);
|
2012-10-07 09:48:59 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* finally names and axes */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) {
|
2012-07-08 20:36:00 +00:00
|
|
|
/* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */
|
2008-12-20 13:29:35 +00:00
|
|
|
if ((G.f & G_PICKSEL) == 0) {
|
|
|
|
|
float vec[3];
|
2010-12-20 03:59:22 +00:00
|
|
|
unsigned char col[4];
|
2012-03-25 23:54:33 +00:00
|
|
|
col[3] = 255;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (eBone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((eBone->flag & BONE_HIDDEN_A) == 0) {
|
2010-12-20 03:59:22 +00:00
|
|
|
|
|
|
|
|
UI_GetThemeColor3ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col);
|
|
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* Draw name */
|
|
|
|
|
if (arm->flag & ARM_DRAWNAMES) {
|
2009-11-10 20:43:45 +00:00
|
|
|
mid_v3_v3v3(vec, eBone->head, eBone->tail);
|
2008-12-20 13:29:35 +00:00
|
|
|
glRasterPos3fv(vec);
|
2014-04-17 15:14:07 +10:00
|
|
|
view3d_cached_text_draw_add(vec, eBone->name, strlen(eBone->name), 10, 0, col);
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
/* Draw additional axes */
|
|
|
|
|
if (arm->flag & ARM_DRAWAXES) {
|
|
|
|
|
glPushMatrix();
|
2009-09-19 18:45:31 +00:00
|
|
|
get_matrix_editbone(eBone, bmat);
|
|
|
|
|
bone_matrix_translate_y(bmat, eBone->length);
|
|
|
|
|
glMultMatrixf(bmat);
|
2010-12-20 03:59:22 +00:00
|
|
|
|
|
|
|
|
glColor3ubv(col);
|
2012-03-25 23:54:33 +00:00
|
|
|
drawaxes(eBone->length * 0.25f, OB_ARROWS);
|
2009-11-09 23:41:48 +00:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-03 19:09:07 +00:00
|
|
|
/* ****************************** Armature Visualization ******************************** */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* ---------- Paths --------- */
|
|
|
|
|
|
|
|
|
|
/* draw bone paths
|
|
|
|
|
* - in view space
|
|
|
|
|
*/
|
2009-09-19 18:45:31 +00:00
|
|
|
static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
bAnimVizSettings *avs = &ob->pose->avs;
|
|
|
|
|
bArmature *arm = ob->data;
|
2008-12-20 13:29:35 +00:00
|
|
|
bPoseChannel *pchan;
|
|
|
|
|
|
2010-01-19 11:31:49 +00:00
|
|
|
/* setup drawing environment for paths */
|
2010-10-14 01:22:14 +00:00
|
|
|
draw_motion_paths_init(v3d, ar);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2010-01-19 11:31:49 +00:00
|
|
|
/* draw paths where they exist and they releated bone is visible */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
2010-01-19 11:31:49 +00:00
|
|
|
if ((pchan->bone->layer & arm->layer) && (pchan->mpath))
|
2010-10-14 01:22:14 +00:00
|
|
|
draw_motion_path_instance(scene, ob, pchan, avs, pchan->mpath);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
2010-01-19 11:31:49 +00:00
|
|
|
/* cleanup after drawing */
|
2010-10-14 01:22:14 +00:00
|
|
|
draw_motion_paths_cleanup(v3d);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------- Ghosts --------- */
|
|
|
|
|
|
|
|
|
|
/* helper function for ghost drawing - sets/removes flags for temporarily
|
|
|
|
|
* hiding unselected bones while drawing ghosts
|
|
|
|
|
*/
|
|
|
|
|
static void ghost_poses_tag_unselected(Object *ob, short unset)
|
|
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
bArmature *arm = ob->data;
|
|
|
|
|
bPose *pose = ob->pose;
|
2008-12-20 13:29:35 +00:00
|
|
|
bPoseChannel *pchan;
|
|
|
|
|
|
|
|
|
|
/* don't do anything if no hiding any bones */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((arm->flag & ARM_GHOST_ONLYSEL) == 0)
|
2008-12-20 13:29:35 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* loop over all pchans, adding/removing tags as appropriate */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
|
|
|
|
|
if (unset) {
|
|
|
|
|
/* remove tags from all pchans if cleaning up */
|
|
|
|
|
pchan->bone->flag &= ~BONE_HIDDEN_PG;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* set tags on unselected pchans only */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((pchan->bone->flag & BONE_SELECTED) == 0)
|
2008-12-20 13:29:35 +00:00
|
|
|
pchan->bone->flag |= BONE_HIDDEN_PG;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* draw ghosts that occur within a frame range
|
2012-03-25 23:54:33 +00:00
|
|
|
* note: object should be in posemode
|
2008-12-20 13:29:35 +00:00
|
|
|
*/
|
2009-09-19 18:45:31 +00:00
|
|
|
static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *ob = base->object;
|
|
|
|
|
AnimData *adt = BKE_animdata_from_id(&ob->id);
|
|
|
|
|
bArmature *arm = ob->data;
|
2008-12-20 13:29:35 +00:00
|
|
|
bPose *posen, *poseo;
|
|
|
|
|
float start, end, stepsize, range, colfac;
|
2015-08-17 14:22:23 +10:00
|
|
|
int cfrao, flago;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-02-10 09:18:04 +00:00
|
|
|
start = (float)arm->ghostsf;
|
|
|
|
|
end = (float)arm->ghostef;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (end <= start)
|
|
|
|
|
return;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
stepsize = (float)(arm->ghostsize);
|
|
|
|
|
range = (float)(end - start);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* store values */
|
2009-08-16 03:24:23 +00:00
|
|
|
ob->mode &= ~OB_MODE_POSE;
|
2012-03-25 23:54:33 +00:00
|
|
|
cfrao = CFRA;
|
|
|
|
|
flago = arm->flag;
|
|
|
|
|
arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* copy the pose */
|
2012-03-25 23:54:33 +00:00
|
|
|
poseo = ob->pose;
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_copy_data(&posen, ob->pose, 1);
|
2012-03-25 23:54:33 +00:00
|
|
|
ob->pose = posen;
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */
|
2012-03-25 23:54:33 +00:00
|
|
|
ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
|
|
/* draw from first frame of range to last */
|
2014-11-16 18:12:35 +13:00
|
|
|
for (CFRA = (int)start; CFRA <= end; CFRA += (int)stepsize) {
|
2009-02-10 09:18:04 +00:00
|
|
|
colfac = (end - (float)CFRA) / range;
|
2014-03-28 14:53:37 +11:00
|
|
|
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
|
2008-12-20 13:29:35 +00:00
|
|
|
|
== RNA Property Updates get called by Animation System now ==
This fixes bug #26764 and several others like it, where modifier
properties (and others, but most visibly modifiers) would not do
anything when animated or driven, as modifier properties require the
RNA update calls to tag the modifiers to get recalculated.
While just adding a call to RNA_property_update() could have gotten
this working (as per the Campbell's patch attached in the report, and
also my own attempt #25881). However, on production rigs, the
performance cost of this is untenatable (on my own tests, without
these updates, I was getting ~5fps on such a rig, but only 0.9fps or
possibly even worse with the updates added).
Hence, this commit adds a property-update caching system to the RNA
level, which aims to reduce to the number of times that the update
functions end up needing to get called.
While this is much faster than without the caching, I also added an
optimisation for pose bones (which are numerous in production rigs) so
that their property updates are skipped, since they are useless to the
animsys (they only tag the depsgraph for updating). This gets things
moving at a more acceptable framerate.
2011-07-24 04:34:46 +00:00
|
|
|
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_where_is(scene, ob);
|
2013-03-20 23:14:18 +00:00
|
|
|
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
2012-08-30 12:59:46 +00:00
|
|
|
|
|
|
|
|
/* before disposing of temp pose, use it to restore object to a sane state */
|
|
|
|
|
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL);
|
|
|
|
|
|
|
|
|
|
/* clean up temporary pose */
|
2012-03-25 23:54:33 +00:00
|
|
|
ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_free(posen);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* restore */
|
2012-03-25 23:54:33 +00:00
|
|
|
CFRA = cfrao;
|
|
|
|
|
ob->pose = poseo;
|
|
|
|
|
arm->flag = flago;
|
2009-08-16 03:24:23 +00:00
|
|
|
ob->mode |= OB_MODE_POSE;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* draw ghosts on keyframes in action within range
|
|
|
|
|
* - object should be in posemode
|
|
|
|
|
*/
|
2009-09-19 18:45:31 +00:00
|
|
|
static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *ob = base->object;
|
|
|
|
|
AnimData *adt = BKE_animdata_from_id(&ob->id);
|
|
|
|
|
bAction *act = (adt) ? adt->action : NULL;
|
|
|
|
|
bArmature *arm = ob->data;
|
2008-12-20 13:29:35 +00:00
|
|
|
bPose *posen, *poseo;
|
2009-07-18 07:11:37 +00:00
|
|
|
DLRBT_Tree keys;
|
2008-12-20 13:29:35 +00:00
|
|
|
ActKeyColumn *ak, *akn;
|
|
|
|
|
float start, end, range, colfac, i;
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
int cfrao, flago;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-07-09 13:14:51 +00:00
|
|
|
start = (float)arm->ghostsf;
|
|
|
|
|
end = (float)arm->ghostef;
|
2008-12-20 13:29:35 +00:00
|
|
|
if (end <= start)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* get keyframes - then clip to only within range */
|
2009-07-18 07:11:37 +00:00
|
|
|
BLI_dlrbTree_init(&keys);
|
2009-07-09 13:14:51 +00:00
|
|
|
action_to_keylist(adt, act, &keys, NULL);
|
2009-07-18 07:11:37 +00:00
|
|
|
BLI_dlrbTree_linkedlist_sync(&keys);
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
range = 0;
|
|
|
|
|
for (ak = keys.first; ak; ak = akn) {
|
|
|
|
|
akn = ak->next;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if ((ak->cfra < start) || (ak->cfra > end))
|
2009-07-18 07:11:37 +00:00
|
|
|
BLI_freelinkN((ListBase *)&keys, ak);
|
2008-12-20 13:29:35 +00:00
|
|
|
else
|
|
|
|
|
range++;
|
|
|
|
|
}
|
|
|
|
|
if (range == 0) return;
|
|
|
|
|
|
|
|
|
|
/* store values */
|
2009-08-16 03:24:23 +00:00
|
|
|
ob->mode &= ~OB_MODE_POSE;
|
2012-03-25 23:54:33 +00:00
|
|
|
cfrao = CFRA;
|
|
|
|
|
flago = arm->flag;
|
|
|
|
|
arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES);
|
2015-08-17 14:22:23 +10:00
|
|
|
|
2008-12-20 13:29:35 +00:00
|
|
|
/* copy the pose */
|
2012-03-25 23:54:33 +00:00
|
|
|
poseo = ob->pose;
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_copy_data(&posen, ob->pose, 1);
|
2012-03-25 23:54:33 +00:00
|
|
|
ob->pose = posen;
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */
|
2012-03-25 23:54:33 +00:00
|
|
|
ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
|
|
/* draw from first frame of range to last */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (ak = keys.first, i = 0; ak; ak = ak->next, i++) {
|
|
|
|
|
colfac = i / range;
|
2014-03-28 14:53:37 +11:00
|
|
|
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
CFRA = (int)ak->cfra;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
== RNA Property Updates get called by Animation System now ==
This fixes bug #26764 and several others like it, where modifier
properties (and others, but most visibly modifiers) would not do
anything when animated or driven, as modifier properties require the
RNA update calls to tag the modifiers to get recalculated.
While just adding a call to RNA_property_update() could have gotten
this working (as per the Campbell's patch attached in the report, and
also my own attempt #25881). However, on production rigs, the
performance cost of this is untenatable (on my own tests, without
these updates, I was getting ~5fps on such a rig, but only 0.9fps or
possibly even worse with the updates added).
Hence, this commit adds a property-update caching system to the RNA
level, which aims to reduce to the number of times that the update
functions end up needing to get called.
While this is much faster than without the caching, I also added an
optimisation for pose bones (which are numerous in production rigs) so
that their property updates are skipped, since they are useless to the
animsys (they only tag the depsgraph for updating). This gets things
moving at a more acceptable framerate.
2011-07-24 04:34:46 +00:00
|
|
|
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_where_is(scene, ob);
|
2013-03-20 23:14:18 +00:00
|
|
|
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
2012-08-30 12:59:46 +00:00
|
|
|
|
|
|
|
|
/* before disposing of temp pose, use it to restore object to a sane state */
|
|
|
|
|
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL);
|
|
|
|
|
|
|
|
|
|
/* clean up temporary pose */
|
2012-03-25 23:54:33 +00:00
|
|
|
ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
|
2009-07-18 07:11:37 +00:00
|
|
|
BLI_dlrbTree_free(&keys);
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_free(posen);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* restore */
|
2012-03-25 23:54:33 +00:00
|
|
|
CFRA = cfrao;
|
|
|
|
|
ob->pose = poseo;
|
|
|
|
|
arm->flag = flago;
|
2009-08-16 03:24:23 +00:00
|
|
|
ob->mode |= OB_MODE_POSE;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* draw ghosts around current frame
|
2012-03-25 23:54:33 +00:00
|
|
|
* - object is supposed to be armature in posemode
|
2008-12-20 13:29:35 +00:00
|
|
|
*/
|
2009-09-19 18:45:31 +00:00
|
|
|
static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *ob = base->object;
|
|
|
|
|
AnimData *adt = BKE_animdata_from_id(&ob->id);
|
|
|
|
|
bArmature *arm = ob->data;
|
2008-12-20 13:29:35 +00:00
|
|
|
bPose *posen, *poseo;
|
|
|
|
|
float cur, start, end, stepsize, range, colfac, actframe, ctime;
|
2009-06-25 10:52:09 +00:00
|
|
|
int cfrao, flago;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* pre conditions, get an action with sufficient frames */
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM(NULL, adt, adt->action))
|
2009-06-25 10:52:09 +00:00
|
|
|
return;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-06-25 10:52:09 +00:00
|
|
|
calc_action_range(adt->action, &start, &end, 0);
|
2008-12-20 13:29:35 +00:00
|
|
|
if (start == end)
|
|
|
|
|
return;
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
stepsize = (float)(arm->ghostsize);
|
|
|
|
|
range = (float)(arm->ghostep) * stepsize + 0.5f; /* plus half to make the for loop end correct */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* store values */
|
2009-08-16 03:24:23 +00:00
|
|
|
ob->mode &= ~OB_MODE_POSE;
|
2012-03-25 23:54:33 +00:00
|
|
|
cfrao = CFRA;
|
|
|
|
|
actframe = BKE_nla_tweakedit_remap(adt, (float)CFRA, 0);
|
|
|
|
|
flago = arm->flag;
|
|
|
|
|
arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* copy the pose */
|
2012-03-25 23:54:33 +00:00
|
|
|
poseo = ob->pose;
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_copy_data(&posen, ob->pose, 1);
|
2012-03-25 23:54:33 +00:00
|
|
|
ob->pose = posen;
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */
|
2012-03-25 23:54:33 +00:00
|
|
|
ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
|
|
/* draw from darkest blend to lowest */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (cur = stepsize; cur < range; cur += stepsize) {
|
|
|
|
|
ctime = cur - (float)fmod(cfrao, stepsize); /* ensures consistent stepping */
|
|
|
|
|
colfac = ctime / range;
|
2014-03-28 14:53:37 +11:00
|
|
|
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* only within action range */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (actframe + ctime >= start && actframe + ctime <= end) {
|
|
|
|
|
CFRA = (int)BKE_nla_tweakedit_remap(adt, actframe + ctime, NLATIME_CONVERT_MAP);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2009-02-10 09:18:04 +00:00
|
|
|
if (CFRA != cfrao) {
|
== RNA Property Updates get called by Animation System now ==
This fixes bug #26764 and several others like it, where modifier
properties (and others, but most visibly modifiers) would not do
anything when animated or driven, as modifier properties require the
RNA update calls to tag the modifiers to get recalculated.
While just adding a call to RNA_property_update() could have gotten
this working (as per the Campbell's patch attached in the report, and
also my own attempt #25881). However, on production rigs, the
performance cost of this is untenatable (on my own tests, without
these updates, I was getting ~5fps on such a rig, but only 0.9fps or
possibly even worse with the updates added).
Hence, this commit adds a property-update caching system to the RNA
level, which aims to reduce to the number of times that the update
functions end up needing to get called.
While this is much faster than without the caching, I also added an
optimisation for pose bones (which are numerous in production rigs) so
that their property updates are skipped, since they are useless to the
animsys (they only tag the depsgraph for updating). This gets things
moving at a more acceptable framerate.
2011-07-24 04:34:46 +00:00
|
|
|
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_where_is(scene, ob);
|
2013-03-20 23:14:18 +00:00
|
|
|
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
ctime = cur + (float)fmod((float)cfrao, stepsize) - stepsize + 1.0f; /* ensures consistent stepping */
|
|
|
|
|
colfac = ctime / range;
|
2014-03-28 14:53:37 +11:00
|
|
|
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* only within action range */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((actframe - ctime >= start) && (actframe - ctime <= end)) {
|
|
|
|
|
CFRA = (int)BKE_nla_tweakedit_remap(adt, actframe - ctime, NLATIME_CONVERT_MAP);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
if (CFRA != cfrao) {
|
== RNA Property Updates get called by Animation System now ==
This fixes bug #26764 and several others like it, where modifier
properties (and others, but most visibly modifiers) would not do
anything when animated or driven, as modifier properties require the
RNA update calls to tag the modifiers to get recalculated.
While just adding a call to RNA_property_update() could have gotten
this working (as per the Campbell's patch attached in the report, and
also my own attempt #25881). However, on production rigs, the
performance cost of this is untenatable (on my own tests, without
these updates, I was getting ~5fps on such a rig, but only 0.9fps or
possibly even worse with the updates added).
Hence, this commit adds a property-update caching system to the RNA
level, which aims to reduce to the number of times that the update
functions end up needing to get called.
While this is much faster than without the caching, I also added an
optimisation for pose bones (which are numerous in production rigs) so
that their property updates are skipped, since they are useless to the
animsys (they only tag the depsgraph for updating). This gets things
moving at a more acceptable framerate.
2011-07-24 04:34:46 +00:00
|
|
|
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_where_is(scene, ob);
|
2013-03-20 23:14:18 +00:00
|
|
|
draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, true, false);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
|
2012-08-30 12:59:46 +00:00
|
|
|
|
|
|
|
|
/* before disposing of temp pose, use it to restore object to a sane state */
|
|
|
|
|
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL);
|
|
|
|
|
|
|
|
|
|
/* clean up temporary pose */
|
2012-03-25 23:54:33 +00:00
|
|
|
ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_free(posen);
|
2008-12-20 13:29:35 +00:00
|
|
|
|
|
|
|
|
/* restore */
|
2012-03-25 23:54:33 +00:00
|
|
|
CFRA = cfrao;
|
|
|
|
|
ob->pose = poseo;
|
|
|
|
|
arm->flag = flago;
|
2009-08-16 03:24:23 +00:00
|
|
|
ob->mode |= OB_MODE_POSE;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ********************************** Armature Drawing - Main ************************* */
|
|
|
|
|
|
2012-06-06 18:00:08 +00:00
|
|
|
/* called from drawobject.c, return 1 if nothing was drawn
|
|
|
|
|
* (ob_wire_col == NULL) when drawing ghost */
|
2013-03-20 23:14:18 +00:00
|
|
|
bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
|
|
|
|
|
const short dt, const short dflag, const unsigned char ob_wire_col[4],
|
|
|
|
|
const bool is_outline)
|
2008-12-20 13:29:35 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *ob = base->object;
|
|
|
|
|
bArmature *arm = ob->data;
|
2013-03-20 23:14:18 +00:00
|
|
|
bool retval = false;
|
2008-12-20 13:29:35 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (v3d->flag2 & V3D_RENDER_OVERRIDE)
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2015-11-27 21:36:59 +01:00
|
|
|
|
|
|
|
|
if (dt > OB_WIRE) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* we use color for solid lighting */
|
2015-11-27 21:36:59 +01:00
|
|
|
if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
|
|
|
|
|
const float diffuse[3] = {0.64f, 0.64f, 0.64f};
|
|
|
|
|
const float specular[3] = {0.5f, 0.5f, 0.5f};
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_colors(diffuse, specular, 35, 1.0f);
|
2015-11-27 21:36:59 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const float diffuse[3] = {1.0f, 1.0f, 1.0f};
|
|
|
|
|
const float specular[3] = {1.0f, 1.0f, 1.0f};
|
2015-12-05 22:11:31 +01:00
|
|
|
GPU_basic_shader_colors(diffuse, specular, 35, 1.0f);
|
2015-11-27 21:36:59 +01:00
|
|
|
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); /* only for lighting... */
|
|
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* arm->flag is being used to detect mode... */
|
|
|
|
|
/* editmode? */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (arm->edbo) {
|
2009-01-02 19:10:35 +00:00
|
|
|
arm->flag |= ARM_EDITMODE;
|
2009-09-19 18:45:31 +00:00
|
|
|
draw_ebones(v3d, ar, ob, dt);
|
2008-12-20 13:29:35 +00:00
|
|
|
arm->flag &= ~ARM_EDITMODE;
|
|
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
else {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* Draw Pose */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->pose && ob->pose->chanbase.first) {
|
2008-12-20 13:29:35 +00:00
|
|
|
/* drawing posemode selection indices or colors only in these cases */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!(base->flag & OB_FROMDUPLI)) {
|
|
|
|
|
if (G.f & G_PICKSEL) {
|
2012-03-25 23:54:33 +00:00
|
|
|
#if 0
|
|
|
|
|
/* nifty but actually confusing to allow bone selection out of posemode */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ob == modifiers_isDeformedByArmature(OBACT))
|
2009-09-19 15:48:47 +00:00
|
|
|
arm->flag |= ARM_POSEMODE;
|
|
|
|
|
}
|
2011-03-23 16:05:35 +00:00
|
|
|
else
|
|
|
|
|
#endif
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->mode & OB_MODE_POSE) {
|
2008-12-20 13:29:35 +00:00
|
|
|
arm->flag |= ARM_POSEMODE;
|
2011-03-23 16:05:35 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (ob->mode & OB_MODE_POSE) {
|
2008-12-20 13:29:35 +00:00
|
|
|
if (arm->ghosttype == ARM_GHOST_RANGE) {
|
2009-09-19 18:45:31 +00:00
|
|
|
draw_ghost_poses_range(scene, v3d, ar, base);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else if (arm->ghosttype == ARM_GHOST_KEYS) {
|
2009-09-19 18:45:31 +00:00
|
|
|
draw_ghost_poses_keys(scene, v3d, ar, base);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
else if (arm->ghosttype == ARM_GHOST_CUR) {
|
|
|
|
|
if (arm->ghostep)
|
2009-09-19 18:45:31 +00:00
|
|
|
draw_ghost_poses(scene, v3d, ar, base);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-06-10 10:15:49 +00:00
|
|
|
if ((dflag & DRAW_SCENESET) == 0) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ob == OBACT)
|
2008-12-20 13:29:35 +00:00
|
|
|
arm->flag |= ARM_POSEMODE;
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ob == modifiers_isDeformedByArmature(OBACT))
|
2009-01-10 14:19:14 +00:00
|
|
|
arm->flag |= ARM_POSEMODE;
|
|
|
|
|
}
|
2009-09-19 18:45:31 +00:00
|
|
|
draw_pose_paths(scene, v3d, ar, ob);
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
2012-06-10 10:15:49 +00:00
|
|
|
draw_pose_bones(scene, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline);
|
2008-12-20 13:29:35 +00:00
|
|
|
arm->flag &= ~ARM_POSEMODE;
|
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->mode & OB_MODE_POSE)
|
2012-03-25 23:54:33 +00:00
|
|
|
UI_ThemeColor(TH_WIRE); /* restore, for extra draw stuff */
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-03-20 23:14:18 +00:00
|
|
|
retval = true;
|
2008-12-20 13:29:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* restore */
|
|
|
|
|
glFrontFace(GL_CCW);
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
}
|