00001 /* 00002 File: PolyLib.cc 00003 00004 Function: See header file 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2000, Andrew Willmott 00009 00010 Notes: 00011 00012 */ 00013 00014 #include "gcl/PolyLib.h" 00015 #include "gcl/SceneLang.h" 00016 00017 Int PolyLib::numTesselations = 32; 00018 00019 Void AddPolyObjects() 00020 { 00021 slAddToLibrary(slBeginObject("tetrahedron")); 00022 CreateSolidTetrahedron(); 00023 slEndObject(); 00024 00025 slAddToLibrary(slBeginObject("cylinder")); 00026 CreateSolidCylinder(); 00027 slEndObject(); 00028 00029 slAddToLibrary(slBeginObject("sphere")); 00030 CreateSolidSphere(); 00031 slEndObject(); 00032 00033 slAddToLibrary(slBeginObject("cone")); 00034 CreateSolidCone(); 00035 slEndObject(); 00036 00037 slAddToLibrary(slBeginObject("cube")); 00038 CreateSolidCube(); 00039 slEndObject(); 00040 00041 slAddToLibrary(slBeginObject("square")); 00042 CreateSquare(); 00043 slEndObject(); 00044 } 00045 00046 Void CreateSquare() 00047 { 00048 slPointList(); 00049 slPoint(Point(-1, 0, -1)); 00050 slPoint(Point(-1, 0, 1)); 00051 slPoint(Point( 1, 0, 1)); 00052 slPoint(Point( 1, 0, -1)); 00053 slPointIndexes(Indexes(0, 1, 2, 3, IDX_END)); 00054 slPoly(); 00055 } 00056 00057 Void CreateSolidCube() 00058 { 00059 slPointList(); 00060 slPoint(Point(-1, -1, -1)); 00061 slPoint(Point( 1, -1, -1)); 00062 slPoint(Point( 1, -1, 1)); 00063 slPoint(Point(-1, -1, 1)); 00064 slPoint(Point(-1, 1, -1)); 00065 slPoint(Point( 1, 1, -1)); 00066 slPoint(Point( 1, 1, 1)); 00067 slPoint(Point(-1, 1, 1)); 00068 00069 slApply(Scalef(0.5)); 00070 slPointIndexes(Indexes(0, 1, 2, 3, IDX_END)); 00071 slPoly(); 00072 00073 slPointIndexes(Indexes(7, 6, 5, 4, IDX_END)); 00074 slPoly(); 00075 00076 slPointIndexes(Indexes(1, 5, 6, 2, IDX_END)); 00077 slPoly(); 00078 00079 slPointIndexes(Indexes(6, 7, 3, 2, IDX_END)); 00080 slPoly(); 00081 00082 slPointIndexes(Indexes(4, 0, 3, 7, IDX_END)); 00083 slPoly(); 00084 00085 slPointIndexes(Indexes(1, 0, 4, 5, IDX_END)); 00086 slPoly(); 00087 } 00088 00089 // --- Tetrahedron creation --------------------------------------------------- 00090 00091 Void TetrahedronPoints() 00092 // Creates a tetrahedron lying on the x-z plane, and centred on the y-axis. 00093 { 00094 GCLReal RecipRoot3; 00095 GCLReal hmax; 00096 00097 RecipRoot3 = 1 / sqrt(3); 00098 hmax = sqrt(2.0 / 3.0); // Height of tetrahedron 00099 00100 slPointList(); 00101 slPoint(Point(0, 0, RecipRoot3)); 00102 slPoint(Point(0.5, 0, -RecipRoot3 / 2)); 00103 slPoint(Point(-0.5, 0, -RecipRoot3 / 2)); 00104 slPoint(Point(0, hmax, 0)); 00105 } 00106 00107 Void CreateSolidTetrahedron() 00108 // Creates a tetrahedron lying on the x-z plane, and centred on the y-axis. 00109 { 00110 TetrahedronPoints(); 00111 00112 slPointIndexes(Indexes(0, 2, 1, IDX_END)); // base 00113 slPoly(); 00114 slPointIndexes(Indexes(0, 1, 3, IDX_END)); // right side 00115 slPoly(); 00116 slPointIndexes(Indexes(3, 1, 2, IDX_END)); // back 00117 slPoly(); 00118 slPointIndexes(Indexes(0, 3, 2, IDX_END)); // left side 00119 slPoly(); 00120 } 00121 00122 00123 // --- Cylinder --------------------------------------------------------------- 00124 00125 00126 Void CylinderPoints() 00127 { 00128 Int i; 00129 GCLReal theta, dTheta, cosTheta, sinTheta; 00130 00131 theta = 0; 00132 dTheta = 2 * vl_pi / PolyLib::numTesselations; 00133 slPointList(); 00134 for (i = 0; i < PolyLib::numTesselations; i++) 00135 { 00136 cosTheta = cos(theta) / 2.0; 00137 sinTheta = sin(theta) / 2.0; 00138 slPoint(Point(cosTheta, 0.5, sinTheta)); 00139 slPoint(Point(cosTheta, -0.5, sinTheta)); 00140 theta = theta + dTheta; 00141 } 00142 } 00143 00144 Void SolidCylinderEnds() 00145 { 00146 Int i; 00147 IndexList topFace, bottomFace; 00148 00149 for (i = 0; i < PolyLib::numTesselations; i++) 00150 { 00151 topFace.Append(2 * (PolyLib::numTesselations - 1 - i)); 00152 bottomFace.Append(2 * i + 1); 00153 } 00154 00155 slPointIndexes(topFace); 00156 slPoly(); 00157 slPointIndexes(bottomFace); 00158 slPoly(); 00159 } 00160 00161 Void SolidCylinderSides() 00162 { 00163 Int topLHS; 00164 IndexList tesselation(4); 00165 Int i; 00166 00167 for (i = 0; i < PolyLib::numTesselations; i++) 00168 { 00169 // Vertex num of top LHS of face 00170 topLHS = 2 * i; 00171 // Do LHS 00172 tesselation[0] = (topLHS + 1); 00173 tesselation[1] = topLHS; 00174 // Last face has to close back to first 2 vertices 00175 if (i == PolyLib::numTesselations - 1) 00176 topLHS = -2; 00177 tesselation[2] = (topLHS + 2); 00178 tesselation[3] = (topLHS + 3); 00179 slPointIndexes(tesselation); 00180 slPoly(); 00181 } 00182 } 00183 00184 Void CreateSolidCylinder() 00185 { 00186 CylinderPoints(); 00187 SolidCylinderEnds(); 00188 SolidCylinderSides(); 00189 } 00190 00191 00192 // --- Cone ------------------------------------------------------------------- 00193 00194 00195 Void ConePoints() 00196 { 00197 Int i; 00198 GCLReal theta, dTheta, cosTheta, sinTheta; 00199 00200 theta = 0; 00201 dTheta = 2 * vl_pi / PolyLib::numTesselations; 00202 slPointList(); 00203 slPoint(Point(0, 1, 0)); 00204 00205 for (i = 0; i < PolyLib::numTesselations; i++) 00206 { 00207 cosTheta = cos(theta) / 2; 00208 sinTheta = sin(theta) / 2; 00209 slPoint(Point(cosTheta, 0, sinTheta)); 00210 theta = theta + dTheta; 00211 } 00212 } 00213 00214 Void SolidConeEnd() 00215 { 00216 Int i; 00217 00218 slPointIndexList(); 00219 for (i = 1; i <= PolyLib::numTesselations; i++) 00220 slPointIndex(i); 00221 00222 slPoly(); 00223 } 00224 00225 Void SolidConeSides() 00226 { 00227 IndexList tesselation(3); 00228 Int i; 00229 00230 tesselation[0] = 0; 00231 00232 for (i = 1; i <= PolyLib::numTesselations; i++) 00233 { 00234 if (i == PolyLib::numTesselations) 00235 // Last face has to close back to first 2 vertices 00236 tesselation[1] = 1; 00237 else 00238 tesselation[1] = i + 1; 00239 tesselation[2] = i; 00240 00241 slPointIndexes(tesselation); 00242 slPoly(); 00243 } 00244 } 00245 00246 Void CreateSolidCone() 00247 { 00248 ConePoints(); 00249 SolidConeEnd(); 00250 SolidConeSides(); 00251 } 00252 00253 00254 // --- Sphere ----------------------------------------------------------------- 00255 00256 Void SpherePoints() 00257 { 00258 Int i, j; 00259 GCLReal theta, dtheta, phi, dphi, z; 00260 00261 slPointList(); 00262 slPoint(Point(0.0, 0.0, 0.5)); 00263 00264 phi = 2.0 * vl_pi / PolyLib::numTesselations; 00265 dphi = phi; 00266 dtheta = dphi; 00267 00268 for (j = 0; j < (PolyLib::numTesselations / 2) - 1; j++) 00269 { 00270 z = cos(phi) / 2.0; 00271 theta = 0.0; 00272 for (i = 0; i < PolyLib::numTesselations; i++) 00273 { 00274 slPoint(Point(sin(phi) * cos(theta) / 2.0, 00275 sin(phi) * sin(theta) / 2.0, 00276 z)); 00277 theta += dtheta; 00278 } 00279 phi += dphi; 00280 } 00281 00282 slPoint(Point(0.0, 0.0, -0.5)); 00283 } 00284 00285 Void AddSphereFaces() 00286 { 00287 Int i, j, p, offset; 00288 IndexList triangle1(3), triangle2(3), square(4); 00289 00290 p = PolyLib::numTesselations; 00291 00292 for (i = 1; i <= PolyLib::numTesselations; i++) 00293 // Step around the sphere... 00294 { 00295 // Make a face on the top of the sphere 00296 triangle1[0] = 0; 00297 triangle1[1] = p; 00298 triangle1[2] = i; 00299 slPointIndexes(triangle1); 00300 slPoly(); 00301 00302 // Make the faces between rings of vertices... 00303 offset = 0; 00304 for (j = 0; j < (PolyLib::numTesselations / 2) - 2; j++) 00305 { 00306 // Make one such face 00307 square[0] = i + offset; 00308 square[1] = p + offset; 00309 offset += PolyLib::numTesselations; 00310 square[2] = p + offset; 00311 square[3] = i + offset; 00312 slPointIndexes(square); 00313 slPoly(); 00314 } 00315 00316 // Make a face on the bottom of the sphere 00317 triangle2[0] = offset + PolyLib::numTesselations + 1; // last vertex 00318 triangle2[1] = offset + i; 00319 triangle2[2] = offset + p; 00320 slPointIndexes(triangle2); 00321 slPoly(); 00322 00323 p = i; 00324 } 00325 } 00326 00327 Void CreateSolidSphere() 00328 { 00329 SpherePoints(); 00330 AddSphereFaces(); 00331 }