Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am using Ogre3d to develop a 3d simulation/game. One task is to determine whether the user has focused the camera on a specific object. So I cast a ray from the camera to what is currently in the center of the screen. This check works fine, I can determine which object is currently in the focus (i.e. centered on the screen).

However, I also need to determine which side of this object is in focus (i.e. centered on the screen). So, for example, when I have a model/object of a human standing on the ground, I need to determine whether the user looks at this model from the front or from the back.

How can I determine which side of an object is currently in the focus of the camera?

share|improve this question
    
I honestly dont know if what I am mentioning is correct or even possible, but I figured I would comment on it. Can you ray cast from the front of the object you have found in focus? Then could you compare the two ray's and calculate an angle between them? You could define front as the front 180 degrees and the back as the back 180 degrees. You could even split that into 90 degree segments and have Front, Right, Left, and Back. Know clue if that is possible, just a thought. –  Dean Knight Jun 21 '13 at 12:19
    
@DeanKnight: Thanks, that sounds at least possible... I will think a bit on that. But I still hope there is some built-in method of doing this in Ogre :) –  Matthias Jun 21 '13 at 12:36
    
I drew it out on paper, and it looks like if you take the ray cast from the object in focus and shift it to the origin of the players ray (so we can calculate angle between the two vectors) you will have an angle of >90 degrees if the object is facing you. It will have an angle of <90 degrees if it is facing away from you. Should be able to find the angle between two rays with this: wikihow.com/Find-the-Angle-Between-Two-Vectors I know I am ignoring one dimension, but I think as long as you only ignore the "up" direction and keep the X and Y direction, the math should check out. –  Dean Knight Jun 21 '13 at 12:37
    
Also, of course, Im assuming the Z direction is "up". Some people use the Y direction as "Up". Make sure you figure out how Ogre does it. –  Dean Knight Jun 21 '13 at 12:38
1  
Just take the dot product between ray direction and object forward? –  Archy Jun 21 '13 at 13:21
show 1 more comment

3 Answers

up vote 4 down vote accepted

Writing up an answer from my comments as I believe it's not such a crazy idea after all.

Assumptions

  • The "Up" direction should not matter in these calculations
  • You have found the object in focus and you can ray cast from its front just like you did with the character
  • The "Up" direction is Z. (This could be Y depending on who you are talking to or what engine you are using)
  • Front is defined as front 180 degrees of the humans view.
  • Back is defined as the back 180 degrees in back of the human model.

Proposed Solution

1) cast a ray from the front of the object in focus. In the case of a human you have a definite front and back.

enter image description here

2) Find the diference in x and y so you can translate the ray from the object in focus on top of the players ray

enter image description here

3) Apply that translation. You should now have what is viewed in picture 3. This allows you to solve for the angle (theta in this case). There are details on solving for theta here: http://www.wikihow.com/Find-the-Angle-Between-Two-Vectors

Just some simple linear algebra. Nothing too bad I think.

enter image description here

Results

1) Now, intuitively, you can see that if this angle theta is >90 degrees then the player is facing the "front" of the object in focus.

2) If the angle is <90 degrees then the object in focus is facing away from you, and the player is looking at its "back".

More Thoughts

Remember the assumption mentioned before on "front" and "Back". Depending on your gameplay needs you may want to define this differently. WoW -seemed- to have this kind of setup when it came to calculating if the player was "in back" of the target. Playing as a rogue, if you are in the back 180 degrees you seemed to get the damage modifier for being "in back" of the target.

Good luck. Hope this helps.

share|improve this answer
1  
+1 for the detailed answer :) –  Matthias Jun 21 '13 at 13:38
    
I +1'ed the question because it was a great question. Definitely something I will come back to in a few months when I start delving into more 3d. –  Dean Knight Jun 21 '13 at 13:41
add comment

bool front = dot( normalize( rayDirection ), normalize( objectForward ) ) < -0.5f;

Does not break, simpler and faster than cross. Using acos you can calculate the exact angle.

share|improve this answer
    
Actually, crossing and dotting are about the same speed. But normalizing slows things down alot (relatively speaking). I think if you did this without the normalizing and simply tested for which side of zero you were on, that would answer the question and be the equivalent of the cross method in terms of perf. –  Steve H Jun 21 '13 at 18:37
    
Cross product: 6 multiplications, 3 additions. Dot product 3 multiplications, 2 additions. The normalization is most likely required as I interprete "is the character facing me" as "is he looking eg max 45° into my direction" not up to 90°. –  Archy Jun 21 '13 at 22:36
    
But, you are right, when you only compute the part of the cross product required for the test it would be cheaper but only if the 90° check is enough. –  Archy Jun 21 '13 at 22:40
    
I think in the end I would go with the dot product way unless the cross result was needed as a rotation axis elsewhere or something. Your dot method is a bit easier to visualize too. For some reason the cross method popped into my mind first. –  Steve H Jun 22 '13 at 2:01
add comment

The result of a cross can give you that answer. This is c#/xna but think of it as pseudo code.

bool lookingAtFront = false;
Vector3 result = Vector3.Cross(directionCamIsLooking, localRightOfLookedAtObject);

if(result.Y > 0) //assumes Y is up. else use result.Z
  lookingAtFront = true;

this may break if the camera is pitched severely (looking straight down or up at object). but otherwise the result vector will either be pointing somewhat upward or downward depending on which side of the localRightOfLookedAtObject the directionCamIsLooking is.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.