#include "Technique.hxx"
#include <osgUtil/CullVisitor>
+#include <osgUtil/TangentSpaceGenerator>
#include <osgDB/Registry>
#include <osgDB/Input>
{
}
-EffectGeode::EffectGeode(const EffectGeode& rhs, const CopyOp& copyop) :
- Geode(rhs, copyop)
+EffectGeode::EffectGeode(const EffectGeode& rhs, const osg::CopyOp& copyop) :
+ Geode(rhs, copyop),
+ _effect(static_cast<Effect*>(copyop(rhs._effect.get())))
{
- _effect = static_cast<Effect*>(rhs._effect->clone(copyop));
+}
+
+void EffectGeode::setEffect(Effect* effect)
+{
+ _effect = effect;
+ if (!_effect)
+ return;
+ addUpdateCallback(new Effect::InitializeCallback);
}
void EffectGeode::resizeGLObjectBuffers(unsigned int maxSize)
Geode::releaseGLObjects(state);
}
+// Generates tangent space vectors or other data from geom, as defined by effect
+void EffectGeode::runGenerators(osg::Geometry *geometry)
+{
+ if(geometry && _effect.valid()) {
+ // Generate tangent vectors for the geometry
+ osg::ref_ptr<osgUtil::TangentSpaceGenerator> tsg = new osgUtil::TangentSpaceGenerator;
+
+ // Generating only tangent vector should be enough
+ // since the binormal is a cross product of normal and tangent
+ // This saves a bit of memory & memory bandwidth!
+ int n = _effect->getGenerator(Effect::TANGENT);
+ tsg->generate(geometry, 0); // 0 is normal_unit, but I have no idea what that is!
+ if (n != -1 && !geometry->getVertexAttribArray(n))
+ geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getTangentArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
+
+ n = _effect->getGenerator(Effect::BINORMAL);
+ if (n != -1 && !geometry->getVertexAttribArray(n))
+ geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getBinormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
+
+ n = _effect->getGenerator(Effect::NORMAL);
+ if (n != -1 && !geometry->getVertexAttribArray(n))
+ geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getNormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
+ }
+}
+
bool EffectGeode_writeLocalData(const Object& obj, osgDB::Output& fw)
{
const EffectGeode& eg = static_cast<const EffectGeode&>(obj);
- fw.indent() << "effect\n";
- fw.writeObject(*eg.getEffect());
+ if (eg.getEffect()) {
+ fw.indent() << "effect\n";
+ fw.writeObject(*eg.getEffect());
+ }
+
return true;
}