#include "SceneEntity.h" #include "Geometry.h" #include "Material.h" #include "RenderState.h" #include "Shape.h" #include "Transform3.h" #include "Camera.h" #include "glInterface.h" #include #include using namespace std; namespace CHCDemoEngine { bool SceneEntity::sUseLODs = true; SceneEntity::SceneEntity(Transform3 *trafo): mTransform(trafo), mCurrentLODLevel(0), mLODLastUpdated(-1) { mBox.Initialize(); } SceneEntity::~SceneEntity() { } void SceneEntity::UpdateLODs(const Vector3 &viewPoint) { mCurrentLODLevel = 0; if (!sUseLODs) return; const Vector3 pos = GetCenter(); const float dist = SqrDistance(pos, viewPoint); // note: we assume that lods are ordered from smallest distance to largest const int l = (int)mLODLevels.size(); for (int i = 0; i < l; ++ i) { LODLevel *lod = mLODLevels[i]; if (lod->GetSquaredDistance() > dist) break; mCurrentLODLevel = i; } } int SceneEntity::GetCurrentLODLevel() { if (mLODLastUpdated != LODLevel::sFrameId) { mLODLastUpdated = LODLevel::sFrameId; UpdateLODs(LODLevel::sViewPoint); } return mCurrentLODLevel; } void SceneEntity::GetCurrentLODLevel(ShapeContainer::iterator &start, ShapeContainer::iterator &end) { if (mLODLastUpdated != LODLevel::sFrameId) { mLODLastUpdated = LODLevel::sFrameId; UpdateLODs(LODLevel::sViewPoint); } start = mLODLevels[mCurrentLODLevel]->GetShapes().begin(); end = mLODLevels[mCurrentLODLevel]->GetShapes().end(); } void SceneEntity::GetLODLevel(int level, ShapeContainer::iterator &start, ShapeContainer::iterator &end) { LODLevel *lod = mLODLevels[level]; start = lod->GetShapes().begin(); end = lod->GetShapes().end(); } void SceneEntity::Render(RenderState *state) { ShapeContainer::iterator sit, sit_end; GetCurrentLODLevel(sit, sit_end); for (; sit != sit_end; ++ sit) { (*sit)->Render(state); } } void SceneEntity::AddShape(Shape *shape) { mShapes.push_back(shape); mBox.Include(shape->GetBoundingBox()); mCenter = mBox.Center(); } void SceneEntity::SetTransform(Transform3 *trafo) { mTransform = trafo; } void SceneEntity::SetLastRendered(int lastRendered) { mLastRendered = lastRendered; } int SceneEntity::GetLastRendered() const { return mLastRendered; } int SceneEntity::CountNumTriangles(int lodLevel) { int numTriangles = 0; ShapeContainer::iterator sit, sit_end; if (lodLevel == -1) { lodLevel = GetCurrentLODLevel(); } return mLODLevels[lodLevel]->GetNumTriangles(); } AxisAlignedBox3 SceneEntity::GetTransformedBoundingBox() const { Matrix4x4 *mat = mTransform->GetMatrix(); if (!mat) return mBox; return Transform(mBox, *mat); } AxisAlignedBox3 SceneEntity::GetBoundingBox() const { return mBox; } Vector3 SceneEntity::GetCenter() const { Matrix4x4 *mat = mTransform->GetMatrix(); if (!mat) return mCenter; return (*mat) * mCenter; } }