Main Page Class Hierarchy Compound List File List Compound Members File Members

SceneObjects.cc

Go to the documentation of this file.
00001 /*
00002 File: SceneObjects.cc
00003 
00004 Function: See header file
00005 
00006 Author: Andrew Willmott
00007 
00008 Notes: 
00009 */
00010 
00011 #include "gcl/SceneObjects.h"
00012 #include "gcl/VecUtil.h"
00013 #include "gcl/GCLConfig.h"
00014 
00015 // --- Polygon methods --------------------------------------------------------
00016 
00017  StrConst scPoly::Label() const
00018 {
00019 return("mesh");
00020 }
00021 
00022  IndexList *gIdentityList = 0;
00023 
00024 
00025 /*
00026 Current defaults:
00027 
00028 point indexes = [0, 1, 2, 3...]
00029 normal, texture indexes: point indexes
00030 colour indexes: normal indexes
00031 */
00032 
00033  Void scPoly::Draw(Renderer &r, SLContext *context)
00034 // draw one or more polygons
00035 {
00036 Int i, j;
00037 Int f, faces, faceS, faceE;
00038 Vector normal;
00039 Colour polyClr;
00040 PointList *points;
00041 NormalList *normals;
00042 ColourList *colours;
00043 CoordList *coords;
00044 Texture *texture;
00045 IndexList *indexes;
00046 IndexList *clrIndexes;
00047 IndexList *normIndexes;
00048 IndexList *coordIndexes;
00049 IndexList *faceIndexes;
00050 scMeshType *meshType;
00051 RenderStyle meshStyle;
00052 
00053 points = SC_GET(Points);
00054 colours = SC_GET(Colours);
00055 normals = SC_GET(Normals);
00056 texture = SC_GET(Texture);
00057 
00058 if (!gIdentityList)
00059 {
00060 gIdentityList = new IndexList(256);
00061 for (i = 0; i < gIdentityList->NumItems(); i++)
00062 gIdentityList->Item(i) = i;
00063 }
00064 
00065 indexes = SC_GET(PointIndexes);
00066 faceIndexes = SC_GET(FaceIndexes);
00067 if (meshType = SC_GET(MeshType))
00068 meshStyle = meshType->itsType;
00069 else
00070 meshStyle = sRenderStyle;
00071 
00072 if (!indexes)
00073 {
00074 indexes = gIdentityList;
00075 Assert(points->NumItems() <= 256, "polygon too large");
00076 // note: we are relying on Array not changing the current items
00077 // array when we resize down and then back up again. 
00078 // (This is currently safe: the items array only changes if the array
00079 // size is increased.)
00080 indexes->SetSize(points->NumItems());
00081 }
00082 
00083 normIndexes = SC_GET(NormalIndexes);
00084 if (!normIndexes)
00085 normIndexes = indexes;
00086 
00087 if (colours)
00088 {
00089 clrIndexes = SC_GET(ColourIndexes);
00090 if (!clrIndexes)
00091 clrIndexes = normIndexes;
00092 }
00093 else
00094 {
00095 if (SC_GET(Colour))
00096 polyClr = *(SC_GET(Colour));
00097 else if (SC_GET(Emittance))
00098 polyClr = *(SC_GET(Emittance));
00099 else
00100 polyClr[0] = -1.0;
00101 }
00102 
00103 if (texture)
00104 {
00105 // texture map
00106 coords = SC_GET(Coords);
00107 if (coords)
00108 {
00109 r.SetTexture(texture->image);
00110 coordIndexes = SC_GET(CoordIndexes);
00111 if (!coordIndexes)
00112 coordIndexes = gIdentityList;
00113 }
00114 }
00115 else 
00116 coords = 0;
00117 
00118 if (faceIndexes)
00119 {
00120 
00121 if (faceIndexes->NumItems() < 2)
00122 {
00123 // XXX empty face index list
00124 // should modify face begin & end routines to cull
00125 // such empty lists; requires object->Remove() method?
00126 // _Warning("Empty face index list");
00127 return;
00128 }
00129 
00130 faceS = faceIndexes->Item(0);
00131 faceE = faceIndexes->Item(1);
00132 faces = faceIndexes->NumItems() - 1;
00133 f = 2;
00134 }
00135 else
00136 {
00137 faceS = 0;
00138 faceE = indexes->NumItems();
00139 faces = 1;
00140 }
00141 
00142 while (true)
00143 {
00144 r.Begin(meshStyle);
00145 
00146 if (!normals)
00147 {
00148 CalcTriAreaNormal((*points)[(*indexes)[faceS]], 
00149 (*points)[(*indexes)[faceS + 1]], 
00150 (*points)[(*indexes)[faceS + 2]], 
00151 normal
00152 );
00153 r.N(normal);
00154 }
00155 
00156 if (!colours && polyClr[0] >= 0.0)
00157 r.SetColour(polyClr);
00158 
00159 for (i = faceS; i < faceE; i++)
00160 {
00161 if (colours)
00162 {
00163 j = (*clrIndexes)[i];
00164 r.SetColour((*colours)[j]);
00165 }
00166 if (coords)
00167 {
00168 j = (*coordIndexes)[i];
00169 r.SetTexCoord((*coords)[j]);
00170 }
00171 if (normals)
00172 {
00173 j = (*normIndexes)[i];
00174 r.SetNormal((*normals)[j]);
00175 }
00176 
00177 j = (*indexes)[i];
00178 r.SetPoint((*points)[j]);
00179 }
00180 r.End();
00181 
00182 if (faces <= 1) break;
00183 faces--;
00184 faceS = faceE;
00185 faceE = faceIndexes->Item(f++);
00186 }
00187 
00188 if (coords)
00189 r.SetTexture(0);
00190 }
00191 
00192  Void scPoly::DecimateSelf(Decimator &dec)
00193 {
00194 Int i, j, n, idx[32], changed;
00195 Int fi, fStart, fEnd, fLen;
00196 SLContext *context = dec.context;
00197 PointList *points = SC_GET(Points);
00198 IndexList *indexes = SC_GET(PointIndexes);
00199 IndexList *faces = SC_GET(FaceIndexes);
00200 
00201 if (!points)
00202 return;
00203 
00204 if (!indexes)
00205 {
00206 if (!gIdentityList)
00207 {
00208 gIdentityList = new IndexList(256);
00209 for (i = 0; i < gIdentityList->NumItems(); i++)
00210 gIdentityList->Item(i) = i;
00211 }
00212 indexes = gIdentityList;
00213 Assert(points->NumItems() <= 256, "polygon too large");
00214 // note: we are relying on Array not changing the current items
00215 // array when we resize down and then back up again. 
00216 // (This is currently safe: the items array only changes if the array
00217 // size is increased.)
00218 indexes->SetSize(points->NumItems());
00219 }
00220 
00221 changed = 1;
00222 if (faces)
00223 {
00224 fStart = (*faces)[0];
00225 fEnd = (*faces)[1];
00226 fLen = fEnd - fStart;
00227 fi = 2;
00228 }
00229 else
00230 {
00231 fStart = 0;
00232 fLen = fEnd = indexes->NumItems();
00233 }
00234 
00235 while (true)
00236 {
00237 if (!(dec.flags & DecTris))
00238 n = fLen;
00239 else if (fLen == 4 && (dec.flags & DecQuads))
00240 {
00241 // XXX : not stable as height of pgram goes to zero.
00242 
00243 Int *ip = &(*indexes)[fStart];
00244 Vector ab = (*points)[ip[1]] - (*points)[ip[0]];
00245 Vector cd = (*points)[ip[2]] - (*points)[ip[3]];
00246 
00247 // ab == cd : |ab - cd| / |ab + cd| < eps?
00248 
00249 if (sqrlen(ab - cd) / sqrlen(ab + cd) < 1e-6)
00250 n = 4;
00251 else
00252 n = 3;
00253 }
00254 else
00255 n = 3;
00256 
00257 for (j = 0; j < n; j++)
00258 idx[j] = (*indexes)[j + fStart] + dec.pointsAccNum;
00259 
00260 dec.HandlePoly(n, idx, changed);
00261 dec.decNum++;
00262 changed = 0;
00263 
00264 if (n == 3)
00265 for (j = fStart + 2; j < fEnd - 1; j++)
00266 {
00267 idx[1] = (*indexes)[j] + dec.pointsAccNum;
00268 idx[2] = (*indexes)[j + 1] + dec.pointsAccNum;
00269 dec.HandlePoly(n, idx, 0);
00270 dec.decNum++;
00271 }
00272 
00273 if (faces && fi < faces->NumItems())
00274 {
00275 fStart = fEnd;
00276 fEnd = (*faces)[fi++];
00277 fLen = fEnd - fStart;
00278 }
00279 else
00280 break;
00281 }
00282 }
00283 
00284  Void scPoly::Parse(istream &s)
00285 {
00286 }
00287 
00288 
00289 // --- Attributes -------------------------------------------------------------
00290 
00291  Void scPoints::Apply(const Transform &m)
00292 {
00293 Int i;
00294 
00295 for (i = 0; i < NumItems(); i++)
00296 SELF[i] = proj(xform(m, Vector4(SELF[i], 1.0)));
00297 }
00298 
00299  Void scCoords::Apply(const Transform &m)
00300 {
00301 }
00302 
00303  Void scTransform::ApplyActionSelf(scSceneAction &a)
00304 {
00305 scObject::ApplyActionSelf(a);
00306 a.transAcc = xform(a.transAcc, SELF);
00307 }
00308 
00309  Void scCamera::Parse(istream &s)
00310 {
00311 String str;
00312 Vector p;
00313 Char c;
00314 Int model = 1;
00315 
00316 ChompWhiteSpace(s);
00317 while (s.peek() == '+') // extension?
00318 {
00319 s.get(c);
00320 str.ReadWord(s);
00321 
00322 if (str == "eye")
00323 s >> position;
00324 else if (str == "dir")
00325 s >> viewDir;
00326 else if (str == "lookAt")
00327 {
00328 s >> lookAt;
00329 model = 2;
00330 }
00331 else if (str == "vup")
00332 s >> up;
00333 else if (str == "scale")
00334 s >> scale;
00335 else if (str == "fov")
00336 s >> fov;
00337 else if (str == "clipNear")
00338 s >> clipNear;
00339 else if (str == "clipFar")
00340 s >> clipFar;
00341 else
00342 cerr << "unknown camera option: '" << str << "'" << endl;
00343 
00344 ChompWhiteSpace(s);
00345 }
00346 
00347 SetupFromParams();
00348 }
00349 
00350  Void scCamera::Print(ostream &s) const
00351 {
00352 // GetViewDirParams(); XXX can't do this 'cause of const
00353 
00354 s << "camera";
00355 
00356 if (scale != 1.0)
00357 s << " +scale " << scale;
00358 
00359 s << " +eye " << position;
00360 s << " +dir " << viewDir;
00361 s << " +vup " << up;
00362 s << " +fov " << fov;
00363 }
00364 
00365  Void scIndexes::Print(ostream &s) const
00366 {
00367 switch (AttrID())
00368 {
00369 case aPointIndexes:
00370 s << "indexes ";
00371 break;
00372 case aNormalIndexes:
00373 s << "n_indexes ";
00374 break;
00375 case aCoordIndexes:
00376 s << "t_indexes ";
00377 break;
00378 case aColourIndexes:
00379 s << "c_indexes ";
00380 break;
00381 case aFaceIndexes:
00382 s << "faces ";
00383 break;
00384 }
00385 
00386 s << (IndexList&) SELF << endl;
00387 }
00388 
00389  Void scTexture::Parse(istream &s)
00390 {
00391 String str;
00392 
00393 ChompWhiteSpace(s);
00394 s >> str;
00395 Load(str);
00396 }
00397 
00398  Void scTexture::Print(ostream &s) const
00399 {
00400 s << "texture \"" << textureFile.GetPath() << '"';
00401 }
00402 
00403  Void scMeshType::Parse(istream &s)
00404 {
00405 String str;
00406 
00407 ChompWhiteSpace(s);
00408 // s >> itsType;
00409 }
00410 
00411  Void scMeshType::Print(ostream &s) const
00412 {
00413 s << "meshtype \"" << itsType << '"';
00414 }
00415 

Generated at Sat Aug 5 00:17:03 2000 for Graphics Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000

AltStyle によって変換されたページ (->オリジナル) /