Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/components/CCmpUnitRenderer.cpp
Show All 34 Lines | |||||
#include "graphics/Unit.h" | #include "graphics/Unit.h" | ||||
#include "maths/BoundingSphere.h" | #include "maths/BoundingSphere.h" | ||||
#include "maths/Matrix3D.h" | #include "maths/Matrix3D.h" | ||||
#include "ps/GameSetup/Config.h" | #include "ps/GameSetup/Config.h" | ||||
#include "ps/Profile.h" | #include "ps/Profile.h" | ||||
#include "renderer/RenderingOptions.h" | #include "renderer/RenderingOptions.h" | ||||
#include "renderer/Scene.h" | #include "renderer/Scene.h" | ||||
#include "renderer/Renderer.h" | |||||
#include "tools/atlas/GameInterface/GameLoop.h" | #include "tools/atlas/GameInterface/GameLoop.h" | ||||
/** | /** | ||||
* Efficiently(ish) renders all the units in the world. | * Efficiently(ish) renders all the units in the world. | ||||
* | * | ||||
* The class maintains a list of all units that currently exist, and the data | * The class maintains a list of all units that currently exist, and the data | ||||
* needed for frustum-culling them. To minimise the amount of work done per | * needed for frustum-culling them. To minimise the amount of work done per | ||||
* frame (despite a unit's interpolated position changing every frame), the | * frame (despite a unit's interpolated position changing every frame), the | ||||
Show All 14 Lines | |||||
{ | { | ||||
public: | public: | ||||
struct SUnit | struct SUnit | ||||
{ | { | ||||
CEntityHandle entity; | CEntityHandle entity; | ||||
CUnit* actor; | CUnit* actor; | ||||
bool LOD; | |||||
vladislavbelov: What does the `LOD` name mean? It's not obvious from the name. | |||||
int flags; | int flags; | ||||
/** | /** | ||||
* m_FrameNumber from when the model's transform was last updated. | * m_FrameNumber from when the model's transform was last updated. | ||||
* This is used to avoid recomputing it multiple times per frame | * This is used to avoid recomputing it multiple times per frame | ||||
* if a model is visible in multiple cull groups. | * if a model is visible in multiple cull groups. | ||||
*/ | */ | ||||
int lastTransformFrame; | int lastTransformFrame; | ||||
▲ Show 20 Lines • Show All 350 Lines • ▼ Show 20 Lines | if (unit.lastTransformFrame != m_FrameNumber) | ||||
unitModel.SetTransform(transform); | unitModel.SetTransform(transform); | ||||
unit.lastTransformFrame = m_FrameNumber; | unit.lastTransformFrame = m_FrameNumber; | ||||
} | } | ||||
if (culling && !frustum.IsBoxVisible(unitModel.GetWorldBoundsRec())) | if (culling && !frustum.IsBoxVisible(unitModel.GetWorldBoundsRec())) | ||||
continue; | continue; | ||||
CMatrix3D worldToCam; | |||||
CRenderer::GetSingleton().GetViewCamera().m_Orientation.GetInverse(worldToCam); | |||||
CVector3D modelpos = unitModel.GetTransform().GetTranslation(); | |||||
float dist = worldToCam.Transform(modelpos).Z; | |||||
if (dist < 0) { | |||||
unit.culled = true; | |||||
continue; | |||||
wraitiiAuthorUnsubmitted Done Inline ActionsDon't implement "behind the camera" culling. Since you don't actually account for the entity BB, you'll fail occasionally and units will "pop-in". Further, culling is already handled, so this is just double-work. wraitii: Don't implement "behind the camera" culling.
Since you don't actually account for the entity… | |||||
} | |||||
if (dist > 100 && !unit.LOD) { | |||||
// Switch to low detail | |||||
std::map<CStr, CStr> selections; | |||||
selections.insert(std::pair<CStr, CStr>("lod", "low")); | |||||
unit.actor->SetEntitySelection(selections); | |||||
CModelAbstract& unitModel2 = unit.actor->GetModel(); | |||||
CmpPtr<ICmpPosition> cmpPosition(unit.entity); | |||||
CMatrix3D transform(cmpPosition->GetInterpolatedTransform(m_FrameOffset)); | |||||
unitModel.SetTransform(transform); | |||||
collector.SubmitRecursive(&unitModel2); | |||||
unit.LOD = true; | |||||
} | |||||
else if(dist <= 100 && unit.LOD) { | |||||
// Switch to high detail | |||||
std::map<CStr, CStr> selections; | |||||
selections.insert(std::pair<CStr, CStr>("lod", "high")); | |||||
unit.actor->SetEntitySelection(selections); | |||||
CModelAbstract& unitModel2 = unit.actor->GetModel(); | |||||
CmpPtr<ICmpPosition> cmpPosition(unit.entity); | |||||
CMatrix3D transform(cmpPosition->GetInterpolatedTransform(m_FrameOffset)); | |||||
collector.SubmitRecursive(&unitModel2); | |||||
unit.LOD = false; | |||||
} | |||||
else { | |||||
collector.SubmitRecursive(&unitModel); | collector.SubmitRecursive(&unitModel); | ||||
} | } | ||||
} | |||||
for (size_t i = 0; i < m_DebugSpheres.size(); ++i) | for (size_t i = 0; i < m_DebugSpheres.size(); ++i) | ||||
collector.Submit(&m_DebugSpheres[i]); | collector.Submit(&m_DebugSpheres[i]); | ||||
} | } | ||||
void CCmpUnitRenderer::UpdateVisibility(SUnit& unit) const | void CCmpUnitRenderer::UpdateVisibility(SUnit& unit) const | ||||
{ | { | ||||
if (unit.inWorld) | if (unit.inWorld) | ||||
Show All 25 Lines |
Wildfire Games · Phabricator
What does the LOD name mean? It's not obvious from the name.