00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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 }