| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | #include <osgSim/Sector> |
|---|
| 15 | #include <osg/Vec2> |
|---|
| 16 | |
|---|
| 17 | using namespace osgSim; |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | void AzimRange::setAzimuthRange(float minAzimuth,float maxAzimuth,float fadeAngle) |
|---|
| 25 | { |
|---|
| 26 | |
|---|
| 27 | const float twoPI = 2.0f*(float)osg::PI; |
|---|
| 28 | while(minAzimuth>maxAzimuth) minAzimuth -= twoPI; |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | float centerAzim = (minAzimuth+maxAzimuth)*0.5f; |
|---|
| 32 | _cosAzim = cos(centerAzim); |
|---|
| 33 | _sinAzim = sin(centerAzim); |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | float angle = (maxAzimuth-minAzimuth)*0.5f; |
|---|
| 37 | _cosAngle = cos(angle); |
|---|
| 38 | |
|---|
| 39 | |
|---|
| 40 | fadeAngle = osg::clampAbove(fadeAngle,0.0f); |
|---|
| 41 | if (angle+fadeAngle>osg::PI) _cosFadeAngle = -1.0f; |
|---|
| 42 | else _cosFadeAngle = cos(angle+fadeAngle); |
|---|
| 43 | |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | void AzimRange::getAzimuthRange(float& minAzimuth, float& maxAzimuth, float& fadeAngle) const |
|---|
| 47 | { |
|---|
| 48 | float centerAzim = atan2(_sinAzim, _cosAzim); |
|---|
| 49 | float angle = acos(_cosAngle); |
|---|
| 50 | minAzimuth = centerAzim - angle; |
|---|
| 51 | maxAzimuth = centerAzim + angle; |
|---|
| 52 | if (_cosFadeAngle == -1.0f) { |
|---|
| 53 | fadeAngle = 2.0f * osg::PI; |
|---|
| 54 | } else { |
|---|
| 55 | fadeAngle = acos(_cosFadeAngle) - angle; |
|---|
| 56 | } |
|---|
| 57 | } |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | |
|---|
| 61 | |
|---|
| 62 | |
|---|
| 63 | void ElevationRange::setElevationRange(float minElevation,float maxElevation,float fadeAngle) |
|---|
| 64 | { |
|---|
| 65 | if (minElevation>maxElevation) |
|---|
| 66 | { |
|---|
| 67 | |
|---|
| 68 | float tmp = minElevation; |
|---|
| 69 | minElevation = maxElevation; |
|---|
| 70 | maxElevation = tmp; |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | minElevation = osg::clampTo(minElevation,(float)-osg::PI_2,(float)osg::PI_2); |
|---|
| 74 | maxElevation = osg::clampTo(maxElevation,(float)-osg::PI_2,(float)osg::PI_2); |
|---|
| 75 | fadeAngle = osg::clampTo(fadeAngle,0.0f,(float)osg::PI_2); |
|---|
| 76 | |
|---|
| 77 | _cosMinElevation = cos(osg::PI_2-minElevation); |
|---|
| 78 | _cosMaxElevation = cos(osg::PI_2-maxElevation); |
|---|
| 79 | |
|---|
| 80 | float minFadeAngle = osg::PI_2-minElevation+fadeAngle; |
|---|
| 81 | if (minFadeAngle>=osg::PI) _cosMinFadeElevation = -1.0f; |
|---|
| 82 | else _cosMinFadeElevation = cos(minFadeAngle); |
|---|
| 83 | |
|---|
| 84 | float maxFadeAngle = osg::PI_2-maxElevation-fadeAngle; |
|---|
| 85 | if (maxFadeAngle<=0.0f) _cosMaxFadeElevation = 1.0f; |
|---|
| 86 | else _cosMaxFadeElevation = cos(maxFadeAngle); |
|---|
| 87 | |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | float ElevationRange::getMinElevation() const |
|---|
| 91 | { |
|---|
| 92 | return osg::PI_2-acos(_cosMinElevation); |
|---|
| 93 | } |
|---|
| 94 | |
|---|
| 95 | float ElevationRange::getMaxElevation() const |
|---|
| 96 | { |
|---|
| 97 | return osg::PI_2-acos(_cosMaxElevation); |
|---|
| 98 | } |
|---|
| 99 | |
|---|
| 100 | float ElevationRange::getFadeAngle() const |
|---|
| 101 | { |
|---|
| 102 | float fadeAngle = 0.0; |
|---|
| 103 | |
|---|
| 104 | |
|---|
| 105 | if (_cosMinFadeElevation != -1.0f) { |
|---|
| 106 | float minFadeAngle = acos(_cosMinFadeElevation); |
|---|
| 107 | float minElevation = osg::PI_2 - acos(_cosMinElevation); |
|---|
| 108 | fadeAngle = minFadeAngle + minElevation - osg::PI_2; |
|---|
| 109 | |
|---|
| 110 | } else if (_cosMaxFadeElevation != 1.0f) { |
|---|
| 111 | float maxFadeAngle = acos(_cosMaxFadeElevation); |
|---|
| 112 | float maxElevation = osg::PI_2 - acos(_cosMaxElevation); |
|---|
| 113 | fadeAngle = osg::PI_2 - maxFadeAngle - maxElevation; |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | return fadeAngle; |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | |
|---|
| 122 | AzimSector::AzimSector(float minAzimuth,float maxAzimuth,float fadeAngle): |
|---|
| 123 | Sector(), |
|---|
| 124 | AzimRange() |
|---|
| 125 | { |
|---|
| 126 | setAzimuthRange(minAzimuth,maxAzimuth,fadeAngle); |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | float AzimSector::operator() (const osg::Vec3& eyeLocal) const |
|---|
| 130 | { |
|---|
| 131 | return azimSector(eyeLocal); |
|---|
| 132 | } |
|---|
| 133 | |
|---|
| 134 | |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | ElevationSector::ElevationSector(float minElevation,float maxElevation,float fadeAngle): |
|---|
| 138 | Sector(), |
|---|
| 139 | ElevationRange() |
|---|
| 140 | { |
|---|
| 141 | setElevationRange(minElevation,maxElevation,fadeAngle); |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | float ElevationSector::operator() (const osg::Vec3& eyeLocal) const |
|---|
| 145 | { |
|---|
| 146 | return elevationSector(eyeLocal); |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | |
|---|
| 152 | AzimElevationSector::AzimElevationSector(float minAzimuth,float maxAzimuth,float minElevation,float maxElevation,float fadeAngle): |
|---|
| 153 | Sector(), |
|---|
| 154 | AzimRange(), |
|---|
| 155 | ElevationRange() |
|---|
| 156 | { |
|---|
| 157 | setAzimuthRange(minAzimuth,maxAzimuth,fadeAngle); |
|---|
| 158 | setElevationRange(minElevation,maxElevation,fadeAngle); |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | |
|---|
| 162 | float AzimElevationSector::operator() (const osg::Vec3& eyeLocal) const |
|---|
| 163 | { |
|---|
| 164 | float azimIntensity = azimSector(eyeLocal); |
|---|
| 165 | if (azimIntensity==0.0) return 0.0; |
|---|
| 166 | float elevIntensity = elevationSector(eyeLocal); |
|---|
| 167 | if (elevIntensity==0.0) return 0.0; |
|---|
| 168 | if (azimIntensity<=elevIntensity) return azimIntensity; |
|---|
| 169 | return elevIntensity; |
|---|
| 170 | } |
|---|
| 171 | |
|---|
| 172 | |
|---|
| 173 | |
|---|
| 174 | |
|---|
| 175 | ConeSector::ConeSector(const osg::Vec3& axis,float angle,float fadeangle): |
|---|
| 176 | Sector() |
|---|
| 177 | { |
|---|
| 178 | setAxis(axis); |
|---|
| 179 | setAngle(angle,fadeangle); |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | void ConeSector::setAxis(const osg::Vec3& axis) |
|---|
| 183 | { |
|---|
| 184 | _axis = axis; |
|---|
| 185 | _axis.normalize(); |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | const osg::Vec3& ConeSector::getAxis() const |
|---|
| 189 | { |
|---|
| 190 | return _axis; |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | void ConeSector::setAngle(float angle,float fadeangle) |
|---|
| 194 | { |
|---|
| 195 | _cosAngle = cos(angle); |
|---|
| 196 | _cosAngleFade = cos(angle+fadeangle); |
|---|
| 197 | } |
|---|
| 198 | |
|---|
| 199 | float ConeSector::getAngle() const |
|---|
| 200 | { |
|---|
| 201 | return acos(_cosAngle); |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | float ConeSector::getFadeAngle() const |
|---|
| 205 | { |
|---|
| 206 | return acos(_cosAngleFade)-acos(_cosAngle); |
|---|
| 207 | } |
|---|
| 208 | |
|---|
| 209 | float ConeSector::operator() (const osg::Vec3& eyeLocal) const |
|---|
| 210 | { |
|---|
| 211 | float dotproduct = eyeLocal*_axis; |
|---|
| 212 | float length = eyeLocal.length(); |
|---|
| 213 | if (dotproduct>_cosAngle*length) return 1.0f; |
|---|
| 214 | if (dotproduct<_cosAngleFade*length) return 0.0f; |
|---|
| 215 | return (dotproduct-_cosAngleFade*length)/((_cosAngle-_cosAngleFade)*length); |
|---|
| 216 | } |
|---|
| 217 | |
|---|
| 218 | |
|---|
| 219 | |
|---|
| 220 | |
|---|
| 221 | DirectionalSector::DirectionalSector(const osg::Vec3& direction,float horizLobeAngle, float vertLobeAngle, float lobeRollAngle, float fadeAngle): |
|---|
| 222 | Sector() |
|---|
| 223 | { |
|---|
| 224 | setDirection(direction); |
|---|
| 225 | setHorizLobeAngle(horizLobeAngle); |
|---|
| 226 | setVertLobeAngle(vertLobeAngle); |
|---|
| 227 | setLobeRollAngle(lobeRollAngle); |
|---|
| 228 | setFadeAngle(fadeAngle); |
|---|
| 229 | } |
|---|
| 230 | |
|---|
| 231 | void DirectionalSector::computeMatrix() |
|---|
| 232 | { |
|---|
| 233 | double heading = atan2(_direction[0], _direction[1]); |
|---|
| 234 | double pitch = atan2(_direction[2], sqrt(_direction[0]*_direction[0] + _direction[1]*_direction[1])); |
|---|
| 235 | double roll = _rollAngle; |
|---|
| 236 | |
|---|
| 237 | _local_to_LP.setRotate(osg::Quat(heading,osg::Vec3d(0.0, 0.0, -1.0))); |
|---|
| 238 | _local_to_LP.preMultRotate(osg::Quat(pitch, osg::Vec3d(1.0, 0.0, 0.0))); |
|---|
| 239 | _local_to_LP.preMultRotate(osg::Quat(roll, osg::Vec3d(0.0, 1.0, 0.0))); |
|---|
| 240 | } |
|---|
| 241 | |
|---|
| 242 | void DirectionalSector::setDirection(const osg::Vec3& direction) |
|---|
| 243 | { |
|---|
| 244 | _direction = direction ; |
|---|
| 245 | computeMatrix() ; |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | const osg::Vec3& DirectionalSector::getDirection() const |
|---|
| 249 | { |
|---|
| 250 | return _direction; |
|---|
| 251 | } |
|---|
| 252 | |
|---|
| 253 | void DirectionalSector::setHorizLobeAngle(float angle) |
|---|
| 254 | { |
|---|
| 255 | _cosHorizAngle = cos(angle*0.5); |
|---|
| 256 | } |
|---|
| 257 | |
|---|
| 258 | float DirectionalSector::getHorizLobeAngle() const |
|---|
| 259 | { |
|---|
| 260 | return acos(_cosHorizAngle)*2.0; |
|---|
| 261 | } |
|---|
| 262 | |
|---|
| 263 | void DirectionalSector::setVertLobeAngle(float angle) |
|---|
| 264 | { |
|---|
| 265 | _cosVertAngle = cos(angle*0.5); |
|---|
| 266 | } |
|---|
| 267 | |
|---|
| 268 | float DirectionalSector::getVertLobeAngle() const |
|---|
| 269 | { |
|---|
| 270 | return acos(_cosVertAngle)*2.0; |
|---|
| 271 | } |
|---|
| 272 | |
|---|
| 273 | void DirectionalSector::setLobeRollAngle(float angle) |
|---|
| 274 | { |
|---|
| 275 | _rollAngle = angle ; |
|---|
| 276 | computeMatrix() ; |
|---|
| 277 | } |
|---|
| 278 | |
|---|
| 279 | float DirectionalSector::getLobeRollAngle() const |
|---|
| 280 | { |
|---|
| 281 | return _rollAngle ; |
|---|
| 282 | } |
|---|
| 283 | |
|---|
| 284 | void DirectionalSector::setFadeAngle(float angle) |
|---|
| 285 | { |
|---|
| 286 | float ang = acos(_cosHorizAngle)+angle ; |
|---|
| 287 | if ( ang > osg::PI ) _cosHorizFadeAngle = -1.0 ; |
|---|
| 288 | else _cosHorizFadeAngle = cos(ang); |
|---|
| 289 | |
|---|
| 290 | ang = acos(_cosVertAngle)+angle ; |
|---|
| 291 | if ( ang > osg::PI ) _cosVertFadeAngle = -1.0 ; |
|---|
| 292 | else _cosVertFadeAngle = cos(ang); |
|---|
| 293 | } |
|---|
| 294 | |
|---|
| 295 | float DirectionalSector::getFadeAngle() const |
|---|
| 296 | { |
|---|
| 297 | return acos(_cosHorizFadeAngle)-acos(_cosHorizAngle); |
|---|
| 298 | } |
|---|
| 299 | |
|---|
| 300 | float DirectionalSector::operator() (const osg::Vec3& eyeLocal) const |
|---|
| 301 | { |
|---|
| 302 | float elev_intensity, azim_intensity ; |
|---|
| 303 | |
|---|
| 304 | |
|---|
| 305 | osg::Vec3 EPlp = _local_to_LP * eyeLocal ; |
|---|
| 306 | |
|---|
| 307 | |
|---|
| 308 | |
|---|
| 309 | |
|---|
| 310 | |
|---|
| 311 | |
|---|
| 312 | osg::Vec2 EPyz(EPlp[1], EPlp[2]) ; |
|---|
| 313 | EPyz.normalize() ; |
|---|
| 314 | |
|---|
| 315 | |
|---|
| 316 | |
|---|
| 317 | |
|---|
| 318 | if ( EPyz[0] < _cosVertFadeAngle ) { |
|---|
| 319 | |
|---|
| 320 | |
|---|
| 321 | return(0.0f) ; |
|---|
| 322 | } |
|---|
| 323 | if ( EPyz[0] < _cosVertAngle ) { |
|---|
| 324 | |
|---|
| 325 | |
|---|
| 326 | elev_intensity = (EPyz[0]-_cosVertFadeAngle)/(_cosVertAngle-_cosVertFadeAngle) ; |
|---|
| 327 | } else { |
|---|
| 328 | |
|---|
| 329 | elev_intensity = 1.0 ; |
|---|
| 330 | |
|---|
| 331 | } |
|---|
| 332 | |
|---|
| 333 | |
|---|
| 334 | |
|---|
| 335 | |
|---|
| 336 | osg::Vec2 EPxy(EPlp[0], EPlp[1]) ; |
|---|
| 337 | EPxy.normalize() ; |
|---|
| 338 | |
|---|
| 339 | |
|---|
| 340 | |
|---|
| 341 | |
|---|
| 342 | |
|---|
| 343 | if ( EPyz[0] < 0.0 ) EPxy.set(-EPxy[0], -EPxy[1]) ; |
|---|
| 344 | if ( EPxy[1] < _cosHorizFadeAngle ) { |
|---|
| 345 | |
|---|
| 346 | |
|---|
| 347 | return(0.0f) ; |
|---|
| 348 | } |
|---|
| 349 | if ( EPxy[1] < _cosHorizAngle ) { |
|---|
| 350 | |
|---|
| 351 | |
|---|
| 352 | azim_intensity = (EPxy[1]-_cosHorizFadeAngle)/(_cosHorizAngle-_cosHorizFadeAngle) ; |
|---|
| 353 | } else { |
|---|
| 354 | |
|---|
| 355 | |
|---|
| 356 | azim_intensity = 1.0 ; |
|---|
| 357 | } |
|---|
| 358 | |
|---|
| 359 | |
|---|
| 360 | |
|---|
| 361 | |
|---|
| 362 | return elev_intensity * azim_intensity ; |
|---|
| 363 | } |
|---|