Get rendered width/height of object

Is it possible to get the rendered width/height of a 3D object in the scene?

I.e. the projected width/height of the object in the camera/screen plane.

I know you can get screen coordinates for a point, but I haven’t been able to figure out how to get the right points to calculate the projected width/height. Perhaps there is a better way?

you could get the coordinates of the bounding box.

It has a center and an x,y,z extend, you could compute the rendered width and height from this.

It’s not completely accurate but it could do the trick

1 Like

Thank you.

That’s what I’ve been trying, but I can’t quite get it to work as expected.

What I did was to get a copy of the center of the bounding sphere (in this case) and add the radius of the bounding sphere to it.

I then tried using the getScreenCoordinates method of the Camera to one “side” point of the projected object.

Then I got another copy of the center and subtracted the radius instead (on each axis) and got the other “side” point via the getScreenCoordinates method. Finally, I subtracted the latter from the first (x for width/y for height) to get the projected size, but the values don’t seem to be right.

I’ll try it again and see if I got it wrong somewhere.



EDIT: Nevermind, this works ok, I just had my bounds messed up.

@Tumaini

Could you post some of your code on this? I think I fried my brain with too much MC this weekend.



I’m guessing I’m doing it all wrong as my results are mostly ok. But mostly isn’t enough.

1 Like

@madjack

Sure.

[java]Spatial o = (Spatial) obj;

BoundingVolume volume = o.getWorldBound();

float size = 15;

if(volume instanceof BoundingBox) {

Vector3f extent = ((BoundingBox)volume).getExtent(null);

size = (extent.x+extent.y+extent.z)/3f;

}

else if(volume instanceof BoundingSphere) {

size = ((BoundingSphere)volume).getRadius();

}

Vector3f world = o.getWorldTranslation();

Vector3f w = (cam.getScreenCoordinates(world.add(size, size, size))

.subtract(cam.getScreenCoordinates(world.subtract(size, size, size)))

);[/java]

where w is the x and y extent of the bound as projected on the screen.

3 Likes

Thanks.



It’s not 100% working but I guess this is as good as it’ll get. I do have to abs() the results but it’s better than what I had.



Very much appreciated. :smiley:

1 Like

Inaccuracies are probably because the bounding box is not oriented to the screen. The error will go up as the object gets larger as the near point appears to be a little too “big” and the far point appears to be a little too “small”.



In my off the cuff opinion, it would be better to multiply “size” by camera.getLeft() and camera.getUp()… add those vectors to the world location of the object and then get the screen coordinates of those. That’s as accurate as you can get and should be at least pixel-accurate if the “size” is correct.



Something kind of like:

[java]

left = cam.getScreenCoordinates( world.add( cam.getLeft().multiply(size) ) );

right = cam.getScreenCoordinates( world.add( cam.getLeft().multiply(-size) ) );

top = cam.getScreenCoordinates( world.add( cam.getUp().multiply(size) ) );

bottom = cam.getScreenCoordinates( world.add( cam.getUp().multiply(-size) ) );



width = right.x - left.x;

height = top.y - bottom.y;

[/java]



…shouldn’t have to abs in that case unless I got something flipped.

4 Likes

Thanks @pspeed that works flawlessly.

1 Like

Thank you @pspeed for that improvement!