Synch with 20010921
This commit is contained in:
@@ -82,6 +82,7 @@ void Billboard::calcRotation(const Vec3& eye_local, const Vec3& pos_local,Matrix
|
||||
float ev_length = ev.length();
|
||||
if (ev_length>0.0f)
|
||||
{
|
||||
mat.makeIdent();
|
||||
//float rotation_zrotation_z = atan2f(ev.x(),ev.y());
|
||||
//mat.makeRot(rotation_z*180.0f/M_PI,0.0f,0.0f,1.0f);
|
||||
float inv = 1.0f/ev_length;
|
||||
|
||||
@@ -11,6 +11,8 @@ using namespace osg;
|
||||
Camera::Camera()
|
||||
{
|
||||
|
||||
_adjustAspectRatioMode = ADJUST_HORIZONTAL;
|
||||
|
||||
// projection details.
|
||||
setPerspective(60,1.0,1.0,1000.0);
|
||||
|
||||
@@ -117,6 +119,34 @@ void Camera::setPerspective(const double fovy,const double aspectRatio,
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/** Set a sysmetical perspective projection using field of view.*/
|
||||
void Camera::setFOV(const double fovx,const double fovy,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
_projectionType = PERSPECTIVE;
|
||||
|
||||
// note, in Frustum/Perspective mode these values are scaled
|
||||
// by the zNear from when they were initialised to ensure that
|
||||
// subsequent changes in zNear do not affect them.
|
||||
|
||||
// calculate the appropriate left, right etc.
|
||||
double tan_fovx = tan(DEG2RAD(fovx*0.5));
|
||||
double tan_fovy = tan(DEG2RAD(fovy*0.5));
|
||||
_right = tan_fovx;
|
||||
_left = -_right;
|
||||
_top = tan_fovy;
|
||||
_bottom = -_top;
|
||||
|
||||
_zNear = zNear;
|
||||
_zFar = zFar;
|
||||
|
||||
notify(INFO)<<"osg::Camera::setFOV(fovx="<<fovx<<",fovy="<<fovy<<","<<endl;
|
||||
notify(INFO)<<" zNear="<<zNear<<", zFar="<<zFar<<")"<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovx()="<<calc_fovx()<<endl;
|
||||
notify(INFO)<<" osg::Camera::calc_fovy()="<<calc_fovy()<<endl;
|
||||
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/** Set the near and far clipping planes.*/
|
||||
void Camera::setNearFar(const double zNear, const double zFar)
|
||||
@@ -134,7 +164,7 @@ void Camera::setNearFar(const double zNear, const double zFar)
|
||||
|
||||
/** Adjust the clipping planes to account for a new window aspcect ratio.
|
||||
* Typicall used after resizeing a window.*/
|
||||
void Camera::adjustAspectRatio(const double newAspectRatio, const AdjustAxis aa)
|
||||
void Camera::adjustAspectRatio(const double newAspectRatio, const AdjustAspectRatioMode aa)
|
||||
{
|
||||
double previousAspectRatio = (_right-_left)/(_top-_bottom);
|
||||
double deltaRatio = newAspectRatio/previousAspectRatio;
|
||||
@@ -668,15 +698,15 @@ void Camera::ensureOrthogonalUpVector()
|
||||
_up.normalize();
|
||||
}
|
||||
|
||||
const bool Camera::project(const Vec3& obj,const int* view,Vec3& win) const
|
||||
const bool Camera::project(const Vec3& obj,const Viewport& viewport,Vec3& win) const
|
||||
{
|
||||
if (_MP.valid())
|
||||
{
|
||||
Vec3 v = obj * (*_MP);
|
||||
|
||||
win.set(
|
||||
view[0] + view[2]*(v[0]+1.0f)*0.5f,
|
||||
view[1] + view[3]*(v[1]+1.0f)*0.5f,
|
||||
(float)viewport.x() + (float)viewport.width()*(v[0]+1.0f)*0.5f,
|
||||
(float)viewport.y() + (float)viewport.height()*(v[1]+1.0f)*0.5f,
|
||||
(v[2]+1.0f)*0.5f
|
||||
);
|
||||
|
||||
@@ -686,13 +716,13 @@ const bool Camera::project(const Vec3& obj,const int* view,Vec3& win) const
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool Camera::unproject(const Vec3& win,const int* view,Vec3& obj) const
|
||||
const bool Camera::unproject(const Vec3& win,const Viewport& viewport,Vec3& obj) const
|
||||
{
|
||||
if (_inverseMP.valid())
|
||||
{
|
||||
Vec3 v(
|
||||
2.0f*(win[0]-view[0])/view[2] - 1.0f,
|
||||
2.0f*(win[1]-view[1])/view[3] - 1.0f,
|
||||
2.0f*(win[0]-(float)viewport.x())/viewport.width() - 1.0f,
|
||||
2.0f*(win[1]-(float)viewport.y())/viewport.height() - 1.0f,
|
||||
2.0f*(win[2]) - 1.0f
|
||||
);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using namespace osg;
|
||||
|
||||
ClipPlane::ClipPlane()
|
||||
{
|
||||
_clipPlane = new double[4];
|
||||
_clipPlane[0] = 0.0;
|
||||
_clipPlane[1] = 0.0;
|
||||
_clipPlane[2] = 0.0;
|
||||
@@ -16,7 +15,6 @@ ClipPlane::ClipPlane()
|
||||
|
||||
ClipPlane::~ClipPlane()
|
||||
{
|
||||
delete _clipPlane;
|
||||
}
|
||||
|
||||
void ClipPlane::setClipPlane(const Vec4& plane)
|
||||
@@ -68,17 +66,10 @@ void ClipPlane::getClipPlane(Plane& plane) const
|
||||
|
||||
void ClipPlane::getClipPlane(double* plane) const
|
||||
{
|
||||
if (plane)
|
||||
{
|
||||
plane[0] = _clipPlane[0];
|
||||
plane[1] = _clipPlane[1];
|
||||
plane[2] = _clipPlane[2];
|
||||
plane[3] = _clipPlane[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(WARN)<<"Warning: ClipPlane::getClipPlane() passed NULL plane array, ignoring operation."<<endl;
|
||||
}
|
||||
plane[0] = _clipPlane[0];
|
||||
plane[1] = _clipPlane[1];
|
||||
plane[2] = _clipPlane[2];
|
||||
plane[3] = _clipPlane[3];
|
||||
}
|
||||
|
||||
void ClipPlane::setClipPlaneNum(const unsigned int num)
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
#include <math.h>
|
||||
#include "osg/Geode"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __sgi
|
||||
using std::find;
|
||||
using std::for_each;
|
||||
#endif
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@@ -5,12 +5,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// #ifdef __sgi
|
||||
// using std::find;
|
||||
// using std::for_each;
|
||||
// using std::string;
|
||||
// #endif
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
using namespace osg;
|
||||
@@ -58,6 +52,16 @@ bool Group::addChild( Node *child )
|
||||
|
||||
dirtyBound();
|
||||
|
||||
// could now require app traversal thanks to the new subgraph,
|
||||
// so need to check and update if required.
|
||||
if (child->getNumChildrenRequiringAppTraversal()>0 ||
|
||||
child->getAppCallback())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(
|
||||
getNumChildrenRequiringAppTraversal()+1
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
@@ -73,10 +77,23 @@ bool Group::removeChild( Node *child )
|
||||
ParentList::iterator pitr = std::find(child->_parents.begin(),child->_parents.end(),this);
|
||||
if (pitr!=child->_parents.end()) child->_parents.erase(pitr);
|
||||
|
||||
// could now require app traversal thanks to the new subgraph,
|
||||
// so need to check and update if required.
|
||||
// note, need to do this checking before the erase of the child
|
||||
// otherwise child will be invalid.
|
||||
if (child->getNumChildrenRequiringAppTraversal()>0 ||
|
||||
child->getAppCallback())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(
|
||||
getNumChildrenRequiringAppTraversal()-1
|
||||
);
|
||||
}
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing child's reference count.
|
||||
_children.erase(itr);
|
||||
dirtyBound();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
@@ -41,7 +41,7 @@ ImpostorSprite::~ImpostorSprite()
|
||||
}
|
||||
}
|
||||
|
||||
const float ImpostorSprite::calcPixelError(const Camera& camera,const int* viewport,const osg::Matrix* matrix) const
|
||||
const float ImpostorSprite::calcPixelError(const Camera& camera,const Viewport& viewport,const osg::Matrix* matrix) const
|
||||
{
|
||||
// find the maximum screen space pixel error between the control coords and the quad coners.
|
||||
float max_error_sqrd = 0.0f;
|
||||
@@ -139,6 +139,12 @@ void ImpostorSprite::setTexture(Texture* tex,int s,int t)
|
||||
|
||||
ImpostorSpriteManager::ImpostorSpriteManager()
|
||||
{
|
||||
_texenv = new TexEnv;
|
||||
_texenv->setMode(TexEnv::REPLACE);
|
||||
|
||||
_alphafunc = new osg::AlphaFunc;
|
||||
_alphafunc->setFunction( AlphaFunc::GREATER, 0.000f );
|
||||
|
||||
_first = NULL;
|
||||
_last = NULL;
|
||||
}
|
||||
@@ -250,8 +256,12 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i
|
||||
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
|
||||
|
||||
Texture* texture = new Texture;
|
||||
stateset->setAttributeAndModes(texture,StateAttribute::ON);
|
||||
|
||||
stateset->setAttributeAndModes(texture,StateAttribute::ON);
|
||||
stateset->setAttributeAndModes( _alphafunc.get(), StateAttribute::ON );
|
||||
stateset->setAttribute(_texenv.get());
|
||||
|
||||
/*
|
||||
TexEnv* texenv = new TexEnv;
|
||||
texenv->setMode(TexEnv::REPLACE);
|
||||
stateset->setAttribute(texenv);
|
||||
@@ -259,6 +269,8 @@ ImpostorSprite* ImpostorSpriteManager::createOrReuseImpostorSprite(int s,int t,i
|
||||
AlphaFunc* alphafunc = new osg::AlphaFunc;
|
||||
alphafunc->setFunction( AlphaFunc::GREATER, 0.000f );
|
||||
stateset->setAttributeAndModes( alphafunc, StateAttribute::ON );
|
||||
*/
|
||||
|
||||
|
||||
// stateset->setMode( GL_ALPHA_TEST, StateAttribute::OFF );
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ C++FILES = \
|
||||
Depth.cpp \
|
||||
Drawable.cpp\
|
||||
Fog.cpp\
|
||||
FrameStamp.cpp\
|
||||
FrontFace.cpp\
|
||||
Geode.cpp\
|
||||
GeoSet.cpp\
|
||||
@@ -48,6 +49,7 @@ C++FILES = \
|
||||
Transform.cpp\
|
||||
Transparency.cpp\
|
||||
Version.cpp\
|
||||
Viewport.cpp\
|
||||
|
||||
|
||||
TARGET_BASENAME = osg
|
||||
@@ -69,6 +71,7 @@ TARGET_INCLUDE_FILES = \
|
||||
osg/Drawable\
|
||||
osg/Export\
|
||||
osg/Fog\
|
||||
osg/FrameStamp\
|
||||
osg/FrontFace\
|
||||
osg/GL\
|
||||
osg/GLExtensions\
|
||||
@@ -86,6 +89,7 @@ TARGET_INCLUDE_FILES = \
|
||||
osg/Matrix\
|
||||
osg/MemoryAdapter\
|
||||
osg/Node\
|
||||
osg/NodeCallback\
|
||||
osg/NodeVisitor\
|
||||
osg/Notify\
|
||||
osg/Object\
|
||||
@@ -112,6 +116,7 @@ TARGET_INCLUDE_FILES = \
|
||||
osg/Vec3\
|
||||
osg/Vec4\
|
||||
osg/Version\
|
||||
osg/Viewport\
|
||||
osg/mem_ptr\
|
||||
osg/ref_ptr\
|
||||
|
||||
|
||||
@@ -1,418 +1,90 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osg/Types>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Notify>
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Types>
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
#include <cstdlib> //memcpy
|
||||
#include <cmath> //acos
|
||||
|
||||
using namespace osg;
|
||||
|
||||
typedef struct quaternion_
|
||||
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
|
||||
|
||||
//#define WARN_DEPRECATED
|
||||
#define ANGLES_IN_DEGREES
|
||||
|
||||
#define SET_ROW(row, v1, v2, v3, v4 ) \
|
||||
_mat[(row)][0] = (v1); \
|
||||
_mat[(row)][1] = (v2); \
|
||||
_mat[(row)][2] = (v3); \
|
||||
_mat[(row)][3] = (v4);
|
||||
|
||||
#define INNER_PRODUCT(a,b,r,c) \
|
||||
((a)._mat[r][0] * (b)._mat[0][c]) \
|
||||
+((a)._mat[r][1] * (b)._mat[1][c]) \
|
||||
+((a)._mat[r][2] * (b)._mat[2][c]) \
|
||||
+((a)._mat[r][3] * (b)._mat[3][c])
|
||||
|
||||
|
||||
Matrix::Matrix() : Object(), fully_realized(false) {}
|
||||
|
||||
Matrix::Matrix( const Matrix& other ) : Object()
|
||||
{
|
||||
double x ;
|
||||
double y ;
|
||||
double z ;
|
||||
double w ;
|
||||
} quaternion ;
|
||||
set( (float const * const) other._mat );
|
||||
}
|
||||
|
||||
/* C = a(row).b(row) */
|
||||
Matrix::Matrix( float const * const def )
|
||||
{
|
||||
set( def );
|
||||
}
|
||||
|
||||
#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] )
|
||||
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)
|
||||
{
|
||||
/* copied from Shoemake/ACM SIGGRAPH 89 */
|
||||
double xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz ;
|
||||
SET_ROW(0, a00, a01, a02, a03 )
|
||||
SET_ROW(1, a10, a11, a12, a13 )
|
||||
SET_ROW(2, a20, a21, a22, a23 )
|
||||
SET_ROW(3, a30, a31, a32, a33 )
|
||||
|
||||
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;
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
Matrix& Matrix::operator = (const Matrix& other ) {
|
||||
if( &other == this ) return *this;
|
||||
set((const float*)other._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;
|
||||
void Matrix::set( float const * const def ) {
|
||||
memcpy( _mat, def, sizeof(_mat) );
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
|
||||
Matrix::~Matrix()
|
||||
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)
|
||||
{
|
||||
SET_ROW(0, a00, a01, a02, a03 )
|
||||
SET_ROW(1, a10, a11, a12, a13 )
|
||||
SET_ROW(2, a20, a21, a22, a23 )
|
||||
SET_ROW(3, a30, a31, a32, a33 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::setTrans is deprecated.";
|
||||
#endif
|
||||
_mat[3][0] = tx;
|
||||
_mat[3][1] = ty;
|
||||
_mat[3][2] = tz;
|
||||
@@ -421,62 +93,238 @@ void Matrix::setTrans( float tx, float ty, float tz )
|
||||
|
||||
void Matrix::setTrans( const Vec3& v )
|
||||
{
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::setTrans is deprecated.";
|
||||
#endif
|
||||
_mat[3][0] = v[0];
|
||||
_mat[3][1] = v[1];
|
||||
_mat[3][2] = v[2];
|
||||
}
|
||||
|
||||
|
||||
void Matrix::preMult(const Matrix& m)
|
||||
void Matrix::makeIdent()
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( m._mat, _mat, tm._mat );
|
||||
*this = tm;
|
||||
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::postMult(const Matrix& m)
|
||||
void Matrix::makeScale( const Vec3& v )
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( _mat, m._mat, tm._mat );
|
||||
*this = tm;
|
||||
makeScale(v[0], v[1], v[2] );
|
||||
}
|
||||
|
||||
|
||||
void Matrix::mult(const Matrix& lhs,const Matrix& rhs)
|
||||
void Matrix::makeScale( float x, float y, float z )
|
||||
{
|
||||
if (&lhs==this || &rhs==this)
|
||||
{
|
||||
osg::Matrix tm;
|
||||
matrix_mult( lhs._mat, rhs._mat, tm._mat );
|
||||
*this = tm;
|
||||
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, 0 )
|
||||
SET_ROW(1, 0, 1, 0, 0 )
|
||||
SET_ROW(2, 0, 0, 1, 0 )
|
||||
SET_ROW(3, x, y, z, 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);
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = RAD2DEG(angle);
|
||||
#endif
|
||||
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;
|
||||
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = DEG2RAD(angle);
|
||||
#endif
|
||||
|
||||
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 );//NOTE: original used a private quaternion made of doubles
|
||||
makeRot( q ); // but Quat stores the values in a Vec4 made of floats.
|
||||
}
|
||||
|
||||
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 + wy, 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)
|
||||
{
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
yaw = DEG2RAD(yaw);
|
||||
pitch = DEG2RAD(pitch);
|
||||
roll = DEG2RAD(roll);
|
||||
#endif
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
if( !fully_realized ) {
|
||||
//act as if this were an identity Matrix
|
||||
set((const float*)other._mat);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
// brute force method requiring a copy
|
||||
//Matrix tmp(other* *this);
|
||||
// *this = tmp;
|
||||
|
||||
// more efficient method just use a float[4] for temporary storage.
|
||||
float t[4];
|
||||
for(int col=0; col<4; ++col) {
|
||||
t[0] = INNER_PRODUCT( other, *this, 0, col );
|
||||
t[1] = INNER_PRODUCT( other, *this, 1, col );
|
||||
t[2] = INNER_PRODUCT( other, *this, 2, col );
|
||||
t[3] = INNER_PRODUCT( other, *this, 3, col );
|
||||
_mat[0][col] = t[0];
|
||||
_mat[1][col] = t[1];
|
||||
_mat[2][col] = t[2];
|
||||
_mat[3][col] = t[3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Matrix::postMult( const Matrix& other )
|
||||
{
|
||||
if( !fully_realized ) {
|
||||
//act as if this were an identity Matrix
|
||||
set((const float*)other._mat);
|
||||
return;
|
||||
}
|
||||
// brute force method requiring a copy
|
||||
//Matrix tmp(*this * other);
|
||||
// *this = tmp;
|
||||
|
||||
// more efficient method just use a float[4] for temporary storage.
|
||||
float t[4];
|
||||
for(int row=0; row<4; ++row)
|
||||
{
|
||||
matrix_mult( lhs._mat, rhs._mat, _mat );
|
||||
t[0] = INNER_PRODUCT( *this, other, row, 0 );
|
||||
t[1] = INNER_PRODUCT( *this, other, row, 1 );
|
||||
t[2] = INNER_PRODUCT( *this, other, row, 2 );
|
||||
t[3] = INNER_PRODUCT( *this, other, row, 3 );
|
||||
SET_ROW(row, t[0], t[1], t[2], t[3] )
|
||||
}
|
||||
}
|
||||
|
||||
#undef SET_ROW
|
||||
#undef INNER_PRODUCT
|
||||
|
||||
Matrix Matrix::operator * (const Matrix& m) const
|
||||
bool Matrix::invert( const Matrix& _m )
|
||||
{
|
||||
Matrix tm;
|
||||
matrix_mult( _mat,m._mat, tm._mat );
|
||||
return tm;
|
||||
}
|
||||
|
||||
|
||||
bool Matrix::invert(const Matrix& invm)
|
||||
{
|
||||
if (&invm==this) {
|
||||
Matrix tm(invm);
|
||||
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<const float*>(invm._mat);
|
||||
const float* a = reinterpret_cast<const float*>(_m._mat);
|
||||
float* b = reinterpret_cast<float*>(_mat);
|
||||
|
||||
int n = 4;
|
||||
@@ -491,7 +339,7 @@ bool Matrix::invert(const Matrix& invm)
|
||||
row[ i] = col[ i] = 0;
|
||||
}
|
||||
|
||||
/* Set working matrix */
|
||||
/* Set working Matrix */
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
for ( j = 0; j < n; j++ )
|
||||
@@ -555,7 +403,7 @@ bool Matrix::invert(const Matrix& invm)
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign invers to a matrix */
|
||||
/* 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];
|
||||
@@ -566,3 +414,154 @@ bool Matrix::invert(const Matrix& invm)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//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.";
|
||||
#endif
|
||||
(*this) = ( scale(sx,sy,sz) * m );
|
||||
}
|
||||
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.";
|
||||
#endif
|
||||
(*this) = ( m * scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::preScale( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preScale is deprecated. Use M.preMult( Matrix::scale ) instead.";
|
||||
#endif
|
||||
preMult( scale(sx,sy,sz) );
|
||||
}
|
||||
void Matrix::postScale( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postScale is deprecated. Use M.postMult( Matrix::scale ) instead.";
|
||||
#endif
|
||||
postMult( scale(sx,sy,sz) );
|
||||
}
|
||||
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.";
|
||||
#endif
|
||||
(*this) = trans(tx,ty,tz) * m;
|
||||
}
|
||||
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.";
|
||||
#endif
|
||||
(*this) = m * trans(tx,ty,tz);
|
||||
}
|
||||
void Matrix::preTrans( float tx, float ty, float tz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.";
|
||||
#endif
|
||||
preMult( trans(tx,ty,tz) );
|
||||
}
|
||||
void Matrix::postTrans( float sx, float sy, float sz ) {
|
||||
#ifdef WARN_DEPRECATED
|
||||
notify(NOTICE) << "Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.";
|
||||
#endif
|
||||
postMult( trans(sx,sy,sz) );
|
||||
}
|
||||
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.";
|
||||
#endif
|
||||
(*this) = rotate(deg,x,y,z) * m;
|
||||
}
|
||||
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.";
|
||||
#endif
|
||||
(*this) = m * rotate(deg,x,y,z);
|
||||
}
|
||||
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.";
|
||||
#endif
|
||||
preMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
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.";
|
||||
#endif
|
||||
postMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
|
||||
@@ -8,7 +8,12 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#define DEG2RAD(x) ((x)*M_PI/180.0)
|
||||
#define RAD2DEG(x) ((x)*180.0/M_PI)
|
||||
|
||||
|
||||
#define WARN_DEPRECATED
|
||||
#define ANGLES_IN_DEGREES
|
||||
|
||||
Matrix::Matrix() : Object(), fully_realized(false) {}
|
||||
|
||||
@@ -86,11 +91,10 @@ void Matrix::set(
|
||||
}
|
||||
|
||||
#define SET_ROW(row, v1, v2, v3, v4 ) \
|
||||
_mat[0][(row)] = (v1); \
|
||||
_mat[1][(row)] = (v2); \
|
||||
_mat[2][(row)] = (v3); \
|
||||
_mat[3][(row)] = (v4);
|
||||
|
||||
_mat[(row)][0] = (v1); \
|
||||
_mat[(row)][1] = (v2); \
|
||||
_mat[(row)][2] = (v3); \
|
||||
_mat[(row)][3] = (v4);
|
||||
|
||||
void Matrix::makeIdent() {
|
||||
SET_ROW(0, 1, 0, 0, 0 )
|
||||
@@ -119,10 +123,10 @@ void Matrix::makeTrans( const Vec3& v ) {
|
||||
}
|
||||
|
||||
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 )
|
||||
SET_ROW(0, 1, 0, 0, 0 )
|
||||
SET_ROW(1, 0, 1, 0, 0 )
|
||||
SET_ROW(2, 0, 0, 1, 0 )
|
||||
SET_ROW(3, x, y, z, 1 )
|
||||
|
||||
fully_realized = true;
|
||||
}
|
||||
@@ -131,6 +135,9 @@ 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);
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = RAD2DEG(angle);
|
||||
#endif
|
||||
Vec3 axis = to ^ from; //we know ((to) x (from)) is perpendicular to both
|
||||
makeRot( angle, axis );
|
||||
}
|
||||
@@ -138,7 +145,8 @@ void Matrix::makeRot( const Vec3& from, const Vec3& to ) {
|
||||
makeIdent();
|
||||
}
|
||||
|
||||
void Matrix::makeRot( float angle, const Vec3& axis ) {
|
||||
void Matrix::makeRot( float angle, const Vec3& axis )
|
||||
{
|
||||
makeRot( angle, axis.x(), axis.y(), axis.z() );
|
||||
}
|
||||
|
||||
@@ -147,6 +155,10 @@ void Matrix::makeRot( float angle, float x, float y, float z ) {
|
||||
if( d == 0 )
|
||||
return;
|
||||
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
angle = DEG2RAD(angle);
|
||||
#endif
|
||||
|
||||
float sin_half = sin( angle/2 );
|
||||
float cos_half = cos( angle/2 );
|
||||
|
||||
@@ -175,15 +187,22 @@ void Matrix::makeRot( const Quat& q ) {
|
||||
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(0, 1.0-(yy+zz), xy + wz, xz - wy, 0.0 )
|
||||
SET_ROW(1, xy - wz, 1.0-(xx+zz),yz + wx, 0.0 )
|
||||
SET_ROW(2, xz + wz, 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) {
|
||||
void Matrix::makeRot( float yaw, float pitch, float roll)
|
||||
{
|
||||
#ifdef ANGLES_IN_DEGREES
|
||||
yaw = DEG2RAD(yaw);
|
||||
pitch = DEG2RAD(pitch);
|
||||
roll = DEG2RAD(roll);
|
||||
#endif
|
||||
|
||||
// lifted straight from SOLID library v1.01 Quaternion.h
|
||||
// available from http://www.win.tue.nl/~gino/solid/
|
||||
// and also distributed under the LGPL
|
||||
@@ -200,11 +219,11 @@ void Matrix::makeRot( float yaw, float pitch, float roll) {
|
||||
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])
|
||||
#define INNER_PRODUCT(a,b,r,c) \
|
||||
((a)._mat[r][0] * (b)._mat[0][c]) \
|
||||
+((a)._mat[r][1] * (b)._mat[1][c]) \
|
||||
+((a)._mat[r][2] * (b)._mat[2][c]) \
|
||||
+((a)._mat[r][3] * (b)._mat[3][c])
|
||||
|
||||
void Matrix::mult( const Matrix& lhs, const Matrix& rhs ) {
|
||||
// PRECONDITION: We assume neither &lhs nor &rhs == this
|
||||
@@ -390,7 +409,7 @@ bool Matrix::invertAffine( const Matrix& _m ) {
|
||||
// returns true if _m is nonsingular, and (*this) contains its inverse
|
||||
// otherwise returns false. (*this unchanged)
|
||||
|
||||
// assert (this.isAffine()) ?
|
||||
// assert( this->isAffine())?
|
||||
double det_1, pos, neg, temp;
|
||||
|
||||
pos = neg = 0.0;
|
||||
@@ -487,72 +506,72 @@ void Matrix::copy( const Matrix& 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
|
||||
(*this) = ( scale(sx,sy,sz) * m );
|
||||
}
|
||||
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
|
||||
(*this) = ( m * scale(sx,sy,sz) );
|
||||
}
|
||||
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
|
||||
preMult( scale(sx,sy,sz) );
|
||||
}
|
||||
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
|
||||
postMult( scale(sx,sy,sz) );
|
||||
}
|
||||
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
|
||||
(*this) = trans(tx,ty,tz) * m;
|
||||
}
|
||||
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
|
||||
(*this) = m * trans(tx,ty,tz);
|
||||
}
|
||||
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
|
||||
preMult( trans(sx,sy,sz) );
|
||||
}
|
||||
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
|
||||
postMult( trans(sx,sy,sz) );
|
||||
}
|
||||
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
|
||||
(*this) = rotate(deg,x,y,z) * m;
|
||||
}
|
||||
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
|
||||
(*this) = m * rotate(deg,x,y,z);
|
||||
}
|
||||
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
|
||||
preMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
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
|
||||
postMult( rotate(deg,x,y,z) );
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ Node::Node()
|
||||
_bsphere_computed = false;
|
||||
_userData = NULL;
|
||||
_nodeMask = 0xffffffff;
|
||||
|
||||
_numChildrenRequiringAppTraversal = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +26,7 @@ Node::~Node()
|
||||
|
||||
void Node::accept(NodeVisitor& nv)
|
||||
{
|
||||
nv.apply(*this);
|
||||
if (nv.validNodeMask(*this)) nv.apply(*this);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +35,83 @@ void Node::ascend(NodeVisitor& nv)
|
||||
std::for_each(_parents.begin(),_parents.end(),NodeAcceptOp(nv));
|
||||
}
|
||||
|
||||
void Node::setAppCallback(NodeCallback* nc)
|
||||
{
|
||||
// if no changes just return.
|
||||
if (_appCallback==nc) return;
|
||||
|
||||
// app callback has been changed, will need to update
|
||||
// both _appCallback and possibly the numChildrenRequiringAppTraversal
|
||||
// if the number of callbacks changes.
|
||||
|
||||
|
||||
// update the parents numChildrenRequiringAppTraversal
|
||||
// note, if _numChildrenRequiringAppTraversal!=0 then the
|
||||
// parents won't be affected by any app callback change,
|
||||
// so no need to inform them.
|
||||
if (_numChildrenRequiringAppTraversal==0 && !_parents.empty())
|
||||
{
|
||||
int delta = 0;
|
||||
if (_appCallback.valid()) --delta;
|
||||
if (nc) ++delta;
|
||||
if (delta!=0)
|
||||
{
|
||||
// the number of callbacks has changed, need to pass this
|
||||
// on to parents so they know whether app traversal is
|
||||
// reqired on this subgraph.
|
||||
for(ParentList::iterator itr =_parents.begin();
|
||||
itr != _parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setNumChildrenRequiringAppTraversal(
|
||||
(*itr)->getNumChildrenRequiringAppTraversal()+delta );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// set the app callback itself.
|
||||
_appCallback = nc;
|
||||
|
||||
}
|
||||
|
||||
void Node::setNumChildrenRequiringAppTraversal(const int num)
|
||||
{
|
||||
// if no changes just return.
|
||||
if (_numChildrenRequiringAppTraversal==num) return;
|
||||
|
||||
// note, if _appCallback is set then the
|
||||
// parents won't be affected by any changes to
|
||||
// _numChildrenRequiringAppTraversal so no need to inform them.
|
||||
if (!_appCallback && !_parents.empty())
|
||||
{
|
||||
|
||||
// need to pass on changes to parents.
|
||||
int delta = 0;
|
||||
if (_numChildrenRequiringAppTraversal>0) --delta;
|
||||
if (num>0) ++delta;
|
||||
if (delta!=0)
|
||||
{
|
||||
// the number of callbacks has changed, need to pass this
|
||||
// on to parents so they know whether app traversal is
|
||||
// reqired on this subgraph.
|
||||
for(ParentList::iterator itr =_parents.begin();
|
||||
itr != _parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setNumChildrenRequiringAppTraversal(
|
||||
(*itr)->getNumChildrenRequiringAppTraversal()+delta
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// finally update this objects value.
|
||||
_numChildrenRequiringAppTraversal=num;
|
||||
|
||||
}
|
||||
|
||||
const bool Node::computeBound() const
|
||||
{
|
||||
_bsphere.init();
|
||||
|
||||
@@ -5,8 +5,12 @@ using namespace osg;
|
||||
|
||||
NodeVisitor::NodeVisitor(TraversalMode tm)
|
||||
{
|
||||
_traversalNumber = -1;
|
||||
|
||||
_traversalVisitor = NULL;
|
||||
_traversalMode = tm;
|
||||
_traversalMask = 0xffffffff;
|
||||
_nodeMaskOverride = 0x0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
// Ideas and code borrowed from GLUT pointburst demo
|
||||
// written by Mark J. Kilgard
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "osg/GL"
|
||||
#include "osg/GLExtensions"
|
||||
#include "osg/Point"
|
||||
|
||||
@@ -8,7 +8,6 @@ using namespace osg;
|
||||
State::State()
|
||||
{
|
||||
_contextID = 0;
|
||||
_frameNumber = 0;
|
||||
_fineGrainedErrorDetection = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,31 +155,6 @@ void StateSet::compile(State& state) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const StateSet::ModeVector StateSet::getModeVector() const
|
||||
{
|
||||
ModeVector vec;
|
||||
for (ModeList::const_iterator itr = _modeList.begin();
|
||||
itr!=_modeList.end();
|
||||
++itr)
|
||||
{
|
||||
vec.push_back(*itr);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
const StateSet::AttributeVector StateSet::getAttributeVector() const
|
||||
{
|
||||
AttributeVector vec;
|
||||
for (AttributeList::const_iterator itr = _attributeList.begin();
|
||||
itr!=_attributeList.end();
|
||||
++itr)
|
||||
{
|
||||
vec.push_back(itr->second.first.get());
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
void StateSet::setRenderingHint(const int hint)
|
||||
{
|
||||
_renderingHint = hint;
|
||||
|
||||
@@ -46,6 +46,50 @@ Texture::~Texture()
|
||||
dirtyTextureObject();
|
||||
}
|
||||
|
||||
int Texture::compare(const StateAttribute& sa) const
|
||||
{
|
||||
// check the types are equal and then create the rhs variable
|
||||
// used by the COMPARE_StateAttribute_Paramter macro's below.
|
||||
COMPARE_StateAttribute_Types(Texture,sa)
|
||||
|
||||
if (_image!=rhs._image) // smart pointer comparison.
|
||||
{
|
||||
if (_image.valid())
|
||||
{
|
||||
if (rhs._image.valid())
|
||||
{
|
||||
if (_image->getFileName()<rhs._image->getFileName()) return -1;
|
||||
else if (_image->getFileName()>rhs._image->getFileName()) return 1;;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // valid lhs._image is greater than null.
|
||||
}
|
||||
}
|
||||
else if (rhs._image.valid())
|
||||
{
|
||||
return -1; // valid rhs._image is greater than null.
|
||||
}
|
||||
}
|
||||
|
||||
// compare each paramter in turn against the rhs.
|
||||
COMPARE_StateAttribute_Parameter(_textureUnit)
|
||||
COMPARE_StateAttribute_Parameter(_wrap_s)
|
||||
COMPARE_StateAttribute_Parameter(_wrap_t)
|
||||
COMPARE_StateAttribute_Parameter(_wrap_r)
|
||||
COMPARE_StateAttribute_Parameter(_min_filter)
|
||||
COMPARE_StateAttribute_Parameter(_mag_filter)
|
||||
COMPARE_StateAttribute_Parameter(_internalFormatMode)
|
||||
COMPARE_StateAttribute_Parameter(_internalFormatValue)
|
||||
COMPARE_StateAttribute_Parameter(_textureWidth)
|
||||
COMPARE_StateAttribute_Parameter(_textureHeight)
|
||||
COMPARE_StateAttribute_Parameter(_subloadMode)
|
||||
COMPARE_StateAttribute_Parameter(_subloadOffsX)
|
||||
COMPARE_StateAttribute_Parameter(_subloadOffsY)
|
||||
|
||||
return 0; // passed all the above comparison macro's, must be equal.
|
||||
}
|
||||
|
||||
void Texture::setImage(Image* image)
|
||||
{
|
||||
// delete old texture objects.
|
||||
@@ -410,7 +454,7 @@ void Texture::applyImmediateMode(State& state) const
|
||||
* OpenGL texture objects to cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
* by contextID.*/
|
||||
void Texture::deleteTextureObject(uint contextID,uint handle)
|
||||
void Texture::deleteTextureObject(uint contextID,GLuint handle)
|
||||
{
|
||||
if (handle!=0)
|
||||
{
|
||||
@@ -443,7 +487,7 @@ void Texture::copyTexImage2D(State& state, int x, int y, int width, int height )
|
||||
const uint contextID = state.getContextID();
|
||||
|
||||
// get the globj for the current contextID.
|
||||
uint& handle = getHandle(contextID);
|
||||
GLuint& handle = getHandle(contextID);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
@@ -484,7 +528,6 @@ void Texture::copyTexImage2D(State& state, int x, int y, int width, int height )
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
|
||||
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, width, height, 0 );
|
||||
|
||||
|
||||
@@ -515,7 +558,6 @@ void Texture::copyTexSubImage2D(State& state, int xoffset, int yoffset, int x, i
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrap_t );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min_filter );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag_filter );
|
||||
// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, xoffset,yoffset, x, y, width, height);
|
||||
|
||||
/* Redundant, delete later */
|
||||
|
||||
@@ -1,273 +1,203 @@
|
||||
#include <stdlib.h>
|
||||
//#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef macintosh
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
#ifdef WIN32 // [
|
||||
// follows are the constructors of the Timer class, once version
|
||||
// for each OS combination. The order is WIN32, FreeBSD, Linux, IRIX,
|
||||
// and the rest of the world.
|
||||
//
|
||||
// all the rest of the timer methods are implemented within the header.
|
||||
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#ifdef WIN32
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
Timer_t start_time = tick();
|
||||
Sleep (1000);
|
||||
Timer_t end_time = tick();
|
||||
cpu_mhz = (double)(end_time-start_time)*1e-6;
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
if( !inited ) init();
|
||||
}
|
||||
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (((double)delta/cpu_mhz)*1e-6);
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (((double)delta/cpu_mhz)*1e-3);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0)/cpu_mhz);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0) * 1e3/cpu_mhz);
|
||||
}
|
||||
#endif // ]
|
||||
|
||||
#if defined(__linux) || defined(__FreeBSD__) // [
|
||||
|
||||
# include <unistd.h>
|
||||
# if defined(__linux)
|
||||
# include <sys/mman.h>
|
||||
# elif defined(__FreeBSD__)
|
||||
# include <sys/types.h>
|
||||
# include <sys/sysctl.h>
|
||||
# endif
|
||||
|
||||
int Timer::inited = 0;
|
||||
double Timer::cpu_mhz = 0.0;
|
||||
|
||||
void Timer::init( void )
|
||||
{
|
||||
# if defined(__FreeBSD__)
|
||||
int cpuspeed;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(cpuspeed);
|
||||
if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &len, NULL, NULL) == -1) {
|
||||
perror("sysctlbyname(machdep.tsc_freq)");
|
||||
return;
|
||||
}
|
||||
cpu_mhz = cpuspeed / 1e6;
|
||||
|
||||
# elif defined(__linux)
|
||||
char buff[128];
|
||||
FILE *fp = fopen( "/proc/cpuinfo", "r" );
|
||||
|
||||
while( fgets( buff, sizeof( buff ), fp ) > 0 )
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
Timer::Timer()
|
||||
{
|
||||
if( !strncmp( buff, "cpu MHz", strlen( "cpu MHz" )))
|
||||
{
|
||||
char *ptr = buff;
|
||||
_useStandardClock = false;
|
||||
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = (1.0 / (double) CLOCKS_PER_SEC);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
while( ptr && *ptr != ':' ) ptr++;
|
||||
if( ptr )
|
||||
{
|
||||
ptr++;
|
||||
sscanf( ptr, "%lf", &cpu_mhz );
|
||||
}
|
||||
break;
|
||||
}
|
||||
Timer_t start_time = tick();
|
||||
Sleep (1000);
|
||||
Timer_t end_time = tick();
|
||||
|
||||
_secsPerClick = 1.0/(double)(end_time-start_time);
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
# endif
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
if( !inited ) init();
|
||||
}
|
||||
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta/cpu_mhz*1e-6);
|
||||
}
|
||||
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta/cpu_mhz*1e-3);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0)/cpu_mhz);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t0, Timer_t t1 )
|
||||
{
|
||||
return (Timer_t)((double)(t1 - t0) * 1e3/cpu_mhz);
|
||||
}
|
||||
#endif // ]
|
||||
#ifdef __sgi // [
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/syssgi.h>
|
||||
#include <sys/immu.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
unsigned long Timer::dummy = 0;
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
__psunsigned_t phys_addr, raddr;
|
||||
unsigned int cycleval;
|
||||
volatile unsigned long counter_value, *iotimer_addr;
|
||||
int fd, poffmask;
|
||||
|
||||
poffmask = getpagesize() - 1;
|
||||
phys_addr = syssgi( SGI_QUERY_CYCLECNTR, &cycleval );
|
||||
microseconds_per_click = (double)cycleval/1e6;
|
||||
nanoseconds_per_click = (double)cycleval/1e3;
|
||||
raddr = phys_addr & ~poffmask;
|
||||
|
||||
clk = &dummy;
|
||||
|
||||
if( (fd = open( "/dev/mmem", O_RDONLY )) < 0 )
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
Timer::Timer()
|
||||
{
|
||||
perror( "/dev/mmem" );
|
||||
return;
|
||||
_useStandardClock = false;
|
||||
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
else
|
||||
{
|
||||
int cpuspeed;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(cpuspeed);
|
||||
if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &len, NULL, NULL) == -1)
|
||||
{
|
||||
_useStandardClock = true;
|
||||
perror("sysctlbyname(machdep.tsc_freq)");
|
||||
return;
|
||||
}
|
||||
|
||||
_secsPerClick = 1.0/cpuspeed;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__linux)
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
Timer::Timer()
|
||||
{
|
||||
_useStandardClock = false;
|
||||
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
else
|
||||
{
|
||||
char buff[128];
|
||||
FILE *fp = fopen( "/proc/cpuinfo", "r" );
|
||||
|
||||
double cpu_mhz=0.0f;
|
||||
|
||||
while( fgets( buff, sizeof( buff ), fp ) > 0 )
|
||||
{
|
||||
if( !strncmp( buff, "cpu MHz", strlen( "cpu MHz" )))
|
||||
{
|
||||
char *ptr = buff;
|
||||
|
||||
while( ptr && *ptr != ':' ) ptr++;
|
||||
if( ptr )
|
||||
{
|
||||
ptr++;
|
||||
sscanf( ptr, "%lf", &cpu_mhz );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
|
||||
if (cpu_mhz==0.0f)
|
||||
{
|
||||
// error - no cpu_mhz found.
|
||||
Timer_t start_time = tick();
|
||||
sleep (1);
|
||||
Timer_t end_time = tick();
|
||||
_secsPerClick = 1.0/(double)(end_time-start_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
_secsPerClick = 1e-6/cpu_mhz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iotimer_addr = (volatile unsigned long *)mmap(
|
||||
(void *)0L,
|
||||
(size_t)poffmask,
|
||||
(int)PROT_READ,
|
||||
(int)MAP_PRIVATE, fd, (off_t)raddr);
|
||||
#elif defined(__sgi)
|
||||
|
||||
iotimer_addr = (unsigned long *)(
|
||||
(__psunsigned_t)iotimer_addr + (phys_addr & poffmask)
|
||||
);
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syssgi.h>
|
||||
#include <sys/immu.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
cycleCntrSize = syssgi( SGI_CYCLECNTR_SIZE );
|
||||
unsigned long Timer::_dummy = 0;
|
||||
|
||||
if( cycleCntrSize > 32 )
|
||||
++iotimer_addr;
|
||||
Timer::Timer( void )
|
||||
{
|
||||
_useStandardClock = false;
|
||||
|
||||
clk = (unsigned long *)iotimer_addr;
|
||||
}
|
||||
if (_useStandardClock)
|
||||
{
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
else
|
||||
{
|
||||
__psunsigned_t phys_addr, raddr;
|
||||
unsigned int cycleval;
|
||||
volatile unsigned long counter_value, *iotimer_addr;
|
||||
int fd, poffmask;
|
||||
|
||||
poffmask = getpagesize() - 1;
|
||||
phys_addr = syssgi( SGI_QUERY_CYCLECNTR, &cycleval );
|
||||
raddr = phys_addr & ~poffmask;
|
||||
|
||||
_clockAddress = &_dummy;
|
||||
|
||||
if( (fd = open( "/dev/mmem", O_RDONLY )) < 0 )
|
||||
{
|
||||
perror( "/dev/mmem" );
|
||||
return;
|
||||
}
|
||||
|
||||
iotimer_addr = (volatile unsigned long *)mmap(
|
||||
(void *)0L,
|
||||
(size_t)poffmask,
|
||||
(int)PROT_READ,
|
||||
(int)MAP_PRIVATE, fd, (off_t)raddr);
|
||||
|
||||
iotimer_addr = (unsigned long *)(
|
||||
(__psunsigned_t)iotimer_addr + (phys_addr & poffmask)
|
||||
);
|
||||
|
||||
_cycleCntrSize = syssgi( SGI_CYCLECNTR_SIZE );
|
||||
|
||||
if( _cycleCntrSize > 32 )
|
||||
++iotimer_addr;
|
||||
|
||||
_clockAddress = (unsigned long *)iotimer_addr;
|
||||
_secsPerClick = (double)(cycleval)* 1e-12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
#elif defined(unix)
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
_useStandardClock = true;
|
||||
_secsPerClick = 1e-6; // gettimeofday()'s precision.
|
||||
}
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-6);
|
||||
}
|
||||
#else
|
||||
|
||||
// handle the rest of the OS world by just using the std::clock,
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-3);
|
||||
}
|
||||
Timer::Timer( void )
|
||||
{
|
||||
_useStandardClock = true;
|
||||
_secsPerClick = (1.0 / (double) CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (Timer_t)((double)delta * microseconds_per_click);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
unsigned long delta = t2 - t1;
|
||||
return (Timer_t )((double)delta * nanoseconds_per_click);
|
||||
}
|
||||
|
||||
#endif // ]
|
||||
|
||||
#ifdef macintosh // [
|
||||
|
||||
Timer::Timer( void )
|
||||
{
|
||||
microseconds_per_click = (1.0 / (double) CLOCKS_PER_SEC) * 1e6;
|
||||
nanoseconds_per_click = (1.0 / (double) CLOCKS_PER_SEC) * 1e9;
|
||||
}
|
||||
|
||||
Timer::~Timer( void )
|
||||
{
|
||||
}
|
||||
|
||||
double Timer::delta_s( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-6);
|
||||
}
|
||||
|
||||
double Timer::delta_m( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return ((double)delta * microseconds_per_click*1e-3);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_u( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
Timer_t delta = t2 - t1;
|
||||
return (Timer_t)((double)delta * microseconds_per_click);
|
||||
}
|
||||
|
||||
Timer_t Timer::delta_n( Timer_t t1, Timer_t t2 )
|
||||
{
|
||||
unsigned long delta = t2 - t1;
|
||||
return (Timer_t )((double)delta * nanoseconds_per_click);
|
||||
}
|
||||
#endif // ]
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user