// // Vrml 97 library // Copyright (C) 1998 Chris Morley // // %W% %G% // VrmlNodeBillboard.cpp #include "VrmlNodeBillboard.h" #include "MathUtils.h" #include "VrmlNodeType.h" static VrmlNode *creator(VrmlScene *s) { return new VrmlNodeBillboard(s); } // Define the built in VrmlNodeType:: "Billboard" fields VrmlNodeType *VrmlNodeBillboard::defineType(VrmlNodeType *t) { static VrmlNodeType *st = 0; if (! t) { if (st) return st; t = st = new VrmlNodeType("Billboard", creator); } VrmlNodeGroup::defineType(t); // Parent class t->addExposedField("axisOfRotation", VrmlField::SFVEC3F); return t; } VrmlNodeType *VrmlNodeBillboard::nodeType() const { return defineType(0); } VrmlNodeBillboard::VrmlNodeBillboard(VrmlScene *scene) : VrmlNodeGroup(scene), d_axisOfRotation(0.0, 1.0, 0.0), d_xformObject(0) { } VrmlNodeBillboard::~VrmlNodeBillboard() { // delete d_xformObject... } VrmlNode *VrmlNodeBillboard::cloneMe() const { return new VrmlNodeBillboard(*this); } ostream& VrmlNodeBillboard::printFields(ostream& os, int indent) { if (! FPZERO(d_axisOfRotation.x()) || ! FPZERO(d_axisOfRotation.y()) || ! FPZERO(d_axisOfRotation.z()) ) PRINT_FIELD(axisOfRotation); VrmlNodeGroup::printFields(os, indent); return os; } void VrmlNodeBillboard::render(Viewer *viewer) { if ( d_xformObject && isModified() ) { viewer->removeObject(d_xformObject); d_xformObject = 0; } if (d_xformObject) viewer->insertReference(d_xformObject); else if (d_children.size() > 0) { d_xformObject = viewer->beginObject(name()); viewer->setBillboardTransform( d_axisOfRotation.get() ); // Render children VrmlNodeGroup::render(viewer); viewer->unsetBillboardTransform( d_axisOfRotation.get() ); viewer->endObject(); } clearModified(); } // Cache a pointer to (one of the) parent transforms for proper // rendering of bindables. void VrmlNodeBillboard::accumulateTransform( VrmlNode *parent ) { d_parentTransform = parent; int i, n = d_children.size(); for (i = 0; iaccumulateTransform( this ); } } VrmlNode* VrmlNodeBillboard::getParentTransform() { return d_parentTransform; } void VrmlNodeBillboard::inverseTransform(Viewer *viewer) { VrmlNode *parentTransform = getParentTransform(); if (parentTransform) parentTransform->inverseTransform(viewer); // Apply inverted bb transforms... //viewer->setBillboardTransform( d_axisOfRotation.get() ); } void VrmlNodeBillboard::inverseTransform(double m[4][4]) { VrmlNode *parentTransform = getParentTransform(); if (parentTransform) parentTransform->inverseTransform(m); else Midentity(m); // Invert bb transform... // ... } // Set the value of one of the node fields. void VrmlNodeBillboard::setField(const char *fieldName, const VrmlField &fieldValue) { if TRY_FIELD(axisOfRotation, SFVec3f) else VrmlNodeGroup::setField(fieldName, fieldValue); }