Particles Rotation

Started by
11 comments, last by Medo Mex 10 years, 8 months ago

I have rain particles and I want to make them face the camera BUT ONLY horizontally so when the player look up, the rain should never rotate vertically or face the camera vertically.

My current code is making the particles face the camera both vertically and horizontally, how do I set static rotation vertically and make the particles only face the camera horizontally?


const D3DXMATRIX& viewMat = getCameraViewMatrix();

float f = 0.5f * particleSize;
D3DXVECTOR3 horizontal(viewMat(0,0) * f, viewMat(1,0) * f, viewMat(2,0) * f);
f = -0.5f * particleSize;
D3DXVECTOR3 vertical(viewMat(0,1) * f, viewMat(1,1) * f, viewMat(2,1) * f);
D3DXVECTOR3 view(-viewMat(0,2), -viewMat(1,2) , -viewMat(2,2));

D3DXVECTOR3 shorizontal = horizontal * particleSize;
D3DXVECTOR3 svertical = vertical * particleSize;

vertices[j*4+0] = CUSTOM_VERTEX(particlePosition + shorizontal + svertical);
vertices[j*4+1] = CUSTOM_VERTEX(particlePosition + shorizontal - svertical);
vertices[j*4+2] = CUSTOM_VERTEX(particlePosition - shorizontal - svertical);
vertices[j*4+3] = CUSTOM_VERTEX(particlePosition - shorizontal + svertical);

Advertisement

This works for me:


// Get the position of the camera.
D3DXVECTOR3 *cameraPosition = Camera->GetPostion();

// Calculate the rotation that needs to be applied to the billboard model to face the current camera position using the arc tangent function.
double angle = atan2(position.x - cameraPosition->x, position.z - cameraPosition->z) * (180.0 / D3DX_PI);

// Convert rotation into radians.
float arotation = (float)angle * 0.0174532925f;

// Setup the rotation the billboard at the origin using the world matrix.
RotateY(arotation);

I think this is what you need, the RotateY function created a matrix which is applied in the shaders.

FastCall22: "I want to make the distinction that my laptop is a whore-box that connects to different network"

Blog about... stuff (GDNet, WordPress): www.gamedev.net/blog/1882-the-cuboid-zone/, cuboidzone.wordpress.com/

@Migi0027: I think you misunderstood me, I have the particles facing the camera already.

I want to make it STOP facing the camera vertically.

You could just set up to UNIT_Y (some pseudocode):


view = normalize(cameraOrigin - particleOrigin);
if (sphericalBillboard) // whenever the particle normal should truly face the camera
{
  vertical = cameraUpVector;
}
else
{
  vertical = Vector3::UNIT_Y;
}
horizontal = cross(view, vertical);

Keep in mind to do the calculation in the right space (i.e. worldspace) and to adjust to your coordinate system.

@David_pb: Still couldn't get it to work as expected.

vertical and horizontal are D3DXVECTOR3, I already have horizontal set to face the camera in the code I posted.

Now, how do I set static rotation for D3DXVECTOR3 vertical?

I think what you want is for the particles to face the camera, but still be constrained to the up/down of the world.


Vec3 up = world.up; // (usually (0,1,0)
Vec3 side = crossproduct(up, -camera.forward);
vec3 forward = crossproduct(side,up);
 
Matrix4 particleworld= (  Vec4(side, 0), Vec4(up,0), Vec4(forward,0), Vec4(particle.position, 1));

as long as your camera cannot look directly up or down this should work. EDIT: but be forewarned, i'm low on caffeine at the moment.

Burnt_Fyr's response should do the trick. If you want further information, the term to Google is "axis-aligned billboard." Most of the results look like they're written for OpenGL, but if you grok the theory it shouldn't be too difficult to align billboards to whatever axis you need.

another option:

apparently, rain falls faster than the eye can see individual drops when looking straight ahead. it just started raining here now, and its true. you can look up, and follow a drop down, but you cant follow a drop as it falls while looking straight ahead.

this is a rain effect i read about that takes advantage of this:

you draw a cone around the camera (pointing up), with an animated random raindrops texture on it. i tried it, looks just like real rain, and no particle system. i used to use particles, but this is now my preferred method.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

@Burnt_Fyr: I just need to modify my own variable, I don't have a matrix for the particles, I'm setting the vertices position directly.

Here is how the particles face the camera in the code I posted:

const D3DXMATRIX& viewMat = getCameraViewMatrix();

float f = 0.5f * particleSize;
D3DXVECTOR3 horizontal(viewMat(0,0) * f, viewMat(1,0) * f, viewMat(2,0) * f);
f = -0.5f * particleSize;
D3DXVECTOR3 vertical(viewMat(0,1) * f, viewMat(1,1) * f, viewMat(2,1) * f); // This line is making the particles face the camera vertically, I need to modify this line to make the particles never face the camera vertically, instead I want to set a vertical rotation

D3DXVECTOR3 shorizontal = horizontal * particleSize;
D3DXVECTOR3 svertical = vertical * particleSize;

// NOTICE: I'm setting the particles vertices directly

vertices[j*4+0] = CUSTOM_VERTEX(particlePosition + shorizontal + svertical);

vertices[j*4+1] = CUSTOM_VERTEX(particlePosition + shorizontal - svertical);
vertices[j*4+2] = CUSTOM_VERTEX(particlePosition - shorizontal - svertical);
vertices[j*4+3] = CUSTOM_VERTEX(particlePosition - shorizontal + svertical);

ok, so using your process:

f = -0.5f * particleSize;
D3DXVECTOR3 vertical(0,1*f,0)

this *might* work. The issue is that you you are using the camera's up vector as the up for your particle. As you pitch the camera(what you call a vertical rotation) the camera's up vector changes, which causes your vertical vec3 to point somewhere that is not aligned with the world up. By using the Y axis(which i assume to be world up) directly, as shown above, you ensure that the particle's quad is parallel to the Y axis.

This topic is closed to new replies.

Advertisement