diff options
Diffstat (limited to 'source/blender/src/drawobject.c')
-rw-r--r-- | source/blender/src/drawobject.c | 3579 |
1 files changed, 3579 insertions, 0 deletions
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c new file mode 100644 index 00000000000..83657303628 --- /dev/null +++ b/source/blender/src/drawobject.c @@ -0,0 +1,3579 @@ +/** + * $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 _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); + } +} |