/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 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 ***** */ /* drawobject.c GRAPHICS * * jan 95 * * Version: $Id: drawobject.c,v 1.19 2000/09/17 21:16:25 ton Exp $ */ #include "blender.h" #include "graphics.h" #include "edit.h" #include "effect.h" #include "game.h" uint rect_desel[16]= {0x707070,0x0,0x0,0x707070,0x407070,0x70cccc,0x407070,0x0,0xaaffff,0xffffff,0x70cccc,0x0,0x70cccc,0xaaffff,0x407070,0x707070}; uint rect_sel[16]= {0x707070,0x0,0x0,0x707070,0x702070,0xcc50cc,0x702070,0x0,0xff80ff,0xffffff,0xcc50cc,0x0,0xcc50cc,0xff80ff,0x702070,0x707070}; uint rectu_desel[16]= {0xff4e4e4e,0xff5c2309,0xff000000,0xff4e4f4d,0xff000000,0xffff9d72,0xffff601c,0xff000000,0xff5d2409,0xffffffff,0xffff9d72,0xff5b2209,0xff4e4e4e,0xff5c2309,0xff010100,0xff4f4f4f}; uint rectu_sel[16]= {0xff4e4e4e,0xff403c00,0xff000000,0xff4e4e4d,0xff000000,0xfffff64c,0xffaaa100,0xff000000,0xff403c00,0xffffffff,0xfffff64c,0xff403c00,0xff4f4f4f,0xff403c00,0xff010100,0xff4e4e4e}; uint 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}; uint 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}; uint 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}; uint 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}; uint 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}; uint 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}; uint 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 uint selcol= 0xFF88FF; uint actselcol= 0xFFBBFF; uint colortab[24]= {0x0, 0xFF88FF, 0xFFBBFF, 0x403000, 0xFFFF88, 0xFFFFBB, 0x104040, 0x66CCCC, 0x77CCCC, 0x101040, 0x5588FF, 0x88BBFF, 0xFFFFFF }; 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}, }; float cube1[8][3] = { {-1.2, -1.2, -1.0}, {-1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0}, {-1.2, 1.2, -1.0}, { 1.2, -1.2, -1.0}, { 1.0, -1.0, 1.0}, { 1.0, 1.0, 1.0}, { 1.2, 1.2, -1.0}, }; void init_draw_rects() { if(G.order==B_ENDIAN) { convert_rgba_to_abgr(16, rect_desel); convert_rgba_to_abgr(16, rect_sel); convert_rgba_to_abgr(16, rectu_desel); convert_rgba_to_abgr(16, rectu_sel); convert_rgba_to_abgr(81, rectl_desel); convert_rgba_to_abgr(81, rectl_sel); convert_rgba_to_abgr(81, rectlus_desel); convert_rgba_to_abgr(81, rectlus_sel); convert_rgba_to_abgr(81, rectllib_desel); convert_rgba_to_abgr(81, rectllib_sel); convert_rgba_to_abgr(81, rectl_set); } } void tekenrect9(float *vec, uint *rect) { const GLubyte dummy=0; if(vec) { glRasterPos3f(vec[0], vec[1], vec[2]); /* bitmap is used as a patch to move the rasterpos a few pixels */ glBitmap(1, 1, 0.0, 0.0, -4.5, -4.5, &dummy); glFinish(); /* for sun */ glDrawPixels(9, 9, GL_RGBA, GL_UNSIGNED_BYTE, rect); } } void tekenrect4(float *vec, uint *rect) { const GLubyte dummy=0; if(vec) { glRasterPos3f(vec[0], vec[1], vec[2]); /* bitmap is used as a patch to move the rasterpos a few pixels */ glBitmap(1, 1, 0.0, 0.0, -2.0, -2.0, &dummy); glFinish(); /* for sun */ glDrawPixels(4, 4, GL_RGBA, GL_UNSIGNED_BYTE, rect); } } void tekenrect3(float *vec, uint *rect) { const GLubyte dummy=0; if(vec) { glRasterPos3f(vec[0], vec[1], vec[2]); /* bitmap is used as a patch to move the rasterpos a few pixels */ glBitmap(1, 1, 0.0, 0.0, -1.5, -1.5, &dummy); glFinish(); /* for sun */ glDrawPixels(3, 3, 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) { float v1[3], v2[3]; float f800, f125; fmsetfont(G.font); f125= 0.125*size; f800= 0.8*size; v1[0]=v1[1]=v1[2]=v2[0]=v2[1]=v2[2]= 0.0; /* X-AS: pijl */ v2[0]= size; LINE3F(v1, v2); v1[0]= f800; v1[1]= -f125; LINE3F(v1, v2); v1[1]= f125; LINE3F(v1, v2); glRasterPos3f(size+f125, 0.0, 0.0); fmprstr("x"); /* Y-AS: pijl */ v1[0]=v1[1]=v1[2]=v2[0]=v2[1]=v2[2]= 0.0; v2[1]= size; LINE3F(v1, v2); v1[1]= f800; v1[0]= -f125; LINE3F(v1, v2); v1[0]= f125; LINE3F(v1, v2); glRasterPos3f(0.0, size+f125, 0.0); fmprstr("y"); /* Z-AS: pijl */ v1[0]=v1[1]=v1[2]=v2[0]=v2[1]=v2[2]= 0.0; v2[2]= size; LINE3F(v1, v2); v1[2]= f800; v1[0]= -f125; LINE3F(v1, v2); v1[0]= f125; LINE3F(v1, v2); glRasterPos3f(0.0, 0.0, size+f125); fmprstr("z"); } void drawgourcube() { float vec[3]; float n[3]; n[0]=0; n[1]=0; n[2]=0; glBegin(GL_POLYGON); n[0]= -1.0; glNormal3fv(n); glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]); n[0]=0; glEnd(); glBegin(GL_POLYGON); n[1]= -1.0; glNormal3fv(n); glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]); n[1]=0; glEnd(); glBegin(GL_POLYGON); n[0]= 1.0; glNormal3fv(n); glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]); n[0]=0; glEnd(); glBegin(GL_POLYGON); n[1]= 1.0; glNormal3fv(n); glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]); n[1]=0; glEnd(); glBegin(GL_POLYGON); n[2]= 1.0; glNormal3fv(n); glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]); n[2]=0; glEnd(); glBegin(GL_POLYGON); n[2]= -1.0; glNormal3fv(n); glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]); glEnd(); } void drawcube() { 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(); } 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(); } void tekenshadbuflimits(Lamp *la, float mat[][4]) { float sta[3], end[3], lavec[3]; short s[2]; 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); } void spotvolume(lvec,vvec,inp) float *lvec,*vvec,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,*rt; 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 = safacos(plane[2])/2.0; co = fcos(hoek); si = fsqrt(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 = fsqrt(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; } 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 = fcos( 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*fsqrt(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; getmatrix(tmat); Mat4Invert(imat, tmat); drawcircball(vec, la->dist, imat); } } loadmatrix(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); } } void draw_limit_line(float sta, float end, uint col) { float vec[2][3]; short mval[2]; vec[0][0]= 0.0; vec[0][1]= 0.0; vec[0][2]= -sta; vec[1][0]= 0.0; vec[1][1]= 0.0; vec[1][2]= -end; LINE3F(vec[0], vec[1]); glPointSize(3.0); glBegin(GL_POINTS); cpack(col); glVertex3fv(vec[0]); glVertex3fv(vec[1]); 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; short mval[2]; 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_POLYGON); 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_POLYGON); 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)) { loadmatrix(G.vd->viewmat); Mat4CpyMat4(vec, ob->obmat); Mat4Ortho(vec); multmatrix(vec); 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); Mat4SwapMat4(G.vd->persmat, tmat); } } void tekenvertslatt(short sel) { Lattice *lt; BPoint *bp; uint *rect; 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; wpntsw; w++) { if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0; for(v=0; vpntsv; v++) { if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0; for(u=0; upntsu; 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(); } void calc_lattverts() { BPoint *bp; float mat[4][4]; int a, tot, b; short *sp; 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++; } Mat4SwapMat4(G.vd->persmat, mat); } void calc_lattverts_ext() { areawinset(curarea->win); multmatrix(G.obedit->obmat); calc_lattverts(); loadmatrix(G.vd->viewmat); } 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; wpntsw; w++) { if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0; for(v=0; vpntsv; v++) { if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0; for(u=0, bpu=0; upntsu; 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; wpntsw; w++) { for(v=0; vpntsv; v++) { for(u=0, bpu=0; upntsu; 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() { EditVert *eve; float mat[4][4]; if(G.edve.first==0) return; eve= G.edve.first; 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; } Mat4SwapMat4(G.vd->persmat, mat); } void calc_meshverts_ext() { areawinset(curarea->win); multmatrix(G.obedit->obmat); calc_meshverts(); loadmatrix(G.vd->viewmat); } void calc_Nurbverts(Nurb *nurb) { Nurb *nu; BezTriple *bezt; BPoint *bp; float mat[4][4]; int a, tot, b; short *sp; 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; } Mat4SwapMat4(G.vd->persmat, mat); } void calc_nurbverts_ext() { areawinset(curarea->win); multmatrix(G.obedit->obmat); calc_Nurbverts(editNurb.first); loadmatrix(G.vd->viewmat); } void tekenvertices(short sel) { EditVert *eve; short xs,ys; glPointSize(2.0); if(sel) cpack(B_YELLOW); else cpack(B_PURPLE); glBegin(GL_POINTS); eve= (EditVert *)G.edve.first; while(eve) { if(eve->h==0 && (eve->f & 1)==sel ) { glVertex3fv(eve->co); } 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); multmatrix(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; loadmatrix(G.vd->viewmat); } } sa= sa->next; } if(curarea!=tempsa) areawinset(tempsa->win); glDrawBuffer(GL_BACK); if(G.zbuf) glEnable(GL_DEPTH_TEST); } /* ************** DRAW DISPLIST ****************** */ int draw_index_wire= 1; int index3_nors_incr= 1; void drawDispListwire(ListBase *dlbase) { DispList *dl; int parts, nr, ofs, p1, p2, p3, p4, a, b, *index; float *data, *v1, *v2, *v3, *v4, side; 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_STRIP); 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_STRIP); 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; } dl= dl->next; } } void drawDispListsolid(ListBase *lb, Object *ob) { DispList *dl; int parts, nr, ofs, p1, p2, p3, p4, a, b, *index; float *data, *v1, *v2, *v3, *v4, side; float *ndata, *n1, *n2, *n3, *n4; short col[3]; char *cp; if(lb==0) return; if( (G.f & G_BACKBUFSEL)==0 ) { glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); } dl= lb->first; while(dl) { data= dl->verts; ndata= dl->nors; switch(dl->type) { case DL_SURF: if(G.f & G_BACKBUFSEL) { for(a=0; aparts; 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(; bnr; 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; aparts*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; aparts; 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(; bnr; 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(G.f & G_BACKBUFSEL) { while(parts--) { glBegin(GL_POLYGON); 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_POLYGON); 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_POLYGON); 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(G.f & G_BACKBUFSEL) { while(parts--) { glBegin(GL_POLYGON); 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(GL_POLYGON); 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; } dl= dl->next; } if(G.f & G_BACKBUFSEL); else { glShadeModel(GL_FLAT); glDisable(GL_LIGHTING); } } void drawDispListshaded(ListBase *lb, Object *ob) { DispList *dl, *dlob; int parts, nr, ofs, p1, p2, p3, p4, a, b, *index; float *data, *v1, *v2, *v3, *v4, side, *extverts=0; uint *cdata, *c1, *c2, *c3, *c4; short col[3]; 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; aparts; 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(; bnr; b++) { glBegin(GL_POLYGON); 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_POLYGON); 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(GL_POLYGON); 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; } dl= dl->next; dlob= dlob->next; } glShadeModel(GL_FLAT); } 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; vertexpaint= (G.f & (G_VERTEXPAINT+G_FACESELECT)) && (ob==OBACT); 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==OBACT) 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; av3) { 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); } void drawmeshshaded(Object *ob, uint *col1, uint *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; glShadeModel(GL_SMOOTH); glDisable(GL_LIGHTING); me= ob->data; mface= me->mface; /* tekent ie geen hide */ if( (G.f & G_FACESELECT) && ob==OBACT) 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(GL_QUADS); cp1= (char *)col1; if(col2) cp2= (char *)col2; for(a=start; av3) { if(tface && (tface->flag & TF_HIDE)) 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); } 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 ); } else glVertex3fv( v3 ); 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 ); } else glVertex3fv( v1 ); } } } if(col2) cp2+= 16; } glEnd(); glShadeModel(GL_FLAT); if(twoside) glDisable(GL_CULL_FACE); } void drawDispList(Object *ob, int dt) { ListBase *lb=0; DispList *dl; Mesh *me; int a, 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(me->flag & ME_SMESH) { init_gl_materials(ob); two_sided(0); drawDispListsolid(lb, ob); } else drawmeshsolid(ob, dl->nors); } else if(dt==OB_SHADED) { if( G.f & G_VERTEXPAINT) { /* in deze volgorde: vertexpaint heeft soms al mcol gemaakt */ if(me->mcol) drawmeshshaded(ob, (uint *)me->mcol, 0); else if(me->tface) { tface_to_mcol(me); drawmeshshaded(ob, (uint *)me->mcol, 0); 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(me->flag & ME_SMESH) drawDispListshaded(&me->disp, ob); else drawmeshshaded(ob, dl->col1, dl->col2); } } } if(ob==OBACT && (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; } } /* ******************************** */ 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; } loadmatrix(G.vd->viewmat); if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf; else ptime= 0.0; ctime= bsystem_time(ob, 0, (float)CFRA, ptime); glPointSize(1.0); if(paf->stype!=PAF_VECT) glBegin(GL_POINTS); for(a=0; atotpart; 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(); } void draw_static_particle_system(Object *ob, PartEff *paf) { Particle *pa; float ptime, 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; atotpart; a++, pa+=paf->totkey) { where_is_particle(paf, pa, pa->time, vec1); mtime= pa->time+pa->lifetime+paf->staticstep-1; for(ctime= pa->time; ctimestaticstep) { /* 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(); } void drawmeshwire(Object *ob) { extern float editbutsize; /* buttons.c */ Mesh *me; MVert *mvert; MFace *mface; DispList *dl; Material *ma; EditVert *eve; 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 && me->flag & ME_SMESH) { 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); 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; } if(me->flag & ME_SMESH) { cpack(0xEE4422); eve= G.edve.first; while(eve) { if(eve->h==0) { VECCOPY(fvec, eve->co); glVertex3fv(fvec); fvec[0]+= editbutsize*eve->no[0]; fvec[1]+= editbutsize*eve->no[1]; fvec[2]+= editbutsize*eve->no[2]; glVertex3fv(fvec); } eve= eve->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(me->flag & ME_SMESH) 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; aco); } } glEnd(); glPointSize(1.0); } else { start= 0; end= me->totface; set_buildvars(ob, &start, &end); mface+= start; for(a=start; aedcode; 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(); } } } } } } } uint nurbcol[8]= { 0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 }; void tekenhandlesN(nu, sel) Nurb *nu; short sel; { BezTriple *bezt; float *fp; uint *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++; } } } void tekenvertsN(nu, sel) Nurb *nu; short sel; { BezTriple *bezt; BPoint *bp; uint *rect; 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); } 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; bpntsv; b++) { if(nu->flagu & 1) glBegin(GL_LINE_LOOP); else glBegin(GL_LINE_STRIP); for(a=0; apntsu; a++, bp++) { glVertex3fv(bp->vec); } if(nu->flagu & 1) glEnd(); else glEnd(); } break; case CU_NURBS: bp= nu->bp; for(b=0; bpntsv; 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; bpntsu; 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; } } void drawnurb(Object *ob, Nurb *nurb, int dt) { extern float editbutsize; /* buttons.c */ Curve *cu; Nurb *nu; BezTriple *bezt; BPoint *bp, *bp1; BevPoint *bevp; BevList *bl; float vec[3], seg[12], *fp, *data; int a, b, ofs, 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); } void tekentextcurs() { cpack(0); glBegin(GL_POLYGON); 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; adata; 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; } getmatrix(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; } } 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; } } void draw_bb_quadric(BoundBox *bb, short type) { float *vec, size[3], cent[3]; GLUquadricObj *qobj = gluNewQuadric(); gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); vec= bb->vec[0]; 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); } void draw_bounding_volume(Object *ob) { Mesh *me; BoundBox *bb=0; float *vec; 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); } 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); } void draw_object(Base *base) { PartEff *paf; Object *ob; Curve *cu; Mesh *me; ListBase elems; CfraElem *ce; float cfraont, axsize=1.0; uint *rect, col=0; static int warning_recursive= 0; int sel, drawtype, colindex= 0, ipoflag; short dt, dtx, zbufoff= 0; char str[4]; ob= base->object; /* keys tekenen? */ if(base==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= 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) { CFRA= ce->cfra/G.scene->r.framelen; base->flag= 0; where_is_object_time(ob, CFRA); draw_object(base); } ce= ce->next; } } ce= elems.first; while(ce) { if(ce->sel) { CFRA= ce->cfra/G.scene->r.framelen; base->flag= SELECT; where_is_object_time(ob, 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 */ CFRA= cfraont; memcpy(&ob->loc, temp, 7*3*sizeof(float)); where_is_object(ob); G.vd->drawtype= drawtype; freelistN(&elems); warning_recursive= 0; } } } /* patch? kinderen met timeoffs verprutsen ouders. Hoe los je dat op! */ /* if( ((int)ob->ctime) != F_CFRA) where_is_object(ob); */ multmatrix(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(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==OBACT && (G.f & (G_FACESELECT+G_VERTEXPAINT))) { 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_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(base->flag & OB_RADIO); else if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { if(dt<=OB_WIRE) drawmeshwire(ob); else { if(me->flag & ME_SMESH) { init_gl_materials(ob); two_sided(0); 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(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( ((Mesh *)ob->data)->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) { if( paf=give_parteff(ob) ) { 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 loadmatrix */ 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; 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); str[0]= ' '; str[1]= 0; fmsetfont(G.font); fmprstr(str); fmprstr(ob->id.name+2); } if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp); } if(dtgameflag & OB_DYNAMIC) { float tmat[4][4], imat[4][4], vec[3]; vec[0]= vec[1]= vec[2]= 0.0; getmatrix(tmat); Mat4Invert(imat, tmat); setlinestyle(2); drawcircball(vec, ob->inertia, imat); setlinestyle(0); } } loadmatrix(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); LINE3F(ob->obmat[3], ob->orig); 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; } tekenrect9(ob->obmat[3], rect); } 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==BASACT) rect= rect_sel; else rect= rect_desel; } tekenrect4(ob->obmat[3], rect); } if(G.zbuf) glEnable(GL_DEPTH_TEST); } else if((G.f & (G_VERTEXPAINT|G_FACESELECT))==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); #if defined(__BeOS) || defined(WIN32) || defined(PPC) || defined(MESA30) glDrawBuffer(GL_FRONT); draw_object(base); sa->win_swap= WIN_FRONT_OK; #else if(sa->win_swap==WIN_EQUAL) glDrawBuffer(GL_FRONT_AND_BACK); else { glDrawBuffer(GL_FRONT); sa->win_swap= WIN_FRONT_OK; } draw_object(base); #endif } } sa= sa->next; } if(curarea!=tempsa) areawinset(tempsa->win); G.f &= ~G_DRAW_EXT; glDrawBuffer(GL_BACK); if(G.zbuf) { G.zbuf= 0; glDisable(GL_DEPTH_TEST); } }