# Particles Rotation

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

## Recommended Posts

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);


##### Share on other sites

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);

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.

##### Share on other sites

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

I want to make it STOP facing the camera vertically.

##### Share on other sites

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.

##### Share on other sites

@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?

##### Share on other sites

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.

Edited by Burnt_Fyr

##### Share on other sites

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.

##### Share on other sites

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.

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.

##### Share on other sites

@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);

Edited by Medo3337

##### Share on other sites

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.

• 21
• 11
• 9
• 17
• 13