Simplified the TangentSpaceGenerator so that is automatically converts any models

with indices to one without indices and then runs the tangent space generation code on the result.
This commit is contained in:
Robert Osfield
2005-11-22 21:14:26 +00:00
parent 48a8f14ae7
commit f78a37be9c
4 changed files with 62 additions and 369 deletions

View File

@@ -40,7 +40,7 @@ public:
TangentSpaceGenerator();
TangentSpaceGenerator(const TangentSpaceGenerator &copy, const osg::CopyOp &copyop = 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 &copy, const osg::CopyOp &copyop);
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<osg::Vec4Array> T_;
osg::ref_ptr<osg::Vec4Array> B_;

View File

@@ -589,7 +589,9 @@ bool BumpMapping::define_techniques()
void BumpMapping::prepareGeometry(osg::Geometry* geo)
{
osg::ref_ptr<osgUtil::TangentSpaceGenerator> 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))

View File

@@ -21,24 +21,23 @@ TangentSpaceGenerator::TangentSpaceGenerator(const TangentSpaceGenerator &copy,
{
}
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"<<std::endl;
geo->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<BasisVectorsComputer> 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; i<N; i+=3) {
computer->compute(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; i<N; i+=4) {
computer->compute(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<unsigned>(*pi-2);
for (i=0; i<iN; ++i, ++j) {
if ((i%2) == 0) {
computer->compute(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; i<N-2; ++i) {
if ((i%2) == 0) {
computer->compute(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<unsigned>(*pi-2);
for (i=0; i<iN; ++i) {
computer->compute(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; i<N-2; ++i) {
computer->compute(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<const osg::Vec2Array&>(*vx)[viA].ptr()[i];
P2.ptr()[i] = static_cast<const osg::Vec2Array&>(*vx)[viB].ptr()[i];
P3.ptr()[i] = static_cast<const osg::Vec2Array&>(*vx)[viC].ptr()[i];
}
break;
case osg::Array::Vec3ArrayType:
P1 = static_cast<const osg::Vec3Array&>(*vx)[viA];
P2 = static_cast<const osg::Vec3Array&>(*vx)[viB];
P3 = static_cast<const osg::Vec3Array&>(*vx)[viC];
break;
case osg::Array::Vec4ArrayType:
for (i=0; i<3; ++i) {
P1.ptr()[i] = static_cast<const osg::Vec4Array&>(*vx)[viA].ptr()[i];
P2.ptr()[i] = static_cast<const osg::Vec4Array&>(*vx)[viB].ptr()[i];
P3.ptr()[i] = static_cast<const osg::Vec4Array&>(*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<const osg::Vec2Array&>(*nx)[niA].ptr()[i];
N2.ptr()[i] = static_cast<const osg::Vec2Array&>(*nx)[niB].ptr()[i];
N3.ptr()[i] = static_cast<const osg::Vec2Array&>(*nx)[niC].ptr()[i];
}
break;
case osg::Array::Vec3ArrayType:
N1 = static_cast<const osg::Vec3Array&>(*nx)[niA];
N2 = static_cast<const osg::Vec3Array&>(*nx)[niB];
N3 = static_cast<const osg::Vec3Array&>(*nx)[niC];
break;
case osg::Array::Vec4ArrayType:
for (i=0; i<3; ++i) {
N1.ptr()[i] = static_cast<const osg::Vec4Array&>(*nx)[niA].ptr()[i];
N2.ptr()[i] = static_cast<const osg::Vec4Array&>(*nx)[niB].ptr()[i];
N3.ptr()[i] = static_cast<const osg::Vec4Array&>(*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<const osg::Vec2Array&>(*tx)[tiA];
uv2 = static_cast<const osg::Vec2Array&>(*tx)[tiB];
uv3 = static_cast<const osg::Vec2Array&>(*tx)[tiC];
break;
case osg::Array::Vec3ArrayType:
for (i=0; i<2; ++i) {
uv1.ptr()[i] = static_cast<const osg::Vec3Array&>(*tx)[tiA].ptr()[i];
uv2.ptr()[i] = static_cast<const osg::Vec3Array&>(*tx)[tiB].ptr()[i];
uv3.ptr()[i] = static_cast<const osg::Vec3Array&>(*tx)[tiC].ptr()[i];
}
break;
case osg::Array::Vec4ArrayType:
for (i=0; i<2; ++i) {
uv1.ptr()[i] = static_cast<const osg::Vec4Array&>(*tx)[tiA].ptr()[i];
uv2.ptr()[i] = static_cast<const osg::Vec4Array&>(*tx)[tiB].ptr()[i];
uv3.ptr()[i] = static_cast<const osg::Vec4Array&>(*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;
}
}

View File

@@ -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);