## Idea: Calculate Max Pixel Count for HOQs

tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:

### Idea: Calculate Max Pixel Count for HOQs

This should be an easy project for a student.

Utilize the HOQ Wiki Entry http://www.ogre3d.org/wiki/index.php/Ha ... ixel_Count to design an algorithm that can estimate the pixel count for an Ogre::Billboard at various resolutions and camera field of views.

lodi
Greenskin
Posts: 103
Joined: Sat Jul 24, 2004 7:06 pm
Why would you use an occlusion query on a billboard? You can just run the vertices through the current projection matrix and then do a simple formula to get the area in normalised screen coordinates (which you can easily change to # of pixels, or leave it as a ratio of total screen area, which is probably what you wanted in the first place.)

buddy
Posts: 78
Joined: Tue Mar 29, 2005 3:35 pm
Location: USA
lodi wrote: You can just run the vertices through the current projection matrix and then do a simple formula to get the area in normalised screen coordinates.
The idea seems to be about applying it to things like lens flares, and then you need to know how much of it was, well, occluded..

Kencho
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:
Think that the student will be rewarded with 4500\$ for this, so it shouldn't be that easily done.
Besides, this year seems to be a lot of really useful projects for Ogre!

lodi
Greenskin
Posts: 103
Joined: Sat Jul 24, 2004 7:06 pm
Ahh yes, my bad. For some reason I was thinking only about using the pixel count for lod purposes, etc.

And I also agree that this isn't really worthy of a SoC project...

tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:
Kencho wrote:Think that the student will be rewarded with 4500\$ for this, so it shouldn't be that easily done.
Besides, this year seems to be a lot of really useful projects for Ogre!
Hey that's about 3 month's rent in Seattle.

buddy
Posts: 78
Joined: Tue Mar 29, 2005 3:35 pm
Location: USA
tgraupmann wrote:Hey that's about 3 month's rent in Seattle.
Well, in some parts of the world it isn't so. No way can SoC compete money-wise with your average tech internship in US, even at undergraduate level. Is it a reason to let "do-in-a-week" projects in? I dunno, but I doubt it .

OGRE Retired Team Member
Posts: 19265
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:
I also think this is too small for a whole project, although if it were an extended proposal with a framework for using HOQs in various cases it would be worth consideration.

tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:
lodi wrote:Why would you use an occlusion query on a billboard? You can just run the vertices through the current projection matrix and then do a simple formula to get the area in normalised screen coordinates (which you can easily change to # of pixels, or leave it as a ratio of total screen area, which is probably what you wanted in the first place.)
I had figured to get the corners of the billboard in screen coordinates to calculate width and height. This figuring area is simply width X height.

Man that sounds so easy. Is there a working example of this somewhere?

I'll post this in the wiki as soon as I figure it out...

lodi
Greenskin
Posts: 103
Joined: Sat Jul 24, 2004 7:06 pm
Well as buddy pointed out, I forgot about the case when part of the billboard is occluded by something. But you can still use that kind of idea for lod purposes etc.

The billboard is already orthogonal to the camera, so you don't even need to transform the vertices, you can just get a height and width vector and transform those. Multiply first by the inverse of the camera's view matrix and then the cameras projcection matrix. Normalize w, then height * height of the window * width * width of the window and you have your approximate pixel count. Probably more useful to just use height*width since that'll give you the percentage used (of the whole screen, regardless of resolution)

tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:
This is not the most efficient code but it seems to be working. I'll refine in the morning.

ToScreenCoordinates

Code: Select all

``````inline Ogre::Vector2 ToScreenCoordinates(Ogre::Camera *_camera, const Ogre::Vector3 &_position)
{
Ogre::Vector3 hcsPosition = _camera->getProjectionMatrix() * _camera->getViewMatrix() * _position;
return Ogre::Vector2(0.5 - hcsPosition.x * 0.5f, hcsPosition.y * 0.5f + 0.5);
}``````
Sample code

Code: Select all

``````	// Get the pixel count
unsigned int pixelCount = m_RenderableOcclusionPair->GetPixelCount();

// Get the render window
Ogre::RenderWindow* renderWindow = Game::GetSingleton()->GetWindow();
assert (renderWindow);

// Get the Camera Scene Node
Ogre::Camera* camera = GetCamera();
assert (camera);

// Approximate area
float halfWidth = m_BillboardWidth*0.5f;
float halfHeight = m_BillboardHeight*0.5f;

Ogre::Vector3 pos = m_OcclusionTestSceneNode->getPosition();
Ogre::Vector3 nX = camera->getOrientation().xAxis().normalisedCopy();
Ogre::Vector3 nY = camera->getOrientation().yAxis().normalisedCopy();

Ogre::Vector2 topLeft = ToScreenCoordinates(camera, pos + nX*(-halfWidth) + nY*halfHeight);
Ogre::Vector2 topRight = ToScreenCoordinates(camera, pos + nX*halfWidth + nY*halfHeight);
Ogre::Vector2 bottomLeft = ToScreenCoordinates(camera, pos + nX*(-halfWidth) + nY*(-halfHeight));
Ogre::Vector2 bottomRight = ToScreenCoordinates(camera, pos + nX*halfWidth + nY*(-halfHeight));

float aX = std::min(0.0f, std::min(topLeft.x, std::min(topRight.x, std::min(bottomLeft.x, bottomRight.x))));
float aY = std::min(0.0f, std::min(topLeft.y, std::min(topRight.y, std::min(bottomLeft.y, bottomRight.y))));
float bX = std::max(1.0f, std::max(topLeft.x, std::max(topRight.x, std::max(bottomLeft.x, bottomRight.x))));
float bY = std::min(1.0f, std::max(topLeft.y, std::max(topRight.y, std::max(bottomLeft.y, bottomRight.y))));

float width = (bX - aX) * renderWindow->getWidth();
float height = (bY - aY) * renderWindow->getHeight();
float area = width*height;
if (area)
{
float ratio = pixelCount/area;
}``````

bleubleu
Kobold
Posts: 27
Joined: Mon Dec 11, 2006 4:38 am
One way to approximate the area would be to use the Camera::projectSphere() method.

Code: Select all

``````bool Ogre::Camera::projectSphere  (  const Sphere &  sphere,
Real *  left,
Real *  top,
Real *  right,
Real *  bottom
)  const [virtual]``````
This is nice because it returns the bounds of a square in screen coordinate so you can basically replace all your code with a single call. I will try this tonight.

Mat