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

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