Thanks Marcin, fix merged and submitted to SVN.

On Tue, Dec 9, 2008 at 10:09 AM, Marcin Prus <[EMAIL PROTECTED]> wrote:
> Hi all,
> some time ago there was an optimization fix including change in
> DirectionalSector::computeMatrix().
> Rotation matrices were replaced with quaternions but incorrect contructor
> was used. There was a call to Quat(angle, xAxis, yAxis, zAxis ) but there is
> no such constructor in Quat class to create quaternion for rotation. As a
> result we got this values being written into quaternion directly.
>
> I've replaced Quat contructor calls with the ones creating rotation
> quaternions Quat( angle, Vec3( axis ) ).
>
> Best Regards,
> Marcin Prus
>
>
> /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
>  *
>  * This library is open source and may be redistributed and/or modified
> under
>  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
>  * (at your option) any later version.  The full license is in LICENSE file
>  * included with this distribution, and on the openscenegraph.org website.
>  *
>  * This library is distributed in the hope that it will be useful,
>  * but WITHOUT ANY WARRANTY; without even the implied warranty of
>  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  * OpenSceneGraph Public License for more details.
> */
>
> #include <osgSim/Sector>
> #include <osg/Vec2>
>
> using namespace osgSim;
>
>
> //
> // Elevation Range
> //
>
> void AzimRange::setAzimuthRange(float minAzimuth,float maxAzimuth,float
> fadeAngle)
> {
>    // clamp the azimuth range.
>    const float twoPI = 2.0f*(float)osg::PI;
>    while(minAzimuth>maxAzimuth) minAzimuth -= twoPI;
>
>    // compute the centerline
>    float centerAzim = (minAzimuth+maxAzimuth)*0.5f;
>    _cosAzim = cos(centerAzim);
>    _sinAzim = sin(centerAzim);
>
>    // compute the half angle range of the sector.
>    float angle = (maxAzimuth-minAzimuth)*0.5f;
>    _cosAngle = cos(angle);
>
>    // clamp the fade angle to valid values.
>    fadeAngle = osg::clampAbove(fadeAngle,0.0f);
>    if (angle+fadeAngle>osg::PI) _cosFadeAngle = -1.0f;
>    else _cosFadeAngle = cos(angle+fadeAngle);
>
> }
>
> void AzimRange::getAzimuthRange(float& minAzimuth, float& maxAzimuth, float&
> fadeAngle) const
> {
>    float centerAzim = atan2(_sinAzim, _cosAzim);
>    float angle = acos(_cosAngle);
>    minAzimuth = centerAzim - angle;
>    maxAzimuth = centerAzim + angle;
>    if (_cosFadeAngle == -1.0f) {
>        fadeAngle = 2.0f * osg::PI;
>    } else {
>        fadeAngle = acos(_cosFadeAngle) - angle;
>    }
> }
>
>
> //
> // Elevation Range
> //
> void ElevationRange::setElevationRange(float minElevation,float
> maxElevation,float fadeAngle)
> {
>    if (minElevation>maxElevation)
>    {
>        // need to swap angle pair.
>        float tmp = minElevation;
>        minElevation = maxElevation;
>        maxElevation = tmp;
>    }
>
>    minElevation =
> osg::clampTo(minElevation,(float)-osg::PI_2,(float)osg::PI_2);
>    maxElevation =
> osg::clampTo(maxElevation,(float)-osg::PI_2,(float)osg::PI_2);
>    fadeAngle = osg::clampTo(fadeAngle,0.0f,(float)osg::PI_2);
>
>    _cosMinElevation = cos(osg::PI_2-minElevation);
>    _cosMaxElevation = cos(osg::PI_2-maxElevation);
>
>    float minFadeAngle = osg::PI_2-minElevation+fadeAngle;
>    if (minFadeAngle>=osg::PI) _cosMinFadeElevation = -1.0f;
>    else _cosMinFadeElevation = cos(minFadeAngle);
>
>    float maxFadeAngle = osg::PI_2-maxElevation-fadeAngle;
>    if (maxFadeAngle<=0.0f) _cosMaxFadeElevation = 1.0f;
>    else _cosMaxFadeElevation = cos(maxFadeAngle);
>
> }
>
> float ElevationRange::getMinElevation() const
> {
>    return osg::PI_2-acos(_cosMinElevation);
> }
>
> float ElevationRange::getMaxElevation() const
> {
>    return osg::PI_2-acos(_cosMaxElevation);
> }
>
> float ElevationRange::getFadeAngle() const
> {
>    float fadeAngle = 0.0;
>
>    // Take the appropriate (unclipped) elevation angle to calculate the fade
> angle
>    if (_cosMinFadeElevation != -1.0f) {
>        float minFadeAngle = acos(_cosMinFadeElevation);
>        float minElevation = osg::PI_2 - acos(_cosMinElevation);
>        fadeAngle = minFadeAngle + minElevation - osg::PI_2;
>
>    } else if (_cosMaxFadeElevation != 1.0f) {
>        float maxFadeAngle = acos(_cosMaxFadeElevation);
>        float maxElevation = osg::PI_2 - acos(_cosMaxElevation);
>        fadeAngle = osg::PI_2 - maxFadeAngle - maxElevation;
>    }
>
>    return fadeAngle;
> }
>
> //
> // ElevationSector
> //
> AzimSector::AzimSector(float minAzimuth,float maxAzimuth,float fadeAngle):
>    Sector(),
>    AzimRange()
> {
>    setAzimuthRange(minAzimuth,maxAzimuth,fadeAngle);
> }
>
> float AzimSector::operator() (const osg::Vec3& eyeLocal) const
> {
>    return azimSector(eyeLocal);
> }
>
> //
> // ElevationSector
> //
> ElevationSector::ElevationSector(float minElevation,float maxElevation,float
> fadeAngle):
>    Sector(),
>    ElevationRange()
> {
>    setElevationRange(minElevation,maxElevation,fadeAngle);
> }
>
> float ElevationSector::operator() (const osg::Vec3& eyeLocal) const
> {
>    return elevationSector(eyeLocal);
> }
>
> //
> // AzimElevationSector
> //
> AzimElevationSector::AzimElevationSector(float minAzimuth,float
> maxAzimuth,float minElevation,float maxElevation,float fadeAngle):
>    Sector(),
>    AzimRange(),
>    ElevationRange()
> {
>    setAzimuthRange(minAzimuth,maxAzimuth,fadeAngle);
>    setElevationRange(minElevation,maxElevation,fadeAngle);
> }
>
>
> float AzimElevationSector::operator() (const osg::Vec3& eyeLocal) const
> {
>    float azimIntensity = azimSector(eyeLocal);
>    if (azimIntensity==0.0) return 0.0; // out of sector.
>    float elevIntensity = elevationSector(eyeLocal);
>    if (elevIntensity==0.0) return 0.0; // out of sector.
>    if (azimIntensity<=elevIntensity) return azimIntensity;
>    return elevIntensity;
> }
>
> //
> // ConeSector
> //
> ConeSector::ConeSector(const osg::Vec3& axis,float angle,float fadeangle):
>            Sector()
> {
>    setAxis(axis);
>    setAngle(angle,fadeangle);
> }
>
> void ConeSector::setAxis(const osg::Vec3& axis)
> {
>    _axis = axis;
>    _axis.normalize();
> }
>
> const osg::Vec3& ConeSector::getAxis() const
> {
>    return _axis;
> }
>
> void ConeSector::setAngle(float angle,float fadeangle)
> {
>    _cosAngle = cos(angle);
>    _cosAngleFade = cos(angle+fadeangle);
> }
>
> float ConeSector::getAngle() const
> {
>    return acos(_cosAngle);
> }
>
> float ConeSector::getFadeAngle() const
> {
>    return acos(_cosAngleFade)-acos(_cosAngle);
> }
>
> float ConeSector::operator() (const osg::Vec3& eyeLocal) const
> {
>    float dotproduct = eyeLocal*_axis;
>    float length = eyeLocal.length();
>    if (dotproduct>_cosAngle*length) return 1.0f; // fully in sector
>    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()
> {
>  double heading = atan2(_direction[0], _direction[1]);
>  double pitch   = atan2(_direction[2], sqrt(_direction[0]*_direction[0] +
> _direction[1]*_direction[1]));
>  double roll    = _rollAngle;
>
>  _local_to_LP.setRotate(osg::Quat(heading,osg::Vec3d(0.0, 0.0, -1.0)));
>  _local_to_LP.preMultRotate(osg::Quat(pitch, osg::Vec3d(1.0, 0.0, 0.0)));
>  _local_to_LP.preMultRotate(osg::Quat(roll, osg::Vec3d(0.0, 1.0, 0.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 ;
> }
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to