00001 /*
00002 File: Scene.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/Scene.h"
00015 #include "gcl/Avars.h"
00016 #include <iomanip.h>
00017 #include "gcl/VecUtil.h"
00018 #include "gcl/SceneObjects.h"
00019 #include "gcl/ParseSL.h"
00020
00021 // 'gAttributeNameTable' is a Table for the names of the various attributes.
00022 // Should be more extendable than this...
00023
00024 Char *gAttributeNameTable[] =
00025 {
00026 "State",
00027 "Colour",
00028 "Emittance",
00029
00030 "Points",
00031 "Colours",
00032 "Normals",
00033 "Texture Coordinates",
00034
00035 "Point Indexes",
00036 "Colour Indexes",
00037 "Normal Indexes",
00038 "TexCoord Indexes",
00039
00040 "Faces",
00041 "Mesh Type",
00042
00043 "Transformation",
00044 "Camera",
00045 "Texture",
00046 "ObjHide",
00047 "Avar List",
00048 0
00049 };
00050
00051
00052 /*
00053 Notes on polygonal data:
00054
00055 The scene format is made up of a number of layers, with defaults
00056
00057 points/colours/normals lists: contain the actual data.
00058
00059 if there exist indexes/cindexes/nindexes lists, these contain indices
00060 into the most recent entity lists; if not, the indexes are assumed to
00061 read 1, 2, 3, ...
00062
00063 if there is a faces list, it is assumed to define polygonal faces by
00064 the range of indices into the indexes lists. If not, the lists are
00065 assumed to define a single face.
00066
00067 (i) points a, b, c
00068 points c, d, a
00069
00070 (ii) points a, b, c, d
00071 indexes 0, 1, 2
00072 indexes 2, 3, 0
00073
00074 (iii) points a, b, c, d
00075 indexes 0, 1, 2, 2, 3, 0
00076 faces 0,3,6
00077
00078 for this trivial example, (ii) and (iii) might not seem that useful. For
00079 a large model, with a number of different vertex properties (points,
00080 surface normals, texture coordinates, etc.) they provide more
00081 flexibility and space savings.
00082
00083 */
00084
00085
00086 // --- scObject methods -------------------------------------------------------
00087
00088
00089 scObject::~scObject()
00090 {
00091 }
00092
00093 Void scObject::Apply(const Transform &m)
00094 {
00095 }
00096
00097 Void scObject::ApplyAction(scSceneAction &a)
00098 {
00099 a.Start();
00100 ApplyActionSelf(a);
00101 a.Stop();
00102 }
00103
00104 Void scObject::ApplyActionSelf(scSceneAction &a)
00105 {
00106 if (IsAttr())
00107 a.Attribute(AttrCast(this));
00108 else if (IsPrim())
00109 a.Primitive(PrimCast(this));
00110 }
00111
00112 Void scObject::Print(ostream &s) const
00113 {
00114 s << "Undefined object";
00115 }
00116
00117 Void scObject::HierPrint(ostream &s, Int indent) const
00118 {
00119 Int i;
00120
00121 for (i = 0; i < indent; i++)
00122 s << ' ';
00123
00124 Print(s);
00125
00126 s << endl;
00127 }
00128
00129 Void scObject::Decimate(Decimator &dec, UInt32 flags)
00130 {
00131 SLContext context(aNumAttributes);
00132
00133 dec.decNum = 0;
00134 dec.pointsAccNum = 0;
00135 dec.transAcc = vl_I;
00136 dec.flags.Clear();
00137 dec.flags.Set(flags);
00138 dec.context = &context;
00139
00140 if (flags & DecUseMaster)
00141 dec.pointsAcc = new PointList;
00142 else
00143 dec.pointsAcc = 0;
00144
00145 dec.HandlePoly(DEC_Start, 0, false);
00146 DecimateSelf(dec);
00147 dec.HandlePoly(DEC_End, 0, false);
00148 }
00149
00150
00151 // --- Printing operator ------------------------------------------------------
00152
00153
00154 Int scObject::prIndent = 4;
00155
00156 ostream &operator << (ostream &s, const scScenePtr scene)
00157 {
00158 scene->HierPrint(s, 0); // Start from 0 indentation
00159
00160 return(s);
00161 }
00162
00163
00164 // --- scAttribute methods ----------------------------------------------------
00165
00166
00167 Void scAttribute::Print(ostream &s) const
00168 {
00169 s << "set " << gAttributeNameTable[AttrID()] << " [" << (Int) AttrID() << "]";
00170 }
00171
00172 Void scAttribute::AddToContext(SLContext *context)
00173 {
00174 context->Set(AttrID(), this);
00175 }
00176
00177 Bool scAttribute::HasAvar(Avar &avar, Int slot)
00178 {
00179 return(false);
00180 }
00181
00182 #ifdef UNFINISHED
00183 Bool scAttribute::HasAvars(Avar &avar, Int slot)
00184 {
00185 rotSlot = list.RegisterAvar("rotate_c");
00186 list.RegisterAvar("rotate_c");
00187 list.RegisterAvar("rotate_c");
00188 return(false);
00189 }
00190 #endif
00191
00192 Void scClearAttr::Print(ostream &s) const
00193 {
00194 s << "clear " << gAttributeNameTable[AttrID()] << " ["
00195 << (Int) AttrID() << "]";
00196 }
00197
00198 Void scClearAttr::AddToContext(SLContext *context)
00199 {
00200 context->Set(AttrID(), 0);
00201 }
00202
00203
00204 // --- scPrimitive methods ----------------------------------------------------
00205
00206
00207 RenderStyle scPrimitive::sRenderStyle = renPoly;
00208 Colour scPrimitive::sDefaultColour(cOrange);
00209
00210 Void scPrimitive::Draw(Renderer &r)
00211 {
00212 SLContext context(aNumAttributes);
00213
00214 context.Clear();
00215
00216 Draw(r, &context);
00217 }
00218
00219 Void scPrimitive::Draw(Renderer &r, SLContext *context)
00220 {
00221 }
00222
00223 Void scPrimitive::Print(ostream &s) const
00224 {
00225 s << Label();
00226 }
00227
00228 Void scPrimitive::Apply(const Transform& m)
00229 {
00230 }
00231
00232 Void scPrimitive::Set(scAttribute *sa)
00233 {
00234 Assert(false, "can't set attribute of a non-group.");
00235 if (parent)
00236 {
00237 Int i;
00238
00239 for (i = 0; i < parent->NumChildren(); i++)
00240 if (parent->Child(i) == this)
00241 {
00242 parent->children.Insert(i, sa);
00243 return;
00244 }
00245
00246 _Error("Bad parent pointer...");
00247 }
00248 else
00249 Assert(false, "can't set attribute of a parentless primitive.");
00250 }
00251
00252 scAttribute *scPrimitive::Get(scAttributeID searchID)
00253 {
00254 Int i;
00255 scAttribute *result = 0;
00256
00257 if (parent == 0)
00258 return(0);
00259
00260 for (i = 0; i < parent->NumChildren(); i++)
00261 if (parent->Child(i)->AttrID() == searchID)
00262 result = AttrCast(parent->Child(i));
00263 else if (parent->Child(i) == this)
00264 break;
00265
00266 if (result == 0)
00267 return(parent->Get(searchID));
00268 else
00269 return(result);
00270 }
00271
00272 scAttribute *scPrimitive::FindFirst(scAttributeID id)
00273 {
00274 return(0);
00275 }
00276
00277 Void scPrimitive::Normalise()
00278 {
00279 Point min, max;
00280 GCLReal scale;
00281 Vector centre;
00282
00283 // scale so longest dimension is 1
00284 // center on y axis such that bottom of object touches z-x plane.
00285
00286 FindBounds(min, max);
00287 scale = MaxElt(max - min) / 2.0;
00288 centre = (min + max) * 0.5;
00289 centre[vl_y] -= (max[vl_y] - min[vl_y]) * 0.5;
00290 Apply(xform(Scalef(1.0 / scale), Shift(-centre)));
00291 }
00292
00293 Void scPrimitive::FindBounds(Point &min, Point &max)
00294 {
00295 min.MakeBlock(HUGE_VAL);
00296 max.MakeBlock(-HUGE_VAL);
00297 UpdateBounds(min, max, vl_I);
00298 }
00299
00300 Void scPrimitive::UpdateBounds(Point &min, Point &max,
00301 const Transform &t)
00302 {
00303 }
00304
00305 Void scPrimitive::ExtDispatch(Int method, Void *data)
00306 {
00307 if (method == -1)
00308 cerr << "ExtDispatch called, data = " << data << endl;
00309 }
00310
00311 // --- scGroup methods --------------------------------------------------------
00312
00313 scGroup::scGroup(const scGroup &sg) :
00314 scPrimitive(sg),
00315 children(sg.children),
00316 name(sg.name)
00317 {
00318 int i;
00319
00320 for (i = 0; i < children.NumItems(); i++)
00321 if (Child(i)->IsPrim())
00322 PrimCast(Child(i))->parent = this;
00323 }
00324
00325 Void scGroup::ApplyActionSelf(scSceneAction &a)
00326 {
00327 if (a.context->Get(aObjHide)) return;
00328
00329 Int i;
00330 Transform saveAcc;
00331
00332 a.context->Push();
00333 saveAcc = a.transAcc;
00334
00335 for (i = 0; i < NumChildren(); i++)
00336 Child(i)->ApplyActionSelf(a);
00337
00338 a.transAcc = saveAcc;
00339 a.context->Pop();
00340 }
00341
00342 Void scGroup::Apply(const Transform &m)
00343 {
00344 children.Prepend(new scTransform(m));
00345 }
00346
00347 Void scGroup::UpdateBounds(Vector &min, Vector &max,
00348 const Transform &transform)
00349 {
00350 Int i, j;
00351 Transform groupTransform(transform);
00352
00353 // should change this to call attr->UpdateBounds?
00354
00355 for (i = 0; i < NumChildren(); i++)
00356 if (Child(i)->IsAttr())
00357 {
00358 if (Child(i)->AttrID() == aTransform)
00359 {
00360 groupTransform = xform(groupTransform,
00361 (scTransform &) *AttrCast(Child(i)));
00362 }
00363 else if (Child(i)->AttrID() == aPoints)
00364 {
00365 PointList *pl = (scPoints*) AttrCast(Child(i));
00366 for (j = 0; j < pl->NumItems(); j++)
00367 ::UpdateBounds(xform(groupTransform, (*pl)[j]), min, max);
00368 }
00369 }
00370 else
00371 PrimCast(Child(i))->UpdateBounds(min, max, groupTransform);
00372 }
00373
00374 Void scGroup::SetName(StrConst newName)
00375 {
00376 name = newName;
00377 }
00378
00379 Void scGroup::Add(scObject *so)
00380 {
00381 if (so->IsPrim())
00382 PrimCast(so)->parent = this;
00383 children.Append(so);
00384 }
00385
00386 scObject *scGroup::Last()
00387 {
00388 return((scObject *) children.Top());
00389 }
00390
00391 StrConst scGroup::Label() const
00392 {
00393 return(name);
00394 }
00395
00396 Void scGroup::Print(ostream &s) const
00397 {
00398 HierPrint(s, 0); // Start from 0 indentation
00399 }
00400
00401 Void scGroup::DecimateSelf(Decimator &dec)
00402 {
00403 if (dec.context->Get(aObjHide)) return;
00404
00405 Int i, j, k, savePointsAccNum;
00406 Transform saveTransAcc;
00407
00408 // push current state.
00409 dec.context->Push();
00410 saveTransAcc = dec.transAcc;
00411 savePointsAccNum = dec.pointsAccNum;
00412
00413 for (i = 0; i < NumChildren(); i++)
00414 if (Child(i)->IsPrim())
00415 PrimCast(Child(i))->DecimateSelf(dec);
00416 else
00417 {
00418 AttrCast(Child(i))->AddToContext(dec.context);
00419
00420 if (Child(i)->AttrID() == aPoints && (dec.flags.IsSet(DecUseMaster)))
00421 {
00422 PointList *points;
00423
00424 // need to append this to the master points list
00425 points = (scPoints*) AttrCast(Child(i));
00426 // save the current end of the list as the new numbering
00427 // offset.
00428 dec.pointsAccNum = dec.pointsAcc->NumItems();
00429 dec.pointsAcc->Add(points->NumItems());
00430 // apply the current model transform to the new points
00431 k = dec.pointsAccNum;
00432 for (j = 0; j < points->NumItems(); j++)
00433 (*dec.pointsAcc)[k++] = xform(dec.transAcc,
00434 (*points)[j]);
00435 }
00436 else
00437 {
00438 // if it's a transform, concatenate it to transAcc
00439 if (Child(i)->AttrID() == aTransform)
00440 dec.transAcc = xform(dec.transAcc,
00441 *(scTransform*)(dec.context->Get(aTransform)));
00442 }
00443 }
00444
00445 // pop current state.
00446 dec.context->Pop();
00447 dec.transAcc = saveTransAcc;
00448 dec.pointsAccNum = savePointsAccNum;
00449 }
00450
00451 Void scGroup::HierPrint(ostream &s, Int indent) const
00452 {
00453 Int i, j;
00454
00455 for (j = 0; j < indent; j++)
00456 s << ' ';
00457 s << "object \"";
00458 if (name)
00459 s << name;
00460 s << "\"" << endl; // " << (Void *) this << ' ' << (Void *) parent << endl;
00461
00462 for (i = 0; i < NumChildren(); i++)
00463 Child(i)->HierPrint(s, indent + prIndent);
00464
00465 for (j = 0; j < indent; j++)
00466 s << ' ';
00467
00468 s << "end" << endl;
00469 }
00470
00471
00472 Void scGroup::Parse(istream &s)
00473 {
00474 Char c;
00475 scObject *newObj;
00476 String *str = new String;
00477
00478 while (isspace(s.peek())) // chomp white space
00479 s.get(c);
00480
00481 s >> *str;
00482 *str = SubstituteEnvVars(*str);
00483
00484 name = str->Ref();
00485
00486 children.Clear();
00487
00488 while (1)
00489 {
00490 newObj = ParseSLObject(s);
00491 if (newObj == 0)
00492 break;
00493 if (!s)
00494 {
00495 Expect(false, "Couldn't read object component");
00496 return;
00497 }
00498
00499 Add(newObj);
00500 }
00501 }
00502
00503 Object *scGroup::Clone() const
00504 {
00505 Int i;
00506 scGroup *result;
00507
00508 result = new scGroup(name);
00509
00510 for (i = 0; i < children.NumItems(); i++)
00511 result->Add((scObject*) children[i]->Clone());
00512
00513 return(result);
00514 }
00515
00516 #include "gcl/SceneObjects.h"
00517
00518 Void scGroup::Draw(Renderer &r, SLContext *context)
00519 {
00520 if (context->Get(aObjHide)) return;
00521
00522 Int i;
00523
00524 r.Push();
00525 context->Push();
00526
00527 for (i = 0; i < NumChildren(); i++)
00528 if (Child(i)->IsPrim())
00529 PrimCast(Child(i))->Draw(r, context);
00530 else
00531 {
00532 // ignore cameras other than the first one
00533 if (Child(i)->AttrID() == aCamera && context->Get(aCamera))
00534 continue;
00535
00536 AttrCast(Child(i))->AddToContext(context);
00537 if (Child(i)->AttrID() == aTransform)
00538 r.SetTransform((scTransform &) *AttrCast(Child(i)));
00539 else if (Child(i)->AttrID() == aCamera)
00540 r.SetCamera((scCamera &) *AttrCast(Child(i)));
00541 }
00542
00543 context->Pop();
00544 r.Pop();
00545 }
00546
00547 Void scGroup::Set(scAttribute *sa)
00548 {
00549 Int i;
00550
00551 #ifdef UNFINISHED
00552 for (i = 0; i < NumChildren() && Child(i)->IsAttr(); i++)
00553 if (Child(i)->AttrID() == sa->AttrID())
00554 {
00555 Child(i)->Free();
00556 children[i] = sa;
00557 return;
00558 }
00559 #endif
00560
00561 children.Prepend(sa);
00562 }
00563
00564 scAttribute *scGroup::FindFirst(scAttributeID id)
00565 {
00566 // if (!on) return(0); XXX
00567
00568 Int i;
00569 scAttribute *result;
00570
00571 for (i = 0; i < NumChildren(); i++)
00572 if (Child(i)->IsPrim())
00573 {
00574 result = PrimCast(Child(i))->FindFirst(id);
00575 if (result)
00576 return(result);
00577 }
00578 else if (Child(i)->AttrID() == id)
00579 return(AttrCast(Child(i)));
00580
00581 return(0);
00582 }
00583
00584 // --- Actions ----------------------------------------------------------------
00585
00586
00595 Void scSceneAction::Start()
00596 {
00597 transAcc = vl_I;
00598 context = new SLContext(aNumAttributes);
00599 }
00600
00601 Void scSceneAction::Stop()
00602 {
00603 delete context;
00604 context = 0;
00605 }
00606
00607 Void scSceneAction::Primitive(scPrimitive *sp)
00608 {
00609 }
00610
00611 Void scSceneAction::Attribute(scAttribute *sa)
00612 {
00613 sa->AddToContext(context);
00614 }
00615
00616
00617 // --- Avar methods/operators -------------------------------------------------
00618
00619
00620 ostream &operator << (ostream &s, const Avar &avar)
00621 {
00622 s << avar.name << " [" << avar.lowerBound << " " << avar.value << " " <<
00623 avar.upperBound << "]";
00624
00625 return(s);
00626 }
00627
00628
00629 // --- extras -----------------------------------------------------------------
00630
00631 Void FindDecInfo::HandlePoly(
00632 Int numVertices,
00633 Int vertices[],
00634 Int changed
00635 )
00636 {
00637 if (numVertices == DEC_Start)
00638 {
00639 numProps = 0;
00640 numTris = 0;
00641 numQuads = 0;
00642 numPolys = 0;
00643 }
00644
00645 if (numVertices < 0) return;
00646
00647 if (changed)
00648 numProps++;
00649
00650 if (numVertices == 3)
00651 numTris++;
00652 else if (numVertices == 4)
00653 numQuads++;
00654
00655 numPolys++;
00656 }