From Terry Welsh, mplemented POINT_ROT_EYE.

This commit is contained in:
Robert Osfield
2006-10-14 21:47:13 +00:00
parent b439c08b71
commit 660cda57c8
2 changed files with 46 additions and 9 deletions

View File

@@ -116,6 +116,7 @@ class OSG_EXPORT Billboard : public Geode
Mode _mode;
Vec3 _axis;
Vec3 _normal;
Matrix _rotateNormalToZAxis;
PositionList _positionList;
// used internally as cache of which what _axis is aligned to help

View File

@@ -23,7 +23,8 @@ Billboard::Billboard()
{
_mode = AXIAL_ROT;
_axis.set(0.0f,0.0f,1.0f);
_normal.set(0.0f,-1.0f,0.0f);
//_normal.set(0.0f,-1.0f,0.0f);
setNormal(Vec3(0.0f,-1.0f,0.0f));
updateCache();
}
@@ -59,6 +60,22 @@ void Billboard::setNormal(const Vec3& normal)
_normal = normal;
_normal.normalize();
updateCache();
// Build rotation from normal to z-axis,
// for use with POINT_ROT_EYE
Vec3 z(0.0, 0.0, 1.0);
Vec3 cp(z^_normal);
float dot = z*_normal;
float cp_len = cp.length();
if (cp_len != 0.0f)
{
cp /= cp_len;
float rotation_cp = acosf(dot);
Matrix rotateNormalToZ;
_rotateNormalToZAxis.makeRotate(-rotation_cp, cp);
}
else
_rotateNormalToZAxis.makeIdentity();
}
void Billboard::updateCache()
@@ -204,15 +221,7 @@ bool Billboard::computeMatrix(Matrix& modelview, const Vec3& eye_local, const Ve
break;
}
case(POINT_ROT_WORLD):
case(POINT_ROT_EYE):
{
// currently treat both POINT_ROT_WORLD and POINT_ROT_EYE the same,
// this is only a temporary and 'incorrect' implementation, will
// implement fully on second pass of Billboard.
// Will also need up vector to calc POINT_ROT_EYE, so this will
// have to be added to the above method paramters.
// Robert Osfield, Jan 2001.
float ev_len = ev.length();
if (ev_len != 0.0f)
{
@@ -232,6 +241,33 @@ bool Billboard::computeMatrix(Matrix& modelview, const Vec3& eye_local, const Ve
}
break;
}
case(POINT_ROT_EYE):
{
float ev_len = ev.length();
if (ev_len != 0.0f)
{
ev /= ev_len;
Vec3 up(modelview(0,1), modelview(1,1), modelview(2,1));
Vec3 right(up^ev);
right.normalize();
up = ev^right;
up.normalize();
matrix(0,0) = right.x();
matrix(0,1) = right.y();
matrix(0,2) = right.z();
matrix(1,0) = up.x();
matrix(1,1) = up.y();
matrix(1,2) = up.z();
matrix(2,0) = ev.x();
matrix(2,1) = ev.y();
matrix(2,2) = ev.z();
matrix.preMult(_rotateNormalToZAxis);
}
break;
}
case(POINT_ROT_WORLD_Z_AXIS):
{
// float rotation_about_z = atan2( -ev.y(), ev.x() );