Very fast & dirty rotations?

Started by
15 comments, last by Sander 20 years, 7 months ago
Nope, in OpenGL you have to do everything yourself. No predefined vertex format here. I calculate the particle veretex positions by adding and/or substracting the camera''s up and right vector from the particle position. The camera''s vectors are ofcourse provided by OpenGL.

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Advertisement
Oh and BTW, I wrote that quickly. But of course in pure maths conventions to rotate a point by a quad it's Q*P*Q^-1. Don't fear this formula it's speedy. In fact it nearly gives the cross prod formula with the right scaling to maintain a pure rotation. What I meant by Q*P is a matrix analogy in fact a function like :

QuatRotatePoint( Pout, Q, Pin );

Now I understand your problem better. I thought you wanted the quads to rotate around their center, not around the player. Which is totally different. BTW do you wish all your axes pass by a given point attached to the player ? Or may they be different centers for each rotation ?

Then Uthman's idea was great. You could use group transfos with hardware caps. Sadly you also want to keep your quads facing the camera, which makes it all impossible like this. Still you can use the same idea in software. Then you can speed it up by coding an optimized loop (SIMD?) for the same transfo. Then you have 3 possibilities remaining : cross prod, matrix or quat.

I think the most convenient here would be a 3*3 or 4*4 matrix since this enables you to shape much more transfos and make your code more general. In perfs terms, all the transfos are nearly equivalent specially if you want to add a scaling to the cross prod. Same number of ops roughly. You can also implement a version for vertex shaders to speed it up.

There is an old style (Amiga like) trick that could speed it up tho. You could used cached transfos in fixed point. Imagine all your particule centers start on discrete local coords (3 bytes).
Then accumulate the matrix transfo each frame, then get the new center like this :

uint xyz; // 10 10 10 coords. (for 1 meter radius 2mm precision)
xyz = TransfoX[(uint)p.x];
xyz += TransfoY[(uint)p.y];
xyz += TransfoZ[(uint)p.z];
unpack( QuadCorners, xyz, RCamX, RCamY ); // Can be hugely speeded up, specially if you work in camera space.

This may give all in all around 30 clock cycles to form your 4quad vertices. Also, you don't need to update your particules, only the group matrices.

You'll need 256*3 additions to create the tables each frame. But that's very speed, you can even use smaller luts (32 coords ?). Specially if you use the transfo for let's say numGroup > 64 particules, it really pays. Note that like this you can also use far less mem for the particules.

I think that's what you wanted, fast and dirty ? That cant' be beaten I think

Another track could be a physics like model, central forces, gravity like. Only the initial speed will condition the trajectory : circle, ellipse or spiral.

Acc = -Pos*1/norm(Pos);
Vel+= Acc*dt;
Pos+= Vel*dt;
You can use quick 1/sqrt(dist2) tricks with Taylor series and movemement continuity. I can explain this to you later. What's better here is you can handle collsions. That's probably the most elegant and speedy solution of all.



[edited by - Charles B on September 4, 2003 5:28:16 AM]
"Coding math tricks in asm is more fun than Java"
Hmm, this problem also could be solved with a Tree, my idea is to sort, the Tree in that direction that Particels, which have the Same roations are rotated together...

An other way could be to Calculate the Hole vertex with the Intel IPL, which is designed to Calculate( Multiply, Add, Subtract, Divide, usw. ) image Array''s and is really fast, because using internal Codes & Structures of the Intel CPU, but the Disadvantage of that is that on an AMD PC you have to do it per Software or find a Good Speed Up Lib for AMD.
J.A.N.K.E.Y.: Journeying Artificial Nocturnal Killing and Exploration Youth
The vector that I want the particles to rotate around is the orientation vector of the player at the moment the particle was emitted. Ofcourse, a few milliseconds later, the player will have moved and rotated, emitting new particles in it''s wake, with a new orientation vector. To be more graphical here''s a pic of the particle system I want to apply it to:



This rocket is going straight forward, but when attached to the player (or a guided missile for example) it can go in many directions. What I try to accomplish is to make the smoketrail swirl around the center of the trail at that position.

The tree sounds like a good solution to sort the particles by their general orientation. I think I could group the particles together that have been emitted in roughly the same timeframe (say 0.1 or 0.2 seconds). Those particles will roughly all have the same rotation and scale (since the dot-product trick will also scale the particles for me, I can''t use bigger timeframes if the rocket goes straight ahead). I can then rotate each timeframe group with the optimizations that Charles provided. This sounds like a speedy solution Wow!

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

When your ready with that, and this works, can i see the code?

Would be interessting if this works for my application: Using the Smoke from a Rocket in a Tunnel... Particles with Collision Detection...
J.A.N.K.E.Y.: Journeying Artificial Nocturnal Killing and Exploration Youth
Could also be Faster if a Particle is "Far Far" away, you can Draw the Particle as "Point" with the Mean Value Color or the Inherited Texture... just an idea...
J.A.N.K.E.Y.: Journeying Artificial Nocturnal Killing and Exploration Youth
Just code and optimize Navier-Stokes equations ion vortices then No thanks.
Well I had more te picture of whirlwinds or willowisps around a character.
However, what you want then is a kind of spiral movement.

Not sure it won''t be noticeable if you group near transfos during 0.2 seconds. but then you could add linear interp (like bones) to your transfos :
VPacked P; // Will be a weird kind of hacked double (all platforms)
P = float3( r0*(T0X[p.x] + T0Y[p.y]) + r1*(T1X[p.x] + T1Y[p.y]) ) + C;

r0=1-r1, C being the center of the translating circle. That''s symbolic code, not the exact implementation but it''s possible to use a fast scaling trick (r0*) in 64bits precision with the FPU. That''s what I used to do bilinear filtering a long time ago. If you use 6 bits for r0 [0..63] you''ll still have 10 bits available for the x,y,z components (2mm as I already said for 1 meter radius). I use the 51 lower bits of the doubles for my REALLY dirty (but solid) tricks.

I assume I can get rid of the initial z component since your particules will describe a circle perp to the initial axis. So that''s still much faster than matrices or anything else and you need only to keep r0, p and C (12bytes) for each particule and one matrix per group (memory) !

Else the physics point of view could still also compete to describe a spiral. The fact that you add a linear velocity just transforms the circle into a spiral. It''s still probably the best and most elegant solution, but you need to maintain the center, center velocity and particule relative velocity (9 floats) + a float for 1/R (*). Beware numeric precision and discrete time steps issues. That should be ez solve however.

(*) Stupid me just cache that variable, no need for any Taylor computation of
1/sqrt(CP*CP)







"Coding math tricks in asm is more fun than Java"

This topic is closed to new replies.

Advertisement