GraphicsUtils.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2005 Dave Griffiths
00002 //
00003 // This program is free software; you can redistribute it and/or modify
00004 // it under the terms of the GNU General Public License as published by
00005 // the Free Software Foundation; either version 2 of the License, or
00006 // (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00016 
00017 #include "PolyPrimitive.h"
00018 #include "GraphicsUtils.h"
00019 
00020 using namespace Fluxus;
00021 
00023 
00024 void Fluxus::MakeCube(PolyPrimitive *p, float size)
00025 {
00026     dVector boxv0; dVector boxv1;
00027     dVector boxv2; dVector boxv3;
00028     dVector boxv4; dVector boxv5;
00029     dVector boxv6; dVector boxv7;
00030     dVector Normal; 
00031 
00032     size/=2.0f;
00033 
00034     boxv0.x = -size; boxv0.y = -size; boxv0.z = -size;
00035     boxv1.x =  size; boxv1.y = -size; boxv1.z = -size;
00036     boxv2.x =  size; boxv2.y =  size; boxv2.z = -size;
00037     boxv3.x = -size; boxv3.y =  size; boxv3.z = -size;
00038     boxv4.x = -size; boxv4.y = -size; boxv4.z =  size;
00039     boxv5.x =  size; boxv5.y = -size; boxv5.z =  size;
00040     boxv6.x =  size; boxv6.y =  size; boxv6.z =  size;
00041     boxv7.x = -size; boxv7.y =  size; boxv7.z =  size;
00042         
00043     Normal=dVector(0,0,-1);
00044     p->AddVertex(dVertex(boxv3,Normal,0,0));
00045     p->AddVertex(dVertex(boxv2,Normal,1,0));
00046     p->AddVertex(dVertex(boxv1,Normal,1,1));
00047     p->AddVertex(dVertex(boxv0,Normal,0,1));
00048 
00049     Normal=dVector(0,-1,0);
00050     p->AddVertex(dVertex(boxv1,Normal,0,0));
00051     p->AddVertex(dVertex(boxv5,Normal,1,0));
00052     p->AddVertex(dVertex(boxv4,Normal,1,1));
00053     p->AddVertex(dVertex(boxv0,Normal,0,1));
00054 
00055     Normal=dVector(0,1,0);
00056     p->AddVertex(dVertex(boxv3,Normal,0,0));
00057     p->AddVertex(dVertex(boxv7,Normal,1,0));
00058     p->AddVertex(dVertex(boxv6,Normal,1,1));
00059     p->AddVertex(dVertex(boxv2,Normal,0,1));
00060 
00061     Normal=dVector(0,0,1);
00062     p->AddVertex(dVertex(boxv4,Normal,0,0));
00063     p->AddVertex(dVertex(boxv5,Normal,1,0));
00064     p->AddVertex(dVertex(boxv6,Normal,1,1));
00065     p->AddVertex(dVertex(boxv7,Normal,0,1));
00066 
00067     Normal=dVector(-1,0,0);
00068     p->AddVertex(dVertex(boxv4,Normal,0,0));
00069     p->AddVertex(dVertex(boxv7,Normal,1,0));
00070     p->AddVertex(dVertex(boxv3,Normal,1,1));
00071     p->AddVertex(dVertex(boxv0,Normal,0,1));
00072 
00073     Normal=dVector(1,0,0);
00074     p->AddVertex(dVertex(boxv2,Normal,0,0));
00075     p->AddVertex(dVertex(boxv6,Normal,1,0));
00076     p->AddVertex(dVertex(boxv5,Normal,1,1));
00077     p->AddVertex(dVertex(boxv1,Normal,0,1));
00078 }
00079 
00080 void Fluxus::MakePlane(PolyPrimitive *p)
00081 {
00082     p->AddVertex(dVertex(dVector(-0.5,-0.5,0),dVector(0,0,1),0,0));
00083     p->AddVertex(dVertex(dVector(0.5,-0.5,0),dVector(0,0,1),1,0));
00084     p->AddVertex(dVertex(dVector(0.5,0.5,0),dVector(0,0,1),1,1));
00085     p->AddVertex(dVertex(dVector(-0.5,0.5,0),dVector(0,0,1),0,1));
00086 
00087     p->AddVertex(dVertex(dVector(-0.5,0.5,0),dVector(0,0,-1),0,1));
00088     p->AddVertex(dVertex(dVector(0.5,0.5,0),dVector(0,0,-1),1,1));
00089     p->AddVertex(dVertex(dVector(0.5,-0.5,0),dVector(0,0,-1),1,0));
00090     p->AddVertex(dVertex(dVector(-0.5,-0.5,0),dVector(0,0,-1),0,0));
00091 }
00092 
00093 void Fluxus::MakePlane(PolyPrimitive *p, int xsegs, int ysegs)
00094 {
00095     float usegsize=1/(float)xsegs;
00096     float vsegsize=1/(float)ysegs;
00097     
00098     for (int x=0; x<xsegs; x++)
00099     {
00100         for (int y=0; y<ysegs; y++)
00101         {
00102             float u=x/(float)xsegs;
00103             float v=y/(float)ysegs; 
00104             p->AddVertex(dVertex(dVector(u,v,0),dVector(0,0,1),u,v));
00105             p->AddVertex(dVertex(dVector(u+usegsize,v,0),dVector(0,0,1),u+usegsize,v));
00106             p->AddVertex(dVertex(dVector(u+usegsize,v+vsegsize,0),dVector(0,0,1),u+usegsize,v+vsegsize));
00107             p->AddVertex(dVertex(dVector(u,v+vsegsize,0),dVector(0,0,1),u,v+vsegsize));
00108         }
00109     }
00110 }
00111 
00112 void Fluxus::MakeCylinder(PolyPrimitive *p, float height, float radius, int hsegments, int rsegments)
00113 {
00114     float heightpersegment = height/hsegments;
00115     float radpersegment = (360/rsegments)*DEG_CONV;
00116     for (int j=0; j<hsegments; j++)
00117     {
00118         for (int i=0; i<rsegments; i++)
00119         {
00120             dVector point(sin(i*radpersegment)*radius,0,cos(i*radpersegment)*radius);
00121             dVector point2(sin((i+1)*radpersegment)*radius,0,cos((i+1)*radpersegment)*radius);
00122         
00123             dVector ntemp(sin(i*radpersegment)*(radius+1.0),0,cos(i*radpersegment)*(radius+1.0));
00124             dVector ntemp2(sin((i+1)*radpersegment)*(radius+1.0),0,cos((i+1)*radpersegment)*(radius+1.0));
00125             dVector n(ntemp-point);
00126             dVector n2(ntemp2-point2);
00127             n.normalise();
00128             n2.normalise();
00129             
00130             p->AddVertex(dVertex(dVector(point2.x,j*heightpersegment,point2.z),n2,i/(float)rsegments,j*heightpersegment));          
00131             p->AddVertex(dVertex(dVector(point.x,(j+1)*heightpersegment,point.z),n,i/(float)rsegments,(j+1)*heightpersegment));
00132             p->AddVertex(dVertex(dVector(point.x,j*heightpersegment,point.z),n,i/(float)rsegments,j*heightpersegment));
00133             
00134             p->AddVertex(dVertex(dVector(point2.x,j*heightpersegment,point2.z),n2,i/(float)rsegments,j*heightpersegment));
00135             p->AddVertex(dVertex(dVector(point2.x,(j+1)*heightpersegment,point2.z),n2,i/(float)rsegments,(j+1)*heightpersegment));
00136             p->AddVertex(dVertex(dVector(point.x,(j+1)*heightpersegment,point.z),n,i/(float)rsegments,(j+1)*heightpersegment));
00137         }
00138     }
00139     
00140     // cap the cylinder at both ends
00141     dVector centre(0,0,0);
00142     dVector normal(0,-1,0);
00143     
00144     for (int i=0; i<rsegments; i++)
00145     {
00146         dVector point(sin(i*radpersegment)*radius,0,cos(i*radpersegment)*radius);
00147         dVector point2(sin((i+1)*radpersegment)*radius,0,cos((i+1)*radpersegment)*radius);      
00148         p->AddVertex(dVertex(dVector(point2.x,centre.y,point2.z),normal,0,i/(float)rsegments));
00149         p->AddVertex(dVertex(dVector(point.x,centre.y,point.z),normal,0,i/(float)rsegments));
00150         p->AddVertex(dVertex(centre,normal,0,0));           
00151     }
00152         
00153     centre=dVector(0,height,0);
00154     normal=dVector(0,1,0);
00155     for (int i=0; i<rsegments; i++)
00156     {
00157         dVector point(sin(i*radpersegment)*radius,0,cos(i*radpersegment)*radius);
00158         dVector point2(sin((i+1)*radpersegment)*radius,0,cos((i+1)*radpersegment)*radius);
00159         p->AddVertex(dVertex(centre,normal,1,1));           
00160         p->AddVertex(dVertex(dVector(point.x,centre.y,point.z),normal,1,i/(float)rsegments));
00161         p->AddVertex(dVertex(dVector(point2.x,centre.y,point2.z),normal,1,i/(float)rsegments));
00162     }   
00163 }
00164 
00165 void Fluxus::MakeSphere(PolyPrimitive *p, float radius, int hsegments, int rsegments)
00166 {
00167     float radpersegment = (360/(float)rsegments)*DEG_CONV;
00168     for (int j=0; j<hsegments; j++)
00169     {
00170         float scale[2],height[2],nheight[2];
00171         scale[0] = sin((j/(float)hsegments)*180*DEG_CONV);
00172         scale[1] = sin(((j+1)/(float)hsegments)*180*DEG_CONV);
00173         height[0] = cos((j/(float)hsegments)*180*DEG_CONV)*radius;
00174         height[1] = cos(((j+1)/(float)hsegments)*180*DEG_CONV)*radius;  
00175         nheight[0] = cos((j/(float)hsegments)*180*DEG_CONV)*(radius+1.0f);
00176         nheight[1] = cos(((j+1)/(float)hsegments)*180*DEG_CONV)*(radius+1.0f);
00177         
00178         for (int i=0; i<rsegments; i++)
00179         {
00180             dVector point[2],npoint[2];
00181             point[0]=dVector(sin(i*radpersegment)*radius,0,cos(i*radpersegment)*radius);
00182             point[1]=dVector(sin((i+1)*radpersegment)*radius,0,cos((i+1)*radpersegment)*radius);
00183             npoint[0]=dVector(sin(i*radpersegment)*(radius+1.0f),0,cos(i*radpersegment)*(radius+1.0f));
00184             npoint[1]=dVector(sin((i+1)*radpersegment)*(radius+1.0f),0,cos((i+1)*radpersegment)*(radius+1.0f));
00185             
00186             dVector tex[4];
00187             tex[0]=dVector((i+1)/(float)rsegments,j/(float)hsegments,0);
00188             tex[1]=dVector(i/(float)rsegments,(j+1)/(float)hsegments,0);
00189             tex[2]=dVector(i/(float)rsegments,j/(float)hsegments,0);
00190             tex[3]=dVector((i+1)/(float)rsegments,(j+1)/(float)hsegments,0);
00191             
00192             dVector verts[4];
00193             verts[0]=dVector(point[1].x*scale[0],height[0],point[1].z*scale[0]);
00194             verts[1]=dVector(point[0].x*scale[1],height[1],point[0].z*scale[1]);
00195             verts[2]=dVector(point[0].x*scale[0],height[0],point[0].z*scale[0]);
00196             verts[3]=dVector(point[1].x*scale[1],height[1],point[1].z*scale[1]);
00197             
00198             dVector normals[4];
00199             normals[0]=(dVector(npoint[1].x*scale[0],nheight[0],npoint[1].z*scale[0])-verts[0]).normalise();
00200             normals[1]=(dVector(npoint[0].x*scale[1],nheight[1],npoint[0].z*scale[1])-verts[1]).normalise();
00201             normals[2]=(dVector(npoint[0].x*scale[0],nheight[0],npoint[0].z*scale[0])-verts[2]).normalise();
00202             normals[3]=(dVector(npoint[1].x*scale[1],nheight[1],npoint[1].z*scale[1])-verts[3]).normalise();
00203             
00204             p->AddVertex(dVertex(verts[2],normals[2],tex[2].x,tex[2].y));           
00205             p->AddVertex(dVertex(verts[1],normals[1],tex[1].x,tex[1].y));
00206             p->AddVertex(dVertex(verts[0],normals[0],tex[0].x,tex[0].y));
00207             
00208             p->AddVertex(dVertex(verts[0],normals[0],tex[0].x,tex[0].y));
00209             p->AddVertex(dVertex(verts[1],normals[1],tex[1].x,tex[1].y));
00210             p->AddVertex(dVertex(verts[3],normals[3],tex[3].x,tex[3].y));
00211         }
00212     }
00213 }
00214 
00215 void Fluxus::MakeTorus(PolyPrimitive *p, float innerradius, float outerradius, int hsegments, int rsegments)
00216 {
00217     float radperouter = (360/(float)rsegments)*DEG_CONV;
00218     float radperinner = (360/(float)hsegments)*DEG_CONV;
00219     
00220     for(int j=0; j<rsegments; j++)
00221     {
00222         float cpsi = cos(j*radperouter);
00223         float spsi = sin(j*radperouter);
00224         float cpsi2 = cos((j+1)*radperouter);
00225         float spsi2 = sin((j+1)*radperouter);
00226  
00227         for(int i=0; i<hsegments; i++)
00228         {
00229             float cphi = cos(i*radperinner);
00230             float sphi = sin(i*radperinner);
00231             float cphi2 = cos((i+1)*radperinner);
00232             float sphi2 = sin((i+1)*radperinner);
00233             
00234             dVector verts[4];
00235             verts[0].x = cpsi * (outerradius + cphi * innerradius);
00236             verts[0].y = spsi * (outerradius + cphi * innerradius);
00237             verts[0].z = sphi * innerradius;
00238             verts[1].x = cpsi * (outerradius + cphi2 * innerradius);
00239             verts[1].y = spsi * (outerradius + cphi2 * innerradius);
00240             verts[1].z = sphi2 * innerradius;
00241             verts[2].x = cpsi2 * (outerradius + cphi2 * innerradius);
00242             verts[2].y = spsi2 * (outerradius + cphi2 * innerradius);
00243             verts[2].z = sphi2 * innerradius;
00244             verts[3].x = cpsi2 * (outerradius + cphi * innerradius);
00245             verts[3].y = spsi2 * (outerradius + cphi * innerradius);
00246             verts[3].z = sphi * innerradius;
00247             
00248             dVector normals[4];
00249             normals[0].x = cpsi*cphi;
00250             normals[0].y = spsi*cphi;
00251             normals[0].z = sphi;
00252             normals[1].x = cpsi*cphi2;
00253             normals[1].y = spsi*cphi2;
00254             normals[1].z = sphi2;
00255             normals[2].x = cpsi2*cphi2;
00256             normals[2].y = spsi2*cphi2;
00257             normals[2].z = sphi2;
00258             normals[3].x = cpsi2*cphi;
00259             normals[3].y = spsi2*cphi;
00260             normals[3].z = sphi;
00261 
00262             dVector tex[4];
00263             tex[0]=dVector(i/(float)rsegments,j/(float)hsegments,0);
00264             tex[1]=dVector((i+1)/(float)rsegments,j/(float)hsegments,0);
00265             tex[2]=dVector((i+1)/(float)rsegments,(j+1)/(float)hsegments,0);
00266             tex[3]=dVector(i/(float)rsegments,(j+1)/(float)hsegments,0);
00267 
00268             p->AddVertex(dVertex(verts[3],normals[3],tex[3].x,tex[3].y));
00269             p->AddVertex(dVertex(verts[2],normals[2],tex[2].x,tex[2].y));
00270             p->AddVertex(dVertex(verts[1],normals[1],tex[1].x,tex[1].y));
00271             p->AddVertex(dVertex(verts[0],normals[0],tex[0].x,tex[0].y));           
00272         }
00273     }
00274 }
00275 
00276 void Fluxus::MakeNURBSSphere(NURBSPrimitive *p, float radius, int hsegments, int rsegments)
00277 {
00278     p->Init(3,3,hsegments,rsegments);
00279             
00280     for (int n=-3; n<=hsegments+2; n++) p->AddUKnot(n/(float)hsegments);
00281     for (int n=-1; n<=rsegments; n++) p->AddVKnot(n/(float)rsegments);
00282     
00283     float radpersegment = (360/(float)(rsegments-3))*DEG_CONV;
00284     for (int j=-1; j<=hsegments+1; j++)
00285     {
00286         float scale = sin((j/(float)hsegments)*180*DEG_CONV);
00287         float height = cos((j/(float)hsegments)*180*DEG_CONV)*radius;
00288                 
00289         for (int i=0; i<rsegments; i++)
00290         {           
00291             p->AddCV(dVector(sin(i*radpersegment)*radius*scale,height,cos(i*radpersegment)*radius*scale));
00292             p->AddN(dVector(sin(i*radpersegment)*scale,height,cos(i*radpersegment)*scale));
00293             p->AddTex(dVector(i/(float)rsegments,j/(float)hsegments,0));
00294         }
00295     }
00296 }
00297 
00298 void Fluxus::MakeNURBSPlane(NURBSPrimitive *p, int usegments, int vsegments)
00299 {
00300     p->Init(3,3,usegments,vsegments);
00301     
00302     for (int n=-1; n<=usegments+1; n++) p->AddUKnot(n/(float)usegments);
00303     for (int n=-1; n<=vsegments+1; n++) p->AddVKnot(n/(float)vsegments);
00304     
00305     for (int j=0; j<vsegments; j++)
00306     {
00307         for (int i=0; i<usegments; i++)
00308         {           
00309             p->AddCV(dVector(i/(float)usegments,0,j/(float)vsegments));
00310             p->AddN(dVector(0,1,0));
00311             p->AddTex(dVector(i/(float)usegments,j/(float)vsegments,0));
00312         }
00313     }
00314 }

Generated on Mon Feb 11 06:54:25 2008 for The Fluxus Renderer (libfluxus) by  doxygen 1.5.1