From Corbin Holtz, "I have completed my mods to the OpenFlight loader (modified files are

attached):
   * Light point strings using the REPLICATE opcode should now be supported
(>=15.6?)

   * Directional lights should now work as in Performer using a viewing
frustrum defined by a direction vector, horizontal angular width, vertical
angular width, and roll angle about the direction vector.  The current
directional light implementation had some bad assumptions which caused
problems with direction vectors not on the XY plane.

   * IVE and OSG reader/writers were updated as appropriate"
This commit is contained in:
Robert Osfield
2004-05-08 22:18:38 +00:00
parent b6c1c44bd0
commit 86d323752d
15 changed files with 817 additions and 135 deletions

View File

@@ -12,6 +12,7 @@
*/
#include <osgSim/Sector>
#include <osg/Vec2>
using namespace osgSim;
@@ -213,3 +214,154 @@ float ConeSector::operator() (const osg::Vec3& eyeLocal) const
if (dotproduct<_cosAngleFade*length) return 0.0f; // out of sector
return (dotproduct-_cosAngleFade*length)/((_cosAngle-_cosAngleFade)*length);
}
//
// DirectionalSector
//
DirectionalSector::DirectionalSector(const osg::Vec3& direction,float horizLobeAngle, float vertLobeAngle, float lobeRollAngle, float fadeAngle):
Sector()
{
setDirection(direction);
setHorizLobeAngle(horizLobeAngle);
setVertLobeAngle(vertLobeAngle);
setLobeRollAngle(lobeRollAngle);
setFadeAngle(fadeAngle);
}
void DirectionalSector::computeMatrix()
{
float cR = cos(_rollAngle) ;
float sR = sin(_rollAngle) ;
osg::Vec3 &D(_direction) ; // Just for clarity
_local_to_LP.set(
cR*D[1]+sR*D[0]*D[2], -cR*D[0]+sR*D[1]*D[2], -sR*(D[0]*D[0]+D[1]*D[1]), 0.0,
D[0], D[1], D[2], 0.0,
sR*D[1]-cR*D[0]*D[2], -sR*D[0]-cR*D[1]*D[2], cR*(D[0]*D[0]+D[1]*D[1]), 0.0,
0.0, 0.0, 0.0, 1.0) ;
}
void DirectionalSector::setDirection(const osg::Vec3& direction)
{
_direction = direction ;
computeMatrix() ;
}
const osg::Vec3& DirectionalSector::getDirection() const
{
return _direction;
}
void DirectionalSector::setHorizLobeAngle(float angle)
{
_cosHorizAngle = cos(angle*0.5);
}
float DirectionalSector::getHorizLobeAngle() const
{
return acos(_cosHorizAngle)*2.0;
}
void DirectionalSector::setVertLobeAngle(float angle)
{
_cosVertAngle = cos(angle*0.5);
}
float DirectionalSector::getVertLobeAngle() const
{
return acos(_cosVertAngle)*2.0;
}
void DirectionalSector::setLobeRollAngle(float angle)
{
_rollAngle = angle ;
computeMatrix() ;
}
float DirectionalSector::getLobeRollAngle() const
{
return _rollAngle ;
}
void DirectionalSector::setFadeAngle(float angle)
{
float ang = acos(_cosHorizAngle)+angle ;
if ( ang > osg::PI ) _cosHorizFadeAngle = -1.0 ;
else _cosHorizFadeAngle = cos(ang);
ang = acos(_cosVertAngle)+angle ;
if ( ang > osg::PI ) _cosVertFadeAngle = -1.0 ;
else _cosVertFadeAngle = cos(ang);
}
float DirectionalSector::getFadeAngle() const
{
return acos(_cosHorizFadeAngle)-acos(_cosHorizAngle);
}
float DirectionalSector::operator() (const osg::Vec3& eyeLocal) const
{
float elev_intensity, azim_intensity ;
// Tranform eyeLocal into the LightPoint frame
osg::Vec3 EPlp = _local_to_LP * eyeLocal ;
/*fprintf(stderr, " eyeLocal = %f, %f, %f\n", eyeLocal[0], eyeLocal[1], eyeLocal[2]) ;
fprintf(stderr, " EPlp = %f, %f, %f\n", EPlp[0], EPlp[1], EPlp[2]) ;*/
// Elevation check
// Project EPlp into LP YZ plane and dot with LPy
osg::Vec2 EPyz(EPlp[1], EPlp[2]) ;
EPyz.normalize() ;
/*fprintf(stderr, " EPyz.normalize() = %f, %f\n", EPyz[0], EPyz[1]) ;
fprintf(stderr, " _cosVertFadeAngle = %f\n", _cosVertFadeAngle) ;
fprintf(stderr, " _cosVertAngle = %f\n", _cosVertAngle) ;*/
// cosElev = EPyz* LPy = EPyz[0]
if ( EPyz[0] < _cosVertFadeAngle ) {
// Completely outside elevation range
//fprintf(stderr, " >> outside el range\n") ;
return(0.0f) ;
}
if ( EPyz[0] < _cosVertAngle ) {
// In the fade range
//fprintf(stderr, " >> inside el fade range\n") ;
elev_intensity = (_cosVertAngle-EPyz[0])/(_cosVertAngle-_cosVertFadeAngle) ;
} else {
// Fully in elevation range
elev_intensity = 1.0 ;
//fprintf(stderr, " >> fully inside el range\n") ;
}
// Elevation check passed
// Azimuth check
// Project EPlp into LP XY plane and dot with LPy
osg::Vec2 EPxy(EPlp[0], EPlp[1]) ;
EPxy.normalize() ;
/*fprintf(stderr, " EPxy.normalize() = %f, %f\n", EPxy[0], EPxy[1]) ;
fprintf(stderr, " _cosHorizFadeAngle = %f\n", _cosHorizFadeAngle) ;
fprintf(stderr, " _cosHorizAngle = %f\n", _cosHorizAngle) ;*/
// cosAzim = EPxy * LPy = EPxy[1]
// if cosElev < 0.0, then need to negate EP for azimuth check
if ( EPyz[0] < 0.0 ) EPxy.set(-EPxy[0], -EPxy[1]) ;
if ( EPxy[1] < _cosHorizFadeAngle ) {
// Completely outside azimuth range
//fprintf(stderr, " >> outside az range\n") ;
return(0.0f) ;
}
if ( EPxy[1] < _cosHorizAngle ) {
// In fade range
//fprintf(stderr, " >> inside az fade range\n") ;
azim_intensity = (_cosHorizAngle-EPxy[1])/(_cosHorizAngle-_cosHorizFadeAngle) ;
} else {
// Fully in azimuth range
//fprintf(stderr, " >> fully inside az range\n") ;
azim_intensity = 1.0 ;
}
// Azimuth check passed
// We're good! Return full intensity
//fprintf(stderr, " %%%% Returing intensity = %f\n", elev_intensity * azim_intensity) ;
return elev_intensity * azim_intensity ;
}