00001 /*
00002 File: SceneLang.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
00015 #include "gcl/SceneLang.h"
00016 #include "gcl/SLContext.h"
00017 #include "gcl/Readers.h"
00018
00019
00020 // --- Current library & scene-parsing context --------------------------------
00021
00022 #ifdef UNFINISHED
00023 class SLC
00024 {
00025 static SLContext *slContext = new SLContext(aNumAttributes);
00026 static SLLibrary *slLibrary = 0;
00027 static scGroup *slCurrentGroupPtr;
00028 };
00029 #endif
00030
00031 static SLContext *slContext = new SLContext(aNumAttributes);
00032 static SLLibrary *slLibrary = 0;
00033 static scGroup *slCurrentGroupPtr;
00034
00035 // --- Scene command definitions ----------------------------------------------
00036
00037 Void slInit()
00038 {
00039 slSetLibrary(new SLLibrary);
00040 }
00041
00042 scObject *slCurrent()
00043 {
00044 return(slCurrentGroupPtr->Last());
00045 }
00046
00047 scScenePtr slCurrentGroup()
00048 {
00049 return(slCurrentGroupPtr);
00050 }
00051
00052 scScenePtr slBeginObject(const Char *name)
00053 {
00054 if (slLibrary == 0)
00055 {
00056 cerr << "GCL Error in slBeginObject: slInit() was not called." << endl;
00057 exit(1);
00058 }
00059
00060 scScenePtr newGroup = GroupCast(Clone(slLibrary->Member("group")));
00061
00062 newGroup->SetName(name);
00063
00064 if (slCurrentGroupPtr)
00065 slCurrentGroupPtr->Add(newGroup);
00066
00067 slCurrentGroupPtr = newGroup;
00068 slContext->Push();
00069
00070 return(newGroup);
00071 }
00072
00073 Void slEndObject()
00074 {
00075 slCurrentGroupPtr = slCurrentGroupPtr->parent;
00076 slContext->Pop();
00077 }
00078
00079
00080 // --- Attribute routines -----------------------------------------------------
00081
00082
00083 Void slPointList()
00084 {
00085 scPoints *points = new scPoints;
00086
00087 points->AddToContext(slContext);
00088 slCurrentGroupPtr->Add(points);
00089 }
00090
00091 Int slPoint(const Point &p)
00092 {
00093 scPoints *points = SL_GET(Points);
00094
00095 if (!points)
00096 {
00097 slPointList();
00098 points = (scPoints*) slCurrent();
00099 }
00100
00101 points->Append(p);
00102
00103 return(points->NumItems() - 1);
00104 }
00105
00106 Void slPoints(const PointList &pl)
00107 {
00108 scPoints *points = new scPoints(pl);
00109
00110 slCurrentGroupPtr->Add(points);
00111 points->AddToContext(slContext);
00112 }
00113
00114 Void slColourList()
00115 {
00116 scColours *colours = new scColours;
00117
00118 colours->AddToContext(slContext);
00119 slCurrentGroupPtr->Add(colours);
00120 }
00121
00122 Int slColour(const Colour &c)
00123 // XXX this is overloaded -- have slColour as vertex colour, and
00124 // define different colour type as object colours (slDiffColour?)
00125 {
00126 scColours *colours;
00127
00128 if (colours = SL_GET(Colours))
00129 {
00130 colours->Append(c);
00131 return(colours->NumItems() - 1);
00132 }
00133 else
00134 {
00135 scColour *colour = new scColour(c);
00136
00137 slCurrentGroupPtr->Add(colour);
00138 colour->AddToContext(slContext);
00139 return(-1);
00140 }
00141 }
00142
00143 Void slNormalList()
00144 {
00145 scNormals *normals = new scNormals;
00146
00147 normals->AddToContext(slContext);
00148 slCurrentGroupPtr->Add(normals);
00149 }
00150
00151 Int slNormal(const Vector &p)
00152 {
00153 scNormals *normals = SL_GET(Normals);
00154
00155 if (!normals)
00156 {
00157 slNormalList();
00158 normals = (scNormals*) slCurrent();
00159 }
00160
00161 normals->Append(p);
00162
00163 return(normals->NumItems() - 1);
00164 }
00165
00166 Void slCoordList()
00167 {
00168 scCoords *coords = new scCoords;
00169
00170 coords->AddToContext(slContext);
00171 slCurrentGroupPtr->Add(coords);
00172 }
00173
00174 Int slCoord(const Coord &c)
00175 {
00176 scCoords *coords = SL_GET(Coords);
00177
00178 if (!coords)
00179 {
00180 slCoordList();
00181 coords = (scCoords*) slCurrent();
00182 }
00183
00184 coords->Append(c);
00185
00186 return(coords->NumItems() - 1);
00187 }
00188
00189 Void slCoords(const CoordList &cl)
00190 {
00191 scCoords *coords = new scCoords(cl);
00192
00193 slCurrentGroupPtr->Add(coords);
00194 coords->AddToContext(slContext);
00195 }
00196
00197 // --- Index types -------------------------------------------------------
00198
00199 // Generic
00200
00201 Void slIndexList(scAttributeID id)
00202 {
00203 scIndexes *indexes = new scIndexes(id);
00204
00205 indexes->AddToContext(slContext);
00206 slCurrentGroupPtr->Add(indexes);
00207 }
00208
00209 Void slIndex(scAttributeID id, Int i)
00210 {
00211 Assert(i >= 0, "(slIndex) negative index!");
00212
00213 scIndexes *indexes = (scIndexes*) slContext->Get(id);
00214
00215 if (!indexes)
00216 {
00217 slIndexList(id);
00218 indexes = (scIndexes*) slCurrent();
00219 }
00220
00221 indexes->Append(i);
00222 }
00223
00224 Void slIndexes(scAttributeID id, const IndexList &il)
00225 {
00226 scIndexes *indexes = new scIndexes(id, il);
00227
00228 slCurrentGroupPtr->Add(indexes);
00229 indexes->AddToContext(slContext);
00230 }
00231
00232 // Specific
00233
00234 Void slPointIndexList() { slIndexList(aPointIndexes); }
00235 Void slColourIndexList() { slIndexList(aColourIndexes); }
00236 Void slNormalIndexList() { slIndexList(aNormalIndexes); }
00237 Void slCoordIndexList() { slIndexList(aCoordIndexes); }
00238
00239 Void slPointIndex(Int i) { slIndex(aPointIndexes, i); }
00240 Void slColourIndex(Int i) { slIndex(aColourIndexes, i); }
00241 Void slNormalIndex(Int i) { slIndex(aNormalIndexes, i); }
00242 Void slCoordIndex(Int i) { slIndex(aCoordIndexes, i); }
00243
00244 Void slPointIndexes(const IndexList &il) { slIndexes(aPointIndexes, il); }
00245 Void slColourIndexes(const IndexList &il) { slIndexes(aColourIndexes, il); }
00246 Void slNormalIndexes(const IndexList &il) { slIndexes(aNormalIndexes, il); }
00247 Void slCoordIndexes(const IndexList &il) { slIndexes(aCoordIndexes, il); }
00248
00249 // ----------------------------------------------------------------------------
00250
00251 Void slTexture(StrConst filename)
00252 {
00253 scTexture *texture = new scTexture;
00254
00255 texture->Load(filename);
00256
00257 slCurrentGroupPtr->Add(texture);
00258 texture->AddToContext(slContext);
00259 }
00260
00261 Void slCamera()
00262 {
00263 scCamera *camera = new scCamera;
00264
00265 camera->AddToContext(slContext);
00266 slCurrentGroupPtr->Add(camera);
00267 }
00268
00269 Void slTransform(const Transform &t)
00270 {
00271 scTransform *transform = new scTransform(t);
00272
00273 slCurrentGroupPtr->Add(transform);
00274 transform->AddToContext(slContext);
00275 }
00276
00277 Void slEmittance(const Colour &c)
00278 {
00279 scEmittance *emit = new scEmittance(c);
00280
00281 slCurrentGroupPtr->Add(emit);
00282 emit->AddToContext(slContext);
00283 }
00284
00285 Void slPoly()
00286 {
00287 scPrimitive *poly;
00288
00289 poly = Clone(slLibrary->Member("poly"));
00290
00291 slCurrentGroupPtr->Add(poly);
00292 }
00293
00294 Void slBeginFaces()
00295 {
00296 scIndexes *indexes = SL_GET(PointIndexes);
00297 scIndexes *faceIndexes = new scIndexes(aFaceIndexes);
00298
00299 if (!indexes)
00300 {
00301 slPointIndexList();
00302 indexes = (scIndexes*) slCurrent();
00303 }
00304
00305 faceIndexes->AddToContext(slContext);
00306 slCurrentGroupPtr->Add(faceIndexes);
00307 faceIndexes->Append(indexes->NumItems());
00308 }
00309
00310 Void slFace()
00311 {
00312 scIndexes *faceIdxs = SL_GET(FaceIndexes);
00313 scIndexes *idxs = SL_GET(PointIndexes);
00314
00315 if (!faceIdxs)
00316 _Warning("slFace() without an slBeginFaces()");
00317 else
00318 faceIdxs->Append(idxs->NumItems());
00319 }
00320
00321 Void slEndFaces()
00322 {
00323 scIndexes *faceIdxs = SL_GET(FaceIndexes);
00324
00325 if (!faceIdxs)
00326 _Warning("slFace() without an slBeginFaces()");
00327 else if (faceIdxs->NumItems() > 1)
00328 slPoly();
00329 // XXX else remove empty face list.
00330 }
00331
00332 // --- Generic ----------------------------------------------------------------
00333
00334 Void slApply(const Transform &t)
00335 {
00336 slCurrent()->Apply(t);
00337 }
00338
00339 Bool slObjectExists(const Char *name)
00340 {
00341 if (slLibrary)
00342 return(slLibrary->MemberExists(name));
00343 else
00344 return(false);
00345 }
00346
00347 scPrimitive *slObject(const Char *name)
00348 {
00349 scPrimitive *newObj = Clone(slLibrary->Member(name));
00350
00351 slCurrentGroupPtr->Add(newObj);
00352
00353 return(newObj);
00354 }
00355
00356 scPrimitive *slObject(scPrimitive *object)
00357 {
00358 slCurrentGroupPtr->Add(object);
00359 return(object);
00360 }
00361
00362 scPrimitive *slObjectFile(StrConst filename)
00363 {
00364 scScenePtr scenePtr;
00365 FileName sceneFile;
00366
00367 sceneFile.SetPath(SubstituteEnvVars(filename));
00368 scenePtr = SceneReader::Load(sceneFile);
00369
00370 if (scenePtr)
00371 slCurrentGroupPtr->Add(scenePtr);
00372
00373 return(scenePtr);
00374 }
00375
00376 Void slBeginObject(scScenePtr object)
00377 {
00378 if (slCurrentGroupPtr)
00379 slCurrentGroupPtr->Add(object);
00380
00381 slCurrentGroupPtr = object;
00382 slContext->Push();
00383 }
00384
00385 Void slAttribute(scAttribute *attrPtr)
00386 {
00387 slCurrentGroupPtr->Add(attrPtr);
00388 attrPtr->AddToContext(slContext);
00389 }
00390
00391 Void slEndAttribute(Int attr)
00392 {
00393 slCurrentGroupPtr->Add(new scClearAttr(attr));
00394 }
00395
00396 Void slMeshType(RenderStyle renStyle)
00397 {
00398 scMeshType *sm = new scMeshType;
00399
00400 sm->itsType = renStyle;
00401 slCurrentGroupPtr->Add(sm);
00402 }
00403
00404 SLContext *slGetContext()
00405 {
00406 return(slContext);
00407 }
00408
00409 // --- Library routines -------------------------------------------------------
00410
00411
00412 Void slSetLibrary(SLLibrary *library)
00413 {
00414 delete slLibrary;
00415
00416 slLibrary = library;
00417 slLibrary->Create();
00418 }
00419
00420 SLLibrary *slSwapLibrary(SLLibrary *newLib)
00421 {
00422 SLLibrary *tl = slLibrary;
00423
00424 slLibrary = newLib;
00425 return(tl);
00426 }
00427
00428 Void slAddToLibrary(scGroup *newGroup)
00429 {
00430 slLibrary->AddMember(newGroup);
00431 }
00432
00433 SLLibrary *slGetLibrary()
00434 {
00435 return(slLibrary);
00436 }