Bill-boarding oriented rectangle

Started by
17 comments, last by Trienco 10 years, 9 months ago
Oh i assumed the points to be same depth. Might want to do this in screen space.

Screen space you would just transform the points to screen space, then make quad of correct size (distance between points) and rotate it in 2D.

o3o

Advertisement

Creating the mesh quad should be more straightforward, like you said.

The following was taken from user Floyd of the BlitzBasic forums. Say that the vector from Point 1 to Point 2 describes the Z axis of the quad, and say that the Y axis of this quad is aligned to the mesh normal (so the Y axis is perpendicular to the quad). You can figure global Pitch (X) and Yaw (Y) rotation values from these axes.

We need to find the Roll (Z) value.

A way to find this Roll (Z) rotation value for the quad to face the camera is to imagine that this value will make the quad place the camera in this quad's ZY plane.

There may be some negations needed based on what you consider as positive or negative sides, angles etc., but the logic is here.

2ps3ymg.png

To do the above, you need to get the camera's position in the quad's local space. Store it in a vector like "cameraLocalPos".

Then you can find the global Roll (Z) value for the quad with this: roll = ATan2( cameraLocalPos.X, cameraLocalPos.Y )

Note the inversion of the ATan2 parameters since we want the angle relative to the Y axis rather than the usual X axis.

Then rotate the quad in global coordinates by the following: Quad.Rotate( GlobalPItch, GlobalYaw, roll ).

@Kryzon

Sounds exactly what I need, although the rectangle should not be aligned with any standard axis;

So, one million dollar question: how do I get it to rotate around a particular non-aligned axis (which should correspond to the distance between the points) a certain angle, such that said angle returns a bill-boarded normal (which if I got it right, should be the same formula you showed)?

What you're asking depends on how you created the mesh, and how it's positioned relative to its "pivot point" (or transformation matrix, in other words).

Steps:

1) Create a blank mesh object with an identity pivot point. This pivot point being identity means it's located at the world's origin and has zero orientation.

2) Measure the distance between the two 3D points and consider this as the length of the quad. The height of the quad is some predefined value.

Build the quad with absolute world coordinates and centered on the world's origin (so this mesh is actually centered on its own pivot point, which is also at the worlds origin).

Make sure the length of the quad goes along the world's Z axis.

Make sure the visible face of the quad points along the world's Y axis.

This mesh is aligned to the world, it's not facing the camera yet.

3) Build a rotation matrix from vectors A and B.

Vector A is the 'vector going from point 1 to point 2' (considered as Z).

Vector B is the resulting vector from 'crossProduct( A, World_Y_Axis )' (considered as X).

With these two vectors A and B you can find an orientation matrix O.

4) Find the location at 'the middle point between point 1 and point 2' (it's just the average of their coordinates). This finds a location vector L.

5) Transform the quad's matrix by orientation O and location L. This positions and orients the quad just like you want it to be, except it's not facing the camera yet.

6) Transform the quad's matrix Roll (Z) value by the way previously described in post #12. This way the rectangle faces the camera.

Building the objects transformation matrix yourself sounds like the easiest approach, except that the two vectors to build the rotation part from are p2-p1 and (to make it face the camera) camera.position - p1 (or any other point on the line).

From there you just get the third vector with a cross product and after that use another cross product between the first and third vector to "fix" the second one (to be orthogonal). Normalize all vectors and you should be done. In your matrix, the first vector is the x-axis, the third one is the y-axis and the second is z. That choice is arbitrary and only depends on how your rectangle is modeled (I assume x being along the length, y being the width and z being the normal vector facing the camera).

There is no manual scaling going on unless what you mean is that is has to scale itself to cancel out the scaling you get from perspective projection.

When you create the geometry, do _not_ center it around the origin or you're just making it pointlessly complicated to move it into position. Just use (0,width,0), (0,-width,0), (length,width,0) and ((length,-width,0).

That approach has worked perfectly fine to have a ton of laser beams flying around. At least it's how I remember it, since the whole project seems to have disappeared.

f@dzhttp://festini.device-zero.de

camera.position - p1 (or any other point on the line).

[...]


From there you just get the third vector with a cross product and after that use another cross product between the first and third vector to "fix" the second one (to be orthogonal).

That's an interesting way to get the orientation, it should be much faster.

Thanks for sharing.

As Trienco proposed i removed scaling and created geometry with predetermined width and length (height in my case) and now it seems to work correctly.

Thank you.

Mh, I'll try this one as soon as I get my hard disk fixed (hope soon... sigh)

Thanks!

There is one special case that needs to be considered. If the camera and both points are on the same line, the cross product will be all 0 (or very close to it). On the bright side, in this special case you would be looking at the front or rear edge of the rectangle and couldn't see it anyway.

f@dzhttp://festini.device-zero.de

This topic is closed to new replies.

Advertisement