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 }