// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // VrmlNodeShape.cpp #include "VrmlNodeShape.h" #include "VrmlNodeAppearance.h" #include "VrmlNodeGeometry.h" #include "VrmlNodeTexture.h" #include "VrmlNodeType.h" #include "Viewer.h" static VrmlNode *creator( VrmlScene *s ) { return new VrmlNodeShape(s); } // Define the built in VrmlNodeType:: "Shape" fields VrmlNodeType *VrmlNodeShape::defineType(VrmlNodeType *t) { static VrmlNodeType *st = 0; if (! t) { if (st) return st; t = st = new VrmlNodeType("Shape", creator); } VrmlNodeChild::defineType(t); // Parent class t->addExposedField("appearance", VrmlField::SFNODE); t->addExposedField("geometry", VrmlField::SFNODE); return t; } VrmlNodeType *VrmlNodeShape::nodeType() const { return defineType(0); } VrmlNodeShape::VrmlNodeShape(VrmlScene *scene) : VrmlNodeChild(scene), d_viewerObject(0) { } VrmlNodeShape::~VrmlNodeShape() { // need viewer to free d_viewerObject ... } VrmlNode *VrmlNodeShape::cloneMe() const { return new VrmlNodeShape(*this); } void VrmlNodeShape::cloneChildren(VrmlNamespace *ns) { if (d_appearance.get()) d_appearance.set(d_appearance.get()->clone(ns)); if (d_geometry.get()) d_geometry.set(d_geometry.get()->clone(ns)); } bool VrmlNodeShape::isModified() const { return ( d_modified || (d_geometry.get() && d_geometry.get()->isModified()) || (d_appearance.get() && d_appearance.get()->isModified()) ); } void VrmlNodeShape::clearFlags() { VrmlNode::clearFlags(); if (d_appearance.get()) d_appearance.get()->clearFlags(); if (d_geometry.get()) d_geometry.get()->clearFlags(); } void VrmlNodeShape::addToScene(VrmlScene *s, const char *relUrl) { d_scene = s; if (d_appearance.get()) d_appearance.get()->addToScene(s,relUrl); if (d_geometry.get()) d_geometry.get()->addToScene(s,relUrl); } void VrmlNodeShape::copyRoutes(VrmlNamespace *ns) const { VrmlNode::copyRoutes(ns); if (d_appearance.get()) d_appearance.get()->copyRoutes(ns); if (d_geometry.get()) d_geometry.get()->copyRoutes(ns); } ostream& VrmlNodeShape::printFields(ostream& os, int indent) { if (d_appearance.get()) PRINT_FIELD(appearance); if (d_geometry.get()) PRINT_FIELD(geometry); return os; } VrmlNodeShape* VrmlNodeShape::toShape() const { return (VrmlNodeShape*) this; } void VrmlNodeShape::render(Viewer *viewer) { if ( d_viewerObject && isModified() ) { viewer->removeObject(d_viewerObject); d_viewerObject = 0; } VrmlNodeGeometry *g = d_geometry.get() ? d_geometry.get()->toGeometry() : 0; if (d_viewerObject) viewer->insertReference(d_viewerObject); else if ( g ) { d_viewerObject = viewer->beginObject( name() ); // Don't care what color it is if we are picking bool picking = (Viewer::RENDER_MODE_PICK == viewer->getRenderMode()); if (! picking ) { int nTexComponents = 0; if (! picking && d_appearance.get() && d_appearance.get()->toAppearance() ) { VrmlNodeAppearance *a = d_appearance.get()->toAppearance(); a->render(viewer); if (a->texture() && a->texture()->toTexture()) nTexComponents = a->texture()->toTexture()->nComponents(); } else { viewer->setColor(1.0, 1.0, 1.0); // default object color viewer->enableLighting(false); // turn lighting off } // hack for opengl material mode viewer->setMaterialMode( nTexComponents, g->color() != 0 ); } // render geometry g->render(viewer); viewer->endObject(); } else if (d_appearance.get()) d_appearance.get()->clearModified(); clearModified(); } // Set the value of one of the node fields. void VrmlNodeShape::setField(const char *fieldName, const VrmlField &fieldValue) { if TRY_SFNODE_FIELD(appearance, Appearance) else if TRY_SFNODE_FIELD(geometry, Geometry) else VrmlNodeChild::setField(fieldName, fieldValue); }