Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions examples/js/loaders/ColladaLoader2.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
THREE.ColladaLoader = function ( manager ) {

this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
this.options = {
convertUpAxis: false
};

};

Expand All @@ -30,16 +33,6 @@ THREE.ColladaLoader.prototype = {

},

options: {

set convertUpAxis( value ) {

console.log( 'THREE.ColladaLoader.options.convertUpAxis: TODO' );

}

},

setCrossOrigin: function ( value ) {

this.crossOrigin = value;
Expand Down Expand Up @@ -2660,9 +2653,13 @@ THREE.ColladaLoader.prototype = {

var scene = parseScene( getElementsByTagName( collada, 'scene' )[ 0 ] );

if ( asset.upAxis === 'Z_UP' ) {
if ( this.options.convertUpAxis === true ) {

if ( asset.upAxis === 'Z_UP' ) {

scene.rotation.x = - Math.PI / 2;
THREE.SceneUtils.convertFromZUp( scene, animations );

}

}

Expand Down
236 changes: 236 additions & 0 deletions src/extras/SceneUtils.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { Vector3 } from '../math/Vector3';
import { Quaternion } from '../math/Quaternion';
import { Matrix4 } from '../math/Matrix4';
import { Matrix3 } from '../math/Matrix3';
import { Mesh } from '../objects/Mesh';
import { Group } from '../objects/Group';
import { PropertyBinding } from '../animation/PropertyBinding';

/**
* @author alteredq / http://alteredqualia.com/
* @author Mugen87 / https://github.com/Mugen87
*/

var SceneUtils = {
Expand Down Expand Up @@ -37,9 +42,240 @@ var SceneUtils = {
scene.remove( child );
parent.add( child );

},

convertFromZUp: function ( root, animations ) {

// see https://gamedev.stackexchange.com/a/7932

// this matrix will change the coordinate system of an object hierarchy and
// animations (optional) from right-handed Z-up to right-handed Y-up

var matrix = new Matrix4().set(
1, 0, 0, 0,
0, 0, 1, 0,
0, - 1, 0, 0,
0, 0, 0, 1
);

var converter = new BasisConverter( matrix );
converter.convert( root, animations );

}

};

function BasisConverter( matrix ) {

this.matrix = matrix;

}

Object.assign( BasisConverter.prototype, {

convert: function ( root, animations ) {

var scope = this;

root.traverse( function( object ) {

// position, quaternion, scale

scope.convertMatrix4( object.matrix );
object.matrix.decompose( object.position, object.quaternion, object.scale );

// geometry

var geometry = object.geometry;

if ( geometry !== undefined && geometry.isBufferGeometry === true ) {

var position = geometry.attributes.position;
var normal = geometry.attributes.normal;

var matrix = scope.matrix;

if ( position !== null ) {

matrix.applyToBufferAttribute( position );

}

if ( normal !== null ) {

var normalMatrix = new Matrix3().setFromMatrix4( matrix );
normalMatrix.applyToBufferAttribute( normal );

}

}

// skinned mesh

if ( object.isSkinnedMesh ) {

scope.convertMatrix4( object.bindMatrix );
scope.convertMatrix4( object.bindMatrixInverse );

var boneInverses = object.skeleton.boneInverses;

for ( var i = 0, il = boneInverses.length; i < il; i ++ ) {

scope.convertMatrix4( boneInverses[ i ] );

}

// bones are already converted within the scene hierarchy

}

} );

// animations

if ( animations !== undefined ) {

for ( var i = 0, il = animations.length; i < il; i ++ ) {

var clip = animations[ i ];
var tracks = clip.tracks;

for ( var j = 0, jl = tracks.length; j < jl; j ++ ) {

this.convertKeyframeTrack( tracks[ j ] );

}

}

}

},

convertMatrix4: function() {

var xAxis = new Vector3();
var yAxis = new Vector3();
var zAxis = new Vector3();
var translation = new Vector3();

return function convertMatrix4( matrix ) {

// columns first

matrix.extractBasis( xAxis, yAxis, zAxis );
translation.setFromMatrixColumn( matrix, 3 );

xAxis.applyMatrix4( this.matrix );
yAxis.applyMatrix4( this.matrix );
zAxis.applyMatrix4( this.matrix );

matrix.makeBasis( xAxis, yAxis, zAxis );

// then rows

matrix.transpose();

matrix.extractBasis( xAxis, yAxis, zAxis );

xAxis.applyMatrix4( this.matrix );
yAxis.applyMatrix4( this.matrix );
zAxis.applyMatrix4( this.matrix );

matrix.makeBasis( xAxis, yAxis, zAxis );

matrix.transpose();

// translation at the end

translation.applyMatrix4( this.matrix );

matrix.elements[ 12 ] = translation.x;
matrix.elements[ 13 ] = translation.y;
matrix.elements[ 14 ] = translation.z;

return matrix;

};

} (),

convertKeyframeTrack: function() {

var vector = new Vector3();
var quaternion = new Quaternion();
var rotationMatrix = new Matrix4();

return function convertKeyframeTrack( track ) {

var result = PropertyBinding.parseTrackName( track.name );
var propertyName = result.propertyName;

var values = track.values;
var times = track.times;
var stride = values.length / times.length;

var i, il, j, jl;

switch ( propertyName ) {

case 'position':

for ( i = 0, il = values.length; i < il; i += stride ) {

vector.fromArray( values, i ).applyMatrix4( this.matrix );

for ( j = 0, jl = stride; j < jl; j ++ ) {

values[ i + j ] = vector.getComponent( j );

}

}

break;

case 'scale':

for ( i = 0, il = values.length; i < il; i += stride ) {

vector.fromArray( values, i ).applyMatrix4( this.matrix );

for ( j = 0, jl = stride; j < jl; j ++ ) {

values[ i + j ] = Math.abs( vector.getComponent( j ) );

}

}

break;

case 'quaternion':

for ( i = 0, il = values.length; i < il; i += stride ) {

quaternion.fromArray( values, i );
rotationMatrix.makeRotationFromQuaternion( quaternion );
this.convertMatrix4( rotationMatrix );
quaternion.setFromRotationMatrix( rotationMatrix );

values[ i + 0 ] = quaternion.x;
values[ i + 1 ] = quaternion.y;
values[ i + 2 ] = quaternion.z;
values[ i + 3 ] = quaternion.w;

}

break;

}

};

} (),

} );


export { SceneUtils };