Makes vectors normalized and orthogonal to each other.

Normalizes `normal`

.
Normalizes `tangent`

and makes sure it is orthogonal to `normal`

(that is, angle between them is 90 degrees).

Additional resources: Normalize function.

Makes vectors normalized and orthogonal to each other.

Normalizes `normal`

.
Normalizes `tangent`

and makes sure it is orthogonal to `normal`

.
Normalizes `binormal`

and makes sure it is orthogonal to both `normal`

and `tangent`

.

Points in space are usually specified with coordinates in the standard XYZ axis system. However, you
can interpret any three vectors as "axes" if they are normalized (ie, have a magnitude of 1) and are
orthogonal (ie, perpendicular to each other).

Creating your own coordinate axes is useful, say, if you want to scale a mesh
in arbitrary directions rather than just along the XYZ axes - you can transform the vertices
to your own coordinate system, scale them and then transform back. Often, a transformation like this will
be carried out along only one axis while the other two are either left as they are or treated equally.
For example, a stretching effect can be applied to a mesh by scaling up on one axis while scaling down
proportionally on the other two. This means that once the first axis vector is specified, it doesn't
greatly matter what the other two are as long as they are normalized and orthogonal. OrthoNormalize
can be used to ensure the first vector is normal and then generate two normalized, orthogonal vectors
for the other two axes.

// Mesh "stretch" effect along a chosen axis.

using UnityEngine; using System.Collections;

public class ExampleClass : MonoBehaviour { // The axis and amount of scaling. public Vector3 stretchAxis; public float stretchFactor = 1.0F;

// MeshFilter component and arrays for the original and transformed vertices. private MeshFilter mf; private Vector3[] origVerts; private Vector3[] newVerts;

// Our new basis vectors. private Vector3 basisA; private Vector3 basisB; private Vector3 basisC;

void Start() { // Get the Mesh Filter, then make a copy of the original vertices // and a new array to calculate the transformed vertices. mf = GetComponent<MeshFilter>(); origVerts = mf.mesh.vertices; newVerts = new Vector3[origVerts.Length]; }

void Update() { // BasisA is just the specified axis for stretching - the // other two are just arbitrary axes generated by OrthoNormalize. basisA = stretchAxis; Vector3.OrthoNormalize(ref basisA, ref basisB, ref basisC);

// Copy the three new basis vectors into the rows of a matrix // (since it is actually a 4x4 matrix, the bottom right corner // should also be set to 1). Matrix4x4 toNewSpace = new Matrix4x4(); toNewSpace.SetRow(0, basisA); toNewSpace.SetRow(1, basisB); toNewSpace.SetRow(2, basisC); toNewSpace[3, 3] = 1.0F;

// The scale values are just the diagonal entries of the scale // matrix. The vertices should be stretched along the first axis // and squashed proportionally along the other two. Matrix4x4 scale = new Matrix4x4(); scale[0, 0] = stretchFactor; scale[1, 1] = 1.0F / stretchFactor; scale[2, 2] = 1.0F / stretchFactor; scale[3, 3] = 1.0F;

// The inverse of the first matrix transforms the vertices back to // the original XYZ coordinate space(transpose is the same as inverse // for an orthogonal matrix, which this is). Matrix4x4 fromNewSpace = toNewSpace.transpose;

// The three matrices can now be combined into a single symmetric matrix. Matrix4x4 trans = toNewSpace * scale * fromNewSpace;

// Transform each of the mesh's vertices by the symmetric matrix. int i = 0; while (i < origVerts.Length) { newVerts[i] = trans.MultiplyPoint3x4(origVerts[i]); i++; }

// ...and finally, update the mesh with the new vertex array. mf.mesh.vertices = newVerts; } }

Additional resources: Normalize function.