diff --git a/Metrowerks/Metrowerks.mcp b/Metrowerks/Metrowerks.mcp new file mode 100644 index 000000000..eff0ddd6e Binary files /dev/null and b/Metrowerks/Metrowerks.mcp differ diff --git a/doc/doc++/osg/MatrixProduct.html b/doc/doc++/osg/MatrixProduct.html new file mode 100644 index 000000000..711d0f320 --- /dev/null +++ b/doc/doc++/osg/MatrixProduct.html @@ -0,0 +1,51 @@ + + + + + class osg::Matrix::MatrixProduct + + + + +

class MatrixProduct


+ +
+

+

Public Fields

+[more]const Matrix& A +
+[more]const Matrix& B +

+ +

+

Public Methods

+[more] MatrixProduct( const Matrix& lhs, const Matrix& rhs ) +

+ +
+ + +
+

Documentation

+
+ + + +
oconst Matrix& A +

+ + +

oconst Matrix& B +

+ + +

o MatrixProduct( const Matrix& lhs, const Matrix& rhs ) +

+ +
This class has no child classes.
+ +

Alphabetic index HTML hierarchy of classes or Java


+
+This page was generated with the help of DOC++. + + diff --git a/doc/doc++/osg/NodeCallback.html b/doc/doc++/osg/NodeCallback.html new file mode 100644 index 000000000..a5bb99de5 --- /dev/null +++ b/doc/doc++/osg/NodeCallback.html @@ -0,0 +1,137 @@ + + + + + class SG_EXPORT osg::NodeCallback + + + + +

class SG_EXPORT osg::NodeCallback


+ +

Inheritance:

+ + + + + + + +
+ +
+

+

Public Fields

+[more]Requirements _requirements +

+ +

+

Public Methods

+[more] NodeCallback(const Requirements ncr=NO_REQUIREMENTS) +
+[more]virtual ~NodeCallback() +
+[more]inline void setRequirements(const Requirements ncr) +
Set what values from traversal are required by this NodeCallback +
+[more]inline const Requirements getRequirements() const +
Get what values from traversal are required by this NodeCallback +
+[more]virtual void operator()(Node*, NodeVisitor*) +
Callback method call by the NodeVisitor when visiting a node +

+ +

+

Public Members

+[more]enum Requirements +
The range of values which can be accumulated by the NodeVisitor. +

+ +
+

Inherited from Referenced:

+
+

+

Public Methods

+oinline Referenced& operator = (Referenced&) +
+oinline void ref() const +
+oinline void unref() const +
+oinline const int referenceCount() const +

+ +

+

Protected Fields

+omutable int _refCount +

+ +
+ + +
+

Documentation

+
+ + + +
oenum Requirements +
The range of values which can be accumulated by the NodeVisitor. +

+ + + +
o NO_REQUIREMENTS +

+ + +

o REQUIRES_TRAVERSAL +

+ + +

o REQUIRES_PARENT_PATH +

+ + +

o REQUIRES_ACCUMULATED_MATRIX +

+ + +

o REQUIRES_ACCUMULATED_INVERSE +

+ + + +
o NodeCallback(const Requirements ncr=NO_REQUIREMENTS) +

+ + +

ovirtual ~NodeCallback() +

+ + +

oinline void setRequirements(const Requirements ncr) +
Set what values from traversal are required by this NodeCallback +

+ + +

oinline const Requirements getRequirements() const +
Get what values from traversal are required by this NodeCallback +

+ + +

ovirtual void operator()(Node*, NodeVisitor*) +
Callback method call by the NodeVisitor when visiting a node +

+ + +

oRequirements _requirements +

+ +
This class has no child classes.
+ +

Alphabetic index HTML hierarchy of classes or Java


+
+This page was generated with the help of DOC++. + + diff --git a/doc/doc++/osg/Viewport.html b/doc/doc++/osg/Viewport.html new file mode 100644 index 000000000..ed736af69 --- /dev/null +++ b/doc/doc++/osg/Viewport.html @@ -0,0 +1,203 @@ + + + + + class SG_EXPORT osg::Viewport + + + + +

class SG_EXPORT osg::Viewport

Encapsulte OpenGL glViewport
+
+ +

Inheritance:

+ + + + + + + +
+ +
+

+

Public Methods

+[more] Viewport() +
+[more]virtual bool isSameKindAs(const Object* obj) const +
+[more]virtual Object* clone() const +
+[more]virtual const char* className() const +
+[more]virtual const Type getType() const +
+[more]inline void setViewport(const int x, const int y, const int width, const int height) +
+[more]void getViewport(int& x, int& y, int& width, int& height) +
+[more]inline const int x() const +
+[more]inline const int y() const +
+[more]inline const int width() const +
+[more]inline const int height() const +
+[more]inline const float aspectRatio() const +
return the aspcetRatio of the viewport, which is equal to width/height +
+[more]virtual void apply(State& state) const +

+ +

+

Protected Fields

+[more]int _x +
+[more]int _y +
+[more]int _width +
+[more]int _height +

+ +

+

Protected Methods

+[more]virtual ~Viewport() +

+ +
+

Inherited from StateAttribute:

+
+

+

Public Methods

+ovirtual void setStateSetModes(StateSet&, const GLModeValue) const +
+ovirtual void compile(State&) const +

+ +

+

Public Members

+otypedef GLenum GLMode +
+otypedef unsigned int GLModeValue +
+otypedef unsigned int OverrideValue +
+oenum Values +
+oenum Type +

+ +
+

Inherited from Object:

+
+
+

Inherited from Referenced:

+
+

+

Public Methods

+oinline Referenced& operator = (Referenced&) +
+oinline void ref() const +
+oinline void unref() const +
+oinline const int referenceCount() const +

+ +

+

Protected Fields

+omutable int _refCount +

+ +
+ + +
+

Documentation

+
Encapsulte OpenGL glViewport
+
+ + + +
o Viewport() +

+ + +

ovirtual bool isSameKindAs(const Object* obj) const +

+ + +

ovirtual Object* clone() const +

+ + +

ovirtual const char* className() const +

+ + +

ovirtual const Type getType() const +

+ + +

oinline void setViewport(const int x, const int y, const int width, const int height) +

+ + +

ovoid getViewport(int& x, int& y, int& width, int& height) +

+ + +

oinline const int x() const +

+ + +

oinline const int y() const +

+ + +

oinline const int width() const +

+ + +

oinline const int height() const +

+ + +

oinline const float aspectRatio() const +
return the aspcetRatio of the viewport, which is equal to width/height +

+ + +

ovirtual void apply(State& state) const +

+ + +

ovirtual ~Viewport() +

+ + +

oint _x +

+ + +

oint _y +

+ + +

oint _width +

+ + +

oint _height +

+ +
This class has no child classes.
+ +

Alphabetic index HTML hierarchy of classes or Java


+
+This page was generated with the help of DOC++. + + diff --git a/doc/doc++/osgUtil/AppVisitor.html b/doc/doc++/osgUtil/AppVisitor.html new file mode 100644 index 000000000..d001f5c94 --- /dev/null +++ b/doc/doc++/osgUtil/AppVisitor.html @@ -0,0 +1,142 @@ + + + + + class OSGUTIL_EXPORT osgUtil::AppVisitor + + + + +

class OSGUTIL_EXPORT osgUtil::AppVisitor

Basic AppVisitor implementation for animating a scene.
+
+ +

Inheritance:

+ + + + + + + +
+ +
+

+

Public Methods

+[more] AppVisitor() +
+[more]virtual ~AppVisitor() +
+[more]virtual void reset() +
+[more]virtual void apply(osg::Node& node) +
+[more]virtual void apply(osg::Geode& node) +
+[more]virtual void apply(osg::Billboard& node) +
+[more]virtual void apply(osg::LightSource& node) +
+[more]virtual void apply(osg::Group& node) +
+[more]virtual void apply(osg::Transform& node) +
+[more]virtual void apply(osg::Switch& node) +
+[more]virtual void apply(osg::LOD& node) +
+[more]virtual void apply(osg::Impostor& node) +

+ +

+

Protected Methods

+[more] AppVisitor(const AppVisitor&) +
prevent unwanted copy construction +
+[more]AppVisitor& operator = (const AppVisitor&) +
prevent unwanted copy operator +
+[more]inline void handle_callbacks(osg::Node& node) +

+ +
+ + +
+

Documentation

+
+Basic AppVisitor implementation for animating a scene. +This visitor traverses the scene graph, call each nodes appCallback if +it exists.
+
+ + + +
o AppVisitor() +

+ + +

ovirtual ~AppVisitor() +

+ + +

ovirtual void reset() +

+ + +

ovirtual void apply(osg::Node& node) +

+ + +

ovirtual void apply(osg::Geode& node) +

+ + +

ovirtual void apply(osg::Billboard& node) +

+ + +

ovirtual void apply(osg::LightSource& node) +

+ + +

ovirtual void apply(osg::Group& node) +

+ + +

ovirtual void apply(osg::Transform& node) +

+ + +

ovirtual void apply(osg::Switch& node) +

+ + +

ovirtual void apply(osg::LOD& node) +

+ + +

ovirtual void apply(osg::Impostor& node) +

+ + +

o AppVisitor(const AppVisitor&) +
prevent unwanted copy construction +

+ + +

oAppVisitor& operator = (const AppVisitor&) +
prevent unwanted copy operator +

+ + +

oinline void handle_callbacks(osg::Node& node) +

+ +
This class has no child classes.
+ +

Alphabetic index HTML hierarchy of classes or Java


+
+This page was generated with the help of DOC++. + + diff --git a/include/osg/Matrix.new b/include/osg/Matrix.new new file mode 100644 index 000000000..e05ddcc65 --- /dev/null +++ b/include/osg/Matrix.new @@ -0,0 +1,224 @@ + +#ifndef OSG_Matrix +#define OSG_Matrix 1 + +#include +#include +#include +//#include + +#ifdef OSG_USE_IO_DOT_H +#include +#else +#include +using namespace std; +#endif + +#define METAOBJ(name) \ + virtual Object* clone() const { return new name (); } \ + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } \ + virtual const char* className() const { return #name; } + +namespace osg { + +class Quat; + +class SG_EXPORT Matrix : public Object +{ +// private: + public: + float _mat[4][4]; + bool fully_realized; + + public: +// const char* name() { return "My Matrix "; } + METAOBJ(Matrix) + + Matrix(); + Matrix( const Matrix& other ); + explicit Matrix( float const * const def ); + Matrix( float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33); + + virtual ~Matrix() {} + + Matrix& operator = (const Matrix& ); + + inline float& operator()(int col, int row) { return _mat[col][row]; } + inline float operator()(int col, int row) const { return _mat[col][row]; } + + void set( float const * const ); + void set( float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33); + const float * values() { return (const float *)_mat; } + + void makeIdent(); + void makeScale( const Vec3& ); + void makeScale( float, float, float ); + + void makeTrans( const Vec3& ); + void makeTrans( float, float, float ); + //TODO: original preTrans was optimized (M=Tr*M) + // but also has the assumption that M (this) is an affine transformation Matrix + // can I still do something to optimize the same case now? + + void makeRot( const Vec3& from, const Vec3& to ); + void makeRot( float angle, const Vec3& orientation ); + void makeRot( float angle, float x, float y, float z ); + void makeRot( const Quat& ); + void makeRot( float, float, float ); //Euler angles + + bool invert( const Matrix& ); + bool invertAffine( const Matrix& ); + + //basic utility functions to create new matrices or vectors + static Matrix scale( const Vec3& ); + static Matrix scale( float, float, float ); + static Matrix trans( const Vec3& ); + static Matrix trans( float, float, float ); + static Matrix rotate( const Vec3&, const Vec3& ); + static Matrix rotate( float, float, float, float ); + static Matrix rotate( const Quat& ); + + inline Vec3 preMult( const Vec3& v ) const; + inline Vec3 postMult( const Vec3& v ) const; + inline Vec3 operator* ( const Vec3& v ) const; + inline Vec4 preMult( const Vec4& v ) const; + inline Vec4 postMult( const Vec4& v ) const; + inline Vec4 operator* ( const Vec4& v ) const; + +//start of Deprecated methods + + void copy( const Matrix& ); + void preScale( float sx, float sy, float sz, const Matrix& m ); + void postScale( const Matrix& m, float sx, float sy, float sz ); + void preScale( float sx, float sy, float sz ); + void postScale( float sx, float sy, float sz ); + + void preTrans( float tx, float ty, float tz, const Matrix& m ); + void postTrans( const Matrix& m, float tx, float ty, float tz ); + void preTrans( float tx, float ty, float tz); + void postTrans( float tx, float ty, float tz ); + + void preRot( float deg, float x, float y, float z, const Matrix& m ); + void postRot( const Matrix& m, float deg, float x, float y, float z ); + void preRot( float deg, float x, float y, float z ); + void postRot( float deg, float x, float y, float z ); + + /** apply apply an 3x3 transform of v*M[0..2,0..2] */ + inline static Vec3 transform3x3(const Vec3& v,const Matrix& m); + /** apply apply an 3x3 transform of M[0..2,0..2]*v */ + inline static Vec3 transform3x3(const Matrix& m,const Vec3& v); + +//end of Deprecated methods + + + // basic matrix multiplication, our workhorse methods. + void mult( const Matrix&, const Matrix& ); + void preMult( const Matrix& ); + void postMult( const Matrix& ); + + // Helper class to optimize product expressions somewhat + class MatrixProduct { + public: + const Matrix& A; + const Matrix& B; + + MatrixProduct( const Matrix& lhs, const Matrix& rhs ) : A(lhs), B(rhs) {} + }; + + inline MatrixProduct operator * ( const Matrix& other ) const + { return MatrixProduct(*this, other); } + + inline void operator *= ( const Matrix& other ) + { if( this == &other ) { + Matrix temp(other); + postMult( temp ); + } + else postMult( other ); + } + inline void operator = ( const MatrixProduct& p ) + { + if( this == &(p.A)) postMult(p.B); + else if( this == &(p.B)) preMult(p.A); + else mult( p.A, p.B ); + } + + Matrix( const MatrixProduct& p ) //allows implicit evaluation of the product + { mult( p.A, p.B ); } +}; + +inline Vec3 Matrix::postMult ( const Vec3& v ) const { + float d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ; + return Vec3( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d, + (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d, + (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ; +} + +inline Vec3 Matrix::preMult (const Vec3& v ) const { + float d = 1.0f/(_mat[0][3]*v.x()+_mat[1][3]*v.y()+_mat[2][3]*v.z()+_mat[3][3]) ; + return Vec3( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0])*d, + (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1])*d, + (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2])*d); +} +inline Vec3 Matrix::operator* (const Vec3& v) const { + return postMult(v); +} +inline Vec3 operator* (const Vec3& v, const Matrix& m ) { + return m.preMult(v); +} +inline Vec4 Matrix::postMult(const Vec4& v) const { + return Vec4( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()), + (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()), + (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()), + (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ; +} +/* +inline Vec4 Matrix::preMult(const Vec4& v,const Matrix& m) { + return Vec4( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z() + m._mat[3][0]*v.w()), + (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z() + m._mat[3][1]*v.w()), + (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z() + m._mat[3][2]*v.w()), + (m._mat[0][3]*v.x() + m._mat[1][3]*v.y() + m._mat[2][3]*v.z() + m._mat[3][3]*v.w())); +} +*/ +inline Vec4 Matrix::operator* (const Vec4& v) const { + return postMult(v); +} +inline Vec4 operator* (const Vec4& v, const Matrix& m ) { + return m.preMult(v); +} + +inline Vec3 Matrix::transform3x3(const Vec3& v,const Matrix& m) +{ + return Vec3( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()), + (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()), + (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z())); +} + +inline Vec3 Matrix::transform3x3(const Matrix& m,const Vec3& v) +{ + return Vec3( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()), + (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()), + (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ; +} + +inline ostream& operator<< (ostream& os, const Matrix& m ) { + os << "{"; + for(int row=0; row<4; ++row) { + os << "\t"; + for(int col=0; col<4; ++col) + os << m(col,row) << " "; + os << endl; + } + os << "}" << endl; + return os; +} + +}; //namespace osg + + +#endif diff --git a/include/osg/Matrix.old b/include/osg/Matrix.old new file mode 100644 index 000000000..0455d431d --- /dev/null +++ b/include/osg/Matrix.old @@ -0,0 +1,184 @@ +#ifndef OSG_MATRIX +#define OSG_MATRIX 1 + +#include +#include +#include + +#ifdef OSG_USE_IO_DOT_H +#include +#else +#include +using namespace std; +#endif + +namespace osg { + +/** 4x4 Matrix for storage & manipulation of transformations in scene graph. + Provides basic maths operations, IO and via osg::Object reference counting. + You can directly load the matrix with OpenGL's LoadMatrixf() function via + the public member _mat as the matrix is stored in the OpenGL format. + Caution: The disadvantage of this feature is, that the matrix access is + 'transposed' if you compare it with the standard C/C++ 2d-array-access + convention . I.e. _mat[i][j] accesses the ith column of the jth row in the + 4x4 matrix. +*/ + +class SG_EXPORT Matrix : public Object +{ + public: + Matrix(); + Matrix(const Matrix& matrix); + Matrix( float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33); + + Matrix& operator = (const Matrix& matrix); + + virtual ~Matrix(); + + virtual Object* clone() const { return new Matrix(); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "Matrix"; } + + void makeIdent(); + + void set(const float* m); + + void set( float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33); + + void copy(const Matrix& matrix); + + void makeScale(float sx, float sy, float sz); + void preScale( float sx, float sy, float sz, const Matrix& m ); + void postScale( const Matrix& m, float sx, float sy, float sz ); + + void preScale( float sx, float sy, float sz ); + void postScale( float sx, float sy, float sz ); + + + void makeTrans( float tx, float ty, float tz ); + void preTrans( float tx, float ty, float tz, const Matrix& m ); + void postTrans( const Matrix& m, float tx, float ty, float tz ); + + void preTrans( float tx, float ty, float tz ); + void postTrans( float tx, float ty, float tz ); + + + /** + * Calc the rotation matrix which aligns vector \a old_vec with + * vector \a new_vec. Both \a old_vec and \a new_vec must have + * length 1.0. + */ + void makeRot( const Vec3& old_vec, const Vec3& new_vec ); + + void makeRot( float deg, float x, float y, float z ); + void preRot( float deg, float x, float y, float z, const Matrix& m ); + void postRot( const Matrix& m, float deg, float x, float y, float z ); + + void preRot( float deg, float x, float y, float z ); + void postRot( float deg, float x, float y, float z ); + + void setTrans( float tx, float ty, float tz ); + void setTrans( const Vec3& v ); + Vec3 getTrans() const { return Vec3(_mat[3][0],_mat[3][1],_mat[3][2]); } + + void preMult(const Matrix& m); + void postMult(const Matrix& m); + void mult(const Matrix& lhs,const Matrix& rhs); + + Matrix operator * (const Matrix& m) const; + + /** apply apply an 3x3 transform of v*M[0..2,0..2] */ + inline static Vec3 transform3x3(const Vec3& v,const Matrix& m); + /** apply apply an 3x3 transform of M[0..2,0..2]*v */ + inline static Vec3 transform3x3(const Matrix& m,const Vec3& v); + + /** post multipy v. ie. (m*v) */ + inline Vec3 operator * (const Vec3& v) const; + + /** pre multipy v. ie. (v*m) */ + friend inline Vec3 operator * (const Vec3& v,const Matrix& m); + + /** post multipy v. ie. (m*v) */ + inline Vec4 operator * (const Vec4& v) const; + + /** pre multipy v. ie. (v*m) */ + friend inline Vec4 operator * (const Vec4& v,const Matrix& m); + + friend inline ostream& operator << (ostream& output, const Matrix& matrix); + + bool invert(const Matrix& m); + + public : + float _mat[4][4]; + + protected: +}; + +inline Vec3 Matrix::operator * (const Vec3& v) const +{ + float d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ; + return Vec3( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d, + (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d, + (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ; +} + + +inline Vec3 operator * (const Vec3& v,const Matrix& m) +{ + float d = 1.0f/(m._mat[0][3]*v.x()+m._mat[1][3]*v.y()+m._mat[2][3]*v.z()+m._mat[3][3]) ; + return Vec3( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z() + m._mat[3][0])*d, + (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z() + m._mat[3][1])*d, + (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z() + m._mat[3][2])*d); +} + +inline Vec4 Matrix::operator * (const Vec4& v) const +{ + return Vec4( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()), + (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()), + (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()), + (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ; +} + + +inline Vec4 operator * (const Vec4& v,const Matrix& m) +{ + return Vec4( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z() + m._mat[3][0]*v.w()), + (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z() + m._mat[3][1]*v.w()), + (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z() + m._mat[3][2]*v.w()), + (m._mat[0][3]*v.x() + m._mat[1][3]*v.y() + m._mat[2][3]*v.z() + m._mat[3][3]*v.w())); +} + +inline Vec3 Matrix::transform3x3(const Vec3& v,const Matrix& m) +{ + return Vec3( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()), + (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()), + (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z())); +} + +inline Vec3 Matrix::transform3x3(const Matrix& m,const Vec3& v) +{ + return Vec3( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()), + (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()), + (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ; +} + +inline ostream& operator << (ostream& output, const Matrix& matrix) +{ + output << "{"< + +namespace osg { + +class Node; +class NodeVisitor; + +class SG_EXPORT NodeCallback : public Referenced { + + public : + + /** The range of values which can be accumulated by the NodeVisitor. */ + enum Requirements + { + NO_REQUIREMENTS = 0x0, + REQUIRES_TRAVERSAL = 0x1, + REQUIRES_PARENT_PATH = 0x2, + REQUIRES_ACCUMULATED_MATRIX = 0x4, + REQUIRES_ACCUMULATED_INVERSE = 0x8, + }; + + NodeCallback(const Requirements ncr=NO_REQUIREMENTS):_requirements(ncr) {} + virtual ~NodeCallback() {} + + + /** Set what values from traversal are required by this NodeCallback.*/ + inline void setRequirements(const Requirements ncr) { _requirements=ncr; } + + /** Get what values from traversal are required by this NodeCallback.*/ + inline const Requirements getRequirements() const { return _requirements; } + + /** Callback method call by the NodeVisitor when visiting a node.*/ + virtual void operator()(Node*, NodeVisitor*) {} + + public: + + Requirements _requirements; +}; + +}; // namespace + +#endif + diff --git a/include/osg/Viewport b/include/osg/Viewport new file mode 100644 index 000000000..12a6dd953 --- /dev/null +++ b/include/osg/Viewport @@ -0,0 +1,63 @@ +#ifndef OSG_VIEWPORT +#define OSG_VIEWPORT 1 + +#include +#include +#include + +namespace osg { + +/** Encapsulte OpenGL glViewport. +*/ +class SG_EXPORT Viewport : public StateAttribute +{ + public : + + + Viewport(); + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=0L; } + virtual Object* clone() const { return new Viewport(); } + virtual const char* className() const { return "Viewport"; } + + virtual const Type getType() const { return VIEWPORT; } + + inline void setViewport(const int x,const int y,const int width,const int height) + { + _x = x; + _y = y; + _width = width; + _height = height; + } + + void getViewport(int& x,int& y,int& width,int& height) + { + x = _x; + y = _y; + width = _width; + height = _height; + } + + inline const int x() const { return _x; } + inline const int y() const { return _y; } + inline const int width() const { return _width; } + inline const int height() const { return _height; } + + /** return the aspcetRatio of the viewport, which is equal to width/height.*/ + inline const float aspectRatio() const { return (float)_width/(float)_height; } + + virtual void apply(State& state) const; + + protected: + + virtual ~Viewport(); + + int _x; + int _y; + int _width; + int _height; + +}; + +}; + +#endif diff --git a/include/osgUtil/AppVisitor b/include/osgUtil/AppVisitor new file mode 100644 index 000000000..36e38e115 --- /dev/null +++ b/include/osgUtil/AppVisitor @@ -0,0 +1,67 @@ +#ifndef OSGUTIL_APPVISITOR +#define OSGUTIL_APPVISITOR 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace osgUtil { + +/** + * Basic AppVisitor implementation for animating a scene. + * This visitor traverses the scene graph, call each nodes appCallback if + * it exists. + */ +class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor +{ + public: + + AppVisitor(); + virtual ~AppVisitor(); + + virtual void reset(); + + virtual void apply(osg::Node& node) { handle_callbacks(node); } + + virtual void apply(osg::Geode& node) { handle_callbacks(node); } + virtual void apply(osg::Billboard& node) { handle_callbacks(node); } + virtual void apply(osg::LightSource& node){ handle_callbacks(node); } + + virtual void apply(osg::Group& node) { handle_callbacks(node); } + virtual void apply(osg::Transform& node) { handle_callbacks(node); } + virtual void apply(osg::Switch& node) { handle_callbacks(node); } + virtual void apply(osg::LOD& node) { handle_callbacks(node); } + virtual void apply(osg::Impostor& node) { handle_callbacks(node); } + + + protected: + + /** prevent unwanted copy construction.*/ + AppVisitor(const AppVisitor&):osg::NodeVisitor() {} + + /** prevent unwanted copy operator.*/ + AppVisitor& operator = (const AppVisitor&) { return *this; } + + inline void handle_callbacks(osg::Node& node) + { + osg::NodeCallback* callback = node.getAppCallback(); + if (callback) (*callback)(&node,this); + else if (node.getNumChildrenRequiringAppTraversal()>0) traverse(node); + } + + + +}; + +}; + +#endif + diff --git a/src/Demos/osgcluster/Makedepend b/src/Demos/osgcluster/Makedepend new file mode 100644 index 000000000..e69de29bb diff --git a/src/Demos/osgcluster/Makefile b/src/Demos/osgcluster/Makefile new file mode 100644 index 000000000..0236fafff --- /dev/null +++ b/src/Demos/osgcluster/Makefile @@ -0,0 +1,25 @@ +#!smake +include ../../../Make/makedefs + +C++FILES = \ + broadcaster.cpp\ + receiver.cpp\ + osgcluster.cpp + +C++FLAGS += -g + +TARGET = ../../../bin/osgcluster + +TARGET_BIN_FILES = osgcluster + +#note, use this library list when using the Performer osgPlugin. +#LIBS = ${PFLIBS} -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi + +#note, standard library list. +LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi + +C++FLAGS += -I../../../include +LDFLAGS += -L../../../lib + +include ../../../Make/makerules + diff --git a/src/Demos/osgcluster/README b/src/Demos/osgcluster/README new file mode 100644 index 000000000..2d9da8288 --- /dev/null +++ b/src/Demos/osgcluster/README @@ -0,0 +1,67 @@ +osgcluster demonstates basic clustering of machines across a local area +network using UDP packets to send camera position updates from a master viewer +to slave viewers. + +Note, the broadcaster and reciever classes have currently been implement +for Linux/IRIX, hence osgcluster will only work on these systems. It should +also work with little extra work on other Unix based OS's. Support for +WinSocket needs to be added to allow support for Windows. Anybody know +WinSocket enough to tackle this? If so let us know. + +- + +On the master machine run: + + osgcluster -m -f 30 mymodel.osg + + +On the slave machines run: + + for left channel: + + osgcluster -s -f 30 -o 30 mymodel.osg + + for right channel: + + osgcluster -s -f 30 -o 30 mymodel.osg + +The options are : + + -m set to viewer to master so that it broadcasts its camera postion. + -s set to viewer to slave so that it recivers its camera postion. + -n set the socket number to communicate over, defaults to 8100. + -o set offset the slave camera from the master position by specified + number of degress. positive offset turns camera towards right. + -f set the horizontal field of view of the camera. + +Sepetember 2001. +Robert Osfield. + + + +Note: Using sgv with Peformer (for IRIX and Linux users only) +============================================================= + +If you find problems with loading .pfb files its likely that its due to undefined +symbols. This isn't a problem with the OSG implementation, but alas the only +current solution is to directly link you app with the Performer libraries. The +Makefile contains two library list. In Makefile you'll see something like : + + #note, use this library list when using the Performer osgPlugin. + #LIBS = ${PFLIBS} -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi + + #note, standard library list. + LIBS = -losgGLUT -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi + +Simple comment in the LIBS line with PFLIBS and comment out the standard LIBS, +then : + + make clean + make + +Hopefully the Performer distribution will eventually work as a dynamic plugin +but until that day we're stuck with this 'hack'... + + +Robert Osfield, +March 20001. diff --git a/src/Demos/osgcluster/broadcaster.cpp b/src/Demos/osgcluster/broadcaster.cpp new file mode 100644 index 000000000..5a6819d94 --- /dev/null +++ b/src/Demos/osgcluster/broadcaster.cpp @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux +#include +#else +#include +#endif + +#include "broadcaster.h" + +#define _VERBOSE 1 + +Broadcaster::Broadcaster( void ) +{ + _port = 0; + _initialized = false; + _buffer = 0L; + _address = 0; +} + +Broadcaster::~Broadcaster( void ) +{ + close( _so ); +} + +bool Broadcaster::init( void ) +{ + if( _port == 0 ) + { + fprintf( stderr, "Broadcaster::init() - port not defined\n" ); + return false; + } + + if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) + { + perror( "socket" ); + return false; + } + int on = 1; + setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + saddr.sin_family = AF_INET; + saddr.sin_port = htons( _port ); + if( _address == 0 ) + { + struct ifreq ifr; + setsockopt( _so, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); +#ifdef __linux + strcpy( ifr.ifr_name, "eth0" ); +#else + strcpy( ifr.ifr_name, "ef0" ); +#endif + if( (ioctl( _so, SIOCGIFBRDADDR, &ifr)) < 0 ) + { + perror( "Broadcaster::init() Cannot get Broadcast Address" ); + return false; + } + saddr.sin_addr.s_addr = ( + ((sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr.s_addr); + } + else + { + saddr.sin_addr.s_addr = _address; + } +#ifdef _VERBOSE + unsigned char *ptr = (unsigned char *)&saddr.sin_addr.s_addr; + printf( "Broadcast address : %u.%u.%u.%u\n", ptr[0], ptr[1], ptr[2], ptr[3] ); +#endif + + _initialized = true; + return _initialized; +} + +void Broadcaster::setHost( const char *hostname ) +{ + struct hostent *h; + if( (h = gethostbyname( hostname )) == 0L ) + { + fprintf( stderr, "Broadcaster::setHost() - Cannot resolv an address for \"%s\".\n", hostname ); + _address = 0; + } + else + _address = *(( unsigned long *)h->h_addr); +} + +void Broadcaster::setPort( const short port ) +{ + _port = port; +} + +void Broadcaster::setBuffer( void *buffer, const unsigned int size ) +{ + _buffer = buffer; + _buffer_size = size; +} + +void Broadcaster::sync( void ) +{ + _initialized || init(); + + if( _buffer == 0L ) + { + fprintf( stderr, "Broadcaster::sync() - No buffer\n" ); + return; + } + + unsigned int size = sizeof( struct sockaddr_in ); + sendto( _so, (const void *)_buffer, _buffer_size, + 0, (struct sockaddr *)&saddr, size ); + +} + diff --git a/src/Demos/osgcluster/broadcaster.h b/src/Demos/osgcluster/broadcaster.h new file mode 100644 index 000000000..8475619fa --- /dev/null +++ b/src/Demos/osgcluster/broadcaster.h @@ -0,0 +1,45 @@ +#ifndef __BROADCASTER_H +#define __BROADCASTER_H + +//////////////////////////////////////////////////////////// +// Broadcaster.h +// +// Class definition for broadcasting a buffer to a LAN +// + +#include + +class Broadcaster +{ + public : + + Broadcaster( void ); + ~Broadcaster( void ); + + // Set the broadcast port + void setPort( const short port ); + + // Set the buffer to be broadcast + void setBuffer( void *buffer, const unsigned int buffer_size ); + + // Set a recipient host. If this is used, the Broadcaster + // no longer broadcasts, but rather directs UDP packets at + // host. + void setHost( const char *hostname ); + + // Sync broadcasts the buffer + void sync( void ); + + private : + bool init( void ); + + private : + int _so; + bool _initialized; + short _port; + void *_buffer; + unsigned int _buffer_size; + struct sockaddr_in saddr; + unsigned long _address; +}; +#endif diff --git a/src/Demos/osgcluster/osgcluster.cpp b/src/Demos/osgcluster/osgcluster.cpp new file mode 100644 index 000000000..35b696f99 --- /dev/null +++ b/src/Demos/osgcluster/osgcluster.cpp @@ -0,0 +1,350 @@ +#ifdef USE_MEM_CHECK +#include +#endif + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "receiver.h" +#include "broadcaster.h" + + +class CameraPacket { + public: + + CameraPacket():_masterKilled(false) {} + + void setPacket(const osg::Camera& camera,int tnum, double rtime) + { + _eye = camera.getEyePoint(); + _center = camera.getCenterPoint(); + _up = camera.getUpVector(); + _traversalNumber = tnum; + _referenceTime = rtime; + } + + void getCamera(osg::Camera& camera,float angle_offset=0.0f) + { + + osg::Vec3 lv = _center-_eye; + osg::Matrix matrix; + matrix.makeIdent(); + matrix.makeRot(angle_offset,_up.x(),_up.y(),_up.z()); + lv = lv*matrix; + + camera.setLookAt(_eye,_eye+lv,_up); + + } + + void getSceneViewUpdate(osgUtil::SceneView& sv) + { + sv.setTraversalNumber(_traversalNumber); + sv.setReferenceTime(_referenceTime); + } + + void setMasterKilled(const bool flag) { _masterKilled = flag; } + const bool getMasterKilled() const { return _masterKilled; } + + bool _masterKilled; + osg::Vec3 _eye; + osg::Vec3 _center; + osg::Vec3 _up; + bool _attachMatrix; + osg::Matrix _matrix; + + int _traversalNumber; + double _referenceTime; + +}; + + +class MySceneView : public osgUtil::SceneView { + + public: + + enum ViewerMode + { + STAND_ALONE, + SLAVE, + MASTER + }; + + MySceneView(ViewerMode viewerMode,int socketNumber,float camera_fov, float camera_offset): + _viewerMode(viewerMode),_socketNumber(socketNumber), + _camera_fov(camera_fov), _camera_offset(camera_offset) + { + setDefaults(); + getCamera()->setAdjustAspectRatioMode(osg::Camera::ADJUST_VERTICAL); + getCamera()->setFOV(camera_fov,camera_fov*(600.0f/800.0f),1.0f,1000.0f); + + _bc.setPort(socketNumber); + _rc.setPort(socketNumber); + }; + + ~MySceneView() + { + if (_viewerMode==MASTER) + { + // need to broadcast my death. + CameraPacket cp; + cp.setPacket(*getCamera(),getTraversalNumber(),getReferenceTime()); + cp.setMasterKilled(true); + + _bc.setBuffer(&cp, sizeof( CameraPacket )); + _bc.sync(); + + cout << "broadcasting death"< NodeList; + NodeList nodeList; + for( i = 1; i < argc; i++ ) + { + + if (argv[i][0]=='-') + { + switch(argv[i][1]) + { + + case('m'): + viewerMode = MySceneView::MASTER; + break; + case('s'): + viewerMode = MySceneView::SLAVE; + break; + case('n'): + ++i; + if (iloadLibrary(argv[i]); + } + break; + case('e'): + ++i; + if (icreateLibraryNameForExt(argv[i]); + osgDB::Registry::instance()->loadLibrary(libName); + } + break; + } + } else + { + osg::Node *node = osgDB::readNodeFile( argv[i] ); + + if( node != (osg::Node *)0L ) + { + if (node->getName().empty()) node->setName( argv[i] ); + nodeList.push_back(node); + } + } + + } + + if (nodeList.size()==0) + { + osg::notify(osg::WARN) << "No data loaded."<1 + { + osg::Group* group = new osg::Group(); + for(NodeList::iterator itr=nodeList.begin(); + itr!=nodeList.end(); + ++itr) + { + group->addChild(*itr); + } + + rootnode = group; + } + + return rootnode; +} + + +int main( int argc, char **argv ) +{ + +#ifdef USE_MEM_CHECK + mtrace(); +#endif + + // initialize the GLUT + glutInit( &argc, argv ); + + if (argc<2) + { + osg::notify(osg::NOTICE)<<"usage:"< mySceneView = new MySceneView(viewerMode,socketNumber,camera_fov,camera_offset); + + mySceneView->setSceneData(rootnode); + + // initialize the viewer. + osgGLUT::Viewer viewer; + viewer.addViewport( mySceneView.get() ); + + // register trackball, flight and drive. + viewer.registerCameraManipulator(new osgUtil::TrackballManipulator); + viewer.registerCameraManipulator(new osgUtil::FlightManipulator); + viewer.registerCameraManipulator(new osgUtil::DriveManipulator); + + viewer.open(); + viewer.run(); + + return 0; +} diff --git a/src/Demos/osgcluster/receiver.cpp b/src/Demos/osgcluster/receiver.cpp new file mode 100644 index 000000000..f24b9162c --- /dev/null +++ b/src/Demos/osgcluster/receiver.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "receiver.h" + +Receiver::Receiver( void ) +{ + _port = 0; + _initialized = false; + _buffer = 0L; +} + +Receiver::~Receiver( void ) +{ + close( _so ); +} + +bool Receiver::init( void ) +{ + if( _port == 0 ) + { + fprintf( stderr, "Receiver::init() - port not defined\n" ); + return false; + } + + if( (_so = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) + { + perror( "socket" ); + return false; + } + int on = 1; + setsockopt( _so, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + struct sockaddr_in saddr; + saddr.sin_family = AF_INET; + saddr.sin_port = htons( _port ); + saddr.sin_addr.s_addr = 0; + + if( bind( _so, (struct sockaddr *)&saddr, sizeof( saddr )) < 0 ) + { + perror( "bind" ); + return false; + } + + _initialized = true; + return _initialized; +} + + +void Receiver::setPort( const short port ) +{ + _port = port; +} + +void Receiver::setBuffer( void *buffer, const unsigned int size ) +{ + _buffer = buffer; + _buffer_size = size; +} + +void Receiver::sync( void ) +{ + _initialized || init(); + + if( _buffer == 0L ) + { + fprintf( stderr, "Receiver::sync() - No buffer\n" ); + return; + } + +#ifdef __linux + socklen_t +#else + int +#endif + size = sizeof( struct sockaddr_in ); + + fd_set fdset; + FD_ZERO( &fdset ); + FD_SET( _so, &fdset ); + + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + + recvfrom( _so, (caddr_t)_buffer, _buffer_size, 0, 0, &size ); + while( select( _so+1, &fdset, 0L, 0L, &tv ) ) + { + if( FD_ISSET( _so, &fdset ) ) + { + recvfrom( _so, (caddr_t)_buffer, _buffer_size, 0, 0, &size ); + } + } +} + diff --git a/src/Demos/osgcluster/receiver.h b/src/Demos/osgcluster/receiver.h new file mode 100644 index 000000000..20597e6d7 --- /dev/null +++ b/src/Demos/osgcluster/receiver.h @@ -0,0 +1,39 @@ +#ifndef __RECEIVER_H +#define __RECEIVER_H + + +//////////////////////////////////////////////////////////// +// Receiver.h +// +// Class definition for the recipient of a broadcasted message +// + + +class Receiver +{ + public : + + Receiver(); + ~Receiver(); + + // setBuffer defines the buffer into which the broadcasted + // message will be received. + void setBuffer( void *buffer, const unsigned int size ); + + // Define what port to listen and bind to + void setPort( const short port ); + + // Sync does a blocking wait to recieve next message + void sync( void ); + + private : + bool init( void ); + + private : + int _so; + bool _initialized; + short _port; + void *_buffer; + unsigned int _buffer_size; +}; +#endif diff --git a/src/osg/Matrix.cpp.new b/src/osg/Matrix.cpp.new new file mode 100644 index 000000000..0eefc82ca --- /dev/null +++ b/src/osg/Matrix.cpp.new @@ -0,0 +1,558 @@ + +#include +#include +#include + +#include //memcpy +#include //acos + +using namespace osg; + +#define WARN_DEPRECATED + +Matrix::Matrix() : Object(), fully_realized(false) {} + +Matrix::Matrix( const Matrix& other ) : Object() { + set( (float const * const) other._mat ); +} + +Matrix::Matrix( float const * const def ) { + set( def ); +} + +Matrix::Matrix( +float a00, float a01, float a02, float a03, +float a10, float a11, float a12, float a13, +float a20, float a21, float a22, float a23, +float a30, float a31, float a32, float a33) +{ + _mat[0][0] = a00; + _mat[0][1] = a01; + _mat[0][2] = a02; + _mat[0][3] = a03; + + _mat[1][0] = a10; + _mat[1][1] = a11; + _mat[1][2] = a12; + _mat[1][3] = a13; + + _mat[2][0] = a20; + _mat[2][1] = a21; + _mat[2][2] = a22; + _mat[2][3] = a23; + + _mat[3][0] = a30; + _mat[3][1] = a31; + _mat[3][2] = a32; + _mat[3][3] = a33; +} + +Matrix& Matrix::operator = (const Matrix& other ) { + if( &other == this ) return *this; + set((const float*)other._mat); + return *this; +} + +void Matrix::set( float const * const def ) { + memcpy( _mat, def, sizeof(_mat) ); + fully_realized = true; +} + +void Matrix::set( + float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33) +{ + _mat[0][0] = a00; + _mat[0][1] = a01; + _mat[0][2] = a02; + _mat[0][3] = a03; + + _mat[1][0] = a10; + _mat[1][1] = a11; + _mat[1][2] = a12; + _mat[1][3] = a13; + + _mat[2][0] = a20; + _mat[2][1] = a21; + _mat[2][2] = a22; + _mat[2][3] = a23; + + _mat[3][0] = a30; + _mat[3][1] = a31; + _mat[3][2] = a32; + _mat[3][3] = a33; +} + +#define SET_ROW(row, v1, v2, v3, v4 ) \ + _mat[0][(row)] = (v1); \ + _mat[1][(row)] = (v2); \ + _mat[2][(row)] = (v3); \ + _mat[3][(row)] = (v4); + + +void Matrix::makeIdent() { + SET_ROW(0, 1, 0, 0, 0 ) + SET_ROW(1, 0, 1, 0, 0 ) + SET_ROW(2, 0, 0, 1, 0 ) + SET_ROW(3, 0, 0, 0, 1 ) + + fully_realized = true; +} + +void Matrix::makeScale( const Vec3& v ) { + makeScale(v[0], v[1], v[2] ); +} + +void Matrix::makeScale( float x, float y, float z ) { + SET_ROW(0, x, 0, 0, 0 ) + SET_ROW(1, 0, y, 0, 0 ) + SET_ROW(2, 0, 0, z, 0 ) + SET_ROW(3, 0, 0, 0, 1 ) + + fully_realized = true; +} + +void Matrix::makeTrans( const Vec3& v ) { + makeTrans( v[0], v[1], v[2] ); +} + +void Matrix::makeTrans( float x, float y, float z ) { + SET_ROW(0, 1, 0, 0, x ) + SET_ROW(1, 0, 1, 0, y ) + SET_ROW(2, 0, 0, 1, z ) + SET_ROW(3, 0, 0, 0, 1 ) + + fully_realized = true; +} + +void Matrix::makeRot( const Vec3& from, const Vec3& to ) { + double d = from * to; // dot product == cos( angle between from & to ) + if( d < 0.9999 ) { + double angle = acos(d); + Vec3 axis = to ^ from; //we know ((to) x (from)) is perpendicular to both + makeRot( angle, axis ); + } + else + makeIdent(); +} + +void Matrix::makeRot( float angle, const Vec3& axis ) { + makeRot( angle, axis.x(), axis.y(), axis.z() ); +} + +void Matrix::makeRot( float angle, float x, float y, float z ) { + float d = sqrt( x*x + y*y + z*z ); + if( d == 0 ) + return; + + float sin_half = sin( angle/2 ); + float cos_half = cos( angle/2 ); + + Quat q( sin_half * (x/d), + sin_half * (y/d), + sin_half * (z/d), + cos_half ); + makeRot( q ); +} + +void Matrix::makeRot( const Quat& q ) { + // taken from Shoemake/ACM SIGGRAPH 89 + Vec4 v = q.asVec4(); + + double xs = 2 * v.x(); //assume q is already normalized? assert? + double ys = 2 * v.y(); // if not, xs = 2 * v.x() / d, ys = 2 * v.y() / d + double zs = 2 * v.z(); // and zs = 2 * v.z() /d where d = v.length2() + + double xx = xs * v.x(); + double xy = ys * v.x(); + double xz = zs * v.x(); + double yy = ys * v.y(); + double yz = zs * v.y(); + double zz = zs * v.z(); + double wx = xs * v.w(); + double wy = ys * v.w(); + double wz = zs * v.w(); + + SET_ROW(0, 1.0-(yy+zz), xy - wz, xz + wz, 0.0 ) + SET_ROW(1, xy + wz, 1.0-(xx+zz),yz - wx, 0.0 ) + SET_ROW(2, xz - wy, yz + wx, 1.0-(xx+yy),0.0 ) + SET_ROW(3, 0.0, 0.0, 0.0, 1.0 ) + + fully_realized = true; +} + +void Matrix::makeRot( float yaw, float pitch, float roll) { + // lifted straight from SOLID library v1.01 Quaternion.h + // available from http://www.win.tue.nl/~gino/solid/ + // and also distributed under the LGPL + float cosYaw = cos(yaw / 2); + float sinYaw = sin(yaw / 2); + float cosPitch = cos(pitch / 2); + float sinPitch = sin(pitch / 2); + float cosRoll = cos(roll / 2); + float sinRoll = sin(roll / 2); + Quat q(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + makeRot( q ); +} + +#define INNER_PRODUCT(a,b,c,r) \ + ((a)._mat[0][r] * (b)._mat[c][0]) \ + +((a)._mat[1][r] * (b)._mat[c][1]) \ + +((a)._mat[2][r] * (b)._mat[c][2]) \ + +((a)._mat[3][r] * (b)._mat[c][3]) + +void Matrix::mult( const Matrix& lhs, const Matrix& rhs ) { +// PRECONDITION: We assume neither &lhs nor &rhs == this +// if it did, use preMult or postMult instead + _mat[0][0] = INNER_PRODUCT(lhs, rhs, 0, 0); + _mat[0][1] = INNER_PRODUCT(lhs, rhs, 0, 1); + _mat[0][2] = INNER_PRODUCT(lhs, rhs, 0, 2); + _mat[0][3] = INNER_PRODUCT(lhs, rhs, 0, 3); + _mat[1][0] = INNER_PRODUCT(lhs, rhs, 1, 0); + _mat[1][1] = INNER_PRODUCT(lhs, rhs, 1, 1); + _mat[1][2] = INNER_PRODUCT(lhs, rhs, 1, 2); + _mat[1][3] = INNER_PRODUCT(lhs, rhs, 1, 3); + _mat[2][0] = INNER_PRODUCT(lhs, rhs, 2, 0); + _mat[2][1] = INNER_PRODUCT(lhs, rhs, 2, 1); + _mat[2][2] = INNER_PRODUCT(lhs, rhs, 2, 2); + _mat[2][3] = INNER_PRODUCT(lhs, rhs, 2, 3); + _mat[3][0] = INNER_PRODUCT(lhs, rhs, 3, 0); + _mat[3][1] = INNER_PRODUCT(lhs, rhs, 3, 1); + _mat[3][2] = INNER_PRODUCT(lhs, rhs, 3, 2); + _mat[3][3] = INNER_PRODUCT(lhs, rhs, 3, 3); + fully_realized = true; +} + +void Matrix::preMult( const Matrix& other ) { + float t1,t2,t3,t4; + if( !fully_realized ) { + //act as if this were an identity Matrix + set((const float*)other._mat); + return; + } + for(int col=0; col<4; ++col) { + t1 = INNER_PRODUCT( other, *this, col, 0 ); + t2 = INNER_PRODUCT( other, *this, col, 1 ); + t3 = INNER_PRODUCT( other, *this, col, 2 ); + t4 = INNER_PRODUCT( other, *this, col, 3 ); + _mat[col][0] = t1; + _mat[col][1] = t2; + _mat[col][2] = t3; + _mat[col][3] = t4; + } +} + +void Matrix::postMult( const Matrix& other ) { + float t[4]; + if( !fully_realized ) { + //act as if this were an identity Matrix + set((const float*)other._mat); + return; + } + for(int row=0; row<4; ++row) { + t[0] = INNER_PRODUCT( *this, other, 0, row ); + t[1] = INNER_PRODUCT( *this, other, 1, row ); + t[2] = INNER_PRODUCT( *this, other, 2, row ); + t[3] = INNER_PRODUCT( *this, other, 3, row ); + SET_ROW(row, t[0], t[1], t[2], t[3] ) + } +} + +#undef SET_ROW +#undef INNER_PRODUCT + +bool Matrix::invert( const Matrix& _m ) { + + if (&_m==this) + { + Matrix tm(_m); + return invert(tm); + } + if ( _m._mat[0][3] == 0.0 + && _m._mat[1][3] == 0.0 + && _m._mat[2][3] == 0.0 + && _m._mat[3][3] == 1.0 ) + { + return invertAffine( _m ); + } + + // code lifted from VR Juggler. + // not cleanly added, but seems to work. RO. + const float* a = reinterpret_cast(_m._mat); + float* b = reinterpret_cast(_mat); + + int n = 4; + int i, j, k; + int r[ 4], c[ 4], row[ 4], col[ 4]; + float m[ 4][ 4*2], pivot, max_m, tmp_m, fac; + + /* Initialization */ + for ( i = 0; i < n; i ++ ) + { + r[ i] = c[ i] = 0; + row[ i] = col[ i] = 0; + } + + /* Set working matrix */ + for ( i = 0; i < n; i++ ) + { + for ( j = 0; j < n; j++ ) + { + m[ i][ j] = a[ i * n + j]; + m[ i][ j + n] = ( i == j ) ? 1.0 : 0.0 ; + } + } + + /* Begin of loop */ + for ( k = 0; k < n; k++ ) + { + /* Choosing the pivot */ + for ( i = 0, max_m = 0; i < n; i++ ) + { + if ( row[ i] ) continue; + for ( j = 0; j < n; j++ ) + { + if ( col[ j] ) continue; + tmp_m = fabs( m[ i][j]); + if ( tmp_m > max_m) + { + max_m = tmp_m; + r[ k] = i; + c[ k] = j; + } + } + } + row[ r[k] ] = col[ c[k] ] = 1; + pivot = m[ r[ k] ][ c[ k] ]; + + if ( fabs( pivot) <= 1e-20) + { + notify(WARN) << "*** pivot = %f in mat_inv. ***\n"; + //exit( 0); + return false; + } + + /* Normalization */ + for ( j = 0; j < 2*n; j++ ) + { + if ( j == c[ k] ) + m[ r[ k]][ j] = 1.0; + else + m[ r[ k]][ j] /=pivot; + } + + /* Reduction */ + for ( i = 0; i < n; i++ ) + { + if ( i == r[ k] ) + continue; + + for ( j=0, fac = m[ i][ c[k]];j < 2*n; j++ ) + { + if ( j == c[ k] ) + m[ i][ j] =0.0; + else + m[ i][ j] -=fac * m[ r[k]][ j]; + } + } + } + + /* Assign invers to a matrix */ + for ( i = 0; i < n; i++ ) + for ( j = 0; j < n; j++ ) + row[ i] = ( c[ j] == i ) ? r[j] : row[ i]; + + for ( i = 0; i < n; i++ ) + for ( j = 0; j < n; j++ ) + b[ i * n + j] = m[ row[ i]][j + n]; + + return true; // It worked +} + +const double PRECISION_LIMIT = 1.0e-15; + +bool Matrix::invertAffine( const Matrix& _m ) { + // adapted from Graphics Gems II. + // + // This method treats the matrix as a block matrix and calculates + // the inverse of one submatrix, improving performance over something + // that inverts any non-singular matrix: + // -1 + // -1 [ A 0 ] -1 [ A 0 ] + // M = [ ] = [ -1 ] + // [ C 1 ] [-CA 1 ] + // + // returns true if _m is nonsingular, and (*this) contains its inverse + // otherwise returns false. (*this unchanged) + + // assert (this.isAffine()) ? + double det_1, pos, neg, temp; + + pos = neg = 0.0; + +#define ACCUMULATE \ + { \ + if(temp < 0.0) pos += temp; \ + else neg += temp; \ + } + + temp = _m._mat[0][0] * _m._mat[1][1] * _m._mat[2][2]; ACCUMULATE; + temp = _m._mat[0][1] * _m._mat[1][2] * _m._mat[2][0]; ACCUMULATE; + temp = _m._mat[0][2] * _m._mat[1][0] * _m._mat[2][1]; ACCUMULATE; + + temp = - _m._mat[0][2] * _m._mat[1][1] * _m._mat[2][0]; ACCUMULATE; + temp = - _m._mat[0][1] * _m._mat[1][0] * _m._mat[2][2]; ACCUMULATE; + temp = - _m._mat[0][0] * _m._mat[1][2] * _m._mat[2][1]; ACCUMULATE; + + det_1 = pos + neg; + + if( (det_1 == 0.0) || (abs(det_1/(pos-neg)) < PRECISION_LIMIT )) { + // _m has no inverse + notify(WARN) << "Matrix::invert(): Matrix has no inverse." << endl; + return false; + } + + // inverse is adj(A)/det(A) + det_1 = 1.0 / det_1; + + _mat[0][0] = (_m._mat[1][1] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][1]) * det_1; + _mat[1][0] = (_m._mat[1][0] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][0]) * det_1; + _mat[2][0] = (_m._mat[1][0] * _m._mat[2][1] - _m._mat[1][1] * _m._mat[2][0]) * det_1; + _mat[0][1] = (_m._mat[0][1] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][1]) * det_1; + _mat[1][1] = (_m._mat[0][0] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][0]) * det_1; + _mat[2][1] = (_m._mat[0][0] * _m._mat[2][1] - _m._mat[0][1] * _m._mat[2][0]) * det_1; + _mat[0][2] = (_m._mat[0][1] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][1]) * det_1; + _mat[1][2] = (_m._mat[0][0] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][0]) * det_1; + _mat[2][2] = (_m._mat[0][0] * _m._mat[1][1] - _m._mat[0][1] * _m._mat[1][0]) * det_1; + + // calculate -C * inv(A) + _mat[3][0] = -(_m._mat[3][0] * _mat[0][0] + _m._mat[3][1] * _mat[1][0] + _m._mat[3][2] * _mat[2][0] ); + _mat[3][1] = -(_m._mat[3][0] * _mat[0][1] + _m._mat[3][1] * _mat[1][1] + _m._mat[3][2] * _mat[2][1] ); + _mat[3][2] = -(_m._mat[3][0] * _mat[0][2] + _m._mat[3][1] * _mat[1][2] + _m._mat[3][2] * _mat[2][2] ); + + _mat[0][3] = 0.0; + _mat[1][3] = 0.0; + _mat[2][3] = 0.0; + _mat[3][3] = 1.0; + + fully_realized = true; + return true; +} + +//static utility methods +Matrix Matrix::scale(float sx, float sy, float sz) { + Matrix m; + m.makeScale(sx,sy,sz); + return m; +} +Matrix Matrix::scale(const Vec3& v ) { + return scale(v.x(), v.y(), v.z() ); +} +Matrix Matrix::trans(float tx, float ty, float tz) { + Matrix m; + m.makeTrans(tx,ty,tz); + return m; +} +Matrix Matrix::trans(const Vec3& v ) { + return trans(v.x(), v.y(), v.z() ); +} +Matrix Matrix::rotate( const Quat& q ) { + Matrix m; + m.makeRot( q ); + return m; +} +Matrix Matrix::rotate(float angle, float x, float y, float z ) { + Matrix m; + m.makeRot(angle,x,y,z); + return m; +} +Matrix Matrix::rotate(const Vec3& from, const Vec3& to ) { + Matrix m; + m.makeRot(from,to); + return m; +} + +//Deprecated methods +void Matrix::copy( const Matrix& other) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::copy is deprecated. Use = instead."; +#endif + (*this) = other; +} +void Matrix::preScale( float sx, float sy, float sz, const Matrix& m ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::preScale is deprecated. Use result = (Matrix::scale * m) instead."; + (*this) = ( scale(sx,sy,sz) * m ); +#endif +} +void Matrix::postScale( const Matrix& m, float sx, float sy, float sz ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::postScale is deprecated. Use result = (m * Matrix::scale()) instead."; + (*this) = ( m * scale(sx,sy,sz) ); +#endif +} +void Matrix::preScale( float sx, float sy, float sz ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::preScale is deprecated. Use M.preMult( Matrix::scale ) instead."; + preMult( scale(sx,sy,sz) ); +#endif +} +void Matrix::postScale( float sx, float sy, float sz ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::postScale is deprecated. Use M.postMult( Matrix::scale ) instead."; + postMult( scale(sx,sy,sz) ); +#endif +} +void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead."; + (*this) = trans(tx,ty,tz) * m; +#endif +} +void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead."; + (*this) = m * trans(tx,ty,tz); +#endif +} +void Matrix::preTrans( float sx, float sy, float sz ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead."; + preMult( trans(sx,sy,sz) ); +#endif +} +void Matrix::postTrans( float sx, float sy, float sz ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead."; + postMult( trans(sx,sy,sz) ); +#endif +} +void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::preRot is deprecated. Use result = Matrix::rot * m instead."; + (*this) = rotate(deg,x,y,z) * m; +#endif +} +void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::postRot is deprecated. Use result = m * Matrix::rotate instead."; + (*this) = m * rotate(deg,x,y,z); +#endif +} +void Matrix::preRot( float deg, float x, float y, float z ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::preRot is deprecated. Use m.preMult( Matrix::rotate ) instead."; + preMult( rotate(deg,x,y,z) ); +#endif +} +void Matrix::postRot( float deg, float x, float y, float z ) { +#ifdef WARN_DEPRECATED + notify(NOTICE) << "Matrix::postRot is deprecated. Use m.postMult( Matrix::rotate ) instead."; + postMult( rotate(deg,x,y,z) ); +#endif +} diff --git a/src/osg/Matrix.cpp.old b/src/osg/Matrix.cpp.old new file mode 100644 index 000000000..d48060776 --- /dev/null +++ b/src/osg/Matrix.cpp.old @@ -0,0 +1,568 @@ +#include +#include + +#include +#include +#include +#include + +#define square(x) ((x)*(x)) +#define DEG2RAD(x) ((x)*M_PI/180.0) +#define RAD2DEG(x) ((x)*180.0/M_PI) + +using namespace osg; + +typedef struct quaternion_ +{ + double x ; + double y ; + double z ; + double w ; +} quaternion ; + +/* C = a(row).b(row) */ + +#define matrix_inner_product( a, b, row, col, C ) \ + { \ + (C)[row][col] = (a)[row][0] * (b)[0][col] + \ + (a)[row][1] * (b)[1][col] + \ + (a)[row][2] * (b)[2][col] + \ + (a)[row][3] * (b)[3][col]; \ + } + +/* C = a.b */ + +#define matrix_mult( a, b, C ) \ + { \ + matrix_inner_product( a, b, 0, 0, C ); \ + matrix_inner_product( a, b, 0, 1, C ); \ + matrix_inner_product( a, b, 0, 2, C ); \ + matrix_inner_product( a, b, 0, 3, C ); \ + matrix_inner_product( a, b, 1, 0, C ); \ + matrix_inner_product( a, b, 1, 1, C ); \ + matrix_inner_product( a, b, 1, 2, C ); \ + matrix_inner_product( a, b, 1, 3, C ); \ + matrix_inner_product( a, b, 2, 0, C ); \ + matrix_inner_product( a, b, 2, 1, C ); \ + matrix_inner_product( a, b, 2, 2, C ); \ + matrix_inner_product( a, b, 2, 3, C ); \ + matrix_inner_product( a, b, 3, 0, C ); \ + matrix_inner_product( a, b, 3, 1, C ); \ + matrix_inner_product( a, b, 3, 2, C ); \ + matrix_inner_product( a, b, 3, 3, C ); \ + } + +static void quaternion_matrix( quaternion *q, double mat[4][4] ) +{ + /* copied from Shoemake/ACM SIGGRAPH 89 */ + double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz ; + + xs = q->x + q->x; + ys = q->y + q->y; + zs = q->z + q->z; + + wx = q->w * xs ; wy = q->w * ys ; wz = q->w * zs ; + xx = q->x * xs ; xy = q->x * ys ; xz = q->x * zs ; + yy = q->y * ys ; yz = q->y * zs ; zz = q->z * zs ; + + mat[0][0] = 1.0 - ( yy + zz ) ; + mat[0][1] = xy - wz ; + mat[0][2] = xz + wy ; + mat[1][0] = xy + wz ; + mat[1][1] = 1.0 - ( xx + zz ) ; + mat[1][2] = yz - wx ; + mat[2][0] = xz - wy ; + mat[2][1] = yz + wx ; + mat[2][2] = 1.0 - ( xx + yy ) ; + + mat[0][3] = 0.0; + mat[1][3] = 0.0; + mat[2][3] = 0.0; + + mat[3][0] = 0.0; + mat[3][1] = 0.0; + mat[3][2] = 0.0; + mat[3][3] = 1.0; +} + + +Matrix::Matrix() +{ + makeIdent(); +} + + +Matrix::Matrix(const Matrix& matrix) : Object() +{ + memcpy(_mat,matrix._mat,sizeof(_mat)); +} + + +Matrix& Matrix::operator = (const Matrix& matrix) +{ + if (&matrix==this) return *this; + memcpy(_mat,matrix._mat,sizeof(_mat)); + return *this; +} + + +Matrix::Matrix( +float a00, float a01, float a02, float a03, +float a10, float a11, float a12, float a13, +float a20, float a21, float a22, float a23, +float a30, float a31, float a32, float a33) +{ + _mat[0][0] = a00; + _mat[0][1] = a01; + _mat[0][2] = a02; + _mat[0][3] = a03; + + _mat[1][0] = a10; + _mat[1][1] = a11; + _mat[1][2] = a12; + _mat[1][3] = a13; + + _mat[2][0] = a20; + _mat[2][1] = a21; + _mat[2][2] = a22; + _mat[2][3] = a23; + + _mat[3][0] = a30; + _mat[3][1] = a31; + _mat[3][2] = a32; + _mat[3][3] = a33; +} + + +Matrix::~Matrix() +{ +} + + +void Matrix::makeIdent() +{ + _mat[0][0] = 1.0f; + _mat[0][1] = 0.0f; + _mat[0][2] = 0.0f; + _mat[0][3] = 0.0f; + + _mat[1][0] = 0.0f; + _mat[1][1] = 1.0f; + _mat[1][2] = 0.0f; + _mat[1][3] = 0.0f; + + _mat[2][0] = 0.0f; + _mat[2][1] = 0.0f; + _mat[2][2] = 1.0f; + _mat[2][3] = 0.0f; + + _mat[3][0] = 0.0f; + _mat[3][1] = 0.0f; + _mat[3][2] = 0.0f; + _mat[3][3] = 1.0f; +} + +void Matrix::set(const float* m) +{ + _mat[0][0] = m[0]; + _mat[0][1] = m[1]; + _mat[0][2] = m[2]; + _mat[0][3] = m[3]; + + _mat[1][0] = m[4]; + _mat[1][1] = m[5]; + _mat[1][2] = m[6]; + _mat[1][3] = m[7]; + + _mat[2][0] = m[8]; + _mat[2][1] = m[9]; + _mat[2][2] = m[10]; + _mat[2][3] = m[11]; + + _mat[3][0] = m[12]; + _mat[3][1] = m[13]; + _mat[3][2] = m[14]; + _mat[3][3] = m[15]; +} + + +void Matrix::set( + float a00, float a01, float a02, float a03, + float a10, float a11, float a12, float a13, + float a20, float a21, float a22, float a23, + float a30, float a31, float a32, float a33) +{ + _mat[0][0] = a00; + _mat[0][1] = a01; + _mat[0][2] = a02; + _mat[0][3] = a03; + + _mat[1][0] = a10; + _mat[1][1] = a11; + _mat[1][2] = a12; + _mat[1][3] = a13; + + _mat[2][0] = a20; + _mat[2][1] = a21; + _mat[2][2] = a22; + _mat[2][3] = a23; + + _mat[3][0] = a30; + _mat[3][1] = a31; + _mat[3][2] = a32; + _mat[3][3] = a33; +} + +void Matrix::copy(const Matrix& matrix) +{ + memcpy(_mat,matrix._mat,sizeof(_mat)); +} + + +void Matrix::makeScale(float sx, float sy, float sz) +{ + makeIdent(); + _mat[0][0] = sx; + _mat[1][1] = sy; + _mat[2][2] = sz; +} + + +void Matrix::preScale( float sx, float sy, float sz, const Matrix& m ) +{ + Matrix transMat; + transMat.makeScale(sx, sy, sz); + mult(transMat,m); +} + + +void Matrix::postScale( const Matrix& m, float sx, float sy, float sz ) +{ + Matrix transMat; + transMat.makeScale(sx, sy, sz); + mult(m,transMat); +} + + +void Matrix::preScale( float sx, float sy, float sz ) +{ + Matrix transMat; + transMat.makeScale(sx, sy, sz); + preMult(transMat); +} + + +void Matrix::postScale( float sx, float sy, float sz ) +{ + Matrix transMat; + transMat.makeScale(sx, sy, sz); + postMult(transMat); +} + + +void Matrix::makeTrans( float tx, float ty, float tz ) +{ + makeIdent(); + _mat[3][0] = tx; + _mat[3][1] = ty; + _mat[3][2] = tz; +} + + +void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m ) +{ + Matrix transMat; + transMat.makeTrans(tx, ty, tz); + mult(transMat,m); +} + + +void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz ) +{ + Matrix transMat; + transMat.makeTrans(tx, ty, tz); + mult(m,transMat); +} + + +void Matrix::preTrans( float tx, float ty, float tz ) +{ + _mat[3][0] = (tx * _mat[0][0]) + (ty * _mat[1][0]) + (tz * _mat[2][0]) + _mat[3][0]; + _mat[3][1] = (tx * _mat[0][1]) + (ty * _mat[1][1]) + (tz * _mat[2][1]) + _mat[3][1]; + _mat[3][2] = (tx * _mat[0][2]) + (ty * _mat[1][2]) + (tz * _mat[2][2]) + _mat[3][2]; + _mat[3][3] = (tx * _mat[0][3]) + (ty * _mat[1][3]) + (tz * _mat[2][3]) + _mat[3][3]; +} + + +void Matrix::postTrans( float tx, float ty, float tz ) +{ + Matrix transMat; + transMat.makeTrans(tx, ty, tz); + postMult(transMat); +} + +void Matrix::makeRot( const Vec3& old_vec, const Vec3& new_vec ) +{ + /* dot product == cos(angle old_vec<>new_vec). */ + double d = new_vec * old_vec; + if ( d < 0.9999 ) + { + double angle = acos( d ); + Vec3 rot_axis = new_vec ^ old_vec; + makeRot( RAD2DEG(angle), + rot_axis.x(), rot_axis.y(), rot_axis.z() ); + } + else + makeIdent(); +} + +void Matrix::makeRot( float deg, float x, float y, float z ) +{ + double __mat[4][4]; + quaternion q; + float d = sqrtf( square(x) + square(y) + square(z) ); + + if( d == 0 ) + return; + + float sin_HalfAngle = sinf( DEG2RAD(deg/2) ); + float cos_HalfAngle = cosf( DEG2RAD(deg/2) ); + + q.x = sin_HalfAngle * (x/d); + q.y = sin_HalfAngle * (y/d); + q.z = sin_HalfAngle * (z/d); + q.w = cos_HalfAngle; + + quaternion_matrix( &q, __mat ); + + for(int i=0;i<4;++i) + { + for(int j=0;j<4;++j) + { + _mat[i][j]=__mat[i][j]; + } + } +} + + +void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m ) +{ + Matrix rotMat; + rotMat.makeRot( deg, x, y, z ); + mult(rotMat,m); +} + + +void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z ) +{ + Matrix rotMat; + rotMat.makeRot( deg, x, y, z ); + mult(m,rotMat); +} + + +void Matrix::preRot( float deg, float x, float y, float z ) +{ + quaternion q; + double __mat[4][4]; + float res_mat[4][4]; + + float d = sqrtf( square(x) + square(y) + square(z) ); + + if( d == 0 ) + return; + + float sin_HalfAngle = sinf( DEG2RAD(deg/2) ); + float cos_HalfAngle = cosf( DEG2RAD(deg/2) ); + + q.x = sin_HalfAngle * (x/d); + q.y = sin_HalfAngle * (y/d); + q.z = sin_HalfAngle * (z/d); + q.w = cos_HalfAngle; + + quaternion_matrix( &q, __mat ); + matrix_mult( __mat, _mat, res_mat ); + memcpy( _mat, res_mat, sizeof( _mat ) ); +} + + +void Matrix::postRot( float deg, float x, float y, float z ) +{ + quaternion q; + double __mat[4][4]; + float res_mat[4][4]; + + float d = sqrtf( square(x) + square(y) + square(z) ); + + if( d == 0 ) + return; + + float sin_HalfAngle = sinf( DEG2RAD(deg/2) ); + float cos_HalfAngle = cosf( DEG2RAD(deg/2) ); + + q.x = sin_HalfAngle * (x/d); + q.y = sin_HalfAngle * (y/d); + q.z = sin_HalfAngle * (z/d); + q.w = cos_HalfAngle; + + quaternion_matrix( &q, __mat ); + matrix_mult( _mat, __mat , res_mat ); + memcpy( _mat, res_mat, sizeof( _mat ) ); +} + + +void Matrix::setTrans( float tx, float ty, float tz ) +{ + _mat[3][0] = tx; + _mat[3][1] = ty; + _mat[3][2] = tz; +} + + +void Matrix::setTrans( const Vec3& v ) +{ + _mat[3][0] = v[0]; + _mat[3][1] = v[1]; + _mat[3][2] = v[2]; +} + + +void Matrix::preMult(const Matrix& m) +{ + Matrix tm; + matrix_mult( m._mat, _mat, tm._mat ); + *this = tm; +} + + +void Matrix::postMult(const Matrix& m) +{ + Matrix tm; + matrix_mult( _mat, m._mat, tm._mat ); + *this = tm; +} + + +void Matrix::mult(const Matrix& lhs,const Matrix& rhs) +{ + if (&lhs==this || &rhs==this) + { + osg::Matrix tm; + matrix_mult( lhs._mat, rhs._mat, tm._mat ); + *this = tm; + } + else + { + matrix_mult( lhs._mat, rhs._mat, _mat ); + } +} + + +Matrix Matrix::operator * (const Matrix& m) const +{ + Matrix tm; + matrix_mult( _mat,m._mat, tm._mat ); + return tm; +} + + +bool Matrix::invert(const Matrix& invm) +{ + if (&invm==this) { + Matrix tm(invm); + return invert(tm); + } + + // code lifted from VR Juggler. + // not cleanly added, but seems to work. RO. + + const float* a = reinterpret_cast(invm._mat); + float* b = reinterpret_cast(_mat); + + int n = 4; + int i, j, k; + int r[ 4], c[ 4], row[ 4], col[ 4]; + float m[ 4][ 4*2], pivot, max_m, tmp_m, fac; + + /* Initialization */ + for ( i = 0; i < n; i ++ ) + { + r[ i] = c[ i] = 0; + row[ i] = col[ i] = 0; + } + + /* Set working matrix */ + for ( i = 0; i < n; i++ ) + { + for ( j = 0; j < n; j++ ) + { + m[ i][ j] = a[ i * n + j]; + m[ i][ j + n] = ( i == j ) ? 1.0 : 0.0 ; + } + } + + /* Begin of loop */ + for ( k = 0; k < n; k++ ) + { + /* Choosing the pivot */ + for ( i = 0, max_m = 0; i < n; i++ ) + { + if ( row[ i] ) continue; + for ( j = 0; j < n; j++ ) + { + if ( col[ j] ) continue; + tmp_m = fabs( m[ i][j]); + if ( tmp_m > max_m) + { + max_m = tmp_m; + r[ k] = i; + c[ k] = j; + } + } + } + row[ r[k] ] = col[ c[k] ] = 1; + pivot = m[ r[ k] ][ c[ k] ]; + + if ( fabs( pivot) <= 1e-20) + { + notify(WARN) << "*** pivot = %f in mat_inv. ***\n"; + //exit( 0); + return false; + } + + /* Normalization */ + for ( j = 0; j < 2*n; j++ ) + { + if ( j == c[ k] ) + m[ r[ k]][ j] = 1.0; + else + m[ r[ k]][ j] /=pivot; + } + + /* Reduction */ + for ( i = 0; i < n; i++ ) + { + if ( i == r[ k] ) + continue; + + for ( j=0, fac = m[ i][ c[k]];j < 2*n; j++ ) + { + if ( j == c[ k] ) + m[ i][ j] =0.0; + else + m[ i][ j] -=fac * m[ r[k]][ j]; + } + } + } + + /* Assign invers to a matrix */ + for ( i = 0; i < n; i++ ) + for ( j = 0; j < n; j++ ) + row[ i] = ( c[ j] == i ) ? r[j] : row[ i]; + + for ( i = 0; i < n; i++ ) + for ( j = 0; j < n; j++ ) + b[ i * n + j] = m[ row[ i]][j + n]; + + return true; // It worked +} diff --git a/src/osg/Viewport.cpp b/src/osg/Viewport.cpp new file mode 100644 index 000000000..5bd5672de --- /dev/null +++ b/src/osg/Viewport.cpp @@ -0,0 +1,22 @@ +#include + +using namespace osg; + +Viewport::Viewport() +{ + _x = 0; + _y = 0; + _width = 800; + _height = 600; +} + + +Viewport::~Viewport() +{ +} + +void Viewport::apply(State&) const +{ + glViewport(_x,_y,_width,_height); +} + diff --git a/src/osgUtil/AppVisitor.cpp b/src/osgUtil/AppVisitor.cpp new file mode 100644 index 000000000..a11665a0c --- /dev/null +++ b/src/osgUtil/AppVisitor.cpp @@ -0,0 +1,18 @@ +#include + +using namespace osg; +using namespace osgUtil; + +AppVisitor::AppVisitor():NodeVisitor(TRAVERSE_ACTIVE_CHILDREN) +{ +} + + +AppVisitor::~AppVisitor() +{ +} + + +void AppVisitor::reset() +{ +}