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 }