Jump to content
  • Advertisement
Sign in to follow this  
FatPope

Billboarding/Rotation Issue

This topic is 3025 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've made a hemisphere of vertices and I'm attempting to get it to rotate so as to always face the camera position. It works for the most part but when the camera position moves into negative X values the rotation seems to go haywire. Negative Y and Z values seem to cause no problems.

It's probably a simple solution but I can't seem to get what the problem is. If anyone could help me I'd greatly appreciate it.

Here's what I'm using to create the rotation matrix. I'm trying to keep the "right" vector on the XZ plane as I only want the hemisphere to pan and tilt, not roll.


origTarget = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
origRight = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
origUp = D3DXVECTOR3(0.0f, 1.0f, 0.0f);

D3DXVECTOR3 terrainToCamera = D3DXVECTOR3(GetCamera().position().x - mInfo.PlanetPosition.x, GetCamera().position().y - mInfo.PlanetPosition.y, GetCamera().position().z - mInfo.PlanetPosition.z);

// Project the vector to the XZ plane
D3DXVECTOR3 terrainToCameraXZ = D3DXVECTOR3(terrainToCamera.x, 0.0f, terrainToCamera.z);
D3DXVec3Normalize(&terrainToCameraXZ, &terrainToCameraXZ);
float yRotation = acos( D3DXVec3Dot( &terrainToCameraXZ, &origTarget) );

D3DXMATRIX yRotationMatrix;
D3DXMatrixRotationY(&yRotationMatrix, yRotation);
D3DXVECTOR3 rotatedRight;
D3DXVec3TransformCoord(&rotatedRight, &origRight, &yRotationMatrix);

D3DXVec3Normalize(&rotatedRight, &rotatedRight);
D3DXVec3Normalize(&terrainToCamera, &terrainToCamera);
D3DXVECTOR3 rotatedUp;
D3DXVec3Cross(&rotatedUp, &rotatedRight, &terrainToCamera);
D3DXVec3Normalize(&rotatedUp, &rotatedUp);

D3DXMATRIX terrainWorld = D3DXMATRIX(rotatedRight.x, rotatedRight.y, rotatedRight.z, 0.0f,
rotatedUp.x, rotatedUp.y, rotatedUp.z, 0.0f,
terrainToCamera.x, terrainToCamera.y, terrainToCamera.z, 0.0f,
mInfo.PlanetPosition.x, mInfo.PlanetPosition.y, mInfo.PlanetPosition.z, 1.0f);





Share this post


Link to post
Share on other sites
Advertisement
You can do this much easier and faster:


D3DXVECTOR3 SpriteRotation;
//Do some computation with the Camera-Rotation
SpriteRotation.y=SharedParams->CamRot->x+D3DXToRadian(180);
SpriteRotation.x=SharedParams->CamRot->y;
SpriteRotation.z=0;





Depending on how your plane is rotated, you may have to change the degrees I add, or some of the axis.
And you said that you want to leave it standing up, but I'm sure you will find out which parameter you have to make constant.

Then, just use this Vector to rotate a matrix as you would normally do.

That's all, no vector math [smile]

Share this post


Link to post
Share on other sites
I'm not sure I entirely understand. The vector there gives the rotation around each of the x, y and z axes to get a final rotation right?

If I obtain the object's rotation from the camera's rotation then the object would rotate whenever the camera rotates. I want to base it entirely on the position of the camera rather than its rotation.

Also, I don't quite see why you are getting the object's y rotation from the camera's x rotation and vice-versa.

Nevertheless, I seem to have solved the main problem. It was something to do with the dot product not returning correctly when the angle between the vectors was greater than 90 degrees. The planet was at (0,0,0) so when the camera pos went into negative x values the angle between the vectors to the original target (which is always (0,0,0)) and the to new target (to the camera position) was over 90. A quick and dirty solution was to simply compare the x coords and give a negative angle in that case, i.e. replace the part of the code above that obtains the "right" vector with this:


float dot = D3DXVec3Dot( &terrainToCameraXZ, &origTarget);
float yRotation = acos( D3DXVec3Dot( &terrainToCameraXZ, &origTarget) );
if (GetCamera().position().x < mInfo.PlanetPosition.x)
yRotation *= -1;

D3DXMATRIX yRotationMatrix;
D3DXMatrixRotationY(&yRotationMatrix, yRotation);
D3DXVECTOR3 rotatedRight;
D3DXVec3TransformCoord(&rotatedRight, &origRight, &yRotationMatrix);



I am, however still having problems if I change the planet's position to anything other than (0,0,0). The hemisphere continually rotates according to the camera's position (as it should), yet it's no longer directly facing the camera. It looks like it's always facing a position a certain distance away from the camera, presumably the offset is the same as the difference in planet position from the origin.

I haven't been able to see yet why this is though. The terrainToCamera vector I have in the first post takes into account the planet's position, so why is this happening? Anybody got any ideas?

Share this post


Link to post
Share on other sites
Quote:

I want to base it entirely on the position of the camera rather than its rotation.


Ok, then you wanted something different then meant. I use this to rotate Point-Sprites for a particle system for example. But they all got it's own location in the world. It just makes the rotation always face the camera.

Quote:

Also, I don't quite see why you are getting the object's y rotation from the camera's x rotation and vice-versa.


The vector is YawPitchRoll or so, not xyz. Well, lets say it just works for me [smile]

Share this post


Link to post
Share on other sites
Yeah Yaw, Pitch, Roll is just a rotation around the Y axis, the X axis and the Z axes respectively, so I see what you're doing.

Anyway, I've got the rotation sorted now when the planet's at the origin, as per my last post, but is there any reason why it doesn't seem to directly face the camera when the planet position is changed?

Share this post


Link to post
Share on other sites
I think I've found the problem. I was right, it was something stupid.

For those who may be interested:

I was using the world matrix for translation and rotation, all the code below is correct. However, when I was building the vertices initially I wasn't building them around the origin. Instead I was taking into account the planet's position and building them around that point. So when the world matrix was applied I was effectively translating them for a second time, thus explaining the offset I was receiving.

I'd kinda forgotten about the problem and gone on to other things, but when I went back to change something else in the method where I was building the vertices I noticed this.

Like I said, a stupid error. It really shouldn't have taken me as long as it did to solve.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!