Get the distance betwen the camera and the surface of object

Bady

13-07-2012 06:52:03

Hy!

I would like to write a code what is show objects in a row away from the camera ( I mean show the closest, and the second closest, etc.)
I know I can get the position of the object, but it is make a problem if an object is longer than an another,but the position is farther than an another, and the surface is closer.


Have the Mogre a command about the check this, or any idea, how to solve this problem?

Thank you

Tubulii

14-07-2012 10:29:33

You have to raycast from the camera to entity (or from entity to entity).
The basic process: Raycasting to the polygon level
A handy library for this: MMOC (highly recommend)

You'll get the: Hitpoint, distance and the entity. You can filter the results (e.g. exclude entites) by the queryflags.

Example (Pseudo code):

enum QueryMask {
Wall = 1<<1
Ground = 1<<2
Player = 1<<3 }

(somewhere in your code)

Entity Groundent = (...);
Groundent.QueryFlags = QueryMask.Ground;

(Somewhere in FrameStarted or similar)

static CollisionTools ct = new CollisionTools(MySceneMgr);
var Result = ct.RaycastFromCamera(RenderWindow, Camera, ScreenPosition, QueryMask.Ground);
if (Result != null)
{
//success, this has to bee an entity with Mask "Ground".
}

Beside that, take a look at this tutorial about Queryflags (also recommend).

Beauty

15-07-2012 12:44:38

Instead of using the referenced code in the wiki I recommend to use my one.
A half year ago I wrote a new class for "raycasting to polygon level".

The code you find here:
http://www.ogre3d.org/forums/viewtopic. ... 83#p446083

Notes about you find here:
http://www.ogre3d.org/forums/viewtopic. ... 51#p448551

In general my code is ready to use. Only some helper classes (e.g. for debugging) are added quick and dirty to a second code file.
When I my diploma thesis work is ready, I want to polish up the code and publish it in a common way (not only as attachment of a forum post).

Note:
The code of the wiki can cause crashes and doesn't support terrain, nor ManualObjects.

If you have specific questions or problems with my new raycasting code, please use my "official" forum topic (here).

Beauty

18-07-2012 00:24:08

Tubulii - thanks for your good notes.
I still didn't know that the Query Flags are descripted by a tutorial.

By publishing your notes I got motivated to update the wiki page Ray query with MOGRE, which I created several years ago.
There I also added your pseudo code snippet. :D

Tubulii

18-07-2012 10:10:11

I'm glad I could help. I really recommend this tutorial with query flags. It's amazing what you can do with it. You can even combine them.
int WallAndGround = QueryMask.Ground | QueryMask.Wall;
But the enum HAS to be a real flag enum. Otherwise you'll get strange results.

Beauty

18-07-2012 10:28:06

Nice example.

What you mean with real flag enum?
An Integer with only one "enabled bit"?
Or a Boolean?

If you like, you can add further information to the wiki page.
It's realy useful when people share their knowledge and experiences.

Tubulii

18-07-2012 11:14:37

An Integer with only one "enabled bit"?
Yes,
my so called "real enum flag":
[FlagsAttribute] // optional, but it makes clear, that this is a flag enum.
enum QueryMasks : uint //Depends on your needs, but I need a lot of flags and bit shifting needs big numbers (int = 32bit = 32 flags, byte = 8 bit = flags, ...).
{
  1. Ground = 1<<0, //bit shift required (2,4,8,16,32,64,128,256,...)
    Wall = 1<<1[/list:u][...]}

At the beginning, I forgot to set the right values. I thought setting the attribute was all i need (not a "real" flag enum ;) )
Of course, you could use normal fields, too, but that's the same.

Edit: my current flag enum:
Public Enum QueryMask As UInteger
COMMON_LEVEL_MESH = 1 << 2
COMMON_LEVEL_ITEM = 1 << 9
INVENTORY_ITEM_MESH = 1 << 3
CHARACTER_MESH = 1 << 4
IS_TARGETABLE = 1 << 5
OTHER_MESH = 1 << 6
NAVMESH = 1 << 7 'Or PHYSX_NON_COLLIDABLE
GIZMO = 1 << 8 'Or PHYSX_NON_COLLIDABLE

'PHYSX_COLLIDABLE = 1 << 10
'PHYSX_NON_COLLIDABLE = 1 << 13
'PHYSX_COLLIDABLE_NON_PUSHABLE = 1 << 11 Or PHYSX_COLLIDABLE
'PHYSX_COLLIDABLE_PUSHABLE = 1 << 12 Or PHYSX_COLLIDABLE
End Enum

Bady

04-08-2012 03:35:31

When I trying the bounding box I found a strange "error":
the boundingbox not the same size as the object, when i rotate it

it is normal? I use the Pitch, yaw, roll commands to rotate

zarfius

04-08-2012 12:10:24

I can't see your image but I suspect you are are seeing the axis aligned bounding box. There are 2 types of bounding boxes typically seen in graphics and physics engines, the first is an axis aligned bounding box (AABB) and the other is the oriented bounding box (OBB). Generally the AABB is much faster to do calculations on during rendering or physics simulation updates, but it has the downside you have discovered. It doesn't fit tightly around the object when it is rotated or odd shaped.

So the answer to your question is, yes, it is normal.

Beauty

04-08-2012 13:03:01

I created a tiny wiki page and a picture for Axis Aligned Bounding Boxes:
http://www.ogre3d.org/tikiwiki/-AABB

The behaviour of the AABB (non-rotated, but scaled) is important to know when you perform ray queries or collision detections. Otherwhise you can get an other result than expected.

I'm not shure, but maybe it's possible to add an additional padding to the AABB. Then the AABB size increases more.
Not important for your question, but maybe a useful background information for the future.

If you want to use ray queries in your application, have a look to this wiki page:
http://www.ogre3d.org/tikiwiki/Ray+query+with+MOGRE
....... By the way: Thanks to Tubulii for the additions :D

Bady

05-08-2012 02:06:32

Ok, one question left:
How Can I get the camera position?
In the reference write this:
http://www.ogre3d.org/docs/api/html/classOgre_1_1Camera.html#a10edefff4b16f45968a0103141194e6d
but this command is not exist :S

Oh, meanvile i found out, but i have some another questions:

what is the difference between Position and DerivedPosition?
And what is the function of the "up" and the "Right" and "Orientation" commands?

and my question is still standing:
how check it, witch object is the closest (and the second closest, etc) from the camera?
example :

here 3 ninjas(they are twins :D)
the "A" ninja's sword the longest, he is the closest from the camera, he disappear first , the "B" ninja further from the camera, than the "A" ninja, he disappear second. and least the furtest ninja disappear last.
how to detect, witch is the closest ninja?

Sorry for the nooby example, but my english occupations using skills is not the best (i hope it is perfectly understandable.)

Tubulii

05-08-2012 12:27:46

Most of the native GetXX/SetXX methods are turned to properties.

"Camera.GetPosition" and "Camera.SetPosition(...)" are merged to the property "Camera.Position".

Diference Position and DerivedPosition (same for all DerivedXX props):

The Position prop indicates the offset to the parent node e.g. :

You have two nodes: A and B. 'A' is offseted to (0,100,0). Now you attach node 'B' to 'A'.
'B' has the position (0,0,0) (default value) but in reality its position is (0,100,0) (DerivedPosition).

If you change B's position to (0,0,200) its real position is (0,100,200) (DerivedPosition).

Conclusion: DerivedPosition: Absolute position in the world; Position: Relative position to the parent node.
Tip: Read the wiki (tutroials!) and the doc, too! Its written there! The position thing is described in the first tut.

And 'Up' and 'Right': Please read the doc. And if you still have no idea, check out the ogre (not mogre) source and take a look at the implementation...

Distance from node to camera: int length = (Camera.RealPosition - MyNode._GetDerivedPosition).Length;

And your scene looks a bit strange, the sword of ninja 'A' is definitly tooo long.

Bady

05-08-2012 17:51:42

Ok, last try...


if i use the objet position, the "A" ninja disappear first, and the "B" ninja Disappear second
but the "B" ninja is closer from the camera, than the "A" ninja (his sword, the red circle)

Tubulii

06-08-2012 11:24:58

You have to get the distance of the AxisAlignedBox of the entities and your camera (easiest solution):
The AABB consists of 6 planes. Iterate through all of them and each time you calculate the distance between the plane and camera position. Mabe you can use the AxisAlignedBoxSceneQuery.

And you may want to check this. You could convert the code to c#. But I do not think that you have to, just try to understand how it works...

Bady

27-08-2012 02:48:18

It is possibe to get the loaded entity's points coordinate somehow?

Tubulii

27-08-2012 09:33:48

It is possibe to get the loaded entity's points coordinate somehow?
Nope. The entities are attached to a scenenode. But the model itself can be offsetted. This depends on the modeller (i.e. the person who made the mesh) because he in in charge of this.

Edit: As Beauty posted correct, it is of course possible to get the vertex informations of each mesh. I refered to the mesh's position.

Beauty

27-08-2012 22:29:32

Here is a (Mogre) code how to read all vertex positions from a ManualObject.
http://www.ogre3d.org/tikiwiki/Read+raw ... ct+-+MOGRE
For Entities (e.g. the loaded Ninja mesh) it's similar.

Here is a (Mogre) code for reading out vertex positions from an Entity:
http://www.ogre3d.org/tikiwiki/Raycasti ... el+-+Mogre
Scroll down to the code section of GetMeshInformation().
Note: This method works only for meshes, which use the render type OT_TRIANGLE_LIST.
When a mesh contains other triangle types or lines or points, then you'll get bad results or a crash. (Or add some lines of code to check for the sections render type and skip all unsupported ones.)
Note 2: The method GetMeshInformation() has no good performance. This doesn't care if you use it from time to time. But if you use it for every frame, it decreases your FPS rate.

Bady

29-08-2012 00:36:05

Thank you :)