Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement distance culling #162

Open
fallenoak opened this issue Jun 17, 2016 · 1 comment
Open

Implement distance culling #162

fallenoak opened this issue Jun 17, 2016 · 1 comment

Comments

@fallenoak
Copy link
Member

fallenoak commented Jun 17, 2016

After watching a few videos of people playing WotLK-era World of Warcraft, I'm almost certain that the client implements distance culling of some sort. In particular, it seems like small-ish map doodads are culled much earlier than large map doodads and WMOs.

Ideas

  • Since WMOs will be portal culled, let's ignore them (and their doodads) for now: if WMOs are loaded, we'll render them
  • Use the radius of the auto-computed bounding sphere to classify map doodads by size
  • Define separate visibility radii (distance from camera) for culling small map doodads vs large map doodads
  • Implement a culling function in VisibilityManager to cull map doodads based on these parameters
  • Bonus points: make culling fade the doodad in / out rather than making it suddenly pop on the screen

Misc

Some client constants (from MoP):

  • CWorldView::s_fadeDistDefault[] = [30.0, 100.0, 200.0, 650.0, 2100.0]
  • CWorldView::s_fadeSizeDefault[] = [1.0, 4.0, 25.0, 100.0, 100000.0]
  • CWorldView::s_fadeRangeDefault[] = [5.0, 10.0, 15.0, 20.0, 50.0]
  • s_fadeDistScale = 1.0
  • World::s_prevFarClip = 0.0
  • World::s_farClip = 0.0
  • World::s_minFarClip = 200.0 (set in World::InitializeStartup())

Potentially interesting client functions (from MoP):

  • CWorldView::ScaleFadeDist()
  • World::GetTerrainLodDist() -> return fmaxf(200.0, World::s_terrainLodDist);
  • World::GetWmoLodDist() -> return fmaxf(200.0, World::s_wmoLodDist);

Other interesting code bits (from MoP):

int CWorldView::Update(*args)
{

  ...

  if (World::GetTerrainLod()) {
    if (World::GetTerrainLodDist() < s_fadeDistScale * CWorldView::s_fadeDistDefault) {
      CWorldView::s_fadeDistMax = LODWORD(World::GetTerrainLodDist());
    } else {
      CWorldView::s_fadeDistMax = s_fadeDistScale * CWorldView::s_fadeDistDefault;
    }
  }

  CWorldView::s_fadeDistMin = CWorldView::s_fadeDistMax - CWorldView::s_fadeRangeDefault;
  CWorldView::s_fadeDistMaxSqr = CWorldView::s_fadeDistMax * CWorldView::s_fadeDistMax;
  CWorldView::s_fadeDistMinSqr = CWorldView::s_fadeDistMin * CWorldView::s_fadeDistMin;

  ...

}
int World::GetTerrainLod()
{
  if (World::s_terrainLodDist >= 0.01) {
    return World::s_terrainLodDist <= fmaxf(World::s_farClip, World::s_minFarClip) * 0.6;
  } else {
    return 0;
  }
}
int World::GetWmoLod()
{
  if (World::s_wmoLodDist >= 0.01) {
    return World::s_wmoLodDist <= fmaxf(World::s_farClip, World::s_minFarClip) * 0.6;
  } else {
    return 0;
  }
}
long double World::GetHorizonFarClip()
{
  return (fmaxf(World::s_farClip, World::s_minFarClip) * World::s_horizonFarClipScale);
}
void World::SetMinFarClip(float minFarClip)
{
  if (minFarClip < 200.0) {
    World::s_minFarClip = 200.0;
  } else if (minFarClip > 2600.0) {
    World::s_minFarClip = 2600.0;
  } else {
    World::s_minFarClip = minFarClip;
  }

  return World::s_minFarClip;
}
@fallenoak
Copy link
Member Author

According to schlumpf on #modcraft:

[10:28:48] [fallenoak] i seem to recall seeing doodads fading in as the camera approaches... but perhaps that's just from the files having to load?
[10:29:44] [schlumpf] should be based on their bounding box + distance, yes
[10:29:57] [fallenoak] right, so bigger objects would stay visible longer?
[10:30:11] [schlumpf] yes

As part of this issue, it might be worth spending some time hunting around IDA to see if there's anything to be gleaned about exactly how the official client handles the relationship between doodad bounding boxes and distance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant