/* * NodeLOD.cpp * * Copyright (C) 1999 Stephen F. White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file "COPYING" for details); if * not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. */ #include #include "stdafx.h" #include "NodeLOD.h" #include "Proto.h" #include "FieldValue.h" #include "MFNode.h" #include "SFVec3f.h" #include "MFFloat.h" ProtoLOD::ProtoLOD(Scene *scene) : Proto(scene, "LOD") { level.set( addExposedField(MFNODE, "level", new MFNode(), CHILD_NODE)); center.set( addField(SFVEC3F, "center", new SFVec3f(0.0f, 0.0f, 0.0f))); range.set( addField(MFFLOAT, "range", new MFFloat(), new SFFloat(0.0f))); } Node * ProtoLOD::create(Scene *scene) { return new NodeLOD(scene, this); } NodeLOD::NodeLOD(Scene *scene, Proto *def) : Node(scene, def) { _nodeToDrawIndex = -1; } void NodeLOD::draw() { NodeList *childList = level()->getValues(); if ((childList->size() > 0) && (_nodeToDrawIndex >= 0)) { glPushName(level_Index()); // field offset childList->get(_nodeToDrawIndex)->bind(); glPushName(0); glLoadName(_nodeToDrawIndex); childList->get(_nodeToDrawIndex)->draw(); glPopName(); childList->get(_nodeToDrawIndex)->unbind(); glPopName(); } } void NodeLOD::preDraw() { accountNodeToDrawIndex(); NodeList *childList = level()->getValues(); if ((childList->size() > 0) && (_nodeToDrawIndex >= 0)) childList->get(_nodeToDrawIndex)->preDraw(); } void NodeLOD::accountNodeToDrawIndex() { NodeList *childList = level()->getValues(); Array indexList; NodeList tmpChildList; for (int i = 0; i < childList->size(); i++) if (childList->get(i)->getType() != NODE_COMMENT) { tmpChildList.append(childList->get(i)); indexList.append(i); } int tmpNodeToDrawIndex = -1; if (tmpChildList.size() > 0) { tmpNodeToDrawIndex = tmpChildList.size() - 1; Matrix matrix; const float *fcenter = center()->getValue(); glPushMatrix(); glTranslatef(fcenter[0], fcenter[1], fcenter[2]); glGetFloatv(GL_MODELVIEW_MATRIX, matrix); glPopMatrix(); Vec3f v(matrix[12], matrix[13], matrix[14]); MFFloat *mfrange = range(); if (tmpNodeToDrawIndex > mfrange->getSize()) tmpNodeToDrawIndex = mfrange->getSize(); // vrml97/part1/nodesRef.html#LOD // | An empty range field ... a hint to the browser that it may // | choose a level automatically to maintain a constant display rate. // we choose the first level 8-( if (mfrange->getSize() > 0) for (int i = tmpNodeToDrawIndex; i >= 0; i--) if ((i < tmpChildList.size()) && (i < mfrange->getSize())) if (v.length() < mfrange->getValues()[i]) tmpNodeToDrawIndex = i; _nodeToDrawIndex = -1; if (tmpNodeToDrawIndex >= 0) _nodeToDrawIndex = indexList.get(tmpNodeToDrawIndex); } } void NodeLOD::flip(int index) { center()->flip(index); NodeList *childList = level()->getValues(); for (int i = 0; i < childList->size(); i++) childList->get(i)->flip(index); } int NodeLOD::countPolygons(void) { NodeList *childList = level()->getValues(); if (_nodeToDrawIndex >= 0) return childList->get(_nodeToDrawIndex)->countPolygons(); else return 0; } int NodeLOD::countPrimitives(void) { NodeList *childList = level()->getValues(); if (_nodeToDrawIndex >= 0) return childList->get(_nodeToDrawIndex)->countPrimitives(); else return 0; }