Given a normalized 3D vector, here’s an efficient method for computing a full basis. The computed basis is axis aligned if the input vector is axis aligned.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void ComputeBasis(const Vec& a, Vec* b, Vec* c) { // Suppose vector a has all equal components and is a unit vector: a = (s, s, s) // Then 3*s*s = 1, s = sqrt(1/3) = 0.57735. This means that at least one component of a // unit vector must be greater or equal to 0.57735. if (Abs(a.x) >= 0.57735f) b->Set(a.y, -a.x, 0.0f); else b->Set(0.0f, a.z, -a.y); b = Normalize(b); *c = Cross(a, *b); } |

In SSE land you can eliminate the branch using a select operation.

Forgive me if I’m misunderstanding, but shouldn’t line 6 have an Abs call wrapped around the a.x value? If you pass in the vector { 0, 0, -1 } don’t you get a zero for b (without the abs)?

You are correct Randy! I updated the code.