Skip to content

Commit

Permalink
fix: vec3OrthoNormalize, handle an edge case
Browse files Browse the repository at this point in the history
  • Loading branch information
0b5vr committed Jan 31, 2022
1 parent bf4c45a commit feaf0af
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
9 changes: 9 additions & 0 deletions src/math/vec3/tests/vec3OrthoNormalize.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import '../../../tests/matchers/toBeCloseToArray';
import { vec3OrthoNormalize } from '../vec3OrthoNormalize';
import { vecLengthSq } from '../../vec/vecLengthSq';
import type { RawVector3 } from '../RawVector3';

describe( 'vec3OrthoNormalize', () => {
Expand Down Expand Up @@ -32,4 +33,12 @@ describe( 'vec3OrthoNormalize', () => {
expect( subject.tangent ).toBeCloseToArray( [ 0.707, 0.707, 0.0 ] );
expect( subject.binormal ).toBeCloseToArray( [ -0.707, 0.707, 0.0 ] );
} );

it( 'does its job even when normal and tangent is same', () => {
const normal: RawVector3 = [ 0.0, 0.0, -1.0 ];
const subject = vec3OrthoNormalize( normal, normal );

expect( subject.normal ).toBeCloseToArray( [ 0.0, 0.0, -1.0 ] );
expect( vecLengthSq( subject.tangent ) ).toBeCloseTo( 1.0 );
} );
} );
23 changes: 19 additions & 4 deletions src/math/vec3/vec3OrthoNormalize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { vec3Cross } from '.';
import { vecDot, vecNeg, vecNormalize, vecScale, vecSub } from '..';
import { vec3Cross } from './vec3Cross';
import { vecDot } from '../vec/vecDot';
import { vecNeg } from '../vec/vecNeg';
import { vecNormalize } from '../vec/vecNormalize';
import { vecScale } from '../vec/vecScale';
import { vecSub } from '../vec/vecSub';
import type { RawVector3 } from './RawVector3';

/**
Expand All @@ -16,9 +20,20 @@ export function vec3OrthoNormalize(
binormal: RawVector3,
} {
const n = vecNormalize( normal );
let t = vecNormalize( tangent );

const dotNT = vecDot( n, tangent );
const t = vecNormalize( vecSub( tangent, vecScale( n, dotNT ) ) );
let dotNT = vecDot( n, t );

if ( dotNT === 1.0 ) {
if ( Math.abs( n[ 1 ] ) > Math.abs( n[ 2 ] ) ) {
t = [ 0.0, 0.0, 1.0 ];
} else {
t = [ 0.0, 1.0, 0.0 ];
}
dotNT = vecDot( n, t );
}

t = vecNormalize( vecSub( t, vecScale( n, dotNT ) ) );

let b = vec3Cross( t, n );
if ( binormal && vecDot( b, binormal ) < 0.0 ) {
Expand Down

0 comments on commit feaf0af

Please sign in to comment.