// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // VrmlNodeLOD.cpp #include "VrmlNodeLOD.h" #include "VrmlNodeType.h" #include "MathUtils.h" #include "Viewer.h" // Return a new VrmlNodeLOD static VrmlNode *creator( VrmlScene *s ) { return new VrmlNodeLOD(s); } // Define the built in VrmlNodeType:: "LOD" fields VrmlNodeType *VrmlNodeLOD::defineType(VrmlNodeType *t) { static VrmlNodeType *st = 0; if (! t) { if (st) return st; t = st = new VrmlNodeType("LOD", creator); } VrmlNodeChild::defineType(t); // Parent class t->addExposedField("level", VrmlField::MFNODE); t->addField("center", VrmlField::SFVEC3F); t->addField("range", VrmlField::MFFLOAT); return t; } VrmlNodeType *VrmlNodeLOD::nodeType() const { return defineType(0); } VrmlNodeLOD::VrmlNodeLOD(VrmlScene *scene) : VrmlNodeChild(scene) { } VrmlNodeLOD::~VrmlNodeLOD() { } VrmlNode *VrmlNodeLOD::cloneMe() const { return new VrmlNodeLOD(*this); } void VrmlNodeLOD::cloneChildren(VrmlNamespace *ns) { int n = d_level.size(); VrmlNode **kids = d_level.get(); for (int i = 0; iclone(ns)->reference(); kids[i]->dereference(); kids[i] = newKid; } } bool VrmlNodeLOD::isModified() const { if (d_modified) return true; int n = d_level.size(); // This should really check which range is being rendered... for (int i = 0; iisModified()) return true; return false; } void VrmlNodeLOD::clearFlags() { VrmlNode::clearFlags(); int n = d_level.size(); for (int i = 0; iclearFlags(); } void VrmlNodeLOD::addToScene( VrmlScene *s, const char *rel ) { d_scene = s; int n = d_level.size(); for (int i = 0; iaddToScene(s, rel); } void VrmlNodeLOD::copyRoutes( VrmlNamespace *ns ) const { VrmlNode::copyRoutes(ns); int n = d_level.size(); for (int i = 0; icopyRoutes(ns); } ostream& VrmlNodeLOD::printFields(ostream& os, int indent) { if (d_level.size() > 0) PRINT_FIELD(level); if (! FPZERO(d_center.x()) || ! FPZERO(d_center.y()) || ! FPZERO(d_center.z()) ) PRINT_FIELD(center); if (d_range.size() > 0) PRINT_FIELD(range); return os; } // Render one of the children void VrmlNodeLOD::render(Viewer *viewer) { clearModified(); if (d_level.size() <= 0) return; float x, y, z; viewer->getPosition( &x, &y, &z ); float dx = x - d_center.x(); float dy = y - d_center.y(); float dz = z - d_center.z(); float d2 = dx*dx + dy*dy + dz*dz; int i, n = d_range.size(); for (i=0; i= d_level.size()) i = d_level.size() - 1; //printf("LOD d2 %g level %d\n", d2, i); d_level[i]->render(viewer); // Don't re-render on their accounts n = d_level.size(); for (i = 0; iclearModified(); } // Set the value of one of the node fields. void VrmlNodeLOD::setField(const char *fieldName, const VrmlField &fieldValue) { if TRY_FIELD(level, MFNode) else if TRY_FIELD(center, SFVec3f) else if TRY_FIELD(range, MFFloat) else VrmlNodeChild::setField(fieldName, fieldValue); } VrmlNodeLOD* VrmlNodeLOD::toLOD() const { return (VrmlNodeLOD*) this; } const VrmlMFFloat& VrmlNodeLOD::getRange() const { return d_range; } const VrmlSFVec3f& VrmlNodeLOD::getCenter() const { return d_center; }