00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "3d/quad_grid_clip_cluster.h"
00029
00030
00031 using namespace NLMISC;
00032 using namespace std;
00033
00034
00035 namespace NL3D {
00036
00037
00038
00039 void CQuadGridClipCluster::registerBasic()
00040 {
00041 CMOT::registerModel( QuadGridClipClusterId, 0, CQuadGridClipCluster::creator);
00042 CMOT::registerObs( ClipTravId, QuadGridClipClusterId, CQuadGridClipClusterClipObs::creator );
00043 }
00044
00045
00046
00047 void CQuadGridClipCluster::extendCluster(const NLMISC::CAABBox &worldBBox)
00048 {
00049 if(_Empty)
00050 {
00051 _Empty= false;
00052 _BBox= worldBBox;
00053 }
00054 else
00055 {
00056
00057 _BBox.extend( worldBBox.getCenter() + worldBBox.getHalfSize() );
00058 _BBox.extend( worldBBox.getCenter() - worldBBox.getHalfSize() );
00059 }
00060
00061
00062 _Radius= _BBox.getRadius();
00063 }
00064
00065
00066
00067 void CQuadGridClipCluster::update()
00068 {
00069
00070 unlinkFromValidateList();
00071 }
00072
00073
00074
00075 CQuadGridClipClusterClipObs::CQuadGridClipClusterClipObs()
00076 {
00077 _LastClipWasDistMaxClip= false;
00078 _LastClipWasFrustumClip= false;
00079 }
00080
00081
00082 void CQuadGridClipClusterClipObs::traverse(IObs *caller)
00083 {
00084 CQuadGridClipCluster *cluster= (CQuadGridClipCluster*)Model;
00085 CClipTrav *clipTrav= (CClipTrav*)Trav;
00086
00087
00088 if(cluster->_Empty)
00089 {
00090
00091
00092
00093 _LastClipWasDistMaxClip= false;
00094 _LastClipWasFrustumClip= false;
00095 return;
00096 }
00097
00098
00099 CAABBox &bbox= cluster->_BBox;
00100
00101 if(cluster->_DistMax!=-1)
00102 {
00103 CVector c= bbox.getCenter();
00104 float dist= (c - clipTrav->CamPos).norm();
00105
00106 if( dist-cluster->_Radius > cluster->_DistMax )
00107 {
00108
00109 if( !_LastClipWasDistMaxClip )
00110 {
00111
00112 forceClip(IBaseClipObs::DistMaxClip);
00113
00114 _LastClipWasDistMaxClip= true;
00115 }
00116
00117 return;
00118 }
00119 else
00120 {
00121
00122 _LastClipWasDistMaxClip= false;
00123 }
00124 }
00125
00126
00127 bool unspecified= false;
00128 bool visible= true;
00129 for(sint i=0;i<(sint)clipTrav->WorldPyramid.size();i++)
00130 {
00131
00132 if(!bbox.clipBack(clipTrav->WorldPyramid[i]))
00133 {
00134 visible= false;
00135 break;
00136 }
00137
00138 else if(!unspecified)
00139 {
00140
00141 if(bbox.clipFront(clipTrav->WorldPyramid[i]))
00142 unspecified= true;
00143 }
00144 }
00145
00146
00147 if(!visible)
00148 {
00149
00150 if( !_LastClipWasFrustumClip )
00151 {
00152
00153 forceClip(IBaseClipObs::FrustumClip);
00154
00155 _LastClipWasFrustumClip= true;
00156 }
00157 }
00158 else
00159 {
00160
00161 _LastClipWasFrustumClip= false;
00162
00163
00164 if(unspecified)
00165 {
00166
00167 traverseSons();
00168 }
00169 else
00170 {
00171
00172 clipTrav->ForceNoFrustumClip= true;
00173 traverseSons();
00174 clipTrav->ForceNoFrustumClip= false;
00175 }
00176 }
00177 }
00178
00179
00180 }