• Create Account

# Garold

Member Since 24 Apr 2012
Offline Last Active Sep 09 2013 02:33 PM

### Rotate A Quad Along Axis To Face Camera

23 January 2013 - 12:49 PM

I am having some success aligning a particle to a direction and then rotating it along its axis. At the moment I am just constantly rotating it. How do I calculate the correct rotation so it always faces the camera?

Please have a look at this video: Quad Slowly Rotating Along Axis

I am using DPSF. I have modified the "FlyingSparks" demo.

To calculate the orientation Quaternion I run this code:

```private void UpdateOrientation(DefaultTextureQuadTextureCoordinatesParticle cparticle, float felapsedtimeinseconds)
{
var normalized = cparticle.Velocity;
normalized.Normalize();
cparticle.Orientation = Quaternion.Identity;
cparticle.Right = -normalized;
_rotation += 0.03f;
cparticle.Orientation = Quaternion.CreateFromAxisAngle(normalized, _rotation) * cparticle.Orientation;
}```

After some trial and error the above code produces what you see in the video.

Line 5: resets the orientation.
Line 6: aligns the quad to the velocity direction.
Line 7: increments the rotation.
Line 8: further rotates the quad along its axis by the rotation.

What I am asking is how do I calculate the rotation?

I am not a maths expert. I can guess that I need the normal of the particle, calculated within line 6 and then use that to determine it's difference from the camera direction. I have looked at some billboarding techniques but they don't offer exactly what I want.

I am very close to finishing my game and this is the last hurdle, any help or pointers would be greatly appreciated, thank you for taking the time to look at this

### I want to align my bullet hole decal with the surface hit

24 April 2012 - 07:58 AM

HI, this is my first post and would appreciate any help.

Here's a video of the problem

I am using the particle system from the "Particles3D" XNA example. Currently the texture is always aligned with the camera. I want it to be aligned with the surface hit.

In the video I have displayed the location and normal of each collision.

The sample particle system has a lot of redundant code that I don't need for the bullet holes. For example I don't need the particles to move, rotate, change size or color.

The vertex shader input contains a float3, Velocity, that I could presumably replace with the normal.

in the ParticleVertexShader the output.Position is calculated in ComputeParticlePosition.

```// Custom vertex shader animates particles entirely on the GPU.
{

// Compute the age of the particle.
float age = CurrentTime - input.Time;

// Apply a random factor to make different particles age at different rates.
age *= 1 + input.Random.x * DurationRandomness;

// Normalize the age into the range zero to one.
float normalizedAge = saturate(age / Duration);
// Compute the particle position, size, color, and rotation.
output.Position = ComputeParticlePosition(input.Position, input.Velocity,
age, normalizedAge);
float size = ComputeParticleSize(input.Random.y, normalizedAge);
float2x2 rotation = ComputeParticleRotation(input.Random.w, age);
output.Position.xy += mul(input.Corner, rotation) * size * ViewportScale;

output.Color = ComputeParticleColor(output.Position, input.Random.z, normalizedAge);
output.TextureCoordinate = (input.Corner + 1) / 2;

return output;
}
```

Inside ComputeParticlePosition the position is multiplied by the view and projection matrix.

```// Vertex shader helper for computing the position of a particle.
float4 ComputeParticlePosition(float3 position, float3 velocity,
float age, float normalizedAge)
{
float startVelocity = length(velocity);
// Work out how fast the particle should be moving at the end of its life,
// by applying a constant scaling factor to its starting velocity.
float endVelocity = startVelocity * EndVelocity;

// Our particles have constant acceleration, so given a starting velocity
// S and ending velocity E, at time T their velocity should be S + (E-S)*T.
// The particle position is the sum of this velocity over the range 0 to T.
// To compute the position directly, we must integrate the velocity
// equation. Integrating S + (E-S)*T for T produces S*T + (E-S)*T*T/2.
float velocityIntegral = startVelocity * normalizedAge +
(endVelocity - startVelocity) * normalizedAge *
normalizedAge / 2;

position += normalize(velocity) * velocityIntegral * Duration;

// Apply the gravitational force.
position += Gravity * age * normalizedAge;

// Apply the camera view and projection transforms.
return mul(mul(float4(position, 1), View), Projection);
}
```

So in summary, I don't need most of this code, I have only included it so you see what is currently happening. The input velocity is zero.

How do I transform the position so that it aligns with the normal?

Any help or pointers would be great.

PARTNERS