#ifdef HAVE_CONFIG_H #include <config.h> #endif Just need to finish cpp files now :) Kent -- mein@cs.umn.edu
3584 lines
78 KiB
C
3584 lines
78 KiB
C
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#include "BLI_winstuff.h"
|
|
#endif
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BMF_Api.h"
|
|
|
|
#include "IMB_imbuf.h"
|
|
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_arithb.h"
|
|
#include "BLI_editVert.h"
|
|
|
|
#include "MTC_matrixops.h"
|
|
|
|
#include "DNA_camera_types.h"
|
|
#include "DNA_curve_types.h"
|
|
#include "DNA_effect_types.h"
|
|
#include "DNA_ipo_types.h"
|
|
#include "DNA_lamp_types.h"
|
|
#include "DNA_lattice_types.h"
|
|
#include "DNA_material_types.h"
|
|
#include "DNA_mesh_types.h"
|
|
#include "DNA_meta_types.h"
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_space_types.h"
|
|
#include "DNA_scene_types.h"
|
|
#include "DNA_screen_types.h"
|
|
#include "DNA_view3d_types.h"
|
|
#include "DNA_world_types.h"
|
|
|
|
#include "BKE_utildefines.h"
|
|
#include "BKE_curve.h"
|
|
#include "BKE_object.h"
|
|
#include "BKE_global.h"
|
|
#include "BKE_displist.h"
|
|
#include "BKE_material.h"
|
|
#include "BKE_ipo.h"
|
|
#include "BKE_mesh.h"
|
|
#include "BKE_effect.h"
|
|
#include "BKE_lattice.h"
|
|
|
|
#include "BIF_gl.h"
|
|
#include "BIF_mywindow.h"
|
|
#include "BIF_screen.h"
|
|
#include "BIF_space.h"
|
|
#include "BIF_editarmature.h"
|
|
#include "BIF_editika.h"
|
|
#include "BIF_editmesh.h"
|
|
|
|
#include "BDR_drawmesh.h"
|
|
#include "BDR_drawobject.h"
|
|
#include "BDR_editobject.h"
|
|
|
|
#include "BSE_view.h"
|
|
#include "BSE_drawview.h"
|
|
#include "BSE_trans_types.h"
|
|
|
|
#include "blendef.h"
|
|
#include "mydevice.h"
|
|
#include "nla.h"
|
|
|
|
#ifdef __NLA
|
|
#include "BKE_deform.h"
|
|
#endif
|
|
|
|
/* pretty stupid */
|
|
/* extern Lattice *editLatt; already in BKE_lattice.h */
|
|
/* editcurve.c */
|
|
extern ListBase editNurb;
|
|
/* editmball.c */
|
|
extern ListBase editelems;
|
|
|
|
/* more or less needed forwards */
|
|
static void drawmeshwire(Object *ob);
|
|
|
|
/***/
|
|
|
|
// Materials start counting at # one....
|
|
#define MAXMATBUF (MAXMAT + 1)
|
|
static float matbuf[MAXMATBUF][2][4];
|
|
|
|
static void init_gl_materials(Object *ob)
|
|
{
|
|
extern Material defmaterial;
|
|
Material *ma;
|
|
int a;
|
|
|
|
if(ob->totcol==0) {
|
|
matbuf[0][0][0]= defmaterial.r;
|
|
matbuf[0][0][1]= defmaterial.g;
|
|
matbuf[0][0][2]= defmaterial.b;
|
|
matbuf[0][0][3]= 1.0;
|
|
|
|
matbuf[0][1][0]= defmaterial.specr;
|
|
matbuf[0][1][1]= defmaterial.specg;
|
|
matbuf[0][1][2]= defmaterial.specb;
|
|
matbuf[0][1][3]= 1.0;
|
|
|
|
/* ook matnr 1, displists! */
|
|
VECCOPY(matbuf[1][0], matbuf[0][0]);
|
|
VECCOPY(matbuf[1][1], matbuf[0][1]);
|
|
}
|
|
|
|
for(a=1; a<=ob->totcol; a++) {
|
|
ma= give_current_material(ob, a);
|
|
if(ma==NULL) ma= &defmaterial;
|
|
if(a<MAXMATBUF) {
|
|
matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r;
|
|
matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g;
|
|
matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b;
|
|
matbuf[a][0][3]= 1.0;
|
|
|
|
matbuf[a][1][0]= ma->spec*ma->specr;
|
|
matbuf[a][1][1]= ma->spec*ma->specg;
|
|
matbuf[a][1][2]= ma->spec*ma->specb;
|
|
matbuf[a][1][3]= 1.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void set_gl_material(int nr)
|
|
{
|
|
if(nr<MAXMATBUF) {
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matbuf[nr][0]);
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matbuf[nr][1]);
|
|
}
|
|
}
|
|
|
|
/***/
|
|
|
|
unsigned int rect_desel[16]= {0x707070,0x0,0x0,0x707070,0x407070,0x70cccc,0x407070,0x0,0xaaffff,0xffffff,0x70cccc,0x0,0x70cccc,0xaaffff,0x407070,0x707070};
|
|
unsigned int rect_sel[16]= {0x707070,0x0,0x0,0x707070,0x702070,0xcc50cc,0x702070,0x0,0xff80ff,0xffffff,0xcc50cc,0x0,0xcc50cc,0xff80ff,0x702070,0x707070};
|
|
|
|
unsigned int rectu_desel[16]= {0xff4e4e4e,0xff5c2309,0xff000000,0xff4e4f4d,0xff000000,0xffff9d72,0xffff601c,0xff000000,0xff5d2409,0xffffffff,0xffff9d72,0xff5b2209,0xff4e4e4e,0xff5c2309,0xff010100,0xff4f4f4f};
|
|
unsigned int rectu_sel[16]= {0xff4e4e4e,0xff403c00,0xff000000,0xff4e4e4d,0xff000000,0xfffff64c,0xffaaa100,0xff000000,0xff403c00,0xffffffff,0xfffff64c,0xff403c00,0xff4f4f4f,0xff403c00,0xff010100,0xff4e4e4e};
|
|
|
|
unsigned int rectl_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x124040,0x0,0x4e4e4e,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0x227777,0x55cccc,0x227777,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x124040,0x88ffff,0xffffff,0x55cccc,0x124040,0x777777,0xaaffff,0xaaffff,0x777777,0x0,0x55cccc,0x88ffff,0x227777,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4f4f4f,0x0,0x124040,0x0,0x4e4e4e,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777};
|
|
unsigned int rectl_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0x774477,0xcc77cc,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x402440,0xffaaff,0xffffff,0xcc77cc,0x412541,0x777777,0xffaaff,0xffaaff,0x777777,0x10101,0xcc77cc,0xffaaff,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777};
|
|
unsigned int rectlus_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0x777777,0xaaffff,0xaaffff,0x777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777};
|
|
unsigned int rectlus_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0x777777,0xffaaff,0xffaaff,0x777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777};
|
|
unsigned int rectllib_desel[81]= {0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xb9b237,0xb9b237,0xb9b237,0xff777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xff777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0xff777777,0xb9b237,0xb9b237,0xff777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777};
|
|
unsigned int rectllib_sel[81]= {0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xfff64c,0xfff64c,0xfff64c,0xff777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xff777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0xff777777,0xfff64c,0xfff64c,0xff777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xfff64c,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777};
|
|
|
|
unsigned int rectl_set[81]= {0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0x4e4e4e,0x10100,0x202020,0x0,0x4e4e4d,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0x0,0xaaa100,0xaaaaaa,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x202020,0xfffde2,0xffffff,0xaaaaaa,0x202020,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x10100,0xaaaaaa,0xfffde2,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0x4f4f4f,0x0,0x202020,0x10100,0x4e4e4e,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777};
|
|
|
|
#define B_YELLOW 0x77FFFF
|
|
#define B_PURPLE 0xFF70FF
|
|
|
|
|
|
unsigned int selcol= 0xFF88FF;
|
|
unsigned int actselcol= 0xFFBBFF;
|
|
|
|
static unsigned int colortab[24]=
|
|
{0x0, 0xFF88FF, 0xFFBBFF,
|
|
0x403000, 0xFFFF88, 0xFFFFBB,
|
|
0x104040, 0x66CCCC, 0x77CCCC,
|
|
0x101040, 0x5588FF, 0x88BBFF,
|
|
0xFFFFFF
|
|
};
|
|
|
|
|
|
static float cube[8][3] = {
|
|
{-1.0, -1.0, -1.0},
|
|
{-1.0, -1.0, 1.0},
|
|
{-1.0, 1.0, 1.0},
|
|
{-1.0, 1.0, -1.0},
|
|
{ 1.0, -1.0, -1.0},
|
|
{ 1.0, -1.0, 1.0},
|
|
{ 1.0, 1.0, 1.0},
|
|
{ 1.0, 1.0, -1.0},
|
|
};
|
|
|
|
void init_draw_rects(void)
|
|
{
|
|
if(G.order==B_ENDIAN) {
|
|
IMB_convert_rgba_to_abgr(16, rect_desel);
|
|
IMB_convert_rgba_to_abgr(16, rect_sel);
|
|
|
|
IMB_convert_rgba_to_abgr(16, rectu_desel);
|
|
IMB_convert_rgba_to_abgr(16, rectu_sel);
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectl_desel);
|
|
IMB_convert_rgba_to_abgr(81, rectl_sel);
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectlus_desel);
|
|
IMB_convert_rgba_to_abgr(81, rectlus_sel);
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectllib_desel);
|
|
IMB_convert_rgba_to_abgr(81, rectllib_sel);
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectl_set);
|
|
}
|
|
}
|
|
|
|
static void draw_icon_centered(float *pos, unsigned int *rect, int rectsize)
|
|
{
|
|
float hsize= (float) rectsize/2.0;
|
|
GLubyte dummy= 0;
|
|
|
|
glRasterPos3fv(pos);
|
|
|
|
/* use bitmap to shift rasterpos in pixels */
|
|
glBitmap(1, 1, 0.0, 0.0, -hsize, -hsize, &dummy);
|
|
glFinish(); /* for sun */
|
|
|
|
glDrawPixels(rectsize, rectsize, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
|
}
|
|
|
|
void helpline(float *vec)
|
|
{
|
|
float vecrot[3];
|
|
short mval[2], mval1[2];
|
|
|
|
VECCOPY(vecrot, vec);
|
|
if(G.obedit) Mat4MulVecfl(G.obedit->obmat, vecrot);
|
|
|
|
getmouseco_areawin(mval);
|
|
project_short_noclip(vecrot, mval1);
|
|
|
|
persp(0);
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
|
|
cpack(0);
|
|
|
|
setlinestyle(3);
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex2sv(mval);
|
|
glVertex2sv(mval1);
|
|
glEnd();
|
|
setlinestyle(0);
|
|
|
|
persp(1);
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
|
|
void drawaxes(float size)
|
|
{
|
|
int axis;
|
|
|
|
for (axis=0; axis<3; axis++) {
|
|
float v1[3]= {0.0, 0.0, 0.0};
|
|
float v2[3]= {0.0, 0.0, 0.0};
|
|
int arrow_axis= (axis==0)?1:0;
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
v2[axis]= size;
|
|
glVertex3fv(v1);
|
|
glVertex3fv(v2);
|
|
|
|
v1[axis]= size*0.8;
|
|
v1[arrow_axis]= -size*0.125;
|
|
glVertex3fv(v1);
|
|
glVertex3fv(v2);
|
|
|
|
v1[arrow_axis]= size*0.125;
|
|
glVertex3fv(v1);
|
|
glVertex3fv(v2);
|
|
|
|
glEnd();
|
|
|
|
v2[axis]+= size*0.125;
|
|
glRasterPos3fv(v2);
|
|
|
|
if (axis==0)
|
|
BMF_DrawString(G.font, "x");
|
|
else if (axis==1)
|
|
BMF_DrawString(G.font, "y");
|
|
else
|
|
BMF_DrawString(G.font, "z");
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
static void drawgourcube(void)
|
|
{
|
|
float n[3];
|
|
|
|
n[0]=0; n[1]=0; n[2]=0;
|
|
glBegin(GL_QUADS);
|
|
n[0]= -1.0;
|
|
glNormal3fv(n);
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
|
n[0]=0;
|
|
glEnd();
|
|
|
|
glBegin(GL_QUADS);
|
|
n[1]= -1.0;
|
|
glNormal3fv(n);
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
|
|
n[1]=0;
|
|
glEnd();
|
|
|
|
glBegin(GL_QUADS);
|
|
n[0]= 1.0;
|
|
glNormal3fv(n);
|
|
glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
|
|
n[0]=0;
|
|
glEnd();
|
|
|
|
glBegin(GL_QUADS);
|
|
n[1]= 1.0;
|
|
glNormal3fv(n);
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
|
n[1]=0;
|
|
glEnd();
|
|
|
|
glBegin(GL_QUADS);
|
|
n[2]= 1.0;
|
|
glNormal3fv(n);
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
|
|
n[2]=0;
|
|
glEnd();
|
|
|
|
glBegin(GL_QUADS);
|
|
n[2]= -1.0;
|
|
glNormal3fv(n);
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
|
|
glEnd();
|
|
}
|
|
#endif
|
|
|
|
static void drawcube(void)
|
|
{
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[3]); glVertex3fv(cube[7]);
|
|
glEnd();
|
|
}
|
|
|
|
#if 0
|
|
static void drawcube_size(float *size)
|
|
{
|
|
|
|
glPushMatrix();
|
|
glScalef(size[0], size[1], size[2]);
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(cube[3]); glVertex3fv(cube[7]);
|
|
glEnd();
|
|
|
|
glPopMatrix();
|
|
}
|
|
#endif
|
|
|
|
static void tekenshadbuflimits(Lamp *la, float mat[][4])
|
|
{
|
|
float sta[3], end[3], lavec[3];
|
|
|
|
lavec[0]= -mat[2][0];
|
|
lavec[1]= -mat[2][1];
|
|
lavec[2]= -mat[2][2];
|
|
Normalise(lavec);
|
|
|
|
sta[0]= mat[3][0]+ la->clipsta*lavec[0];
|
|
sta[1]= mat[3][1]+ la->clipsta*lavec[1];
|
|
sta[2]= mat[3][2]+ la->clipsta*lavec[2];
|
|
|
|
end[0]= mat[3][0]+ la->clipend*lavec[0];
|
|
end[1]= mat[3][1]+ la->clipend*lavec[1];
|
|
end[2]= mat[3][2]+ la->clipend*lavec[2];
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(sta);
|
|
glVertex3fv(end);
|
|
glEnd();
|
|
|
|
glPointSize(3.0);
|
|
glBegin(GL_POINTS);
|
|
cpack(0);
|
|
glVertex3fv(sta);
|
|
glVertex3fv(end);
|
|
glEnd();
|
|
glPointSize(1.0);
|
|
}
|
|
|
|
|
|
|
|
static void spotvolume(float *lvec, float *vvec, float inp)
|
|
{
|
|
/* camera staat op 0,0,0 */
|
|
float temp[3],plane[3],mat1[3][3],mat2[3][3],mat3[3][3],mat4[3][3],q[4],co,si,hoek;
|
|
|
|
Normalise(lvec);
|
|
Normalise(vvec); /* is dit de goede vector ? */
|
|
|
|
Crossf(temp,vvec,lvec); /* vergelijking van vlak door vvec en lvec */
|
|
Crossf(plane,lvec,temp); /* en dan het vlak loodrecht daarop en evenwijdig aan lvec */
|
|
|
|
Normalise(plane);
|
|
|
|
/* nu hebben we twee vergelijkingen: die van de kegel en die van het vlak, maar we hebben
|
|
drie onbekenden We halen nu een onbekende weg door het vlak naar z=0 te roteren */
|
|
/* Ik heb geen flauw idee of dat mag, we moeten tenslotte twee oplossingen krijgen, maar we
|
|
proberen het gewoon: vlak vector moet (0,0,1) worden*/
|
|
|
|
/* roteer om uitproduct vector van (0,0,1) en vlakvector, inproduct graden */
|
|
/* volgens defenitie volgt dat uitproduct is (plane[1],-plane[0],0), en cos() = plane[2]);*/
|
|
|
|
q[1] = plane[1] ;
|
|
q[2] = -plane[0] ;
|
|
q[3] = 0 ;
|
|
Normalise(&q[1]);
|
|
|
|
hoek = saacos(plane[2])/2.0;
|
|
co = cos(hoek);
|
|
si = sqrt(1-co*co);
|
|
|
|
q[0] = co;
|
|
q[1] *= si;
|
|
q[2] *= si;
|
|
q[3] = 0;
|
|
|
|
QuatToMat3(q,mat1);
|
|
|
|
/* lampvector nu over acos(inp) graden roteren */
|
|
|
|
vvec[0] = lvec[0] ;
|
|
vvec[1] = lvec[1] ;
|
|
vvec[2] = lvec[2] ;
|
|
|
|
Mat3One(mat2);
|
|
co = inp;
|
|
si = sqrt(1-inp*inp);
|
|
|
|
mat2[0][0] = co;
|
|
mat2[1][0] = -si;
|
|
mat2[0][1] = si;
|
|
mat2[1][1] = co;
|
|
Mat3MulMat3(mat3,mat2,mat1);
|
|
|
|
mat2[1][0] = si;
|
|
mat2[0][1] = -si;
|
|
Mat3MulMat3(mat4,mat2,mat1);
|
|
Mat3Transp(mat1);
|
|
|
|
Mat3MulMat3(mat2,mat1,mat3);
|
|
Mat3MulVecfl(mat2,lvec);
|
|
Mat3MulMat3(mat2,mat1,mat4);
|
|
Mat3MulVecfl(mat2,vvec);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
static void drawlamp(Object *ob)
|
|
{
|
|
Lamp *la;
|
|
float vec[3], lvec[3], vvec[3],x,y,z;
|
|
|
|
la= ob->data;
|
|
vec[0]=vec[1]=vec[2]= 0.0;
|
|
|
|
setlinestyle(4);
|
|
|
|
if(la->type==LA_SPOT) {
|
|
|
|
lvec[0]=lvec[1]= 0.0;
|
|
lvec[2] = 1.0;
|
|
x = G.vd->persmat[0][2];
|
|
y = G.vd->persmat[1][2];
|
|
z = G.vd->persmat[2][2];
|
|
vvec[0]= x*ob->obmat[0][0] + y*ob->obmat[0][1] + z*ob->obmat[0][2];
|
|
vvec[1]= x*ob->obmat[1][0] + y*ob->obmat[1][1] + z*ob->obmat[1][2];
|
|
vvec[2]= x*ob->obmat[2][0] + y*ob->obmat[2][1] + z*ob->obmat[2][2];
|
|
|
|
y = cos( M_PI*la->spotsize/360.0 );
|
|
spotvolume(lvec, vvec, y);
|
|
x = -la->dist;
|
|
lvec[0] *= x ;
|
|
lvec[1] *= x ;
|
|
lvec[2] *= x;
|
|
vvec[0] *= x ;
|
|
vvec[1] *= x ;
|
|
vvec[2] *= x;
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vvec);
|
|
glVertex3fv(vec);
|
|
glVertex3fv(lvec);
|
|
glEnd();
|
|
|
|
z = x*sqrt(1.0 - y*y);
|
|
x *= y;
|
|
|
|
glTranslatef(0.0 , 0.0 , x);
|
|
if(la->mode & LA_SQUARE) {
|
|
vvec[0]= fabs(z);
|
|
vvec[1]= fabs(z);
|
|
vvec[2]= 0.0;
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(vvec);
|
|
vvec[1]= -fabs(z);
|
|
glVertex3fv(vvec);
|
|
vvec[0]= -fabs(z);
|
|
glVertex3fv(vvec);
|
|
vvec[1]= fabs(z);
|
|
glVertex3fv(vvec);
|
|
glEnd();
|
|
}
|
|
else circ(0.0, 0.0, fabs(z));
|
|
|
|
}
|
|
else if ELEM(la->type, LA_HEMI, LA_SUN) {
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec);
|
|
vec[2]= -la->dist;
|
|
glVertex3fv(vec);
|
|
glEnd();
|
|
}
|
|
else {
|
|
if(la->mode & LA_SPHERE) {
|
|
|
|
float tmat[4][4], imat[4][4];
|
|
|
|
vec[0]= vec[1]= vec[2]= 0.0;
|
|
mygetmatrix(tmat);
|
|
Mat4Invert(imat, tmat);
|
|
|
|
drawcircball(vec, la->dist, imat);
|
|
|
|
}
|
|
}
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
VECCOPY(vec, ob->obmat[3]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec);
|
|
vec[2]= 0;
|
|
glVertex3fv(vec);
|
|
glEnd();
|
|
setlinestyle(0);
|
|
|
|
if(la->type==LA_SPOT && (la->mode & LA_SHAD) ) {
|
|
tekenshadbuflimits(la, ob->obmat);
|
|
}
|
|
}
|
|
|
|
static void draw_limit_line(float sta, float end, unsigned int col)
|
|
{
|
|
glBegin(GL_LINES);
|
|
glVertex3f(0.0, 0.0, -sta);
|
|
glVertex3f(0.0, 0.0, -end);
|
|
glEnd();
|
|
|
|
glPointSize(3.0);
|
|
glBegin(GL_POINTS);
|
|
cpack(col);
|
|
glVertex3f(0.0, 0.0, -sta);
|
|
glVertex3f(0.0, 0.0, -end);
|
|
glEnd();
|
|
glPointSize(1.0);
|
|
}
|
|
|
|
|
|
void drawcamera(Object *ob)
|
|
{
|
|
/* een staande piramide met (0,0,0) als top */
|
|
Camera *cam;
|
|
World *wrld;
|
|
float vec[8][4], tmat[4][4], fac, facx, facy, depth;
|
|
|
|
cam= ob->data;
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
/* zo is ie altijd te zien */
|
|
fac= cam->drawsize;
|
|
if(G.vd->persp>=2) fac= cam->clipsta+0.1;
|
|
|
|
depth= - fac*cam->lens/16.0;
|
|
facx= fac*1.28;
|
|
facy= fac*1.024;
|
|
|
|
vec[0][0]= 0; vec[0][1]= 0; vec[0][2]= 0.001; /* GLBUG: z niet op nul vanwege picking op entry */
|
|
vec[1][0]= facx; vec[1][1]= facy; vec[1][2]= depth;
|
|
vec[2][0]= facx; vec[2][1]= -facy; vec[2][2]= depth;
|
|
vec[3][0]= -facx; vec[3][1]= -facy; vec[3][2]= depth;
|
|
vec[4][0]= -facx; vec[4][1]= facy; vec[4][2]= depth;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(vec[0]);
|
|
glVertex3fv(vec[1]);
|
|
glVertex3fv(vec[2]);
|
|
glVertex3fv(vec[0]);
|
|
glVertex3fv(vec[3]);
|
|
glVertex3fv(vec[4]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3fv(vec[2]);
|
|
glVertex3fv(vec[3]);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3fv(vec[4]);
|
|
glVertex3fv(vec[1]);
|
|
glEnd();
|
|
|
|
if(G.vd->persp>=2) return;
|
|
if(G.f & G_BACKBUFSEL) return;
|
|
|
|
/* pijl aan top */
|
|
vec[0][2]= depth;
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
vec[0][0]= -0.2*cam->drawsize;
|
|
vec[0][1]= cam->drawsize;
|
|
glVertex3fv(vec[0]);
|
|
|
|
vec[0][0]= 0.2*cam->drawsize;
|
|
glVertex3fv(vec[0]);
|
|
|
|
vec[0][1]= 1.6*cam->drawsize;
|
|
glVertex3fv(vec[0]);
|
|
|
|
vec[0][0]= -0.2*cam->drawsize;
|
|
glVertex3fv(vec[0]);
|
|
glEnd();
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
vec[0][0]= -0.4*cam->drawsize;
|
|
vec[0][1]= 1.6*cam->drawsize;
|
|
glVertex3fv(vec[0]);
|
|
|
|
vec[0][0]= 0.0;
|
|
vec[0][1]= 2.0*cam->drawsize;
|
|
glVertex3fv(vec[0]);
|
|
|
|
vec[0][0]= 0.4*cam->drawsize;
|
|
vec[0][1]= 1.6*cam->drawsize;
|
|
glVertex3fv(vec[0]);
|
|
|
|
glEnd();
|
|
|
|
if(cam->flag & (CAM_SHOWLIMITS+CAM_SHOWMIST)) {
|
|
myloadmatrix(G.vd->viewmat);
|
|
Mat4CpyMat4(vec, ob->obmat);
|
|
Mat4Ortho(vec);
|
|
mymultmatrix(vec);
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, tmat);
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
if(cam->flag & CAM_SHOWLIMITS)
|
|
draw_limit_line(cam->clipsta, cam->clipend, B_YELLOW);
|
|
|
|
wrld= G.scene->world;
|
|
if(cam->flag & CAM_SHOWMIST)
|
|
if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF);
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, tmat);
|
|
}
|
|
}
|
|
|
|
static void tekenvertslatt(short sel)
|
|
{
|
|
Lattice *lt;
|
|
BPoint *bp;
|
|
int a, uxt, u, vxt, v, wxt, w;
|
|
|
|
glPointSize(3.0);
|
|
|
|
if(sel) cpack(B_YELLOW);
|
|
else cpack(B_PURPLE);
|
|
|
|
glBegin(GL_POINTS);
|
|
|
|
bp= editLatt->def;
|
|
lt= editLatt;
|
|
|
|
if(lt->flag & LT_OUTSIDE) {
|
|
|
|
for(w=0; w<lt->pntsw; w++) {
|
|
if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0;
|
|
for(v=0; v<lt->pntsv; v++) {
|
|
if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0;
|
|
|
|
for(u=0; u<lt->pntsu; u++, bp++) {
|
|
if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0;
|
|
if(uxt || vxt || wxt) {
|
|
if(bp->hide==0) {
|
|
if((bp->f1 & 1)==sel) glVertex3fv(bp->vec);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
|
|
while(a--) {
|
|
if(bp->hide==0) {
|
|
if((bp->f1 & 1)==sel) glVertex3fv(bp->vec);
|
|
}
|
|
bp++;
|
|
}
|
|
}
|
|
|
|
glPointSize(1.0);
|
|
glEnd();
|
|
}
|
|
|
|
static void calc_lattverts(void)
|
|
{
|
|
BPoint *bp;
|
|
float mat[4][4];
|
|
int a;
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
bp= editLatt->def;
|
|
|
|
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
|
|
while(a--) {
|
|
project_short(bp->vec, bp->s);
|
|
bp++;
|
|
}
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
}
|
|
|
|
|
|
void calc_lattverts_ext(void)
|
|
{
|
|
|
|
areawinset(curarea->win);
|
|
mymultmatrix(G.obedit->obmat);
|
|
calc_lattverts();
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
}
|
|
|
|
|
|
static void drawlattice(Object *ob)
|
|
{
|
|
Lattice *lt;
|
|
BPoint *bp, *bpu;
|
|
int u, v, w, dv, dw, uxt, vxt, wxt;
|
|
|
|
lt= ob->data;
|
|
if(ob==G.obedit) {
|
|
bp= editLatt->def;
|
|
|
|
cpack(0x004000);
|
|
}
|
|
else {
|
|
bp= lt->def;
|
|
}
|
|
|
|
dv= lt->pntsu;
|
|
dw= dv*lt->pntsv;
|
|
|
|
if(lt->flag & LT_OUTSIDE) {
|
|
|
|
for(w=0; w<lt->pntsw; w++) {
|
|
|
|
if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0;
|
|
|
|
for(v=0; v<lt->pntsv; v++) {
|
|
|
|
if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0;
|
|
|
|
for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
|
|
|
|
if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0;
|
|
|
|
if(uxt || vxt || wxt) {
|
|
|
|
if(w && (uxt || vxt)) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
|
|
glEnd();
|
|
}
|
|
if(v && (uxt || wxt)) {
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
|
|
glEnd();
|
|
}
|
|
if(u && (vxt || wxt)) {
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
bpu= bp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for(w=0; w<lt->pntsw; w++) {
|
|
|
|
for(v=0; v<lt->pntsv; v++) {
|
|
|
|
for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
|
|
|
|
if(w) {
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
|
|
glEnd();
|
|
}
|
|
if(v) {
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
|
|
glEnd();
|
|
}
|
|
if(u) {
|
|
|
|
glBegin(GL_LINES);
|
|
glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
|
|
glEnd();
|
|
}
|
|
bpu= bp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(ob==G.obedit) {
|
|
|
|
calc_lattverts();
|
|
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
tekenvertslatt(0);
|
|
tekenvertslatt(1);
|
|
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
}
|
|
|
|
/* ***************** ******************** */
|
|
|
|
void calc_meshverts(void)
|
|
{
|
|
EditVert *eve;
|
|
float mat[4][4];
|
|
|
|
if(G.edve.first==0) return;
|
|
eve= G.edve.first;
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
eve= G.edve.first;
|
|
while(eve) {
|
|
if(eve->h==0) {
|
|
project_short(eve->co, &(eve->xs));
|
|
}
|
|
eve= eve->next;
|
|
}
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
}
|
|
|
|
void calc_meshverts_ext(void)
|
|
{
|
|
|
|
areawinset(curarea->win);
|
|
mymultmatrix(G.obedit->obmat);
|
|
calc_meshverts();
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
}
|
|
|
|
static void calc_Nurbverts(Nurb *nurb)
|
|
{
|
|
Nurb *nu;
|
|
BezTriple *bezt;
|
|
BPoint *bp;
|
|
float mat[4][4];
|
|
int a;
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
nu= nurb;
|
|
while(nu) {
|
|
if((nu->type & 7)==1) {
|
|
bezt= nu->bezt;
|
|
a= nu->pntsu;
|
|
while(a--) {
|
|
project_short(bezt->vec[0], bezt->s[0]);
|
|
project_short(bezt->vec[1], bezt->s[1]);
|
|
project_short(bezt->vec[2], bezt->s[2]);
|
|
bezt++;
|
|
}
|
|
}
|
|
else {
|
|
bp= nu->bp;
|
|
a= nu->pntsu*nu->pntsv;
|
|
while(a--) {
|
|
project_short(bp->vec, bp->s);
|
|
bp++;
|
|
}
|
|
}
|
|
nu= nu->next;
|
|
}
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
}
|
|
|
|
void calc_nurbverts_ext(void)
|
|
{
|
|
|
|
areawinset(curarea->win);
|
|
mymultmatrix(G.obedit->obmat);
|
|
calc_Nurbverts(editNurb.first);
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
}
|
|
|
|
void tekenvertices(short sel)
|
|
{
|
|
EditVert *eve;
|
|
|
|
glPointSize(2.0);
|
|
|
|
if(sel) cpack(B_YELLOW);
|
|
else cpack(B_PURPLE);
|
|
#ifdef __NLA /* __TEKENTEST */
|
|
// if (sel==2)
|
|
// cpack (0x0000FF);
|
|
#endif /* __TEKENTEST */
|
|
glBegin(GL_POINTS);
|
|
|
|
eve= (EditVert *)G.edve.first;
|
|
while(eve) {
|
|
if(eve->h==0 && (eve->f & 1)==sel ) {
|
|
glVertex3fv(eve->co);
|
|
}
|
|
#ifdef __NLA /* __TEKENTEST */
|
|
// if (eve->totweight && sel==2)
|
|
// glVertex3fv(eve->co);
|
|
|
|
#endif /* __TEKENTEST */
|
|
eve= eve->next;
|
|
}
|
|
glEnd();
|
|
|
|
glPointSize(1.0);
|
|
}
|
|
|
|
void tekenvertices_ext(int mode)
|
|
{
|
|
ScrArea *tempsa, *sa;
|
|
View3D *vd;
|
|
|
|
if(G.f & (G_FACESELECT+G_DRAWFACES)) {
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
return;
|
|
}
|
|
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
|
|
/* alle views aflopen */
|
|
tempsa= curarea;
|
|
sa= G.curscreen->areabase.first;
|
|
while(sa) {
|
|
if(sa->spacetype==SPACE_VIEW3D) {
|
|
vd= sa->spacedata.first;
|
|
if(G.obedit->lay & vd->lay) {
|
|
areawinset(sa->win);
|
|
mymultmatrix(G.obedit->obmat);
|
|
|
|
calc_meshverts();
|
|
if(mode==0 || mode==2) tekenvertices(0);
|
|
if(mode==1 || mode==2) tekenvertices(1);
|
|
sa->win_swap= WIN_FRONT_OK;
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
}
|
|
}
|
|
sa= sa->next;
|
|
}
|
|
if(curarea!=tempsa) areawinset(tempsa->win);
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
/* ************** DRAW DISPLIST ****************** */
|
|
|
|
/* DispListMesh */
|
|
|
|
static void displistmesh_draw_wire(DispListMesh *dlm) {
|
|
int i;
|
|
|
|
for (i=0; i<dlm->totface; i++) {
|
|
MFaceInt *mf= &dlm->mface[i];
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(dlm->mvert[mf->v1].co);
|
|
glVertex3fv(dlm->mvert[mf->v2].co);
|
|
if (mf->v3) {
|
|
glVertex3fv(dlm->mvert[mf->v3].co);
|
|
if (mf->v4)
|
|
glVertex3fv(dlm->mvert[mf->v4].co);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
static void displistmesh_draw_solid(DispListMesh *dlm, int drawsmooth, float *nors) {
|
|
int lmode, lshademodel= -1, lmat_nr= -1;
|
|
int i;
|
|
|
|
#define PASSVERT(ind) { \
|
|
if (drawsmooth && lshademodel==GL_SMOOTH) \
|
|
glNormal3sv(dlm->mvert[(ind)].no); \
|
|
glVertex3fv(dlm->mvert[(ind)].co); \
|
|
}
|
|
|
|
glBegin(lmode= GL_QUADS);
|
|
for (i=0; i<dlm->totface; i++) {
|
|
MFaceInt *mf= &dlm->mface[i];
|
|
|
|
if (mf->v3) {
|
|
int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
|
|
|
|
if (nmode!=lmode) {
|
|
glEnd();
|
|
glBegin(lmode= nmode);
|
|
}
|
|
|
|
if (drawsmooth) {
|
|
int nshademodel= (mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
|
|
|
|
if (nshademodel!=lshademodel) {
|
|
glEnd();
|
|
glShadeModel(lshademodel= nshademodel);
|
|
glBegin(lmode);
|
|
}
|
|
|
|
if (mf->mat_nr!=lmat_nr)
|
|
set_gl_material((lmat_nr= mf->mat_nr)+1);
|
|
}
|
|
|
|
if (drawsmooth && lshademodel==GL_FLAT)
|
|
glNormal3fv(&nors[i*3]);
|
|
|
|
PASSVERT(mf->v1);
|
|
PASSVERT(mf->v2);
|
|
PASSVERT(mf->v3);
|
|
if (mf->v4)
|
|
PASSVERT(mf->v4);
|
|
}
|
|
}
|
|
glEnd();
|
|
|
|
#undef PASSVERT
|
|
}
|
|
|
|
static void displistmesh_draw_shaded(DispListMesh *dlm, unsigned char *vcols1, unsigned char *vcols2) {
|
|
int i, lmode;
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
if (vcols2)
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
#define PASSVERT(vidx, fidx) { \
|
|
unsigned char *col= &colbase[fidx*4]; \
|
|
glColor3ub(col[3], col[2], col[1]); \
|
|
glVertex3fv(dlm->mvert[(vidx)].co); \
|
|
}
|
|
|
|
glBegin(lmode= GL_QUADS);
|
|
for (i=0; i<dlm->totface; i++) {
|
|
MFaceInt *mf= &dlm->mface[i];
|
|
|
|
if (mf->v3) {
|
|
int nmode= mf->v4?GL_QUADS:GL_TRIANGLES;
|
|
unsigned char *colbase= &vcols1[i*16];
|
|
|
|
if (nmode!=lmode) {
|
|
glEnd();
|
|
glBegin(lmode= nmode);
|
|
}
|
|
|
|
PASSVERT(mf->v1, 0);
|
|
PASSVERT(mf->v2, 1);
|
|
PASSVERT(mf->v3, 2);
|
|
if (mf->v4)
|
|
PASSVERT(mf->v4, 3);
|
|
|
|
if (vcols2) {
|
|
unsigned char *colbase= &vcols2[i*16];
|
|
|
|
if (mf->v4)
|
|
PASSVERT(mf->v4, 3);
|
|
PASSVERT(mf->v3, 2);
|
|
PASSVERT(mf->v2, 1);
|
|
PASSVERT(mf->v1, 0);
|
|
}
|
|
}
|
|
}
|
|
glEnd();
|
|
|
|
if (vcols2)
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
#undef PASSVERT
|
|
}
|
|
|
|
/***/
|
|
|
|
static int draw_index_wire= 1;
|
|
static int index3_nors_incr= 1;
|
|
|
|
static void drawDispListwire(ListBase *dlbase)
|
|
{
|
|
DispList *dl;
|
|
int parts, nr, ofs, *index;
|
|
float *data;
|
|
|
|
if(dlbase==0) return;
|
|
|
|
dl= dlbase->first;
|
|
while(dl) {
|
|
data= dl->verts;
|
|
|
|
switch(dl->type) {
|
|
case DL_SEGM:
|
|
parts= dl->parts;
|
|
while(parts--) {
|
|
nr= dl->nr;
|
|
glBegin(GL_LINE_STRIP);
|
|
while(nr--) {
|
|
glVertex3fv(data);
|
|
data+=3;
|
|
}
|
|
glEnd();
|
|
}
|
|
break;
|
|
case DL_POLY:
|
|
parts= dl->parts;
|
|
while(parts--) {
|
|
nr= dl->nr;
|
|
glBegin(GL_LINE_LOOP);
|
|
while(nr--) {
|
|
glVertex3fv(data);
|
|
data+=3;
|
|
}
|
|
glEnd();
|
|
}
|
|
break;
|
|
case DL_SURF:
|
|
parts= dl->parts;
|
|
while(parts--) {
|
|
nr= dl->nr;
|
|
if(dl->flag & 1) glBegin(GL_LINE_LOOP);
|
|
else glBegin(GL_LINE_STRIP);
|
|
|
|
while(nr--) {
|
|
glVertex3fv(data);
|
|
data+=3;
|
|
}
|
|
glEnd();
|
|
}
|
|
ofs= 3*dl->nr;
|
|
nr= dl->nr;
|
|
while(nr--) {
|
|
data= ( dl->verts )+3*nr;
|
|
parts= dl->parts;
|
|
if(dl->flag & 2) glBegin(GL_LINE_LOOP);
|
|
else glBegin(GL_LINE_STRIP);
|
|
|
|
while(parts--) {
|
|
glVertex3fv(data);
|
|
data+=ofs;
|
|
}
|
|
glEnd();
|
|
}
|
|
break;
|
|
|
|
case DL_INDEX3:
|
|
if(draw_index_wire) {
|
|
parts= dl->parts;
|
|
data= dl->verts;
|
|
index= dl->index;
|
|
while(parts--) {
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(data+3*index[0]);
|
|
glVertex3fv(data+3*index[1]);
|
|
glVertex3fv(data+3*index[2]);
|
|
glEnd();
|
|
index+= 3;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DL_INDEX4:
|
|
if(draw_index_wire) {
|
|
parts= dl->parts;
|
|
data= dl->verts;
|
|
index= dl->index;
|
|
while(parts--) {
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(data+3*index[0]);
|
|
glVertex3fv(data+3*index[1]);
|
|
glVertex3fv(data+3*index[2]);
|
|
if(index[3]) glVertex3fv(data+3*index[3]);
|
|
glEnd();
|
|
index+= 4;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DL_MESH:
|
|
displistmesh_draw_wire(dl->mesh);
|
|
break;
|
|
}
|
|
dl= dl->next;
|
|
}
|
|
}
|
|
|
|
static void drawDispListsolid(ListBase *lb, Object *ob)
|
|
{
|
|
DispList *dl;
|
|
int parts, ofs, p1, p2, p3, p4, a, b, *index;
|
|
float *data, *v1, *v2, *v3, *v4;
|
|
float *ndata, *n1, *n2, *n3, *n4;
|
|
int drawsmooth= !(G.f & G_BACKBUFSEL);
|
|
|
|
if(lb==0) return;
|
|
if (drawsmooth) {
|
|
glShadeModel(GL_SMOOTH);
|
|
glEnable(GL_LIGHTING);
|
|
}
|
|
|
|
dl= lb->first;
|
|
while(dl) {
|
|
data= dl->verts;
|
|
ndata= dl->nors;
|
|
|
|
switch(dl->type) {
|
|
case DL_SURF:
|
|
if(!drawsmooth) {
|
|
for(a=0; a<dl->parts; a++) {
|
|
|
|
DL_SURFINDEX(dl->flag & 1, dl->flag & 2, dl->nr, dl->parts);
|
|
|
|
v1= data+ 3*p1;
|
|
v2= data+ 3*p2;
|
|
v3= data+ 3*p3;
|
|
v4= data+ 3*p4;
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
glVertex3fv(v2);
|
|
glVertex3fv(v4);
|
|
|
|
for(; b<dl->nr; b++) {
|
|
|
|
glVertex3fv(v1);
|
|
glVertex3fv(v3);
|
|
|
|
v2= v1; v1+= 3;
|
|
v4= v3; v3+= 3;
|
|
}
|
|
|
|
|
|
glEnd();
|
|
}
|
|
}
|
|
else {
|
|
|
|
set_gl_material(dl->col+1);
|
|
/*
|
|
glBegin(GL_LINES);
|
|
for(a=0; a<dl->parts*dl->nr; a++) {
|
|
float nor[3];
|
|
|
|
VECCOPY(nor, data+3*a);
|
|
glVertex3fv(nor);
|
|
VecAddf(nor, nor, ndata+3*a);
|
|
glVertex3fv(nor);
|
|
}
|
|
glEnd();
|
|
*/
|
|
for(a=0; a<dl->parts; a++) {
|
|
|
|
DL_SURFINDEX(dl->flag & 1, dl->flag & 2, dl->nr, dl->parts);
|
|
|
|
v1= data+ 3*p1;
|
|
v2= data+ 3*p2;
|
|
v3= data+ 3*p3;
|
|
v4= data+ 3*p4;
|
|
n1= ndata+ 3*p1;
|
|
n2= ndata+ 3*p2;
|
|
n3= ndata+ 3*p3;
|
|
n4= ndata+ 3*p4;
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
glNormal3fv(n2); glVertex3fv(v2);
|
|
glNormal3fv(n4); glVertex3fv(v4);
|
|
|
|
for(; b<dl->nr; b++) {
|
|
|
|
glNormal3fv(n1); glVertex3fv(v1);
|
|
glNormal3fv(n3); glVertex3fv(v3);
|
|
|
|
v2= v1; v1+= 3;
|
|
v4= v3; v3+= 3;
|
|
n2= n1; n1+= 3;
|
|
n4= n3; n3+= 3;
|
|
}
|
|
|
|
|
|
glEnd();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DL_INDEX3:
|
|
|
|
parts= dl->parts;
|
|
data= dl->verts;
|
|
ndata= dl->nors;
|
|
index= dl->index;
|
|
|
|
if(!drawsmooth) {
|
|
while(parts--) {
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
glVertex3fv(data+3*index[0]);
|
|
glVertex3fv(data+3*index[1]);
|
|
glVertex3fv(data+3*index[2]);
|
|
glEnd();
|
|
index+= 3;
|
|
}
|
|
}
|
|
else {
|
|
|
|
set_gl_material(dl->col+1);
|
|
|
|
/* voor poly's is er maar 1 normaal nodig */
|
|
if(index3_nors_incr==0) {
|
|
while(parts--) {
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
glNormal3fv(ndata);
|
|
glVertex3fv(data+3*index[0]);
|
|
glVertex3fv(data+3*index[1]);
|
|
glVertex3fv(data+3*index[2]);
|
|
glEnd();
|
|
index+= 3;
|
|
}
|
|
}
|
|
else {
|
|
while(parts--) {
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
ofs= 3*index[0];
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
ofs= 3*index[1];
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
ofs= 3*index[2];
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
glEnd();
|
|
index+= 3;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DL_INDEX4:
|
|
|
|
parts= dl->parts;
|
|
data= dl->verts;
|
|
ndata= dl->nors;
|
|
index= dl->index;
|
|
|
|
if(!drawsmooth) {
|
|
while(parts--) {
|
|
|
|
glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
|
|
glVertex3fv(data+3*index[0]);
|
|
glVertex3fv(data+3*index[1]);
|
|
glVertex3fv(data+3*index[2]);
|
|
if(index[3]) glVertex3fv(data+3*index[3]);
|
|
glEnd();
|
|
index+= 4;
|
|
}
|
|
}
|
|
else {
|
|
|
|
set_gl_material(dl->col+1);
|
|
|
|
while(parts--) {
|
|
|
|
glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
|
|
ofs= 3*index[0];
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
ofs= 3*index[1];
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
ofs= 3*index[2];
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
if(index[3]) {
|
|
ofs= 3*index[3];
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
}
|
|
glEnd();
|
|
index+= 4;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DL_MESH:
|
|
if (!dl->nors)
|
|
addnormalsDispList(ob, lb);
|
|
displistmesh_draw_solid(dl->mesh, drawsmooth, dl->nors);
|
|
break;
|
|
|
|
}
|
|
dl= dl->next;
|
|
}
|
|
|
|
if(drawsmooth) {
|
|
glShadeModel(GL_FLAT);
|
|
glDisable(GL_LIGHTING);
|
|
}
|
|
}
|
|
|
|
static void drawDispListshaded(ListBase *lb, Object *ob)
|
|
{
|
|
DispList *dl, *dlob;
|
|
int parts, p1, p2, p3, p4, a, b, *index;
|
|
float *data, *v1, *v2, *v3, *v4;/* , *extverts=0 */
|
|
unsigned int *cdata, *c1, *c2, *c3, *c4;
|
|
char *cp;
|
|
|
|
if(lb==0) return;
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
dl= lb->first;
|
|
dlob= ob->disp.first;
|
|
while(dl && dlob) {
|
|
|
|
cdata= dlob->col1;
|
|
data= dl->verts;
|
|
if(cdata==0) break;
|
|
|
|
switch(dl->type) {
|
|
case DL_SURF:
|
|
|
|
for(a=0; a<dl->parts; a++) {
|
|
|
|
DL_SURFINDEX(dl->flag & 1, dl->flag & 2, dl->nr, dl->parts);
|
|
|
|
v1= data+ 3*p1;
|
|
v2= data+ 3*p2;
|
|
v3= data+ 3*p3;
|
|
v4= data+ 3*p4;
|
|
c1= cdata+ p1;
|
|
c2= cdata+ p2;
|
|
c3= cdata+ p3;
|
|
c4= cdata+ p4;
|
|
|
|
for(; b<dl->nr; b++) {
|
|
|
|
glBegin(GL_QUADS);
|
|
cp= (char *)c1;
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(v1);
|
|
cp= (char *)c2;
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(v2);
|
|
cp= (char *)c4;
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(v4);
|
|
cp= (char *)c3;
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(v3);
|
|
glEnd();
|
|
|
|
v2= v1; v1+= 3;
|
|
v4= v3; v3+= 3;
|
|
c2= c1; c1++;
|
|
c4= c3; c3++;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DL_INDEX3:
|
|
|
|
parts= dl->parts;
|
|
index= dl->index;
|
|
|
|
while(parts--) {
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
cp= (char *)(cdata+index[0]);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(data+3*index[0]);
|
|
|
|
cp= (char *)(cdata+index[1]);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(data+3*index[1]);
|
|
|
|
cp= (char *)(cdata+index[2]);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(data+3*index[2]);
|
|
glEnd();
|
|
index+= 3;
|
|
}
|
|
break;
|
|
|
|
case DL_INDEX4:
|
|
|
|
parts= dl->parts;
|
|
index= dl->index;
|
|
while(parts--) {
|
|
|
|
glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
|
|
cp= (char *)(cdata+index[0]);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(data+3*index[0]);
|
|
|
|
cp= (char *)(cdata+index[1]);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(data+3*index[1]);
|
|
|
|
cp= (char *)(cdata+index[2]);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(data+3*index[2]);
|
|
|
|
if(index[3]) {
|
|
|
|
cp= (char *)(cdata+index[3]);
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
glVertex3fv(data+3*index[3]);
|
|
}
|
|
glEnd();
|
|
index+= 4;
|
|
}
|
|
break;
|
|
|
|
case DL_MESH:
|
|
displistmesh_draw_shaded(dl->mesh, (unsigned char*) dlob->col1, (unsigned char*) dlob->col2);
|
|
break;
|
|
|
|
}
|
|
dl= dl->next;
|
|
dlob= dlob->next;
|
|
}
|
|
|
|
glShadeModel(GL_FLAT);
|
|
}
|
|
|
|
static void drawmeshsolid(Object *ob, float *nors)
|
|
{
|
|
Mesh *me;
|
|
DispList *dl;
|
|
MVert *mvert;
|
|
TFace *tface;
|
|
MFace *mface;
|
|
EditVlak *evl;
|
|
float *extverts=0, *v1, *v2, *v3, *v4;
|
|
int glmode, setsmooth=0, a, start, end, matnr= -1, vertexpaint, i;
|
|
short no[3], *n1, *n2, *n3, *n4 = NULL;
|
|
|
|
vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
|
|
|
|
me= get_mesh(ob);
|
|
if(me==0) return;
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
if( (G.f & G_BACKBUFSEL)==0 ) {
|
|
glEnable(GL_LIGHTING);
|
|
init_gl_materials(ob);
|
|
two_sided( me->flag & ME_TWOSIDED );
|
|
}
|
|
|
|
mface= me->mface;
|
|
if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface;
|
|
else tface= 0;
|
|
|
|
mvert= me->mvert;
|
|
a= me->totface;
|
|
|
|
/* SOLVE */
|
|
/* if ELEM(ob->type, OB_SECTOR, OB_LIFE) glEnable(GL_CULL_FACE); */
|
|
|
|
if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
|
|
|
|
evl= G.edvl.first;
|
|
while(evl) {
|
|
if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) {
|
|
|
|
if(evl->mat_nr!=matnr) {
|
|
matnr= evl->mat_nr;
|
|
set_gl_material(matnr+1);
|
|
}
|
|
|
|
if(evl->v4 && evl->v4->h==0) {
|
|
|
|
glBegin(GL_QUADS);
|
|
glNormal3fv(evl->n);
|
|
glVertex3fv(evl->v1->co);
|
|
glVertex3fv(evl->v2->co);
|
|
glVertex3fv(evl->v3->co);
|
|
glVertex3fv(evl->v4->co);
|
|
glEnd();
|
|
}
|
|
else {
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
glNormal3fv(evl->n);
|
|
glVertex3fv(evl->v1->co);
|
|
glVertex3fv(evl->v2->co);
|
|
glVertex3fv(evl->v3->co);
|
|
glEnd();
|
|
}
|
|
}
|
|
evl= evl->next;
|
|
}
|
|
|
|
glDisable(GL_LIGHTING);
|
|
glShadeModel(GL_FLAT);
|
|
|
|
if(ob==G.obedit) {
|
|
calc_meshverts();
|
|
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
tekenvertices(0);
|
|
tekenvertices(1);
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
start= 0; end= me->totface;
|
|
set_buildvars(ob, &start, &end);
|
|
mface+= start;
|
|
if(tface) tface+= start;
|
|
|
|
dl= find_displist(&ob->disp, DL_VERTS);
|
|
if(dl) extverts= dl->verts;
|
|
|
|
glBegin(GL_QUADS);
|
|
glmode= GL_QUADS;
|
|
|
|
for(a=start; a<end; a++, mface++, nors+=3) {
|
|
if(mface->v3) {
|
|
if(tface && (tface->flag & TF_HIDE)) {
|
|
if( (G.f & G_BACKBUFSEL)==0) {
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv( (mvert+mface->v1)->co);
|
|
glVertex3fv( (mvert+mface->v2)->co);
|
|
glVertex3fv( (mvert+mface->v3)->co);
|
|
if(mface->v4) glVertex3fv( (mvert+mface->v1)->co);
|
|
glEnd();
|
|
tface++;
|
|
}
|
|
}
|
|
else {
|
|
if(extverts) {
|
|
v1= extverts+3*mface->v1;
|
|
v2= extverts+3*mface->v2;
|
|
v3= extverts+3*mface->v3;
|
|
if(mface->v4) v4= extverts+3*mface->v4;
|
|
else v4= 0;
|
|
}
|
|
else {
|
|
v1= (mvert+mface->v1)->co;
|
|
v2= (mvert+mface->v2)->co;
|
|
v3= (mvert+mface->v3)->co;
|
|
if(mface->v4) v4= (mvert+mface->v4)->co;
|
|
else v4= 0;
|
|
}
|
|
|
|
|
|
if(tface) {
|
|
if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE);
|
|
else glDisable(GL_CULL_FACE);
|
|
}
|
|
|
|
|
|
/* dit GL_QUADS grapje is op snelheid getest: factor 2! */
|
|
|
|
if(v4) {if(glmode==GL_TRIANGLES) {glmode= GL_QUADS; glEnd(); glBegin(GL_QUADS);}}
|
|
else {if(glmode==GL_QUADS) {glmode= GL_TRIANGLES; glEnd(); glBegin(GL_TRIANGLES);}}
|
|
|
|
if(G.f & G_BACKBUFSEL) {
|
|
if(vertexpaint) {
|
|
i= index_to_framebuffer(a+1);
|
|
cpack(i);
|
|
}
|
|
|
|
glVertex3fv( v1 );
|
|
glVertex3fv( v2 );
|
|
glVertex3fv( v3 );
|
|
if(v4) glVertex3fv( v4 );
|
|
|
|
}
|
|
else {
|
|
|
|
if(mface->mat_nr!=matnr) {
|
|
matnr= mface->mat_nr;
|
|
set_gl_material(matnr+1);
|
|
}
|
|
|
|
if( (me->flag & ME_AUTOSMOOTH)==0 && (mface->flag & ME_SMOOTH)) {
|
|
if(setsmooth==0) {
|
|
glEnd();
|
|
glShadeModel(GL_SMOOTH);
|
|
if(glmode==GL_TRIANGLES) glBegin(GL_TRIANGLES);
|
|
else glBegin(GL_QUADS);
|
|
setsmooth= 1;
|
|
}
|
|
n1= (mvert+mface->v1)->no;
|
|
n2= (mvert+mface->v2)->no;
|
|
n3= (mvert+mface->v3)->no;
|
|
if(v4) n4= (mvert+mface->v4)->no;
|
|
|
|
if(mface->puno & ME_FLIPV1) {
|
|
no[0]= -n1[0]; no[1]= -n1[1]; no[2]= -n1[2];
|
|
glNormal3sv(no);
|
|
}
|
|
else glNormal3sv(n1);
|
|
glVertex3fv( v1 );
|
|
|
|
if(mface->puno & ME_FLIPV2) {
|
|
no[0]= -n2[0]; no[1]= -n2[1]; no[2]= -n2[2];
|
|
glNormal3sv(no);
|
|
}
|
|
else glNormal3sv(n2);
|
|
glVertex3fv( v2 );
|
|
|
|
if(mface->puno & ME_FLIPV3) {
|
|
no[0]= -n3[0]; no[1]= -n3[1]; no[2]= -n3[2];
|
|
glNormal3sv(no);
|
|
}
|
|
else glNormal3sv(n3);
|
|
glVertex3fv( v3 );
|
|
|
|
if(v4) {
|
|
if(mface->puno & ME_FLIPV4) {
|
|
no[0]= -n4[0]; no[1]= -n4[1]; no[2]= -n4[2];
|
|
glNormal3sv(no);
|
|
}
|
|
else glNormal3sv(n4);
|
|
glVertex3fv( v4 );
|
|
}
|
|
}
|
|
else {
|
|
if(setsmooth==1) {
|
|
glEnd();
|
|
glShadeModel(GL_FLAT);
|
|
if(glmode==GL_TRIANGLES) glBegin(GL_TRIANGLES);
|
|
else glBegin(GL_QUADS);
|
|
setsmooth= 0;
|
|
}
|
|
glNormal3fv(nors);
|
|
glVertex3fv( v1 );
|
|
glVertex3fv( v2 );
|
|
glVertex3fv( v3 );
|
|
if(v4) glVertex3fv( v4 );
|
|
}
|
|
}
|
|
}
|
|
if(tface) tface++;
|
|
}
|
|
}
|
|
|
|
glEnd();
|
|
}
|
|
|
|
/* SOLVE */
|
|
/* if ELEM(ob->type, OB_SECTOR, OB_LIFE) glDisable(GL_CULL_FACE); */
|
|
|
|
if(G.f & G_BACKBUFSEL) {
|
|
glDisable(GL_CULL_FACE);
|
|
}
|
|
glDisable(GL_LIGHTING);
|
|
|
|
}
|
|
|
|
static void drawmeshshaded(Object *ob, unsigned int *col1, unsigned int *col2)
|
|
{
|
|
Mesh *me;
|
|
MVert *mvert;
|
|
MFace *mface;
|
|
TFace *tface;
|
|
DispList *dl;
|
|
float *extverts=0, *v1, *v2, *v3, *v4;
|
|
int a, start, end, twoside;
|
|
char *cp1, *cp2 = NULL;
|
|
int lglmode;
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
glDisable(GL_LIGHTING);
|
|
|
|
me= ob->data;
|
|
mface= me->mface;
|
|
|
|
/* tekent ie geen hide */
|
|
if( (G.f & G_FACESELECT) && ob==((G.scene->basact) ? (G.scene->basact->object) : 0)) tface= me->tface;
|
|
else tface= 0;
|
|
|
|
mvert= me->mvert;
|
|
a= me->totface;
|
|
|
|
twoside= me->flag & ME_TWOSIDED;
|
|
if(col2==0) twoside= 0;
|
|
|
|
if(twoside) glEnable(GL_CULL_FACE);
|
|
|
|
start= 0; end= me->totface;
|
|
set_buildvars(ob, &start, &end);
|
|
mface+= start;
|
|
if(tface) tface+= start;
|
|
col1+= 4*start;
|
|
if(col2) col2+= 4*start;
|
|
|
|
dl= find_displist(&ob->disp, DL_VERTS);
|
|
if(dl) extverts= dl->verts;
|
|
|
|
glBegin(lglmode= GL_QUADS);
|
|
|
|
cp1= (char *)col1;
|
|
if(col2) cp2= (char *)col2;
|
|
|
|
for(a=start; a<end; a++, mface++, cp1+= 16) {
|
|
if(mface->v3) {
|
|
if(tface && (tface->flag & TF_HIDE)) tface++;
|
|
else {
|
|
int nglmode= mface->v4?GL_QUADS:GL_TRIANGLES;
|
|
|
|
if (nglmode!=lglmode) {
|
|
glEnd();
|
|
glBegin(lglmode= nglmode);
|
|
}
|
|
|
|
if(extverts) {
|
|
v1= extverts+3*mface->v1;
|
|
v2= extverts+3*mface->v2;
|
|
v3= extverts+3*mface->v3;
|
|
if(mface->v4) v4= extverts+3*mface->v4;
|
|
else v4= 0;
|
|
}
|
|
else {
|
|
v1= (mvert+mface->v1)->co;
|
|
v2= (mvert+mface->v2)->co;
|
|
v3= (mvert+mface->v3)->co;
|
|
if(mface->v4) v4= (mvert+mface->v4)->co;
|
|
else v4= 0;
|
|
}
|
|
|
|
if(tface) {
|
|
if(tface->mode & TF_TWOSIDE) glEnable(GL_CULL_FACE);
|
|
else glDisable(GL_CULL_FACE);
|
|
}
|
|
|
|
glColor3ub(cp1[3], cp1[2], cp1[1]);
|
|
glVertex3fv( v1 );
|
|
glColor3ub(cp1[7], cp1[6], cp1[5]);
|
|
glVertex3fv( v2 );
|
|
glColor3ub(cp1[11], cp1[10], cp1[9]);
|
|
glVertex3fv( v3 );
|
|
if(v4) {
|
|
glColor3ub(cp1[15], cp1[14], cp1[13]);
|
|
glVertex3fv( v4 );
|
|
}
|
|
|
|
if(twoside) {
|
|
|
|
glColor3ub(cp2[11], cp2[10], cp2[9]);
|
|
glVertex3fv( v3 );
|
|
glColor3ub(cp2[7], cp2[6], cp2[5]);
|
|
glVertex3fv( v2 );
|
|
glColor3ub(cp2[3], cp2[2], cp2[1]);
|
|
glVertex3fv( v1 );
|
|
if(mface->v4) {
|
|
glColor3ub(cp2[15], cp2[14], cp2[13]);
|
|
glVertex3fv( v4 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(col2) cp2+= 16;
|
|
}
|
|
|
|
glEnd();
|
|
glShadeModel(GL_FLAT);
|
|
if(twoside) glDisable(GL_CULL_FACE);
|
|
|
|
}
|
|
|
|
static void drawDispList(Object *ob, int dt)
|
|
{
|
|
ListBase *lb=0;
|
|
DispList *dl;
|
|
Mesh *me;
|
|
int solid;
|
|
|
|
|
|
solid= (dt > OB_WIRE);
|
|
|
|
switch(ob->type) {
|
|
case OB_MESH:
|
|
|
|
me= get_mesh(ob);
|
|
if(me==0) return;
|
|
|
|
if(me->bb==0) tex_space_mesh(me);
|
|
if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return;
|
|
|
|
|
|
|
|
if(dt==OB_SOLID ) {
|
|
|
|
lb= &me->disp;
|
|
if(lb->first==0) addnormalsDispList(ob, lb);
|
|
|
|
dl= lb->first;
|
|
if(dl==0) return;
|
|
|
|
if(mesh_uses_displist(me)) {
|
|
int vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
|
|
|
|
/* vertexpaint only true when selecting */
|
|
if (vertexpaint)
|
|
drawmeshsolid(ob, NULL);
|
|
else {
|
|
init_gl_materials(ob);
|
|
two_sided(me->flag & ME_TWOSIDED);
|
|
drawDispListsolid(lb, ob);
|
|
}
|
|
}
|
|
else drawmeshsolid(ob, dl->nors);
|
|
|
|
}
|
|
else if(dt==OB_SHADED) {
|
|
#ifdef __NLA
|
|
if( G.f & G_WEIGHTPAINT && me->dvert) {
|
|
unsigned char *wtcol, *curwt;
|
|
MFace *curface;
|
|
int i;
|
|
unsigned char r,g,b;
|
|
float val1,val2,val3,val4;
|
|
|
|
wtcol = curwt= MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
|
|
|
|
memset (wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
|
|
for (i=0, curface=(MFace*)me->mface; i<me->totface; i++, curface++){
|
|
|
|
val1 = get_mvert_weight (ob, curface->v1, ob->actdef-1);
|
|
val2 = get_mvert_weight (ob, curface->v2, ob->actdef-1);
|
|
val3 = get_mvert_weight (ob, curface->v3, ob->actdef-1);
|
|
if (curface->v4)
|
|
val4 = get_mvert_weight (ob, curface->v4, ob->actdef-1);
|
|
|
|
color_temperature (val1, &r, &g, &b);
|
|
*curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
|
|
color_temperature (val2, &r, &g, &b);
|
|
*curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
|
|
color_temperature (val3, &r, &g, &b);
|
|
*curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
|
|
color_temperature (val4, &r, &g, &b);
|
|
*curwt++=0; *curwt++=b; *curwt++=g; *curwt++=r;
|
|
|
|
}
|
|
|
|
drawmeshshaded(ob, (unsigned int*)wtcol, 0);
|
|
MEM_freeN (wtcol);
|
|
|
|
}
|
|
else
|
|
#endif
|
|
if( G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) {
|
|
/* in deze volgorde: vertexpaint heeft soms al mcol gemaakt */
|
|
///*
|
|
|
|
//*/
|
|
if(me->mcol)
|
|
drawmeshshaded(ob, (unsigned int *)me->mcol, 0);
|
|
else if(me->tface) {
|
|
tface_to_mcol(me);
|
|
drawmeshshaded(ob, (unsigned int *)me->mcol, 0);
|
|
MEM_freeN(me->mcol); me->mcol= 0;
|
|
}
|
|
else
|
|
drawmeshwire(ob);
|
|
|
|
}
|
|
else {
|
|
dl= ob->disp.first;
|
|
|
|
if(dl==0 || dl->col1==0) {
|
|
shadeDispList(ob);
|
|
dl= ob->disp.first;
|
|
}
|
|
if(dl) {
|
|
if(mesh_uses_displist(me))
|
|
drawDispListshaded(&me->disp, ob);
|
|
else
|
|
drawmeshshaded(ob, dl->col1, dl->col2);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(ob==((G.scene->basact) ? (G.scene->basact->object) : 0) && (G.f & G_FACESELECT)) {
|
|
draw_tfaces3D(ob, me);
|
|
}
|
|
|
|
break;
|
|
|
|
case OB_FONT:
|
|
case OB_CURVE:
|
|
|
|
lb= &((Curve *)ob->data)->disp;
|
|
if(lb->first==0) makeDispList(ob);
|
|
|
|
if(solid && ob!=G.obedit) {
|
|
dl= lb->first;
|
|
if(dl==0) return;
|
|
|
|
/* regel: dl->type INDEX3 altijd vooraan in lijst */
|
|
if(dl->type!=DL_INDEX3) {
|
|
curve_to_filledpoly(ob->data, lb);
|
|
dl= lb->first;
|
|
}
|
|
if(dl->nors==0) addnormalsDispList(ob, lb);
|
|
|
|
index3_nors_incr= 0;
|
|
|
|
if(dt==OB_SHADED) {
|
|
if(ob->disp.first==0) shadeDispList(ob);
|
|
drawDispListshaded(lb, ob);
|
|
}
|
|
else {
|
|
init_gl_materials(ob);
|
|
two_sided(0);
|
|
drawDispListsolid(lb, ob);
|
|
}
|
|
index3_nors_incr= 1;
|
|
}
|
|
else {
|
|
draw_index_wire= 0;
|
|
drawDispListwire(lb);
|
|
draw_index_wire= 1;
|
|
}
|
|
break;
|
|
case OB_SURF:
|
|
|
|
lb= &((Curve *)ob->data)->disp;
|
|
if(lb->first==0) makeDispList(ob);
|
|
|
|
if(solid) {
|
|
dl= lb->first;
|
|
if(dl==0) return;
|
|
|
|
if(dl->nors==0) addnormalsDispList(ob, lb);
|
|
|
|
if(dt==OB_SHADED) {
|
|
if(ob->disp.first==0) shadeDispList(ob);
|
|
drawDispListshaded(lb, ob);
|
|
}
|
|
else {
|
|
init_gl_materials(ob);
|
|
two_sided(0);
|
|
|
|
drawDispListsolid(lb, ob);
|
|
}
|
|
}
|
|
else {
|
|
drawDispListwire(lb);
|
|
}
|
|
break;
|
|
case OB_MBALL:
|
|
|
|
lb= &ob->disp;
|
|
if(lb->first==0) makeDispList(ob);
|
|
|
|
if(solid) {
|
|
|
|
if(dt==OB_SHADED) {
|
|
dl= lb->first;
|
|
if(dl && dl->col1==0) shadeDispList(ob);
|
|
drawDispListshaded(lb, ob);
|
|
}
|
|
else {
|
|
init_gl_materials(ob);
|
|
two_sided(0);
|
|
|
|
drawDispListsolid(lb, ob);
|
|
}
|
|
}
|
|
else drawDispListwire(lb);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/* ******************************** */
|
|
|
|
|
|
static void draw_particle_system(Object *ob, PartEff *paf)
|
|
{
|
|
Particle *pa;
|
|
float ptime, ctime, vec[3], vec1[3];
|
|
int a;
|
|
|
|
pa= paf->keys;
|
|
if(pa==0) {
|
|
build_particle_system(ob);
|
|
pa= paf->keys;
|
|
if(pa==0) return;
|
|
}
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
|
|
else ptime= 0.0;
|
|
ctime= bsystem_time(ob, 0, (float)(G.scene->r.cfra), ptime);
|
|
|
|
glPointSize(1.0);
|
|
if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
|
|
|
|
for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
|
|
|
|
if(ctime > pa->time) {
|
|
if(ctime < pa->time+pa->lifetime) {
|
|
|
|
if(paf->stype==PAF_VECT) {
|
|
where_is_particle(paf, pa, ctime, vec);
|
|
where_is_particle(paf, pa, ctime+1.0, vec1);
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec);
|
|
glVertex3fv(vec1);
|
|
glEnd();
|
|
|
|
}
|
|
else {
|
|
where_is_particle(paf, pa, ctime, vec);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(paf->stype!=PAF_VECT) glEnd();
|
|
|
|
}
|
|
|
|
static void draw_static_particle_system(Object *ob, PartEff *paf)
|
|
{
|
|
Particle *pa;
|
|
float ctime, mtime, vec[3], vec1[3];
|
|
int a;
|
|
|
|
pa= paf->keys;
|
|
if(pa==0) {
|
|
build_particle_system(ob);
|
|
pa= paf->keys;
|
|
if(pa==0) return;
|
|
}
|
|
|
|
glPointSize(1.0);
|
|
if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
|
|
|
|
for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
|
|
|
|
where_is_particle(paf, pa, pa->time, vec1);
|
|
|
|
mtime= pa->time+pa->lifetime+paf->staticstep-1;
|
|
|
|
for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
|
|
|
|
/* make sure hair grows until the end.. */
|
|
if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
|
|
|
|
if(paf->stype==PAF_VECT) {
|
|
where_is_particle(paf, pa, ctime+1, vec);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec);
|
|
glVertex3fv(vec1);
|
|
glEnd();
|
|
|
|
VECCOPY(vec1, vec);
|
|
}
|
|
else {
|
|
where_is_particle(paf, pa, ctime, vec);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
}
|
|
}
|
|
}
|
|
if(paf->stype!=PAF_VECT) glEnd();
|
|
|
|
}
|
|
|
|
static void drawmeshwire(Object *ob)
|
|
{
|
|
extern float editbutsize; /* buttons.c */
|
|
Mesh *me;
|
|
MVert *mvert;
|
|
MFace *mface;
|
|
DispList *dl;
|
|
Material *ma;
|
|
EditEdge *eed;
|
|
EditVlak *evl;
|
|
float fvec[3], cent[3], *f1, *f2, *f3, *f4, *extverts=0;
|
|
int a, start, end, test, /* colbcol=0, */ ok;
|
|
|
|
me= get_mesh(ob);
|
|
|
|
if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
|
|
|
|
if(G.zbuf==0 && mesh_uses_displist(me)) {
|
|
cpack(0x505050);
|
|
drawDispListwire(&me->disp);
|
|
}
|
|
cpack(0x0);
|
|
|
|
eed= G.eded.first;
|
|
|
|
glBegin(GL_LINES);
|
|
while(eed) {
|
|
if(eed->h==0) {
|
|
glVertex3fv(eed->v1->co);
|
|
glVertex3fv(eed->v2->co);
|
|
}
|
|
eed= eed->next;
|
|
}
|
|
glEnd();
|
|
|
|
if(ob!=G.obedit) return;
|
|
|
|
calc_meshverts();
|
|
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
tekenvertices(0);
|
|
tekenvertices(1);
|
|
#ifdef __NLA
|
|
tekenvertices(2); /* __TEKENTEST */
|
|
#endif
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
|
|
if(G.f & G_DRAWNORMALS) { /* normals */
|
|
cpack(0xDDDD22);
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
evl= G.edvl.first;
|
|
while(evl) {
|
|
if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) {
|
|
if(evl->v4) CalcCent4f(fvec, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
|
|
else CalcCent3f(fvec, evl->v1->co, evl->v2->co, evl->v3->co);
|
|
|
|
glVertex3fv(fvec);
|
|
fvec[0]+= editbutsize*evl->n[0];
|
|
fvec[1]+= editbutsize*evl->n[1];
|
|
fvec[2]+= editbutsize*evl->n[2];
|
|
glVertex3fv(fvec);
|
|
|
|
}
|
|
evl= evl->next;
|
|
}
|
|
|
|
glEnd();
|
|
}
|
|
if(G.f & (G_FACESELECT+G_DRAWFACES)) { /* vlakken */
|
|
|
|
evl= G.edvl.first;
|
|
while(evl) {
|
|
if(evl->v1->h==0 && evl->v2->h==0 && evl->v3->h==0) {
|
|
|
|
if(vlakselectedAND(evl, 1)) cpack(0x559999);
|
|
else cpack(0x664466);
|
|
|
|
if(evl->v4 && evl->v4->h==0) {
|
|
|
|
CalcCent4f(cent, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
|
|
glBegin(GL_LINE_LOOP);
|
|
VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec);
|
|
VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec);
|
|
VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec);
|
|
VecMidf(fvec, cent, evl->v4->co); glVertex3fv(fvec);
|
|
glEnd();
|
|
}
|
|
else {
|
|
|
|
CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co);
|
|
glBegin(GL_LINE_LOOP);
|
|
VecMidf(fvec, cent, evl->v1->co); glVertex3fv(fvec);
|
|
VecMidf(fvec, cent, evl->v2->co); glVertex3fv(fvec);
|
|
VecMidf(fvec, cent, evl->v3->co); glVertex3fv(fvec);
|
|
glEnd();
|
|
}
|
|
}
|
|
evl= evl->next;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
if(me==0) return;
|
|
|
|
if(me->bb==0) tex_space_mesh(me);
|
|
if(me->totface>4) if(boundbox_clip(ob->obmat, me->bb)==0) return;
|
|
|
|
if(mesh_uses_displist(me)) drawDispListwire(&me->disp);
|
|
else {
|
|
|
|
mvert= me->mvert;
|
|
mface= me->mface;
|
|
|
|
ok= 0;
|
|
if(me->totface==0) ok= 1;
|
|
else {
|
|
ma= give_current_material(ob, 1);
|
|
if(ma && (ma->mode & MA_HALO)) ok= 1;
|
|
}
|
|
|
|
dl= find_displist(&ob->disp, DL_VERTS);
|
|
if(dl) extverts= dl->verts;
|
|
|
|
if(ok) {
|
|
|
|
start= 0; end= me->totvert;
|
|
set_buildvars(ob, &start, &end);
|
|
|
|
glPointSize(1.5);
|
|
glBegin(GL_POINTS);
|
|
|
|
if(extverts) {
|
|
extverts+= 3*start;
|
|
for(a= start; a<end; a++, extverts+=3) {
|
|
glVertex3fv(extverts);
|
|
}
|
|
}
|
|
else {
|
|
mvert+= start;
|
|
for(a= start; a<end; a++, mvert++) {
|
|
glVertex3fv(mvert->co);
|
|
}
|
|
}
|
|
|
|
glEnd();
|
|
glPointSize(1.0);
|
|
}
|
|
else {
|
|
|
|
start= 0; end= me->totface;
|
|
set_buildvars(ob, &start, &end);
|
|
mface+= start;
|
|
|
|
for(a=start; a<end; a++, mface++) {
|
|
test= mface->edcode;
|
|
|
|
if(test) {
|
|
if(extverts) {
|
|
f1= extverts+3*mface->v1;
|
|
f2= extverts+3*mface->v2;
|
|
}
|
|
else {
|
|
f1= (mvert+mface->v1)->co;
|
|
f2= (mvert+mface->v2)->co;
|
|
}
|
|
|
|
if(mface->v4) {
|
|
if(extverts) {
|
|
f3= extverts+3*mface->v3;
|
|
f4= extverts+3*mface->v4;
|
|
}
|
|
else {
|
|
f3= (mvert+mface->v3)->co;
|
|
f4= (mvert+mface->v4)->co;
|
|
}
|
|
|
|
if(test== ME_V1V2+ME_V2V3+ME_V3V4+ME_V4V1) {
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4);
|
|
glEnd();
|
|
}
|
|
else if(test== ME_V1V2+ME_V2V3+ME_V3V4) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4);
|
|
glEnd();
|
|
}
|
|
else if(test== ME_V2V3+ME_V3V4+ME_V4V1) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1);
|
|
glEnd();
|
|
}
|
|
else if(test== ME_V3V4+ME_V4V1+ME_V1V2) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f3); glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2);
|
|
glEnd();
|
|
}
|
|
else if(test== ME_V4V1+ME_V1V2+ME_V2V3) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f4); glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
|
|
glEnd();
|
|
}
|
|
else {
|
|
if(test & ME_V1V2) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f1); glVertex3fv(f2);
|
|
glEnd();
|
|
}
|
|
if(test & ME_V2V3) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f2); glVertex3fv(f3);
|
|
glEnd();
|
|
}
|
|
if(test & ME_V3V4) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f3); glVertex3fv(f4);
|
|
glEnd();
|
|
}
|
|
if(test & ME_V4V1) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f4); glVertex3fv(f1);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
else if(mface->v3) {
|
|
if(extverts) f3= extverts+3*mface->v3;
|
|
else f3= (mvert+mface->v3)->co;
|
|
|
|
if(test== ME_V1V2+ME_V2V3+ME_V3V1) {
|
|
glBegin(GL_LINE_LOOP);
|
|
glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
|
|
glEnd();
|
|
}
|
|
else if(test== ME_V1V2+ME_V2V3) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f1); glVertex3fv(f2); glVertex3fv(f3);
|
|
glEnd();
|
|
}
|
|
else if(test== ME_V2V3+ME_V3V1) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f2); glVertex3fv(f3); glVertex3fv(f1);
|
|
glEnd();
|
|
}
|
|
else if(test== ME_V1V2+ME_V3V1) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f3); glVertex3fv(f1); glVertex3fv(f2);
|
|
glEnd();
|
|
}
|
|
else {
|
|
if(test & ME_V1V2) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f1); glVertex3fv(f2);
|
|
glEnd();
|
|
}
|
|
if(test & ME_V2V3) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f2); glVertex3fv(f3);
|
|
glEnd();
|
|
}
|
|
if(test & ME_V3V1) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f3); glVertex3fv(f1);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
else if(test & ME_V1V2) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(f1); glVertex3fv(f2);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned int nurbcol[8]= {
|
|
0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 };
|
|
|
|
static void tekenhandlesN(Nurb *nu, short sel)
|
|
{
|
|
BezTriple *bezt;
|
|
float *fp;
|
|
unsigned int *col;
|
|
int a;
|
|
|
|
if(nu->hide) return;
|
|
if( (nu->type & 7)==1) {
|
|
if(sel) col= nurbcol+4;
|
|
else col= nurbcol;
|
|
|
|
bezt= nu->bezt;
|
|
a= nu->pntsu;
|
|
while(a--) {
|
|
if(bezt->hide==0) {
|
|
if( (bezt->f2 & 1)==sel) {
|
|
fp= bezt->vec[0];
|
|
cpack(col[bezt->h1]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(fp);
|
|
glVertex3fv(fp+3);
|
|
glEnd();
|
|
cpack(col[bezt->h2]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(fp+3);
|
|
glVertex3fv(fp+6);
|
|
glEnd();
|
|
}
|
|
else if( (bezt->f1 & 1)==sel) {
|
|
fp= bezt->vec[0];
|
|
cpack(col[bezt->h1]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(fp);
|
|
glVertex3fv(fp+3);
|
|
glEnd();
|
|
}
|
|
else if( (bezt->f3 & 1)==sel) {
|
|
fp= bezt->vec[1];
|
|
cpack(col[bezt->h2]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(fp);
|
|
glVertex3fv(fp+3);
|
|
glEnd();
|
|
}
|
|
}
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void tekenvertsN(Nurb *nu, short sel)
|
|
{
|
|
BezTriple *bezt;
|
|
BPoint *bp;
|
|
int a;
|
|
|
|
if(nu->hide) return;
|
|
|
|
if(sel) cpack(B_YELLOW);
|
|
else cpack(B_PURPLE);
|
|
glPointSize(3.0);
|
|
|
|
glBegin(GL_POINTS);
|
|
|
|
if((nu->type & 7)==1) {
|
|
|
|
bezt= nu->bezt;
|
|
a= nu->pntsu;
|
|
while(a--) {
|
|
if(bezt->hide==0) {
|
|
if((bezt->f1 & 1)==sel) glVertex3fv(bezt->vec[0]);
|
|
if((bezt->f2 & 1)==sel) glVertex3fv(bezt->vec[1]);
|
|
if((bezt->f3 & 1)==sel) glVertex3fv(bezt->vec[2]);
|
|
}
|
|
bezt++;
|
|
}
|
|
}
|
|
else {
|
|
bp= nu->bp;
|
|
a= nu->pntsu*nu->pntsv;
|
|
while(a--) {
|
|
if(bp->hide==0) {
|
|
if((bp->f1 & 1)==sel) glVertex3fv(bp->vec);
|
|
}
|
|
bp++;
|
|
}
|
|
}
|
|
|
|
glEnd();
|
|
glPointSize(1.0);
|
|
}
|
|
|
|
static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
|
|
{
|
|
Nurb *nu;
|
|
BPoint *bp, *bp1;
|
|
int a, b, ofs;
|
|
|
|
nu= nurb;
|
|
while(nu) {
|
|
if(nu->hide==0) {
|
|
switch(nu->type & 7) {
|
|
case CU_POLY:
|
|
cpack(nurbcol[3]);
|
|
bp= nu->bp;
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
if(nu->flagu & 1) glBegin(GL_LINE_LOOP);
|
|
|
|
else glBegin(GL_LINE_STRIP);
|
|
|
|
for(a=0; a<nu->pntsu; a++, bp++) {
|
|
glVertex3fv(bp->vec);
|
|
}
|
|
|
|
if(nu->flagu & 1) glEnd();
|
|
else glEnd();
|
|
}
|
|
break;
|
|
case CU_NURBS:
|
|
|
|
bp= nu->bp;
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
bp1= bp;
|
|
bp++;
|
|
for(a=nu->pntsu-1; a>0; a--, bp++) {
|
|
if(bp->hide==0 && bp1->hide==0) {
|
|
if(sel) {
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
|
|
cpack(nurbcol[5]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(bp->vec);
|
|
glVertex3fv(bp1->vec);
|
|
glEnd();
|
|
}
|
|
}
|
|
else {
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) );
|
|
else {
|
|
cpack(nurbcol[1]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(bp->vec);
|
|
glVertex3fv(bp1->vec);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
bp1= bp;
|
|
}
|
|
}
|
|
if(nu->pntsv > 1) { /* surface */
|
|
|
|
ofs= nu->pntsu;
|
|
for(b=0; b<nu->pntsu; b++) {
|
|
bp1= nu->bp+b;
|
|
bp= bp1+ofs;
|
|
for(a=nu->pntsv-1; a>0; a--, bp+=ofs) {
|
|
if(bp->hide==0 && bp1->hide==0) {
|
|
if(sel) {
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
|
|
cpack(nurbcol[7]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(bp->vec);
|
|
glVertex3fv(bp1->vec);
|
|
glEnd();
|
|
}
|
|
}
|
|
else {
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) );
|
|
else {
|
|
cpack(nurbcol[3]);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(bp->vec);
|
|
glVertex3fv(bp1->vec);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
bp1= bp;
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
nu= nu->next;
|
|
}
|
|
}
|
|
|
|
static void drawnurb(Object *ob, Nurb *nurb, int dt)
|
|
{
|
|
extern float editbutsize; /* buttons.c */
|
|
Curve *cu;
|
|
Nurb *nu;
|
|
BevPoint *bevp;
|
|
BevList *bl;
|
|
float vec[3];
|
|
int a, nr, skip;
|
|
|
|
/* eerst handles niet select */
|
|
nu= nurb;
|
|
while(nu) {
|
|
if((nu->type & 7)==CU_BEZIER) {
|
|
tekenhandlesN(nu, 0);
|
|
}
|
|
nu= nu->next;
|
|
}
|
|
|
|
/* dan DispList */
|
|
|
|
cpack(0);
|
|
cu= ob->data;
|
|
drawDispList(ob, dt);
|
|
|
|
draw_editnurb(ob, nurb, 0);
|
|
draw_editnurb(ob, nurb, 1);
|
|
|
|
if(cu->flag & CU_3D) {
|
|
|
|
if(cu->bev.first==0) makeBevelList(ob);
|
|
|
|
cpack(0x0);
|
|
bl= cu->bev.first;
|
|
nu= nurb;
|
|
while(nu && bl) {
|
|
bevp= (BevPoint *)(bl+1);
|
|
nr= bl->nr;
|
|
|
|
skip= nu->resolu/16;
|
|
|
|
while(nr-- > 0) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
vec[0]= bevp->x-editbutsize*bevp->mat[0][0];
|
|
vec[1]= bevp->y-editbutsize*bevp->mat[0][1];
|
|
vec[2]= bevp->z-editbutsize*bevp->mat[0][2];
|
|
glVertex3fv(vec);
|
|
vec[0]= bevp->x+editbutsize*bevp->mat[0][0];
|
|
vec[1]= bevp->y+editbutsize*bevp->mat[0][1];
|
|
vec[2]= bevp->z+editbutsize*bevp->mat[0][2];
|
|
glVertex3fv(vec);
|
|
|
|
glEnd();
|
|
|
|
bevp++;
|
|
|
|
a= skip;
|
|
while(a--) {
|
|
bevp++;
|
|
nr--;
|
|
}
|
|
}
|
|
|
|
bl= bl->next;
|
|
nu= nu->next;
|
|
}
|
|
}
|
|
|
|
calc_Nurbverts(nurb);
|
|
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
|
|
nu= nurb;
|
|
while(nu) {
|
|
if((nu->type & 7)==1) tekenhandlesN(nu, 1);
|
|
tekenvertsN(nu, 0);
|
|
nu= nu->next;
|
|
}
|
|
|
|
nu= nurb;
|
|
while(nu) {
|
|
tekenvertsN(nu, 1);
|
|
nu= nu->next;
|
|
}
|
|
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
static void tekentextcurs(void)
|
|
{
|
|
cpack(0);
|
|
|
|
glBegin(GL_QUADS);
|
|
glVertex2fv(G.textcurs[0]);
|
|
glVertex2fv(G.textcurs[1]);
|
|
glVertex2fv(G.textcurs[2]);
|
|
glVertex2fv(G.textcurs[3]);
|
|
glEnd();
|
|
}
|
|
|
|
void drawcircball(float *cent, float rad, float tmat[][4])
|
|
{
|
|
float si, co, phi, dphi, vec[3], vx[3], vy[3];
|
|
int a, tot=32;
|
|
|
|
VECCOPY(vx, tmat[0]);
|
|
VECCOPY(vy, tmat[1]);
|
|
VecMulf(vx, rad);
|
|
VecMulf(vy, rad);
|
|
|
|
dphi= 2.0*M_PI/tot;
|
|
phi= 0.0;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
for(a=0; a<tot; a++, phi+= dphi) {
|
|
si= sin(phi);
|
|
co= cos(phi);
|
|
vec[0]= cent[0]+si*vx[0]+co*vy[0];
|
|
vec[1]= cent[1]+si*vx[1]+co*vy[1];
|
|
vec[2]= cent[2]+si*vx[2]+co*vy[2];
|
|
glVertex3fv(vec);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
static void drawmball(Object *ob, int dt)
|
|
{
|
|
MetaBall *mb;
|
|
MetaElem *ml;
|
|
float imat[4][4], tmat[4][4];
|
|
int code= 1;
|
|
|
|
mb= ob->data;
|
|
|
|
if(ob==G.obedit) {
|
|
cpack(0x0);
|
|
if((G.f & G_PICKSEL)==0 ) drawDispList(ob, dt);
|
|
ml= editelems.first;
|
|
}
|
|
else {
|
|
drawDispList(ob, dt);
|
|
ml= mb->elems.first;
|
|
}
|
|
|
|
mygetmatrix(tmat);
|
|
Mat4Invert(imat, tmat);
|
|
Normalise(imat[0]);
|
|
Normalise(imat[1]);
|
|
|
|
while(ml) {
|
|
|
|
if(ob==G.obedit) {
|
|
if(ml->flag & SELECT) cpack(0xA0A0F0);
|
|
else cpack(0x3030A0);
|
|
|
|
if(G.f & G_PICKSEL) {
|
|
ml->selcol= code;
|
|
glLoadName(code++);
|
|
}
|
|
}
|
|
drawcircball(&(ml->x), ml->rad, imat);
|
|
|
|
ml= ml->next;
|
|
}
|
|
|
|
}
|
|
|
|
static void draw_bb_box(BoundBox *bb)
|
|
{
|
|
float *vec;
|
|
|
|
vec= bb->vec[0];
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec); glVertex3fv(vec+3);glVertex3fv(vec+6); glVertex3fv(vec+9);
|
|
glVertex3fv(vec); glVertex3fv(vec+12);glVertex3fv(vec+15); glVertex3fv(vec+18);
|
|
glVertex3fv(vec+21); glVertex3fv(vec+12);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec+3); glVertex3fv(vec+15);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec+6); glVertex3fv(vec+18);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec+9); glVertex3fv(vec+21);
|
|
glEnd();
|
|
|
|
}
|
|
|
|
void get_local_bounds(Object *ob, float *centre, float *size)
|
|
{
|
|
BoundBox *bb= NULL;
|
|
/* uses boundbox, function used by Ketsji */
|
|
|
|
if(ob->type==OB_MESH) {
|
|
bb= ( (Mesh *)ob->data )->bb;
|
|
if(bb==0) {
|
|
tex_space_mesh(ob->data);
|
|
bb= ( (Mesh *)ob->data )->bb;
|
|
}
|
|
}
|
|
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
|
|
bb= ( (Curve *)ob->data )->bb;
|
|
}
|
|
else if(ob->type==OB_MBALL) {
|
|
bb= ob->bb;
|
|
}
|
|
if(bb==NULL) {
|
|
centre[0]= centre[1]= centre[2]= 0.0;
|
|
VECCOPY(size, ob->size);
|
|
}
|
|
else {
|
|
size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
|
|
size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
|
|
size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
|
|
|
|
centre[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0;
|
|
centre[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0;
|
|
centre[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void draw_bb_quadric(BoundBox *bb, short type)
|
|
{
|
|
float size[3], cent[3];
|
|
GLUquadricObj *qobj = gluNewQuadric();
|
|
|
|
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
|
|
|
|
size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
|
|
size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
|
|
size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
|
|
|
|
cent[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0;
|
|
cent[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0;
|
|
cent[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0;
|
|
|
|
if(type==OB_BOUND_SPHERE) {
|
|
glTranslatef(cent[0], cent[1], cent[2]);
|
|
glScalef(size[0], size[1], size[2]);
|
|
gluSphere(qobj, 1.0, 8, 5);
|
|
}
|
|
else if(type==OB_BOUND_CYLINDER) {
|
|
glTranslatef(cent[0], cent[1], cent[2]-size[2]);
|
|
glScalef(size[0], size[1], 2.0*size[2]);
|
|
gluCylinder(qobj, 1.0, 1.0, 1.0, 8, 1);
|
|
}
|
|
else if(type==OB_BOUND_CONE) {
|
|
glTranslatef(cent[0], cent[1], cent[2]-size[2]);
|
|
glScalef(size[0], size[1], 2.0*size[2]);
|
|
gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
|
|
}
|
|
|
|
gluDeleteQuadric(qobj);
|
|
}
|
|
|
|
static void draw_bounding_volume(Object *ob)
|
|
{
|
|
BoundBox *bb=0;
|
|
|
|
if(ob->type==OB_MESH) {
|
|
bb= ( (Mesh *)ob->data )->bb;
|
|
if(bb==0) {
|
|
tex_space_mesh(ob->data);
|
|
bb= ( (Mesh *)ob->data )->bb;
|
|
}
|
|
}
|
|
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
|
|
bb= ( (Curve *)ob->data )->bb;
|
|
if(bb==0) {
|
|
makeDispList(ob);
|
|
bb= ( (Curve *)ob->data )->bb;
|
|
}
|
|
}
|
|
else if(ob->type==OB_MBALL) {
|
|
bb= ob->bb;
|
|
if(bb==0) {
|
|
makeDispList(ob);
|
|
bb= ob->bb;
|
|
}
|
|
}
|
|
else {
|
|
drawcube();
|
|
return;
|
|
}
|
|
|
|
if(bb==0) return;
|
|
|
|
if(ob->boundtype==OB_BOUND_BOX) draw_bb_box(bb);
|
|
else draw_bb_quadric(bb, ob->boundtype);
|
|
|
|
}
|
|
|
|
static void drawtexspace(Object *ob)
|
|
{
|
|
Mesh *me;
|
|
MetaBall *mb;
|
|
Curve *cu;
|
|
BoundBox bb;
|
|
float *vec, *loc, *size;
|
|
|
|
if(ob->type==OB_MESH) {
|
|
me= ob->data;
|
|
size= me->size;
|
|
loc= me->loc;
|
|
}
|
|
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
|
|
cu= ob->data;
|
|
size= cu->size;
|
|
loc= cu->loc;
|
|
}
|
|
else if(ob->type==OB_MBALL) {
|
|
mb= ob->data;
|
|
size= mb->size;
|
|
loc= mb->loc;
|
|
}
|
|
else return;
|
|
|
|
bb.vec[0][0]=bb.vec[1][0]=bb.vec[2][0]=bb.vec[3][0]= loc[0]-size[0];
|
|
bb.vec[4][0]=bb.vec[5][0]=bb.vec[6][0]=bb.vec[7][0]= loc[0]+size[0];
|
|
|
|
bb.vec[0][1]=bb.vec[1][1]=bb.vec[4][1]=bb.vec[5][1]= loc[1]-size[1];
|
|
bb.vec[2][1]=bb.vec[3][1]=bb.vec[6][1]=bb.vec[7][1]= loc[1]+size[1];
|
|
|
|
bb.vec[0][2]=bb.vec[3][2]=bb.vec[4][2]=bb.vec[7][2]= loc[2]-size[2];
|
|
bb.vec[1][2]=bb.vec[2][2]=bb.vec[5][2]=bb.vec[6][2]= loc[2]+size[2];
|
|
|
|
setlinestyle(2);
|
|
|
|
vec= bb.vec[0];
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec); glVertex3fv(vec+3);glVertex3fv(vec+6); glVertex3fv(vec+9);
|
|
glVertex3fv(vec); glVertex3fv(vec+12);glVertex3fv(vec+15); glVertex3fv(vec+18);
|
|
glVertex3fv(vec+21); glVertex3fv(vec+12);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec+3); glVertex3fv(vec+15);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec+6); glVertex3fv(vec+18);
|
|
glEnd();
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
glVertex3fv(vec+9); glVertex3fv(vec+21);
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
|
}
|
|
|
|
static int ob_from_decimator(Object *ob)
|
|
{
|
|
/* note: this is a temporal solution, a reconstruction of the
|
|
displist system should take care of it (ton)
|
|
*/
|
|
DispList *dl;
|
|
|
|
dl= ob->disp.first;
|
|
|
|
if(dl && dl->mesh) return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void draw_object(Base *base)
|
|
{
|
|
PartEff *paf;
|
|
Object *ob;
|
|
Curve *cu;
|
|
Mesh *me;
|
|
ListBase elems;
|
|
CfraElem *ce;
|
|
float cfraont, axsize=1.0;
|
|
unsigned int *rect, col=0;
|
|
static int warning_recursive= 0;
|
|
int sel, drawtype, colindex= 0, ipoflag;
|
|
short dt, dtx, zbufoff= 0;
|
|
|
|
ob= base->object;
|
|
|
|
/* keys tekenen? */
|
|
if(base==(G.scene->basact) || (base->flag & (SELECT+BA_WASSEL))) {
|
|
if(warning_recursive==0 && ob!=G.obedit) {
|
|
if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
|
|
float temp[7][3];
|
|
|
|
warning_recursive= 1;
|
|
|
|
elems.first= elems.last= 0;
|
|
make_cfra_list(ob->ipo, &elems);
|
|
|
|
cfraont= (G.scene->r.cfra);
|
|
drawtype= G.vd->drawtype;
|
|
if(drawtype>OB_WIRE) G.vd->drawtype= OB_WIRE;
|
|
sel= base->flag;
|
|
memcpy(temp, &ob->loc, 7*3*sizeof(float));
|
|
|
|
ipoflag= ob->ipoflag;
|
|
ob->ipoflag &= ~OB_OFFS_OB;
|
|
|
|
set_no_parent_ipo(1);
|
|
disable_speed_curve(1);
|
|
|
|
if ((ob->ipoflag & OB_DRAWKEYSEL)==0) {
|
|
ce= elems.first;
|
|
while(ce) {
|
|
if(!ce->sel) {
|
|
(G.scene->r.cfra)= ce->cfra/G.scene->r.framelen;
|
|
|
|
base->flag= 0;
|
|
|
|
where_is_object_time(ob, (G.scene->r.cfra));
|
|
draw_object(base);
|
|
}
|
|
ce= ce->next;
|
|
}
|
|
}
|
|
|
|
ce= elems.first;
|
|
while(ce) {
|
|
if(ce->sel) {
|
|
(G.scene->r.cfra)= ce->cfra/G.scene->r.framelen;
|
|
|
|
base->flag= SELECT;
|
|
|
|
where_is_object_time(ob, (G.scene->r.cfra));
|
|
draw_object(base);
|
|
}
|
|
ce= ce->next;
|
|
}
|
|
|
|
set_no_parent_ipo(0);
|
|
disable_speed_curve(0);
|
|
|
|
base->flag= sel;
|
|
ob->ipoflag= ipoflag;
|
|
|
|
/* restore icu->curval */
|
|
(G.scene->r.cfra)= cfraont;
|
|
|
|
memcpy(&ob->loc, temp, 7*3*sizeof(float));
|
|
where_is_object(ob);
|
|
G.vd->drawtype= drawtype;
|
|
|
|
BLI_freelistN(&elems);
|
|
|
|
warning_recursive= 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* patch? kinderen met timeoffs verprutsen ouders. Hoe los je dat op! */
|
|
/* if( ((int)ob->ctime) != F_(G.scene->r.cfra)) where_is_object(ob); */
|
|
|
|
mymultmatrix(ob->obmat);
|
|
|
|
/* welke wire kleur */
|
|
if((G.f & (G_BACKBUFSEL+G_PICKSEL)) == 0) {
|
|
project_short(ob->obmat[3], &base->sx);
|
|
|
|
if(G.moving==1 && (base->flag & (SELECT+BA_PARSEL))) colindex= 12;
|
|
else {
|
|
if((G.scene->basact)==base) {
|
|
if(base->flag & (SELECT+BA_WASSEL)) colindex= 2;
|
|
}
|
|
else {
|
|
if(base->flag & (SELECT+BA_WASSEL)) colindex= 1;
|
|
}
|
|
if(ob->id.lib) colindex+= 3;
|
|
else if(warning_recursive==1) colindex+= 6;
|
|
else if(ob->flag & OB_FROMGROUP) colindex+= 9;
|
|
}
|
|
|
|
col= colortab[colindex];
|
|
cpack(col);
|
|
|
|
}
|
|
|
|
/* maximum drawtype */
|
|
dt= MIN2(G.vd->drawtype, ob->dt);
|
|
if(G.zbuf==0 && dt>OB_WIRE) dt= OB_WIRE;
|
|
dtx= 0;
|
|
|
|
/* faceselect uitzondering: ook solid tekenen als dt==wire, behalve in editmode */
|
|
if(ob==((G.scene->basact) ? (G.scene->basact->object) : 0) && (G.f & (G_FACESELECT+G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT))) {
|
|
if(ob->type==OB_MESH) {
|
|
|
|
if(ob==G.obedit) dt= OB_WIRE;
|
|
else {
|
|
if(G.f & G_BACKBUFSEL) dt= OB_SOLID;
|
|
else dt= OB_SHADED;
|
|
|
|
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
zbufoff= 1;
|
|
}
|
|
}
|
|
else {
|
|
if(dt<OB_SOLID) {
|
|
dt= OB_SOLID;
|
|
glClearDepth(1.); glClear(GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
zbufoff= 1;
|
|
}
|
|
}
|
|
}
|
|
else if(dt>=OB_WIRE ) {
|
|
|
|
if(dt>OB_SOLID) if(G.f & G_BACKBUFSEL) dt= OB_SOLID;
|
|
|
|
dtx= ob->dtx;
|
|
if(G.obedit==ob) {
|
|
if(dtx & OB_TEXSPACE) dtx= OB_TEXSPACE;
|
|
else dtx= 0;
|
|
}
|
|
|
|
if(G.f & G_DRAW_EXT) {
|
|
if(ob->type==OB_EMPTY || ob->type==OB_CAMERA || ob->type==OB_LAMP) dt= OB_WIRE;
|
|
}
|
|
|
|
}
|
|
|
|
if( (G.f & G_DRAW_EXT) && dt>OB_WIRE) {
|
|
|
|
switch( ob->type) {
|
|
case OB_MBALL:
|
|
drawmball(ob, dt);
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
|
|
switch( ob->type) {
|
|
|
|
case OB_MESH:
|
|
me= ob->data;
|
|
|
|
#if 1
|
|
#ifdef __NLA
|
|
/* Force a refresh of the display list if the parent is an armature */
|
|
if (ob->parent && ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL){
|
|
#if 0 /* Turn this on if there are problems with deformation lag */
|
|
where_is_armature (ob->parent);
|
|
#endif
|
|
if (ob != G.obedit)
|
|
makeDispList (ob);
|
|
}
|
|
#endif
|
|
#endif
|
|
if(base->flag & OB_RADIO);
|
|
else if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
|
|
if(dt<=OB_WIRE) drawmeshwire(ob);
|
|
else {
|
|
if(mesh_uses_displist(me)) {
|
|
init_gl_materials(ob);
|
|
two_sided( me->flag & ME_TWOSIDED );
|
|
drawDispListsolid(&me->disp, ob);
|
|
drawmeshwire(ob);
|
|
}
|
|
else drawmeshsolid(ob, 0);
|
|
}
|
|
if(ob==G.obedit && (G.f & G_PROPORTIONAL)) draw_prop_circle();
|
|
}
|
|
else {
|
|
Material *ma= give_current_material(ob, 1);
|
|
|
|
if(ob_from_decimator(ob)) drawDispListwire(&ob->disp);
|
|
else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
else if(dt==OB_WIRE) drawmeshwire(ob);
|
|
else if(ma && (ma->mode & MA_HALO)) drawmeshwire(ob);
|
|
else if(me->tface) {
|
|
if(G.f & G_BACKBUFSEL) drawmeshsolid(ob, 0);
|
|
else if(G.f & G_FACESELECT || G.vd->drawtype==OB_TEXTURE) draw_tface_mesh(ob, ob->data, dt);
|
|
else drawDispList(ob, dt);
|
|
}
|
|
else drawDispList(ob, dt);
|
|
}
|
|
if( (ob!=G.obedit)
|
|
&& ((G.f & (G_BACKBUFSEL+G_PICKSEL)) == 0) ) {
|
|
paf = give_parteff(ob);
|
|
if( paf ) {
|
|
if(col) cpack(0xFFFFFF); /* zichtbaarheid */
|
|
if(paf->flag & PAF_STATIC) draw_static_particle_system(ob, paf);
|
|
else draw_particle_system(ob, paf);
|
|
cpack(col);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case OB_FONT:
|
|
cu= ob->data;
|
|
if(ob==G.obedit) {
|
|
tekentextcurs();
|
|
cpack(0xFFFF90);
|
|
drawDispList(ob, OB_WIRE);
|
|
}
|
|
else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
else if(boundbox_clip(ob->obmat, cu->bb)) drawDispList(ob, dt);
|
|
|
|
break;
|
|
case OB_CURVE:
|
|
case OB_SURF:
|
|
cu= ob->data;
|
|
/* een pad niet solid tekenen: wel dus!!! */
|
|
/* if(cu->flag & CU_PATH) if(dt>OB_WIRE) dt= OB_WIRE; */
|
|
|
|
if(ob==G.obedit) {
|
|
drawnurb(ob, editNurb.first, dt);
|
|
if((G.f & G_PROPORTIONAL)) draw_prop_circle();
|
|
}
|
|
else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
else if(boundbox_clip(ob->obmat, cu->bb)) drawDispList(ob, dt);
|
|
|
|
break;
|
|
case OB_MBALL:
|
|
if(ob==G.obedit) drawmball(ob, dt);
|
|
else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
else drawmball(ob, dt);
|
|
break;
|
|
case OB_EMPTY:
|
|
drawaxes(1.0);
|
|
break;
|
|
case OB_LAMP:
|
|
/* doet myloadmatrix */
|
|
drawlamp(ob);
|
|
break;
|
|
case OB_CAMERA:
|
|
drawcamera(ob);
|
|
break;
|
|
case OB_LATTICE:
|
|
drawlattice(ob);
|
|
if(ob==G.obedit && (G.f & G_PROPORTIONAL)) draw_prop_circle();
|
|
break;
|
|
case OB_IKA:
|
|
draw_ika(ob, base->flag & SELECT);
|
|
break;
|
|
#ifdef __NLA
|
|
case OB_ARMATURE:
|
|
draw_armature (ob);
|
|
break;
|
|
#endif
|
|
default:
|
|
drawaxes(1.0);
|
|
}
|
|
}
|
|
|
|
/* draw extra: na gewone draw ivm makeDispList */
|
|
if(dtx) {
|
|
if(G.f & G_SIMULATION);
|
|
else if(dtx & OB_AXIS) {
|
|
drawaxes(axsize);
|
|
}
|
|
if(dtx & OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
if(dtx & OB_TEXSPACE) drawtexspace(ob);
|
|
if(dtx & OB_DRAWNAME) {
|
|
if(ob->type==OB_LAMP) glRasterPos3fv(ob->obmat[3]);
|
|
else glRasterPos3f(0.0, 0.0, 0.0);
|
|
|
|
BMF_DrawString(G.font, " ");
|
|
BMF_DrawString(G.font, ob->id.name+2);
|
|
}
|
|
if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);
|
|
}
|
|
|
|
if(dt<OB_SHADED) {
|
|
if((ob->gameflag & OB_ACTOR) && (ob->gameflag & OB_DYNAMIC)) {
|
|
float tmat[4][4], imat[4][4], vec[3];
|
|
|
|
vec[0]= vec[1]= vec[2]= 0.0;
|
|
mygetmatrix(tmat);
|
|
Mat4Invert(imat, tmat);
|
|
|
|
setlinestyle(2);
|
|
drawcircball(vec, ob->inertia, imat);
|
|
setlinestyle(0);
|
|
}
|
|
}
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
if(zbufoff) glDisable(GL_DEPTH_TEST);
|
|
|
|
if(warning_recursive) return;
|
|
if(base->flag & OB_FROMDUPLI) return;
|
|
if(base->flag & OB_RADIO) return;
|
|
if(G.f & G_SIMULATION) return;
|
|
|
|
if((G.f & (G_BACKBUFSEL+G_PICKSEL))==0) {
|
|
/* hulplijnen e.d. */
|
|
if(ob->parent && (ob->parent->lay & G.vd->lay)) {
|
|
setlinestyle(3);
|
|
glBegin(GL_LINES);
|
|
glVertex3fv(ob->obmat[3]);
|
|
glVertex3fv(ob->orig);
|
|
glEnd();
|
|
setlinestyle(0);
|
|
}
|
|
|
|
/* object centers */
|
|
if(G.zbuf) glDisable(GL_DEPTH_TEST);
|
|
if(ob->type == OB_LAMP) {
|
|
if(ob->id.lib) {
|
|
if(base->flag & SELECT) rect= rectllib_sel;
|
|
else rect= rectllib_desel;
|
|
}
|
|
else if(ob->id.us>1) {
|
|
if(base->flag & SELECT) rect= rectlus_sel;
|
|
else rect= rectlus_desel;
|
|
}
|
|
else {
|
|
if(base->flag & SELECT) rect= rectl_sel;
|
|
else rect= rectl_desel;
|
|
}
|
|
draw_icon_centered(ob->obmat[3], rect, 9);
|
|
}
|
|
else {
|
|
if(ob->id.lib || ob->id.us>1) {
|
|
if(base->flag & SELECT) rect= rectu_sel;
|
|
else rect= rectu_desel;
|
|
}
|
|
else {
|
|
if(base->flag & SELECT) rect= rect_sel;
|
|
else if(base==(G.scene->basact)) rect= rect_sel;
|
|
else rect= rect_desel;
|
|
}
|
|
draw_icon_centered(ob->obmat[3], rect, 4);
|
|
}
|
|
if(G.zbuf) glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
else if((G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
|
|
|
|
glBegin(GL_POINTS);
|
|
glVertex3fv(ob->obmat[3]);
|
|
glEnd();
|
|
|
|
}
|
|
}
|
|
|
|
void draw_object_ext(Base *base)
|
|
{
|
|
ScrArea *tempsa, *sa;
|
|
View3D *vd;
|
|
|
|
if(G.vd==0) return;
|
|
|
|
if(G.vd->drawtype > OB_WIRE) {
|
|
G.zbuf= 1;
|
|
glEnable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
G.f |= G_DRAW_EXT;
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
|
|
/* alle views aflopen */
|
|
tempsa= curarea;
|
|
sa= G.curscreen->areabase.first;
|
|
while(sa) {
|
|
if(sa->spacetype==SPACE_VIEW3D) {
|
|
/* er wordt beperkt in beide buffers getekend: selectbuffer! */
|
|
|
|
vd= sa->spacedata.first;
|
|
if(base->lay & vd->lay) {
|
|
areawinset(sa->win);
|
|
|
|
draw_object(base);
|
|
|
|
sa->win_swap= WIN_FRONT_OK;
|
|
}
|
|
}
|
|
sa= sa->next;
|
|
}
|
|
if(curarea!=tempsa) areawinset(tempsa->win);
|
|
|
|
G.f &= ~G_DRAW_EXT;
|
|
|
|
glFinish();
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
if(G.zbuf) {
|
|
G.zbuf= 0;
|
|
glDisable(GL_DEPTH_TEST);
|
|
}
|
|
}
|