diff --git a/include/osgUtil/TangentSpaceGenerator b/include/osgUtil/TangentSpaceGenerator index 017dfb28a..47baf7d25 100644 --- a/include/osgUtil/TangentSpaceGenerator +++ b/include/osgUtil/TangentSpaceGenerator @@ -40,7 +40,7 @@ public: TangentSpaceGenerator(); TangentSpaceGenerator(const TangentSpaceGenerator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY); - void generate(osg::Geometry *geo, int normal_map_tex_unit = 0, bool use_indices = false); + void generate(osg::Geometry *geo, int normal_map_tex_unit = 0); inline osg::Vec4Array *getTangentArray() { return T_.get(); } inline const osg::Vec4Array *getTangentArray() const { return T_.get(); } @@ -61,70 +61,11 @@ protected: virtual ~TangentSpaceGenerator() {} TangentSpaceGenerator &operator=(const TangentSpaceGenerator &) { return *this; } - // Base class for computing basis vectors - class BasisVectorsComputer : public osg::Referenced - { - public: - explicit BasisVectorsComputer(TangentSpaceGenerator* base) : base_( base ) {} - - virtual void compute(osg::PrimitiveSet *pset, - const osg::Array *vx, - const osg::Array *nx, - const osg::Array *tx, - const osg::IndexArray *vix, - const osg::IndexArray *nix, - const osg::IndexArray *tix, - int iA, int iB, int iC) = 0; - - protected: - virtual ~BasisVectorsComputer() {} - BasisVectorsComputer(const TangentSpaceGenerator ©, const osg::CopyOp ©op); - - TangentSpaceGenerator* base_; - }; - - // Class for computing basis vectors without using indices - class VectorsComputerNoIndices : public BasisVectorsComputer - { - public: - explicit VectorsComputerNoIndices(TangentSpaceGenerator* base) : BasisVectorsComputer( base ) {} - - void compute(osg::PrimitiveSet *pset, - const osg::Array *vx, - const osg::Array *nx, - const osg::Array *tx, - const osg::IndexArray *vix, - const osg::IndexArray *nix, - const osg::IndexArray *tix, - int iA, int iB, int iC); - - protected: - virtual ~VectorsComputerNoIndices() {} - }; - - // Class for computing basis vectors using indices - class VectorsComputerUsingIndices : public BasisVectorsComputer - { - public: - explicit VectorsComputerUsingIndices(TangentSpaceGenerator* base) : BasisVectorsComputer( base ) {} - - void compute(osg::PrimitiveSet *pset, - const osg::Array *vx, - const osg::Array *nx, - const osg::Array *tx, - const osg::IndexArray *vix, - const osg::IndexArray *nix, - const osg::IndexArray *tix, - int iA, int iB, int iC); - - protected: - virtual ~VectorsComputerUsingIndices() {} - }; - - // declare as friends so that may operator on TangentSpaceGenerator protected member variables. - friend class BasisVectorsComputer; - friend class VectorsComputerNoIndices; - friend class VectorsComputerUsingIndices; + void compute(osg::PrimitiveSet *pset, + const osg::Array *vx, + const osg::Array *nx, + const osg::Array *tx, + int iA, int iB, int iC); osg::ref_ptr T_; osg::ref_ptr B_; diff --git a/src/osgFX/BumpMapping.cpp b/src/osgFX/BumpMapping.cpp index 83a8d724e..93d408426 100644 --- a/src/osgFX/BumpMapping.cpp +++ b/src/osgFX/BumpMapping.cpp @@ -589,7 +589,9 @@ bool BumpMapping::define_techniques() void BumpMapping::prepareGeometry(osg::Geometry* geo) { osg::ref_ptr tsg = new osgUtil::TangentSpaceGenerator; + tsg->generate(geo, _normal_unit); + if (!geo->getVertexAttribArray(6)) geo->setVertexAttribData(6, osg::Geometry::ArrayData(tsg->getTangentArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE)); if (!geo->getVertexAttribArray(7)) diff --git a/src/osgUtil/TangentSpaceGenerator.cpp b/src/osgUtil/TangentSpaceGenerator.cpp index 595c2296a..0d4774324 100644 --- a/src/osgUtil/TangentSpaceGenerator.cpp +++ b/src/osgUtil/TangentSpaceGenerator.cpp @@ -21,24 +21,23 @@ TangentSpaceGenerator::TangentSpaceGenerator(const TangentSpaceGenerator ©, { } -void TangentSpaceGenerator::generate(osg::Geometry *geo, int normal_map_tex_unit, bool use_indices) +void TangentSpaceGenerator::generate(osg::Geometry *geo, int normal_map_tex_unit) { + // check to see if vertex attributes indices exists, if so expand them to remove them + if (geo->suitableForOptimization()) + { + // removing coord indices so we don't have to deal with them in the binormal code. + osg::notify(osg::INFO)<<"TangentSpaceGenerator::generate(Geometry*,int): Removing attribute indices"<copyToAndOptimize(*geo); + } + const osg::Array *vx = geo->getVertexArray(); - const osg::IndexArray *vix = geo->getVertexIndices(); - const osg::IndexArray *nix = geo->getNormalIndices(); - const osg::IndexArray *tix = geo->getTexCoordIndices(normal_map_tex_unit); const osg::Array *nx = geo->getNormalArray(); const osg::Array *tx = geo->getTexCoordArray(normal_map_tex_unit); if (!vx || !tx) return; - osg::ref_ptr computer; - if (use_indices) - computer = new VectorsComputerUsingIndices(this); - else - computer = new VectorsComputerNoIndices(this); - unsigned int vertex_count = vx->getNumElements(); if (geo->getVertexIndices() == NULL) { T_->assign(vertex_count, osg::Vec4()); @@ -67,14 +66,14 @@ void TangentSpaceGenerator::generate(osg::Geometry *geo, int normal_map_tex_unit case osg::PrimitiveSet::TRIANGLES: for (i=0; icompute(pset, vx, nx, tx, vix, nix, tix, i, i+1, i+2); + compute(pset, vx, nx, tx, i, i+1, i+2); } break; case osg::PrimitiveSet::QUADS: for (i=0; icompute(pset, vx, nx, tx, vix, nix, tix, i, i+1, i+2); - computer->compute(pset, vx, nx, tx, vix, nix, tix, i+2, i+3, i); + compute(pset, vx, nx, tx, i, i+1, i+2); + compute(pset, vx, nx, tx, i+2, i+3, i); } break; @@ -86,9 +85,9 @@ void TangentSpaceGenerator::generate(osg::Geometry *geo, int normal_map_tex_unit unsigned iN = static_cast(*pi-2); for (i=0; icompute(pset, vx, nx, tx, vix, nix, tix, j, j+1, j+2); + compute(pset, vx, nx, tx, j, j+1, j+2); } else { - computer->compute(pset, vx, nx, tx, vix, nix, tix, j+1, j, j+2); + compute(pset, vx, nx, tx, j+1, j, j+2); } } j += 2; @@ -96,9 +95,9 @@ void TangentSpaceGenerator::generate(osg::Geometry *geo, int normal_map_tex_unit } else { for (i=0; icompute(pset, vx, nx, tx, vix, nix, tix, i, i+1, i+2); + compute(pset, vx, nx, tx, i, i+1, i+2); } else { - computer->compute(pset, vx, nx, tx, vix, nix, tix, i+1, i, i+2); + compute(pset, vx, nx, tx, i+1, i, i+2); } } } @@ -111,13 +110,13 @@ void TangentSpaceGenerator::generate(osg::Geometry *geo, int normal_map_tex_unit for (osg::DrawArrayLengths::const_iterator pi=dal->begin(); pi!=dal->end(); ++pi) { unsigned iN = static_cast(*pi-2); for (i=0; icompute(pset, vx, nx, tx, vix, nix, tix, 0, j+1, j+2); + compute(pset, vx, nx, tx, 0, j+1, j+2); } j += 2; } } else { for (i=0; icompute(pset, vx, nx, tx, vix, nix, tix, 2, i+1, i+2); + compute(pset, vx, nx, tx, 2, i+1, i+2); } } break; @@ -159,15 +158,11 @@ void TangentSpaceGenerator::generate(osg::Geometry *geo, int normal_map_tex_unit * version of each (different indices for each one?) */ } -// Original compute_basis_vectors implementation -void TangentSpaceGenerator::VectorsComputerNoIndices::compute(osg::PrimitiveSet *pset, - const osg::Array* vx, - const osg::Array* nx, - const osg::Array* tx, - const osg::IndexArray* /*vix*/, - const osg::IndexArray* /*nix*/, - const osg::IndexArray* /*tix*/, - int iA, int iB, int iC) +void TangentSpaceGenerator::compute(osg::PrimitiveSet *pset, + const osg::Array* vx, + const osg::Array* nx, + const osg::Array* tx, + int iA, int iB, int iC) { iA = pset->index(iA); iB = pset->index(iB); @@ -315,21 +310,21 @@ void TangentSpaceGenerator::VectorsComputerNoIndices::compute(osg::PrimitiveSet osg::Vec3 tempvec; tempvec = N1 ^ T1; - (*base_->T_)[iA] = osg::Vec4(tempvec ^ N1, 0); + (*T_)[iA] = osg::Vec4(tempvec ^ N1, 0); tempvec = B1 ^ N1; - (*base_->B_)[iA] = osg::Vec4(N1 ^ tempvec, 0); + (*B_)[iA] = osg::Vec4(N1 ^ tempvec, 0); tempvec = N2 ^ T2; - (*base_->T_)[iB] = osg::Vec4(tempvec ^ N2, 0); + (*T_)[iB] = osg::Vec4(tempvec ^ N2, 0); tempvec = B2 ^ N2; - (*base_->B_)[iB] = osg::Vec4(N2 ^ tempvec, 0); + (*B_)[iB] = osg::Vec4(N2 ^ tempvec, 0); tempvec = N3 ^ T3; - (*base_->T_)[iC] = osg::Vec4(tempvec ^ N3, 0); + (*T_)[iC] = osg::Vec4(tempvec ^ N3, 0); tempvec = B3 ^ N3; - (*base_->B_)[iC] = osg::Vec4(N3 ^ tempvec, 0); + (*B_)[iC] = osg::Vec4(N3 ^ tempvec, 0); - (*base_->N_)[iA] += osg::Vec4(N1, 0); - (*base_->N_)[iB] += osg::Vec4(N2, 0); - (*base_->N_)[iC] += osg::Vec4(N3, 0); + (*N_)[iA] += osg::Vec4(N1, 0); + (*N_)[iB] += osg::Vec4(N2, 0); + (*N_)[iC] += osg::Vec4(N3, 0); } else{ osg::Vec3 face_normal = (P2 - P1) ^ (P3 - P1); @@ -340,286 +335,41 @@ void TangentSpaceGenerator::VectorsComputerNoIndices::compute(osg::PrimitiveSet osg::Vec3(P3.x() - P1.x(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); if (V.x() != 0) { V.normalize(); - (*base_->T_)[iA].x() += -V.y() / V.x(); - (*base_->B_)[iA].x() += -V.z() / V.x(); - (*base_->T_)[iB].x() += -V.y() / V.x(); - (*base_->B_)[iB].x() += -V.z() / V.x(); - (*base_->T_)[iC].x() += -V.y() / V.x(); - (*base_->B_)[iC].x() += -V.z() / V.x(); + (*T_)[iA].x() += -V.y() / V.x(); + (*B_)[iA].x() += -V.z() / V.x(); + (*T_)[iB].x() += -V.y() / V.x(); + (*B_)[iB].x() += -V.z() / V.x(); + (*T_)[iC].x() += -V.y() / V.x(); + (*B_)[iC].x() += -V.z() / V.x(); } V = osg::Vec3(P2.y() - P1.y(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ osg::Vec3(P3.y() - P1.y(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); if (V.x() != 0) { V.normalize(); - (*base_->T_)[iA].y() += -V.y() / V.x(); - (*base_->B_)[iA].y() += -V.z() / V.x(); - (*base_->T_)[iB].y() += -V.y() / V.x(); - (*base_->B_)[iB].y() += -V.z() / V.x(); - (*base_->T_)[iC].y() += -V.y() / V.x(); - (*base_->B_)[iC].y() += -V.z() / V.x(); + (*T_)[iA].y() += -V.y() / V.x(); + (*B_)[iA].y() += -V.z() / V.x(); + (*T_)[iB].y() += -V.y() / V.x(); + (*B_)[iB].y() += -V.z() / V.x(); + (*T_)[iC].y() += -V.y() / V.x(); + (*B_)[iC].y() += -V.z() / V.x(); } V = osg::Vec3(P2.z() - P1.z(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ osg::Vec3(P3.z() - P1.z(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); if (V.x() != 0) { V.normalize(); - (*base_->T_)[iA].z() += -V.y() / V.x(); - (*base_->B_)[iA].z() += -V.z() / V.x(); - (*base_->T_)[iB].z() += -V.y() / V.x(); - (*base_->B_)[iB].z() += -V.z() / V.x(); - (*base_->T_)[iC].z() += -V.y() / V.x(); - (*base_->B_)[iC].z() += -V.z() / V.x(); + (*T_)[iA].z() += -V.y() / V.x(); + (*B_)[iA].z() += -V.z() / V.x(); + (*T_)[iB].z() += -V.y() / V.x(); + (*B_)[iB].z() += -V.z() / V.x(); + (*T_)[iC].z() += -V.y() / V.x(); + (*B_)[iC].z() += -V.z() / V.x(); } - (*base_->N_)[iA] += osg::Vec4(face_normal, 0); - (*base_->N_)[iB] += osg::Vec4(face_normal, 0); - (*base_->N_)[iC] += osg::Vec4(face_normal, 0); + (*N_)[iA] += osg::Vec4(face_normal, 0); + (*N_)[iB] += osg::Vec4(face_normal, 0); + (*N_)[iC] += osg::Vec4(face_normal, 0); } } -// This method is the original code of Ruben -void TangentSpaceGenerator::VectorsComputerUsingIndices::compute(osg::PrimitiveSet *pset, - const osg::Array *vx, - const osg::Array *nx, - const osg::Array *tx, - const osg::IndexArray *vix, - const osg::IndexArray *nix, - const osg::IndexArray *tix, - int iA, int iB, int iC) -{ - int v1 = pset->index(iA); - int v2 = pset->index(iB); - int v3 = pset->index(iC); - int viA = v1; - int viB = v2; - int viC = v3; - - if (vix != NULL) { - viA = vix->index(v1); - viB = vix->index(v2); - viC = vix->index(v3); - } - int niA = viA; - int niB = viA; - int niC = viA; - int tiA = viA; - int tiB = viA; - int tiC = viA; - if (nix != NULL) { - niA = nix->index(v1); - niB = nix->index(v2); - niC = nix->index(v3); - } - if (tix != NULL) { - tiA = tix->index(v1); - tiB = tix->index(v2); - tiC = tix->index(v3); - } - - osg::Vec3 P1; - osg::Vec3 P2; - osg::Vec3 P3; - - int i; // VC6 doesn't like for-scoped variables - - switch (vx->getType()) - { - case osg::Array::Vec2ArrayType: - for (i=0; i<2; ++i) { - P1.ptr()[i] = static_cast(*vx)[viA].ptr()[i]; - P2.ptr()[i] = static_cast(*vx)[viB].ptr()[i]; - P3.ptr()[i] = static_cast(*vx)[viC].ptr()[i]; - } - break; - - case osg::Array::Vec3ArrayType: - P1 = static_cast(*vx)[viA]; - P2 = static_cast(*vx)[viB]; - P3 = static_cast(*vx)[viC]; - break; - - case osg::Array::Vec4ArrayType: - for (i=0; i<3; ++i) { - P1.ptr()[i] = static_cast(*vx)[viA].ptr()[i]; - P2.ptr()[i] = static_cast(*vx)[viB].ptr()[i]; - P3.ptr()[i] = static_cast(*vx)[viC].ptr()[i]; - } - break; - - default: - osg::notify(osg::WARN) << "Warning: TangentSpaceGenerator: vertex array must be Vec2Array, Vec3Array or Vec4Array" << std::endl; - } - - osg::Vec3 N1; - osg::Vec3 N2; - osg::Vec3 N3; - - if(nx) - { - switch (nx->getType()) - { - case osg::Array::Vec2ArrayType: - for (i=0; i<2; ++i) { - N1.ptr()[i] = static_cast(*nx)[niA].ptr()[i]; - N2.ptr()[i] = static_cast(*nx)[niB].ptr()[i]; - N3.ptr()[i] = static_cast(*nx)[niC].ptr()[i]; - } - break; - - case osg::Array::Vec3ArrayType: - N1 = static_cast(*nx)[niA]; - N2 = static_cast(*nx)[niB]; - N3 = static_cast(*nx)[niC]; - break; - - case osg::Array::Vec4ArrayType: - for (i=0; i<3; ++i) { - N1.ptr()[i] = static_cast(*nx)[niA].ptr()[i]; - N2.ptr()[i] = static_cast(*nx)[niB].ptr()[i]; - N3.ptr()[i] = static_cast(*nx)[niC].ptr()[i]; - } - break; - - default: - osg::notify(osg::WARN) << "Warning: TangentSpaceGenerator: normal array must be Vec2Array, Vec3Array or Vec4Array" << std::endl; - } - } - - osg::Vec2 uv1; - osg::Vec2 uv2; - osg::Vec2 uv3; - - switch (tx->getType()) - { - case osg::Array::Vec2ArrayType: - uv1 = static_cast(*tx)[tiA]; - uv2 = static_cast(*tx)[tiB]; - uv3 = static_cast(*tx)[tiC]; - break; - - case osg::Array::Vec3ArrayType: - for (i=0; i<2; ++i) { - uv1.ptr()[i] = static_cast(*tx)[tiA].ptr()[i]; - uv2.ptr()[i] = static_cast(*tx)[tiB].ptr()[i]; - uv3.ptr()[i] = static_cast(*tx)[tiC].ptr()[i]; - } - break; - - case osg::Array::Vec4ArrayType: - for (i=0; i<2; ++i) { - uv1.ptr()[i] = static_cast(*tx)[tiA].ptr()[i]; - uv2.ptr()[i] = static_cast(*tx)[tiB].ptr()[i]; - uv3.ptr()[i] = static_cast(*tx)[tiC].ptr()[i]; - } - break; - - default: - osg::notify(osg::WARN) << "Warning: TangentSpaceGenerator::compute_basis_vectors(,,,) texture coord array must be Vec2Array, Vec3Array or Vec4Array" << std::endl; - } - - if (nx) - { - osg::Vec3 V, T1, T2, T3, B1, B2, B3; - - V = osg::Vec3(P2.x() - P1.x(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ - osg::Vec3(P3.x() - P1.x(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); - if (V.x() != 0) { - V.normalize(); - T1.x() = -V.y() / V.x(); - B1.x() = -V.z() / V.x(); - T2.x() = -V.y() / V.x(); - B2.x() = -V.z() / V.x(); - T3.x() = -V.y() / V.x(); - B3.x() = -V.z() / V.x(); - } else { - osg::notify(osg::NOTICE)<<"Bu!" << uv1 << " || " << uv2 << " || " << uv3 << std::endl; - } - - V = osg::Vec3(P2.y() - P1.y(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ - osg::Vec3(P3.y() - P1.y(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); - if (V.x() != 0) { - V.normalize(); - T1.y() = -V.y() / V.x(); - B1.y() = -V.z() / V.x(); - T2.y() = -V.y() / V.x(); - B2.y() = -V.z() / V.x(); - T3.y() = -V.y() / V.x(); - B3.y() = -V.z() / V.x(); - } - - V = osg::Vec3(P2.z() - P1.z(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ - osg::Vec3(P3.z() - P1.z(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); - if (V.x() != 0) { - V.normalize(); - T1.z() = -V.y() / V.x(); - B1.z() = -V.z() / V.x(); - T2.z() = -V.y() / V.x(); - B2.z() = -V.z() / V.x(); - T3.z() = -V.y() / V.x(); - B3.z() = -V.z() / V.x(); - } - - (*base_->T_)[v1] = osg::Vec4(T1, 0); - (*base_->B_)[v1] = osg::Vec4(B1, 0); - (*base_->T_)[v2] = osg::Vec4(T2, 0); - (*base_->B_)[v2] = osg::Vec4(B2, 0); - (*base_->T_)[v3] = osg::Vec4(T3, 0); - (*base_->B_)[v3] = osg::Vec4(B3, 0); - - (*base_->N_)[v1] += osg::Vec4(N1, 0); - (*base_->N_)[v2] += osg::Vec4(N2, 0); - (*base_->N_)[v3] += osg::Vec4(N3, 0); - - } - else{ - osg::Vec3 face_normal = (P2 - P1) ^ (P3 - P1); - - osg::Vec3 V; - - V = osg::Vec3(P2.x() - P1.x(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ - osg::Vec3(P3.x() - P1.x(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); - if (V.x() != 0) { - V.normalize(); - (*base_->T_)[v1].x() += -V.y() / V.x(); - (*base_->B_)[v1].x() += -V.z() / V.x(); - (*base_->T_)[v2].x() += -V.y() / V.x(); - (*base_->B_)[v2].x() += -V.z() / V.x(); - (*base_->T_)[v3].x() += -V.y() / V.x(); - (*base_->B_)[v3].x() += -V.z() / V.x(); - } - - V = osg::Vec3(P2.y() - P1.y(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ - osg::Vec3(P3.y() - P1.y(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); - if (V.x() != 0) { - V.normalize(); - (*base_->T_)[v1].y() += -V.y() / V.x(); - (*base_->B_)[v1].y() += -V.z() / V.x(); - (*base_->T_)[v2].y() += -V.y() / V.x(); - (*base_->B_)[v2].y() += -V.z() / V.x(); - (*base_->T_)[v3].y() += -V.y() / V.x(); - (*base_->B_)[v3].y() += -V.z() / V.x(); - } - - V = osg::Vec3(P2.z() - P1.z(), uv2.x() - uv1.x(), uv2.y() - uv1.y()) ^ - osg::Vec3(P3.z() - P1.z(), uv3.x() - uv1.x(), uv3.y() - uv1.y()); - if (V.x() != 0) { - V.normalize(); - (*base_->T_)[v1].z() += -V.y() / V.x(); - (*base_->B_)[v1].z() += -V.z() / V.x(); - (*base_->T_)[v2].z() += -V.y() / V.x(); - (*base_->B_)[v2].z() += -V.z() / V.x(); - (*base_->T_)[v3].z() += -V.y() / V.x(); - (*base_->B_)[v3].z() += -V.z() / V.x(); - } - - (*base_->N_)[v1] += osg::Vec4(face_normal, 0); - (*base_->N_)[v2] += osg::Vec4(face_normal, 0); - (*base_->N_)[v3] += osg::Vec4(face_normal, 0); - } - if ( (*base_->B_)[v1].length() == 0 || (*base_->B_)[v2].length() == 0 || (*base_->B_)[v3].length() == 0) { - osg::notify(osg::WARN) << "WARNING: zero binormal/s!" << std::endl; - osg::notify(osg::WARN) << " " << P1 << "|" << P2 << "|" << P3 << std::endl; - osg::notify(osg::WARN) << " " << iA << "|" << iB << "|" << iC << std::endl; - } -} diff --git a/src/osgWrappers/osgUtil/TangentSpaceGenerator.cpp b/src/osgWrappers/osgUtil/TangentSpaceGenerator.cpp index 0b7d31e87..b05bf4891 100644 --- a/src/osgWrappers/osgUtil/TangentSpaceGenerator.cpp +++ b/src/osgWrappers/osgUtil/TangentSpaceGenerator.cpp @@ -26,7 +26,7 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::TangentSpaceGenerator) I_BaseType(osg::Referenced); I_Constructor0(); I_ConstructorWithDefaults2(IN, const osgUtil::TangentSpaceGenerator &, copy, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY); - I_MethodWithDefaults3(void, generate, IN, osg::Geometry *, geo, , IN, int, normal_map_tex_unit, 0, IN, bool, use_indices, false); + I_MethodWithDefaults2(void, generate, IN, osg::Geometry *, geo, , IN, int, normal_map_tex_unit, 0); I_Method0(osg::Vec4Array *, getTangentArray); I_Method0(const osg::Vec4Array *, getTangentArray); I_Method1(void, setTangentArray, IN, osg::Vec4Array *, array);