source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.cpp @ 3268

Revision 3268, 4.3 KB checked in by mattausch, 15 years ago (diff)
Line 
1#include "SceneEntity.h"
2#include "Geometry.h"
3#include "Material.h"
4#include "RenderState.h"
5#include "Shape.h"
6#include "Transform3.h"
7#include "Camera.h"
8#include "glInterface.h"
9
10
11using namespace std;
12
13
14namespace CHCDemoEngine
15{
16
17int sCurrentId = 0;
18bool SceneEntity::sUseLODs = true;
19int SceneEntity::sCurrentVisibleId = -1;
20
21SceneEntity::SceneEntity(Transform3 *trafo):
22mTransform(trafo),
23mCurrentLODLevel(0),
24mLODLastUpdated(-1),
25mId(sCurrentId ++),
26mVisibleId(0)
27{
28        mBox.Initialize();
29}
30
31
32SceneEntity::~SceneEntity()
33{
34}
35
36
37void SceneEntity::UpdateLODs(const Vector3 &viewPoint)
38{
39        mCurrentLODLevel = 0;
40
41        if (!sUseLODs) return;
42
43        const Vector3 pos = GetWorldCenter();
44        const float dist = SqrDistance(pos, viewPoint);
45
46        // note: we assume that lods are ordered from smallest distance to largest
47        const int l = (int)mLODLevels.size();
48
49        for (int i = 0; i < l; ++ i)
50        {
51                if (mLODLevels[i].GetSquaredDistance() > dist) break;
52                mCurrentLODLevel = i;
53        }
54}
55
56
57int SceneEntity::GetCurrentLODLevel()
58{
59        if (mLODLastUpdated != LODLevel::sFrameId)
60        {
61                mLODLastUpdated = LODLevel::sFrameId;
62                UpdateLODs(LODLevel::sViewPoint);
63        }
64
65        return mCurrentLODLevel;
66}
67
68
69void SceneEntity::GetCurrentLODLevel(ShapeContainer::iterator &start,
70                                                                         ShapeContainer::iterator &end)
71{
72        if (mLODLastUpdated != LODLevel::sFrameId)
73        {
74                mLODLastUpdated = LODLevel::sFrameId;
75                UpdateLODs(LODLevel::sViewPoint);
76        }
77
78        start = mLODLevels[mCurrentLODLevel].GetShapes().begin();
79        end   = mLODLevels[mCurrentLODLevel].GetShapes().end();
80}
81
82
83void SceneEntity::GetLODLevel(int level,
84                                                          ShapeContainer::iterator &start,
85                                                          ShapeContainer::iterator &end)
86{
87        start = mLODLevels[level].GetShapes().begin();
88        end = mLODLevels[level].GetShapes().end();
89}
90
91
92void SceneEntity::Render(RenderState *state)
93{
94        ShapeContainer::iterator sit, sit_end;
95
96        if (!mLODLevels.empty())
97                GetCurrentLODLevel(sit, sit_end);
98        else
99        {
100                sit = mShapes.begin(); sit_end = mShapes.end();
101        }
102
103        Prepare(state);
104
105        for (; sit != sit_end; ++ sit)
106                (*sit)->Render(state, this);
107
108        mTransform->Unload(state);
109}
110
111
112void SceneEntity::AddShape(Shape *shape)
113{
114        mShapes.push_back(shape);
115        mBox.Include(shape->GetBoundingBox());
116
117        mCenter = mBox.Center();
118}
119
120
121void SceneEntity::SetTransform(Transform3 *trafo)
122{
123        mTransform = trafo;
124}
125
126
127void SceneEntity::SetLastRenderedFrame(int lastRenderedFrame)
128{
129        mLastRenderedFrame = lastRenderedFrame;
130}
131
132
133int SceneEntity::GetLastRenderedFrame() const
134{
135        return mLastRenderedFrame;
136}
137
138
139int SceneEntity::CountNumTriangles(int lodLevel)
140{
141        int numTriangles = 0;
142       
143        ShapeContainer::iterator sit, sit_end;
144
145        if (lodLevel == -1)
146                lodLevel = GetCurrentLODLevel();
147
148        return mLODLevels[lodLevel].GetNumTriangles();
149}
150
151
152AxisAlignedBox3 SceneEntity::GetWorldBoundingBox() const
153{
154        if (mTransform->IsIdentity()) return mBox;
155        Matrix4x4 mat = mTransform->GetMatrix();
156
157        return Transform(mBox, mat);
158}
159
160
161AxisAlignedBox3 SceneEntity::GetBoundingBox() const
162{
163        return mBox;
164}
165
166
167Vector3 SceneEntity::GetWorldCenter() const
168{
169        if (mTransform->IsIdentity()) return mCenter;
170        return mTransform->GetMatrix() * mCenter;
171}
172
173
174void SceneEntity::Prepare(RenderState *state)
175{
176        /*int id[] = {(mId / (255 * 255)) % 255, (mId / 255) % 255, mId % 255, 0};
177
178        GLfloat fogColor[4] = {(float)id[0] / 255.0f, (float)id[1] / 255.0f, (float)id[2] / 255.0f, .0f};
179        glFogfv(GL_FOG_COLOR, fogColor);*/
180
181        mTransform->Load(state);
182}
183
184
185AxisAlignedBox3 SceneEntity::ComputeBoundingBox(SceneEntity **entities, int numEntities)
186{
187        AxisAlignedBox3 box;
188       
189        if (numEntities <= 0)
190        {       // no box => just initialize
191                box.Initialize();
192        }
193        else
194        {
195                box = entities[0]->GetWorldBoundingBox();
196
197                for (int i = 1; i < numEntities; ++ i)
198                {
199                        box.Include(entities[i]->GetWorldBoundingBox());
200                }
201        }
202
203        return box;
204}
205
206
207AxisAlignedBox3 SceneEntity::ComputeBoundingBox(const SceneEntityContainer &entities)
208{
209        AxisAlignedBox3 box;
210       
211        if (entities.empty())
212        {       // no box => just initialize
213                box.Initialize();
214        }
215        else
216        {
217                box = entities[0]->GetWorldBoundingBox();
218
219                for (size_t i = 1; i < entities.size(); ++ i)
220                {
221                        box.Include(entities[i]->GetWorldBoundingBox());
222                }
223        }
224
225        return box;
226}
227
228
229
230
231}
Note: See TracBrowser for help on using the repository browser.