00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <celengine/dsooctree.h>
00014
00015
00016
00017
00018
00019
00020
00021 bool dsoAbsoluteMagnitudePredicate(DeepSkyObject* const & _dso, const float absMag)
00022 {
00023 return _dso->getAbsoluteMagnitude() <= absMag;
00024 }
00025
00026
00027 bool dsoStraddlesNodesPredicate(const Point3d& cellCenterPos, DeepSkyObject* const & _dso, const float absMag)
00028 {
00029
00030 float dsoRadius = _dso->getRadius();
00031
00032 Point3d dsoPos = _dso->getPosition();
00033
00034 return abs(dsoPos.x - cellCenterPos.x) < dsoRadius ||
00035 abs(dsoPos.y - cellCenterPos.y) < dsoRadius ||
00036 abs(dsoPos.z - cellCenterPos.z) < dsoRadius;
00037 }
00038
00039
00040 double dsoAbsoluteMagnitudeDecayFunction(const double excludingFactor)
00041 {
00042 return excludingFactor + 0.5f;
00043 }
00044
00045
00046 template <>
00047 DynamicDSOOctree* DynamicDSOOctree::getChild(DeepSkyObject* const & _obj, const Point3d& cellCenterPos)
00048 {
00049 Point3d objPos = _obj->getPosition();
00050
00051 int child = 0;
00052 child |= objPos.x < cellCenterPos.x ? 0 : XPos;
00053 child |= objPos.y < cellCenterPos.y ? 0 : YPos;
00054 child |= objPos.z < cellCenterPos.z ? 0 : ZPos;
00055
00056 return _children[child];
00057 }
00058
00059
00060 template<> unsigned int DynamicDSOOctree::SPLIT_THRESHOLD = 10;
00061 template<> DynamicDSOOctree::LimitingFactorPredicate*
00062 DynamicDSOOctree::limitingFactorPredicate = dsoAbsoluteMagnitudePredicate;
00063 template<> DynamicDSOOctree::StraddlingPredicate*
00064 DynamicDSOOctree::straddlingPredicate = dsoStraddlesNodesPredicate;
00065 template<> DynamicDSOOctree::ExclusionFactorDecayFunction*
00066 DynamicDSOOctree::decayFunction = dsoAbsoluteMagnitudeDecayFunction;
00067
00068
00069
00070 template<>
00071 void DSOOctree::processVisibleObjects(DSOHandler& processor,
00072 const Point3d& obsPosition,
00073 const Planef* frustumPlanes,
00074 float limitingFactor,
00075 double scale) const
00076 {
00077
00078
00079
00080
00081 for (int i=0; i<5; ++i)
00082 {
00083 const Planef* plane = frustumPlanes + i;
00084 double r = scale * (abs(plane->normal.x) +
00085 abs(plane->normal.y) +
00086 abs(plane->normal.z));
00087
00088 Vec3d vecDbl((double) plane->normal.x, (double) plane->normal.y, (double) plane->normal.z);
00089
00090 if (vecDbl * Vec3d(cellCenterPos.x, cellCenterPos.y, cellCenterPos.z) - plane->d < -r)
00091 return;
00092 }
00093
00094
00095
00096 double minDistance = (obsPosition - cellCenterPos).length() - scale * DSOOctree::SQRT3;
00097
00098
00099 double dimmest = minDistance > 0 ? astro::appToAbsMag(limitingFactor, minDistance) : 1000;
00100
00101 for (unsigned int i=0; i<nObjects; ++i)
00102 {
00103 DeepSkyObject* _obj = _firstObject[i];
00104 float absMag = _obj->getAbsoluteMagnitude();
00105 if ( absMag < dimmest)
00106 {
00107 double distance = obsPosition.distanceTo(_obj->getPosition()) - _obj->getRadius();
00108 float appMag = (distance >= 32.6167)? astro::absToAppMag(absMag, distance): absMag;
00109
00110 if ( appMag < limitingFactor)
00111 processor.process(_obj, distance, absMag);
00112 }
00113 }
00114
00115
00116
00117 if (minDistance <= 0 || astro::absToAppMag(exclusionFactor, minDistance) <= limitingFactor)
00118
00119 if (_children != NULL)
00120 for (int i=0; i<8; ++i)
00121 {
00122 _children[i]->processVisibleObjects(processor,
00123 obsPosition,
00124 frustumPlanes,
00125 limitingFactor,
00126 scale * 0.5f);
00127 }
00128 }
00129
00130
00131 template<>
00132 void DSOOctree::processCloseObjects(DSOHandler& processor,
00133 const Point3d& obsPosition,
00134 double boundingRadius,
00135 double scale) const
00136 {
00137
00138
00139 double nodeDistance = (obsPosition - cellCenterPos).length() - scale * DSOOctree::SQRT3;
00140
00141 if (nodeDistance > boundingRadius)
00142 return;
00143
00144
00145
00146
00147
00148
00149 double radiusSquared = boundingRadius * boundingRadius;
00150
00151
00152 for (unsigned int i=0; i<nObjects; ++i)
00153 {
00154 DeepSkyObject* _obj = _firstObject[i];
00155
00156 if (obsPosition.distanceToSquared(_obj->getPosition()) < radiusSquared)
00157 {
00158 float absMag = _obj->getAbsoluteMagnitude();
00159 double distance = obsPosition.distanceTo(_obj->getPosition()) - _obj->getRadius();
00160
00161 processor.process(_obj, distance, absMag);
00162 }
00163 }
00164
00165
00166 if (_children != NULL)
00167 {
00168 for (int i = 0; i < 8; ++i)
00169 {
00170 _children[i]->processCloseObjects(processor,
00171 obsPosition,
00172 boundingRadius,
00173 scale * 0.5f);
00174 }
00175 }
00176 }