Browse Source

Merge pull request #10280 from sunag/sea3d_1.8.1

Sea3d 1.8.1 - Physics example
Mr.doob 8 years ago
parent
commit
5e37d9dabd

+ 1 - 0
examples/files.js

@@ -109,6 +109,7 @@ var files = {
 		"webgl_loader_sea3d_hierarchy",
 		"webgl_loader_sea3d_keyframe",
 		"webgl_loader_sea3d_morph",
+		"webgl_loader_sea3d_physics",
 		"webgl_loader_sea3d_skinning",
 		"webgl_loader_sea3d_sound",
 		"webgl_loader_scene",

+ 0 - 721
examples/js/loaders/sea3d/SEA3DLegacyZ.js

@@ -1,721 +0,0 @@
-/**
- * 	SEA3D Legacy for Three.JS
- * 	@author Sunag / http://www.sunag.com.br/
- */
-
-'use strict';
-
-//
-//	Header
-//
-
-Object.assign( THREE.SEA3D.prototype, {
-
-	_onHead: THREE.SEA3D.prototype.onHead,
-	_updateTransform: THREE.SEA3D.prototype.updateTransform,
-	_readVertexAnimation: THREE.SEA3D.prototype.readVertexAnimation,
-	_readGeometryBuffer: THREE.SEA3D.prototype.readGeometryBuffer,
-	_readLine: THREE.SEA3D.prototype.readLine,
-	_getAnimationType: THREE.SEA3D.prototype.getAnimationType,
-	_readAnimation: THREE.SEA3D.prototype.readAnimation
-
-} );
-
-//
-//	Utils
-//
-
-THREE.SEA3D.prototype.isLegacy = function ( sea ) {
-
-	var sea3d = sea.sea3d;
-
-	if ( sea3d.sign == 'S3D' && ! sea._legacy ) {
-
-		sea._legacy = sea3d.typeUnique[ sea.type ] == true;
-
-		return sea3d.config.legacy;
-
-	}
-
-	return false;
-
-};
-
-THREE.SEA3D.prototype.flipZVec3 = function ( v ) {
-
-	if ( ! v ) return;
-
-	var i = 2; // z
-
-	while ( i < v.length ) {
-
-		v[ i ] = - v[ i ];
-
-		i += 3;
-
-	}
-
-	return v;
-
-};
-
-THREE.SEA3D.prototype.expandJoints = function ( sea ) {
-
-	var numJoints = sea.numVertex * 4;
-
-	var joint = sea.isBig ? new Uint32Array( numJoints ) : new Uint16Array( numJoints );
-	var weight = new Float32Array( numJoints );
-
-	var w = 0, jpv = sea.jointPerVertex;
-
-	for ( var i = 0; i < sea.numVertex; i ++ ) {
-
-		var tjsIndex = i * 4;
-		var seaIndex = i * jpv;
-
-		joint[ tjsIndex ] = sea.joint[ seaIndex ];
-		if ( jpv > 1 ) joint[ tjsIndex + 1 ] = sea.joint[ seaIndex + 1 ];
-		if ( jpv > 2 ) joint[ tjsIndex + 2 ] = sea.joint[ seaIndex + 2 ];
-		if ( jpv > 3 ) joint[ tjsIndex + 3 ] = sea.joint[ seaIndex + 3 ];
-
-		weight[ tjsIndex ] = sea.weight[ seaIndex ];
-		if ( jpv > 1 ) weight[ tjsIndex + 1 ] = sea.weight[ seaIndex + 1 ];
-		if ( jpv > 2 ) weight[ tjsIndex + 2 ] = sea.weight[ seaIndex + 2 ];
-		if ( jpv > 3 ) weight[ tjsIndex + 3 ] = sea.weight[ seaIndex + 3 ];
-
-		w = weight[ tjsIndex ] + weight[ tjsIndex + 1 ] + weight[ tjsIndex + 2 ] + weight[ tjsIndex + 3 ];
-
-		weight[ tjsIndex ] += 1 - w;
-
-	}
-
-	sea.joint = joint;
-	sea.weight = weight;
-
-	sea.jointPerVertex = 4;
-
-};
-
-THREE.SEA3D.prototype.compressJoints = function ( sea ) {
-
-	var numJoints = sea.numVertex * 4;
-
-	var joint = sea.isBig ? new Uint32Array( numJoints ) : new Uint16Array( numJoints );
-	var weight = new Float32Array( numJoints );
-
-	var w = 0, jpv = sea.jointPerVertex;
-
-	for ( var i = 0; i < sea.numVertex; i ++ ) {
-
-		var tjsIndex = i * 4;
-		var seaIndex = i * jpv;
-
-		joint[ tjsIndex ] = sea.joint[ seaIndex ];
-		joint[ tjsIndex + 1 ] = sea.joint[ seaIndex + 1 ];
-		joint[ tjsIndex + 2 ] = sea.joint[ seaIndex + 2 ];
-		joint[ tjsIndex + 3 ] = sea.joint[ seaIndex + 3 ];
-
-		weight[ tjsIndex ] = sea.weight[ seaIndex ];
-		weight[ tjsIndex + 1 ] = sea.weight[ seaIndex + 1 ];
-		weight[ tjsIndex + 2 ] = sea.weight[ seaIndex + 2 ];
-		weight[ tjsIndex + 3 ] = sea.weight[ seaIndex + 3 ];
-
-		w = weight[ tjsIndex ] + weight[ tjsIndex + 1 ] + weight[ tjsIndex + 2 ] + weight[ tjsIndex + 3 ];
-
-		weight[ tjsIndex ] += 1 - w;
-
-	}
-
-	sea.joint = joint;
-	sea.weight = weight;
-
-	sea.jointPerVertex = 4;
-
-};
-
-THREE.SEA3D.prototype.flipZIndex = function ( v ) {
-
-	var i = 1; // y >-< z
-
-	while ( i < v.length ) {
-
-		var idx = v[ i + 1 ];
-		v[ i + 1 ] = v[ i ];
-		v[ i ] = idx;
-
-		i += 3;
-
-	}
-
-	return v;
-
-};
-
-THREE.SEA3D.prototype.flipMatrixBone = function () {
-
-	var zero = new THREE.Vector3();
-	var buf1 = new THREE.Matrix4();
-
-	return function ( mtx ) {
-
-		buf1.copy( mtx );
-
-		mtx.setPosition( zero );
-		mtx.multiplyMatrices( THREE.SEA3D.MTXBUF.makeRotationZ( THREE.Math.degToRad( 180 ) ), mtx );
-		mtx.makeRotationFromQuaternion( THREE.SEA3D.QUABUF.setFromRotationMatrix( mtx ) );
-
-		var pos = THREE.SEA3D.VECBUF.setFromMatrixPosition( buf1 );
-		pos.z = - pos.z;
-		mtx.setPosition( pos );
-
-		return mtx;
-
-	};
-
-}();
-
-THREE.SEA3D.prototype.flipMatrixScale = function () {
-
-	var pos = new THREE.Vector3();
-	var qua = new THREE.Quaternion();
-	var slc = new THREE.Vector3();
-
-	return function ( local, global, parent, parentGlobal ) {
-
-		if ( parent ) local.multiplyMatrices( parent, local );
-
-		local.decompose( pos, qua, slc );
-
-		slc.z = - slc.z;
-
-		if ( global ) {
-
-			slc.y = - slc.y;
-			slc.x = - slc.x;
-
-		}
-
-		local.compose( pos, qua, slc );
-
-		if ( parent ) {
-
-			parent = parent.clone();
-
-			this.flipMatrixScale( parent, parentGlobal );
-
-			local.multiplyMatrices( parent.getInverse( parent ), local );
-
-		}
-
-		return local;
-
-	};
-
-}();
-
-//
-//	Legacy
-//
-
-THREE.SEA3D.prototype.flipDefaultAnimation = function () {
-
-	var buf1 = new THREE.Matrix4();
-	var buf2 = new THREE.Matrix4();
-
-	var pos = new THREE.Vector3();
-	var qua = new THREE.Quaternion();
-	var slc = new THREE.Vector3();
-
-	var to_pos = new THREE.Vector3();
-	var to_qua = new THREE.Quaternion();
-	var to_slc = new THREE.Vector3();
-
-	return function ( animation, obj3d, relative ) {
-
-		if ( animation.isFliped ) return;
-
-		var dataList = animation.dataList,
-			t_anm = [];
-
-		for ( var i = 0; i < dataList.length; i ++ ) {
-
-			var data = dataList[ i ],
-				raw = data.data,
-				kind = data.kind,
-				numFrames = raw.length / data.blockSize;
-
-			switch ( kind ) {
-
-				case SEA3D.Animation.POSITION:
-				case SEA3D.Animation.ROTATION:
-				case SEA3D.Animation.SCALE:
-
-					t_anm.push( {
-						kind: kind,
-						numFrames: numFrames,
-						raw: raw
-					} );
-
-					break;
-
-			}
-
-		}
-
-		if ( t_anm.length > 0 ) {
-
-			var numFrames = t_anm[ 0 ].numFrames,
-				parent = undefined;
-
-			if ( relative ) {
-
-				buf1.identity();
-				parent = this.flipMatrixScale( buf2.copy( obj3d.matrixWorld ) );
-
-			} else {
-
-				if ( obj3d.parent ) {
-
-					parent = this.flipMatrixScale( buf2.copy( obj3d.parent.matrixWorld ) );
-
-				}
-
-				this.flipMatrixScale( buf1.copy( obj3d.matrix ), false, parent );
-
-			}
-
-			buf1.decompose( pos, qua, slc );
-
-			for ( var f = 0, t, c; f < numFrames; f ++ ) {
-
-				for ( t = 0; t < t_anm.length; t ++ ) {
-
-					var raw = t_anm[ t ].raw,
-						kind = t_anm[ t ].kind;
-
-					switch ( kind ) {
-
-						case SEA3D.Animation.POSITION:
-
-							c = f * 3;
-
-							pos.set(
-								raw[ c ],
-								raw[ c + 1 ],
-								raw[ c + 2 ]
-							);
-
-							break;
-
-						case SEA3D.Animation.ROTATION:
-
-							c = f * 4;
-
-							qua.set(
-								raw[ c ],
-								raw[ c + 1 ],
-								raw[ c + 2 ],
-								raw[ c + 3 ]
-							);
-
-							break;
-
-						case SEA3D.Animation.SCALE:
-
-							c = f * 4;
-
-							slc.set(
-								raw[ c ],
-								raw[ c + 1 ],
-								raw[ c + 2 ]
-							);
-
-							break;
-
-					}
-
-				}
-
-				buf1.compose( pos, qua, slc );
-
-				this.flipMatrixScale( buf1, false, buf2 );
-
-				buf1.decompose( to_pos, to_qua, to_slc );
-
-				for ( t = 0; t < t_anm.length; t ++ ) {
-
-					var raw = t_anm[ t ].raw,
-						kind = t_anm[ t ].kind;
-
-					switch ( kind ) {
-
-						case SEA3D.Animation.POSITION:
-
-							c = f * 3;
-
-							raw[ c ] = to_pos.x;
-							raw[ c + 1 ] = to_pos.y;
-							raw[ c + 2 ] = to_pos.z;
-
-							break;
-
-						case SEA3D.Animation.ROTATION:
-
-							c = f * 4;
-
-							raw[ c ] = to_qua.x;
-							raw[ c + 1 ] = to_qua.y;
-							raw[ c + 2 ] = to_qua.z;
-							raw[ c + 3 ] = to_qua.w;
-
-							break;
-
-						case SEA3D.Animation.SCALE:
-
-							c = f * 3;
-
-							raw[ c ] = to_slc.x;
-							raw[ c + 1 ] = to_slc.y;
-							raw[ c + 2 ] = to_slc.z;
-
-							break;
-
-					}
-
-				}
-
-			}
-
-		}
-
-		animation.isFliped = true;
-
-	};
-
-}();
-
-THREE.SEA3D.prototype.readAnimation = function ( sea ) {
-
-	if ( ! this.isLegacy( sea ) ) {
-
-		this._readAnimation( sea );
-
-	}
-
-};
-
-THREE.SEA3D.prototype.getAnimationType = function ( req ) {
-
-	var sea = req.sea;
-
-	if ( this.isLegacy( sea ) ) {
-
-		switch ( sea.type ) {
-
-			case SEA3D.SkeletonAnimation.prototype.type:
-
-				this.readSkeletonAnimationLegacy( sea, req.skeleton );
-
-				return sea.tag;
-
-				break;
-
-			case SEA3D.Animation.prototype.type:
-
-				if ( req.scope instanceof THREE.Object3D ) {
-
-					this.flipDefaultAnimation( sea, req.scope, req.relative );
-
-				}
-
-				this._readAnimation( sea );
-
-				return sea.tag;
-
-				break;
-
-		}
-
-	}
-
-	return this._getAnimationType( req );
-
-};
-
-THREE.SEA3D.prototype.updateTransform = function () {
-
-	var buf1 = new THREE.Matrix4();
-	var identity = new THREE.Matrix4();
-
-	return function ( obj3d, sea ) {
-
-		if ( this.isLegacy( sea ) ) {
-
-			if ( sea.transform ) buf1.elements.set( sea.transform );
-			else buf1.makeTranslation( sea.position.x, sea.position.y, sea.position.z );
-
-			this.flipMatrixScale(
-				buf1, false,
-				obj3d.parent ? obj3d.parent.matrixWorld : identity,
-				obj3d.parent instanceof THREE.Bone
-			);
-
-			obj3d.position.setFromMatrixPosition( buf1 );
-			obj3d.scale.setFromMatrixScale( buf1 );
-
-			// ignore rotation scale
-
-			buf1.scale( THREE.SEA3D.VECBUF.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
-			obj3d.rotation.setFromRotationMatrix( buf1 );
-
-			obj3d.updateMatrixWorld();
-
-		} else {
-
-			this._updateTransform( obj3d, sea );
-
-		}
-
-	};
-
-}();
-
-THREE.SEA3D.prototype.readSkeleton = function () {
-
-	var mtx_tmp_inv = new THREE.Matrix4(),
-		mtx_local = new THREE.Matrix4(),
-		mtx_parent = new THREE.Matrix4(),
-		pos = new THREE.Vector3(),
-		qua = new THREE.Quaternion();
-
-	return function ( sea ) {
-
-		var bones = [],
-			isLegacy = sea.sea3d.config.legacy;
-
-		for ( var i = 0; i < sea.joint.length; i ++ ) {
-
-			var bone = sea.joint[ i ];
-
-			// get world inverse matrix
-
-			mtx_tmp_inv.elements = bone.inverseBindMatrix;
-
-			// convert to world matrix
-
-			mtx_local.getInverse( mtx_tmp_inv );
-
-			// convert to three.js order
-
-			if ( isLegacy ) this.flipMatrixBone( mtx_local );
-
-			if ( bone.parentIndex > - 1 ) {
-
-				// to world
-
-				mtx_tmp_inv.elements = sea.joint[ bone.parentIndex ].inverseBindMatrix;
-				mtx_parent.getInverse( mtx_tmp_inv );
-
-				// convert parent to three.js order
-
-				if ( isLegacy ) this.flipMatrixBone( mtx_parent );
-
-				// to local
-
-				mtx_parent.getInverse( mtx_parent );
-
-				mtx_local.multiplyMatrices( mtx_parent, mtx_local );
-
-			}
-
-			// apply matrix
-
-			pos.setFromMatrixPosition( mtx_local );
-			qua.setFromRotationMatrix( mtx_local );
-
-			bones[ i ] = {
-				name: bone.name,
-				pos: [ pos.x, pos.y, pos.z ],
-				rotq: [ qua.x, qua.y, qua.z, qua.w ],
-				parent: bone.parentIndex
-			};
-
-		}
-
-		return sea.tag = bones;
-
-	};
-
-}();
-
-THREE.SEA3D.prototype.readSkeletonAnimationLegacy = function () {
-
-	var mtx_tmp_inv = new THREE.Matrix4(),
-		mtx_local = new THREE.Matrix4(),
-		mtx_global = new THREE.Matrix4(),
-		mtx_parent = new THREE.Matrix4();
-
-	return function ( sea, skl ) {
-
-		if ( sea.tag ) return sea.tag;
-
-		var animations = [],
-			delta = ( 1000 / sea.frameRate ) / 1000,
-			scale = [ 1, 1, 1 ];
-
-		for ( var i = 0; i < sea.sequence.length; i ++ ) {
-
-			var seq = sea.sequence[ i ];
-
-			var start = seq.start;
-			var end = start + seq.count;
-
-			var animation = {
-				name: seq.name,
-				repeat: seq.repeat,
-				fps: sea.frameRate,
-				JIT: 0,
-				length: delta * seq.count,
-				hierarchy: []
-			};
-
-			var numJoints = sea.numJoints,
-				raw = sea.raw;
-
-			for ( var j = 0; j < numJoints; j ++ ) {
-
-				var bone = skl.joint[ j ],
-					node = { parent: bone.parentIndex, keys: [] },
-					keys = node.keys,
-					time = 0;
-
-				for ( var frame = start; frame < end; frame ++ ) {
-
-					var idx = ( frame * numJoints * 7 ) + ( j * 7 );
-
-					mtx_local.makeRotationFromQuaternion( THREE.SEA3D.QUABUF.set( raw[ idx + 3 ], raw[ idx + 4 ], raw[ idx + 5 ], raw[ idx + 6 ] ) );
-					mtx_local.setPosition( THREE.SEA3D.VECBUF.set( raw[ idx ], raw[ idx + 1 ], raw[ idx + 2 ] ) );
-
-					if ( bone.parentIndex > - 1 ) {
-
-						// to global
-
-						mtx_tmp_inv.elements = skl.joint[ bone.parentIndex ].inverseBindMatrix;
-
-						mtx_parent.getInverse( mtx_tmp_inv );
-
-						mtx_global.multiplyMatrices( mtx_parent, mtx_local );
-
-						// convert to three.js matrix
-
-						this.flipMatrixBone( mtx_global );
-
-						// flip parent inverse
-
-						this.flipMatrixBone( mtx_parent );
-
-						// to local
-
-						mtx_parent.getInverse( mtx_parent );
-
-						mtx_local.multiplyMatrices( mtx_parent, mtx_global );
-
-					} else {
-
-						this.flipMatrixBone( mtx_local );
-
-					}
-
-					var posQ = THREE.SEA3D.VECBUF.setFromMatrixPosition( mtx_local );
-					var newQ = THREE.SEA3D.QUABUF.setFromRotationMatrix( mtx_local );
-
-					keys.push( {
-						time: time,
-						pos: [ posQ.x, posQ.y, posQ.z ],
-						rot: [ newQ.x, newQ.y, newQ.z, newQ.w ],
-						scl: scale
-					} );
-
-					time += delta;
-
-				}
-
-				animation.hierarchy[ j ] = node;
-
-			}
-
-			animations.push( THREE.SEA3D.AnimationClip.fromClip( THREE.AnimationClip.parseAnimation( animation, skl.tag ), seq.repeat ) );
-
-		}
-
-		this.domain.clips = this.clips = this.clips || [];
-		this.clips.push( this.objects[ sea.name + '.anm' ] = sea.tag = animations );
-
-	};
-
-}();
-
-THREE.SEA3D.prototype.readVertexAnimation = function ( sea ) {
-
-	if ( this.isLegacy( sea ) ) {
-
-		for ( var i = 0, l = sea.frame.length; i < l; i ++ ) {
-
-			var frame = sea.frame[ i ];
-
-			this.flipZVec3( frame.vertex );
-			this.flipZVec3( frame.normal );
-
-		}
-
-	}
-
-	this._readVertexAnimation( sea );
-
-};
-
-THREE.SEA3D.prototype.readGeometryBuffer = function ( sea ) {
-
-	if ( this.isLegacy( sea ) ) {
-
-		this.flipZVec3( sea.vertex );
-		this.flipZVec3( sea.normal );
-
-		this.flipZIndex( sea.indexes );
-
-		if ( sea.jointPerVertex > 4 ) this.compressJoints( sea );
-		else if ( sea.jointPerVertex < 4 ) this.expandJoints( sea );
-
-	}
-
-	this._readGeometryBuffer( sea );
-
-};
-
-THREE.SEA3D.prototype.readLines = function ( sea ) {
-
-	if ( this.isLegacy( sea ) ) {
-
-		this.flipZVec3( sea.vertex );
-
-	}
-
-	this._readLines( sea );
-
-};
-
-THREE.SEA3D.prototype.onHead = function ( args ) {
-
-	// TODO: Ignore sign
-
-};
-
-THREE.SEA3D.EXTENSIONS_LOADER.push( { setTypeRead: function () {
-
-	// CONFIG
-
-	this.config.legacy = this.config.legacy == undefined ? true : this.config.legacy;
-
-	this.file.typeRead[ SEA3D.Skeleton.prototype.type ] = this.readSkeleton;
-
-} } );

+ 8 - 8
examples/js/loaders/sea3d/SEA3DLoader.js

@@ -651,7 +651,7 @@ Object.assign( THREE.SEA3D.Animator.prototype, {
 
 		if ( this.playing ) this.stop();
 
-		if ( this.mixer ) THREE.SEA3D.AnimationHandler.removeAnimator( this );
+		if ( this.mixer ) THREE.SEA3D.AnimationHandler.remove( this );
 
 		this.mixer = mixer;
 
@@ -750,7 +750,7 @@ Object.assign( THREE.SEA3D.Animator.prototype, {
 
 		if ( this.playing && this.currentAnimation ) {
 
-			THREE.SEA3D.AnimationHandler.removeAnimator( this );
+			THREE.SEA3D.AnimationHandler.remove( this );
 
 			this.playing = false;
 
@@ -764,7 +764,7 @@ Object.assign( THREE.SEA3D.Animator.prototype, {
 
 		if ( ! this.playing && this.currentAnimation ) {
 
-			THREE.SEA3D.AnimationHandler.addAnimator( this );
+			THREE.SEA3D.AnimationHandler.add( this );
 
 			this.playing = true;
 
@@ -839,7 +839,7 @@ Object.assign( THREE.SEA3D.Animator.prototype, {
 
 			if ( this.previousAnimation ) this.previousAnimationAction.crossFadeTo( this.currentAnimationAction, crossfade || 0, false );
 
-			THREE.SEA3D.AnimationHandler.addAnimator( this );
+			THREE.SEA3D.AnimationHandler.add( this );
 
 		}
 
@@ -849,7 +849,7 @@ Object.assign( THREE.SEA3D.Animator.prototype, {
 
 	stop: function () {
 
-		if ( this.playing ) THREE.SEA3D.AnimationHandler.removeAnimator( this );
+		if ( this.playing ) THREE.SEA3D.AnimationHandler.remove( this );
 
 		if ( this.currentAnimation ) {
 
@@ -871,7 +871,7 @@ Object.assign( THREE.SEA3D.Animator.prototype, {
 
 	playw: function ( name, weight ) {
 
-		if ( ! this.playing && ! this.paused ) THREE.SEA3D.AnimationHandler.addAnimator( this );
+		if ( ! this.playing && ! this.paused ) THREE.SEA3D.AnimationHandler.add( this );
 
 		var animation = this.getAnimationByName( name );
 
@@ -1455,7 +1455,7 @@ THREE.SEA3D.AnimationHandler = {
 
 	},
 
-	addAnimator: function ( animator ) {
+	add: function ( animator ) {
 
 		var index = this.animators.indexOf( animator );
 
@@ -1463,7 +1463,7 @@ THREE.SEA3D.AnimationHandler = {
 
 	},
 
-	removeAnimator: function ( animator ) {
+	remove: function ( animator ) {
 
 		var index = this.animators.indexOf( animator );
 

+ 0 - 0
examples/js/loaders/sea3d/SEA3DGC.js → examples/js/loaders/sea3d/o3dgc/SEA3DGC.js


+ 405 - 0
examples/js/loaders/sea3d/physics/SEA3DAmmo.js

@@ -0,0 +1,405 @@
+/**   _     _   _         _____  __   _______  ______
+*    | |___| |_| |__    /__  |  |  |     |  _  | * *
+*    | / _ \  _|    |    __\    |  |  \  |  _  |  U _
+*    |_\___/\__|_||_| _ |____/____ |__ \_|_  |_|_____|
+*
+*    @author LoTh / http://3dflashlo.wordpress.com/
+*    @author SUNAG / http://www.sunag.com.br/
+*    @author Ammo.lab / https://github.com/lo-th/Ammo.lab/
+*/
+
+'use strict';
+
+SEA3D.AMMO = {
+	world: null,
+	rigidBodies: [],
+	rigidBodiesTarget: [],
+	rigidBodiesOffset: [],
+	rigidBodiesEnabled: [],
+	constraints: [],
+	vehicles: [],
+	vehiclesWheels: [],
+
+	ACTIVE: 1,
+	ISLAND_SLEEPING: 2,
+	WANTS_DEACTIVATION: 3,
+	DISABLE_DEACTIVATION: 4,
+	DISABLE_SIMULATION: 5,
+	VERSION: 0.8,
+
+	init: function ( gravity, worldScale, broadphase ) {
+
+		gravity = gravity !== undefined ? gravity : - 90.8;
+
+		this.worldScale = worldScale == undefined ? 1 : worldScale;
+		this.broadphase = broadphase == undefined ? 'bvt' : broadphase;
+
+		this.solver = new Ammo.btSequentialImpulseConstraintSolver();
+		this.collisionConfig = new Ammo.btDefaultCollisionConfiguration();
+		this.dispatcher = new Ammo.btCollisionDispatcher( this.collisionConfig );
+
+		switch ( this.broadphase ) {
+
+			case 'bvt':
+
+				this.broadphase = new Ammo.btDbvtBroadphase();
+
+				break;
+
+			case 'sap':
+
+				this.broadphase = new Ammo.btAxisSweep3(
+					new Ammo.btVector3( - this.worldScale, - this.worldScale, - this.worldScale ),
+					new Ammo.btVector3( this.worldScale, this.worldScale, this.worldScale ),
+					4096
+				);
+
+				break;
+
+			case 'simple':
+
+				this.broadphase = new Ammo.btSimpleBroadphase();
+
+				break;
+
+		}
+
+		this.world = new Ammo.btDiscreteDynamicsWorld( this.dispatcher, this.broadphase, this.solver, this.collisionConfig );
+
+		this.setGravity( gravity );
+
+		console.log( "THREE.AMMO " + this.VERSION );
+
+	},
+
+	setGravity: function ( gravity ) {
+
+		this.gravity = gravity;
+
+		this.world.setGravity( new Ammo.btVector3( 0, gravity, 0 ) );
+
+		return this;
+
+	},
+	getGravity: function () {
+
+		return this.gravity;
+
+	},
+
+	setEnabledRigidBody: function ( rb, enabled ) {
+
+		if ( this.getEnabledRigidBody( rb ) == enabled ) return;
+
+		if ( enabled ) this.world.addRigidBody( rb );
+		else this.world.removeRigidBody( rb );
+
+		return this;
+
+	},
+	getEnabledRigidBody: function ( rb ) {
+
+		return this.rigidBodiesEnabled[ this.rigidBodies.indexOf( rb ) ] === true;
+
+	},
+	addRigidBody: function ( rb, target, offset, enabled ) {
+
+		enabled = enabled !== undefined ? enabled : true;
+
+		this.rigidBodies.push( rb );
+		this.rigidBodiesTarget.push( target );
+		this.rigidBodiesOffset.push( offset );
+		this.rigidBodiesEnabled.push( false );
+
+		this.setEnabledRigidBody( rb, enabled );
+
+		return this;
+
+	},
+	removeRigidBody: function ( rb, destroy ) {
+
+		var index = this.rigidBodies.indexOf( rb );
+
+		this.setEnabledRigidBody( rb, false );
+
+		this.rigidBodies.splice( index, 1 );
+		this.rigidBodiesTarget.splice( index, 1 );
+		this.rigidBodiesOffset.splice( index, 1 );
+		this.rigidBodiesEnabled.splice( index, 1 );
+
+		if ( destroy ) Ammo.destroy( rb );
+
+		return this;
+
+	},
+	containsRigidBody: function ( rb ) {
+
+		return this.rigidBodies.indexOf( rb ) > - 1;
+
+	},
+
+	addConstraint: function ( ctrt, disableCollisionsBetweenBodies ) {
+
+		disableCollisionsBetweenBodies = disableCollisionsBetweenBodies == undefined ? true : disableCollisionsBetweenBodies;
+
+		this.constraints.push( ctrt );
+		this.world.addConstraint( ctrt, disableCollisionsBetweenBodies );
+
+		return this;
+
+	},
+	removeConstraint: function ( ctrt, destroy ) {
+
+		this.constraints.splice( this.constraints.indexOf( ctrt ), 1 );
+		this.world.removeConstraint( ctrt );
+
+		if ( destroy ) Ammo.destroy( ctrt );
+
+		return this;
+
+	},
+	containsConstraint: function ( ctrt ) {
+
+		return this.constraints.indexOf( rb ) > - 1;
+
+	},
+
+	addVehicle: function ( vehicle, wheels ) {
+
+		this.vehicles.push( vehicle );
+		this.vehiclesWheels.push( wheels != undefined ? wheels : [] );
+
+		this.world.addAction( vehicle );
+
+		return this;
+
+	},
+	removeVehicle: function ( vehicle, destroy ) {
+
+		var index = this.vehicles.indexOf( vehicle );
+
+		this.vehicles.splice( index, 1 );
+		this.vehiclesWheels.splice( index, 1 );
+
+		this.world.removeAction( vehicle );
+
+		if ( destroy ) Ammo.destroy( vehicle );
+
+		return this;
+
+	},
+	containsVehicle: function ( vehicle ) {
+
+		return this.vehicles.indexOf( vehicle ) > - 1;
+
+	},
+
+	createTriangleMesh: function ( geometry, index, removeDuplicateVertices ) {
+
+		index = index == undefined ? - 1 : index;
+		removeDuplicateVertices = removeDuplicateVertices == undefined ? false : removeDuplicateVertices;
+
+		var mTriMesh = new Ammo.btTriangleMesh();
+
+		var v0 = new Ammo.btVector3( 0, 0, 0 );
+		var v1 = new Ammo.btVector3( 0, 0, 0 );
+		var v2 = new Ammo.btVector3( 0, 0, 0 );
+
+		var vertex = geometry.getAttribute( 'position' ).array;
+		var indexes = geometry.getIndex().array;
+
+		var group = index >= 0 ? geometry.groups[ index ] : undefined,
+			start = group ? group.start : 0,
+			count = group ? group.count : indexes.length;
+
+		var scale = 1 / this.worldScale;
+
+		for ( var idx = start; idx < count; idx += 3 ) {
+
+			var vx1 = indexes[ idx ] * 3,
+				vx2 = indexes[ idx + 1 ] * 3,
+				vx3 = indexes[ idx + 2 ] * 3;
+
+			v0.setValue( vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale );
+			v1.setValue( vertex[ vx2 ] * scale, vertex[ vx2 + 1 ] * scale, vertex[ vx2 + 2 ] * scale );
+			v2.setValue( vertex[ vx3 ] * scale, vertex[ vx3 + 1 ] * scale, vertex[ vx3 + 2 ] * scale );
+
+			mTriMesh.addTriangle( v0, v1, v2, removeDuplicateVertices );
+
+		}
+
+		return mTriMesh;
+
+	},
+	createConvexHull: function ( geometry, index ) {
+
+		index = index == undefined ? - 1 : index;
+
+		var mConvexHull = new Ammo.btConvexHullShape();
+
+		var v0 = new Ammo.btVector3( 0, 0, 0 );
+
+		var vertex = geometry.getAttribute( 'position' ).array;
+		var indexes = geometry.getIndex().array;
+
+		var group = index >= 0 ? geometry.groups[ index ] : undefined,
+			start = group ? group.start : 0,
+			count = group ? group.count : indexes.length;
+
+		var scale = 1 / this.worldScale;
+
+		for ( var idx = start; idx < count; idx += 3 ) {
+
+			var vx1 = indexes[ idx ] * 3;
+
+			var point = new Ammo.btVector3(
+				vertex[ vx1 ] * scale, vertex[ vx1 + 1 ] * scale, vertex[ vx1 + 2 ] * scale
+			);
+
+			mConvexHull.addPoint( point );
+
+		}
+
+		return mConvexHull;
+
+	},
+
+	getTargetByRigidBody: function ( rb ) {
+
+		return this.rigidBodiesTarget[ this.rigidBodies.indexOf( rb ) ];
+
+	},
+	getRigidBodyByTarget: function ( target ) {
+
+		return this.rigidBodies[ this.rigidBodiesTarget.indexOf( target ) ];
+
+	},
+	getTransformFromMatrix: function ( mtx ) {
+
+		var transform = new Ammo.btTransform();
+
+		var pos = THREE.SEA3D.VECBUF.setFromMatrixPosition( mtx );
+		transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
+
+		var scl = THREE.SEA3D.VECBUF.setFromMatrixScale( mtx );
+		mtx.scale( scl.set( 1 / scl.x, 1 / scl.y, 1 / scl.z ) );
+
+		var quat = new THREE.Quaternion().setFromRotationMatrix( mtx );
+
+		var q = new Ammo.btQuaternion();
+		q.setValue( quat.x, quat.y, quat.z, quat.w );
+		transform.setRotation( q );
+
+		Ammo.destroy( q );
+
+		return transform;
+
+	},
+	getMatrixFromTransform: function ( transform ) {
+
+		var position = new THREE.Vector3();
+		var quaternion = new THREE.Quaternion();
+		var scale = new THREE.Vector3( 1, 1, 1 );
+
+		return function ( transform, matrix ) {
+
+			matrix = matrix || new THREE.Matrix4();
+
+			var pos = transform.getOrigin(),
+				quat = transform.getRotation();
+
+			position.set( pos.x(), pos.y(), pos.z() );
+			quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
+
+			matrix.compose( position, quaternion, scale );
+
+			return matrix;
+
+		};
+
+	}(),
+
+	updateTargetTransform: function () {
+
+		var matrix = new THREE.Matrix4();
+
+		var position = new THREE.Vector3();
+		var quaternion = new THREE.Quaternion();
+		var scale = new THREE.Vector3( 1, 1, 1 );
+
+		return function ( obj3d, transform, offset ) {
+
+			var pos = transform.getOrigin(),
+				quat = transform.getRotation();
+
+			if ( offset == undefined ) {
+
+				obj3d.position.set( pos.x(), pos.y(), pos.z() );
+				obj3d.quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
+
+			} else {
+
+				position.set( pos.x(), pos.y(), pos.z() );
+				quaternion.set( quat.x(), quat.y(), quat.z(), quat.w() );
+
+				matrix.compose( position, quaternion, scale );
+
+				matrix.multiplyMatrices( matrix, offset );
+
+				obj3d.position.setFromMatrixPosition( matrix );
+				obj3d.quaternion.setFromRotationMatrix( matrix );
+
+			}
+
+			return this;
+
+		};
+
+	}(),
+	update: function ( delta, iteration, fixedDelta ) {
+
+		this.world.stepSimulation( delta, iteration || 0, fixedDelta || ( 60 / 1000 ) );
+
+		var i, j;
+
+		for ( i = 0; i < this.vehicles.length; i ++ ) {
+
+			var vehicle = this.vehicles[ i ],
+				numWheels = vehicle.getNumWheels(),
+				wheels = this.vehiclesWheels[ i ];
+
+			for ( j = 0; j < numWheels; j ++ ) {
+
+				vehicle.updateWheelTransform( j, true );
+
+				var wheelsTransform = vehicle.getWheelTransformWS( j ),
+					wheelTarget = wheels[ j ];
+
+				if ( wheelTarget ) {
+
+					this.updateTargetTransform( wheelTarget, wheelsTransform );
+
+				}
+
+			}
+
+		}
+
+		for ( i = 0; i < this.rigidBodies.length; i ++ ) {
+
+			var rb = this.rigidBodies[ i ],
+				target = this.rigidBodiesTarget[ i ],
+				offset = this.rigidBodiesOffset[ i ];
+
+			if ( target && rb.isActive() ) {
+
+				this.updateTargetTransform( target, rb.getWorldTransform(), offset );
+
+			}
+
+		}
+
+		return this;
+
+	}
+};

+ 557 - 0
examples/js/loaders/sea3d/physics/SEA3DAmmoLoader.js

@@ -0,0 +1,557 @@
+/**
+ * 	SEA3D+AMMO for Three.JS
+ * 	@author Sunag / http://www.sunag.com.br/
+ */
+
+'use strict';
+
+THREE.SEA3D.prototype.toAmmoVec3 = function ( v ) {
+
+	return new Ammo.btVector3( v.x, v.y, v.z );
+
+};
+
+//
+//	Sphere
+//
+
+THREE.SEA3D.prototype.readSphere = function ( sea ) {
+
+	var shape = new Ammo.btSphereShape( sea.radius );
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Box
+//
+
+THREE.SEA3D.prototype.readBox = function ( sea ) {
+
+	var shape = new Ammo.btBoxShape( new Ammo.btVector3( sea.width * .5, sea.height * .5, sea.depth * .5 ) );
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Cone
+//
+
+THREE.SEA3D.prototype.readCone = function ( sea ) {
+
+	var shape = new Ammo.btConeShape( sea.radius, sea.height );
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Cylinder
+//
+
+THREE.SEA3D.prototype.readCylinder = function ( sea ) {
+
+	var shape = new Ammo.btCylinderShape( new Ammo.btVector3( sea.height, sea.radius, sea.radius ) );
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Capsule
+//
+
+THREE.SEA3D.prototype.readCapsule = function ( sea ) {
+
+	var shape = new Ammo.btCapsuleShape( sea.radius, sea.height );
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Convex Geometry
+//
+
+THREE.SEA3D.prototype.readConvexGeometry = function ( sea ) {
+
+	if ( this.config.convexHull ) {
+
+		var shape = SEA3D.AMMO.createConvexHull( sea.geometry.tag, sea.subGeometryIndex );
+
+	} else {
+
+		var triMesh = SEA3D.AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
+
+		var shape = new Ammo.btConvexTriangleMeshShape( triMesh, true );
+
+	}
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Triangle Geometry
+//
+
+THREE.SEA3D.prototype.readTriangleGeometry = function ( sea ) {
+
+	var triMesh = SEA3D.AMMO.createTriangleMesh( sea.geometry.tag, sea.subGeometryIndex );
+
+	var shape = new Ammo.btBvhTriangleMeshShape( triMesh, true, true );
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Compound
+//
+
+THREE.SEA3D.prototype.readCompound = function ( sea ) {
+
+	var shape = new Ammo.btCompoundShape();
+
+	for ( var i = 0; i < sea.compounds.length; i ++ ) {
+
+		var compound = sea.compounds[ i ];
+
+		THREE.SEA3D.MTXBUF.elements = compound.transform;
+
+		var transform = SEA3D.AMMO.getTransformFromMatrix( THREE.SEA3D.MTXBUF );
+
+		shape.addChildShape( transform, compound.shape.tag );
+
+	}
+
+	this.domain.shapes = this.shapes = this.shapes || [];
+	this.shapes.push( this.objects[ "shpe/" + sea.name ] = sea.tag = shape );
+
+};
+
+//
+//	Rigid Body Base
+//
+
+THREE.SEA3D.prototype.readRigidBodyBase = function ( sea ) {
+
+	var shape = sea.shape.tag,
+		transform;
+
+	if ( sea.target ) {
+
+		transform = SEA3D.AMMO.getTransformFromMatrix( sea.target.tag.matrix );
+
+	} else {
+
+		THREE.SEA3D.MTXBUF.elements.set( sea.transform );
+
+		transform = SEA3D.AMMO.getTransformFromMatrix( THREE.SEA3D.MTXBUF );
+
+	}
+
+	var motionState = new Ammo.btDefaultMotionState( transform );
+	var localInertia = new Ammo.btVector3( 0, 0, 0 );
+
+	shape.calculateLocalInertia( sea.mass, localInertia );
+
+	var info = new Ammo.btRigidBodyConstructionInfo( sea.mass, motionState, shape, localInertia );
+	info.set_m_friction( sea.friction );
+	info.set_m_restitution( sea.restitution );
+	info.set_m_linearDamping( sea.linearDamping );
+	info.set_m_angularDamping( sea.angularDamping );
+
+	var rb = new Ammo.btRigidBody( info );
+
+	this.domain.rigidBodies = this.rigidBodies = this.rigidBodies || [];
+	this.rigidBodies.push( this.objects[ "rb/" + sea.name ] = sea.tag = rb );
+
+	return rb;
+
+};
+
+//
+//	Rigid Body
+//
+
+THREE.SEA3D.prototype.readRigidBody = function ( sea ) {
+
+	var rb = this.readRigidBodyBase( sea );
+
+	SEA3D.AMMO.addRigidBody( rb, sea.target ? sea.target.tag : undefined, sea.offset ? new THREE.Matrix4().elements.set( sea.offset ) : undefined, this.config.enabledPhysics );
+
+};
+
+//
+//	Car Controller
+//
+
+THREE.SEA3D.prototype.readCarController = function ( sea ) {
+
+	var body = this.readRigidBodyBase( sea );
+
+	body.setActivationState( SEA3D.AMMO.DISABLE_DEACTIVATION );
+
+	// Car
+
+	var vehicleRayCaster = new Ammo.btDefaultVehicleRaycaster( SEA3D.AMMO.world );
+
+	var tuning = new Ammo.btVehicleTuning();
+
+	tuning.set_m_suspensionStiffness( sea.suspensionStiffness );
+	tuning.set_m_suspensionDamping( sea.suspensionDamping );
+	tuning.set_m_suspensionCompression( sea.suspensionCompression );
+	tuning.set_m_maxSuspensionTravelCm( sea.maxSuspensionTravelCm );
+	tuning.set_m_maxSuspensionForce( sea.maxSuspensionForce );
+	tuning.set_m_frictionSlip( sea.frictionSlip );
+
+	var vehicle = new Ammo.btRaycastVehicle( tuning, body, vehicleRayCaster ),
+		wheels = [];
+
+	vehicle.setCoordinateSystem( 0, 1, 2 );
+
+	for ( var i = 0; i < sea.wheel.length; i ++ ) {
+
+		var wheel = sea.wheel[ i ];
+
+		var wheelInfo = vehicle.addWheel(
+			this.toAmmoVec3( wheel.pos ),
+			this.toAmmoVec3( wheel.dir ),
+			this.toAmmoVec3( wheel.axle ),
+			wheel.suspensionRestLength,
+			wheel.radius,
+			tuning,
+			wheel.isFront
+		);
+
+		var target = wheels[ i ] = wheel.target ? wheel.target.tag : undefined;
+
+		if ( target ) {
+
+			if ( target.parent ) {
+
+				target.parent.remove( target );
+
+			}
+
+			if ( this.container ) {
+
+				this.container.add( target );
+
+			}
+
+		}
+
+		wheelInfo.set_m_suspensionStiffness( sea.suspensionStiffness );
+		wheelInfo.set_m_wheelsDampingRelaxation( sea.dampingRelaxation );
+		wheelInfo.set_m_wheelsDampingCompression( sea.dampingCompression );
+		wheelInfo.set_m_frictionSlip( sea.frictionSlip );
+
+	}
+
+	SEA3D.AMMO.addVehicle( vehicle, wheels );
+	SEA3D.AMMO.addRigidBody( body, sea.target ? sea.target.tag : undefined, sea.offset ? new THREE.Matrix4().elements.set( sea.offset ) : undefined, this.config.enabledPhysics );
+
+	this.domain.vehicles = this.vehicles = this.vehicles || [];
+	this.vehicles.push( this.objects[ "vhc/" + sea.name ] = sea.tag = vehicle );
+
+};
+
+//
+//	P2P Constraint
+//
+
+THREE.SEA3D.prototype.readP2PConstraint = function ( sea ) {
+
+	var ctrt;
+
+	if ( sea.targetB ) {
+
+		ctrt = new Ammo.btPoint2PointConstraint(
+			sea.targetA.tag,
+			sea.targetB.tag,
+			this.toAmmoVec3( sea.pointA ),
+			this.toAmmoVec3( sea.pointB )
+		);
+
+	} else {
+
+		ctrt = new Ammo.btPoint2PointConstraint(
+			sea.targetA.tag,
+			this.toAmmoVec3( sea.pointA )
+		);
+
+	}
+
+	SEA3D.AMMO.addConstraint( ctrt );
+
+	this.domain.constraints = this.constraints = this.constraints || [];
+	this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
+
+};
+
+//
+//	Hinge Constraint
+//
+
+THREE.SEA3D.prototype.readHingeConstraint = function ( sea ) {
+
+	var ctrt;
+
+	if ( sea.targetB ) {
+
+		ctrt = new Ammo.btHingeConstraint(
+			sea.targetA.tag,
+			sea.targetB.tag,
+			this.toAmmoVec3( sea.pointA ),
+			this.toAmmoVec3( sea.pointB ),
+			this.toAmmoVec3( sea.axisA ),
+			this.toAmmoVec3( sea.axisB ),
+			false
+		);
+
+	} else {
+
+		ctrt = new Ammo.btHingeConstraint(
+			sea.targetA.tag,
+			this.toAmmoVec3( sea.pointA ),
+			this.toAmmoVec3( sea.axisA ),
+			false
+		);
+
+	}
+
+	if ( sea.limit ) {
+
+		ctrt.setLimit( sea.limit.low, sea.limit.high, sea.limit.softness, sea.limit.biasFactor, sea.limit.relaxationFactor );
+
+	}
+
+	if ( sea.angularMotor ) {
+
+		ctrt.enableAngularMotor( true, sea.angularMotor.velocity, sea.angularMotor.impulse );
+
+	}
+
+	SEA3D.AMMO.addConstraint( ctrt );
+
+	this.domain.constraints = this.constraints = this.constraints || [];
+	this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
+
+};
+
+//
+//	Cone Twist Constraint
+//
+
+THREE.SEA3D.prototype.readConeTwistConstraint = function ( sea ) {
+
+	var ctrt;
+
+	if ( sea.targetB ) {
+
+		ctrt = new Ammo.btConeTwistConstraint(
+			sea.targetA.tag,
+			sea.targetB.tag,
+			this.toAmmoVec3( sea.pointA ),
+			this.toAmmoVec3( sea.pointB ),
+			false
+		);
+
+	} else {
+
+		ctrt = new Ammo.btConeTwistConstraint(
+			sea.targetA.tag,
+			this.toAmmoVec3( sea.pointA ),
+			false
+		);
+
+	}
+
+	SEA3D.AMMO.addConstraint( ctrt );
+
+	this.domain.constraints = this.constraints = this.constraints || [];
+	this.constraints.push( this.objects[ "ctnt/" + sea.name ] = sea.tag = ctrt );
+
+};
+
+//
+//	Domain
+//
+
+THREE.SEA3D.Domain.prototype.enabledPhysics = function ( enabled ) {
+
+	var i = this.rigidBodies ? this.rigidBodies.length : 0;
+
+	while ( i -- ) {
+
+		SEA3D.AMMO.setEnabledRigidBody( this.rigidBodies[ i ], enabled );
+
+	}
+
+};
+
+THREE.SEA3D.Domain.prototype.applyContainerTransform = function () {
+
+	this.container.updateMatrix();
+
+	var matrix = this.container.matrix.clone();
+
+	this.container.position.set( 0, 0, 0 );
+	this.container.rotation.set( 0, 0, 0 );
+	this.container.scale.set( 1, 1, 1 );
+
+	this.applyTransform( matrix );
+
+};
+
+THREE.SEA3D.Domain.prototype.applyTransform = function ( matrix ) {
+
+	var mtx = THREE.SEA3D.MTXBUF, vec = THREE.SEA3D.VECBUF;
+
+	var i = this.rigidBodies ? this.rigidBodies.length : 0,
+		childs = this.container ? this.container.children : [],
+		targets = [];
+
+	while ( i -- ) {
+
+		var rb = this.rigidBodies[ i ],
+			target = SEA3D.AMMO.getTargetByRigidBody( rb ),
+			transform = rb.getWorldTransform(),
+			transformMatrix = SEA3D.AMMO.getMatrixFromTransform( transform );
+
+		transformMatrix.multiplyMatrices( transformMatrix, matrix );
+
+		transform = SEA3D.AMMO.getTransformFromMatrix( transformMatrix );
+
+		rb.setWorldTransform( transform );
+
+		if ( target ) targets.push( target );
+
+	}
+
+	for ( i = 0; i < childs.length; i ++ ) {
+
+		var obj3d = childs[ i ];
+
+		if ( targets.indexOf( obj3d ) > - 1 ) continue;
+
+		obj3d.updateMatrix();
+
+		mtx.copy( obj3d.matrix );
+
+		mtx.multiplyMatrices( matrix, mtx );
+
+		obj3d.position.setFromMatrixPosition( mtx );
+		obj3d.scale.setFromMatrixScale( mtx );
+
+		// ignore rotation scale
+
+		mtx.scale( vec.set( 1 / obj3d.scale.x, 1 / obj3d.scale.y, 1 / obj3d.scale.z ) );
+		obj3d.rotation.setFromRotationMatrix( mtx );
+
+	}
+
+};
+
+//
+//	Extension
+//
+
+THREE.SEA3D.Domain.prototype.getShape = THREE.SEA3D.prototype.getShape = function ( name ) {
+
+	return this.objects[ "shpe/" + name ];
+
+};
+
+THREE.SEA3D.Domain.prototype.getRigidBody = THREE.SEA3D.prototype.getRigidBody = function ( name ) {
+
+	return this.objects[ "rb/" + name ];
+
+};
+
+THREE.SEA3D.Domain.prototype.getConstraint = THREE.SEA3D.prototype.getConstraint = function ( name ) {
+
+	return this.objects[ "ctnt/" + name ];
+
+};
+
+THREE.SEA3D.EXTENSIONS_LOADER.push( {
+
+	parse: function () {
+
+		delete this.shapes;
+		delete this.rigidBodies;
+		delete this.vehicles;
+		delete this.constraints;
+
+	},
+
+	setTypeRead: function () {
+
+		// CONFIG
+
+		this.config.physics = this.config.physics !== undefined ? this.config.physics : true;
+		this.config.convexHull = this.config.convexHull !== undefined ? this.config.convexHull : true;
+		this.config.enabledPhysics = this.config.enabledPhysics !== undefined ? this.config.enabledPhysics : true;
+
+		if ( this.config.physics ) {
+
+			// SHAPES
+
+			this.file.typeRead[ SEA3D.Sphere.prototype.type ] = this.readSphere;
+			this.file.typeRead[ SEA3D.Box.prototype.type ] = this.readBox;
+			this.file.typeRead[ SEA3D.Capsule.prototype.type ] = this.readCapsule;
+			this.file.typeRead[ SEA3D.Cone.prototype.type ] = this.readCone;
+			this.file.typeRead[ SEA3D.Cylinder.prototype.type ] = this.readCylinder;
+			this.file.typeRead[ SEA3D.ConvexGeometry.prototype.type ] = this.readConvexGeometry;
+			this.file.typeRead[ SEA3D.TriangleGeometry.prototype.type ] = this.readTriangleGeometry;
+			this.file.typeRead[ SEA3D.Compound.prototype.type ] = this.readCompound;
+
+			// CONSTRAINTS
+
+			this.file.typeRead[ SEA3D.P2PConstraint.prototype.type ] = this.readP2PConstraint;
+			this.file.typeRead[ SEA3D.HingeConstraint.prototype.type ] = this.readHingeConstraint;
+			this.file.typeRead[ SEA3D.ConeTwistConstraint.prototype.type ] = this.readConeTwistConstraint;
+
+			// PHYSICS
+
+			this.file.typeRead[ SEA3D.RigidBody.prototype.type ] = this.readRigidBody;
+			this.file.typeRead[ SEA3D.CarController.prototype.type ] = this.readCarController;
+
+		}
+
+	}
+} );
+
+THREE.SEA3D.EXTENSIONS_DOMAIN.push( {
+
+	dispose: function () {
+
+		var i;
+
+		i = this.rigidBodies ? this.rigidBodies.length : 0;
+		while ( i -- ) SEA3D.AMMO.removeRigidBody( this.rigidBodies[ i ], true );
+
+		i = this.vehicles ? this.vehicles.length : 0;
+		while ( i -- ) SEA3D.AMMO.removeVehicle( this.vehicles[ i ], true );
+
+		i = this.constraints ? this.constraints.length : 0;
+		while ( i -- ) SEA3D.AMMO.removeConstraint( this.constraints[ i ], true );
+
+		i = this.shapes ? this.shapes.length : 0;
+		while ( i -- ) Ammo.destroy( this.shapes[ i ] );
+
+	}
+
+} );

+ 426 - 0
examples/js/loaders/sea3d/physics/SEA3DRigidBody.js

@@ -0,0 +1,426 @@
+/**
+ * 	SEA3D - Rigid Body
+ * 	@author Sunag / http://www.sunag.com.br/
+ */
+
+'use strict';
+
+//
+//	Sphere
+//
+
+SEA3D.Sphere = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.radius = data.readFloat();
+
+};
+
+SEA3D.Sphere.prototype.type = "sph";
+
+//
+//	Box
+//
+
+SEA3D.Box = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.width = data.readFloat();
+	this.height = data.readFloat();
+	this.depth = data.readFloat();
+
+};
+
+SEA3D.Box.prototype.type = "box";
+
+//
+//	Cone
+//
+
+SEA3D.Cone = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.radius = data.readFloat();
+	this.height = data.readFloat();
+
+};
+
+SEA3D.Cone.prototype.type = "cone";
+
+//
+//	Capsule
+//
+
+SEA3D.Capsule = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.radius = data.readFloat();
+	this.height = data.readFloat();
+
+};
+
+SEA3D.Capsule.prototype.type = "cap";
+
+//
+//	Cylinder
+//
+
+SEA3D.Cylinder = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.radius = data.readFloat();
+	this.height = data.readFloat();
+
+};
+
+SEA3D.Cylinder.prototype.type = "cyl";
+
+//
+//	Convex Geometry
+//
+
+SEA3D.ConvexGeometry = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.geometry = sea3d.getObject( data.readUInt() );
+	this.subGeometryIndex = data.readUByte();
+
+};
+
+SEA3D.ConvexGeometry.prototype.type = "gs";
+
+//
+//	Triangle Geometry
+//
+
+SEA3D.TriangleGeometry = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.geometry = sea3d.getObject( data.readUInt() );
+	this.subGeometryIndex = data.readUByte();
+
+};
+
+SEA3D.TriangleGeometry.prototype.type = "sgs";
+
+//
+//	Compound
+//
+
+SEA3D.Compound = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.compounds = [];
+
+	var count = data.readUByte();
+
+	for ( var i = 0; i < count; i ++ ) {
+
+		this.compounds.push( {
+			shape: sea3d.getObject( data.readUInt() ),
+			transform: data.readMatrix()
+		} );
+
+	}
+
+};
+
+SEA3D.Compound.prototype.type = "cmps";
+
+//
+//	Physics
+//
+
+SEA3D.Physics = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.attrib = data.readUShort();
+
+	this.shape = sea3d.getObject( data.readUInt() );
+
+	if ( this.attrib & 1 ) this.target = sea3d.getObject( data.readUInt() );
+	else this.transform = data.readMatrix();
+
+};
+
+SEA3D.Physics.prototype.readTag = function ( kind, data, size ) {
+
+};
+
+//
+//	Rigidy Body Base
+//
+
+SEA3D.RigidBodyBase = function ( name, data, sea3d ) {
+
+	SEA3D.Physics.call( this, name, data, sea3d );
+
+	if ( this.attrib & 32 ) {
+
+		this.linearDamping = data.readFloat();
+		this.angularDamping = data.readFloat();
+
+	} else {
+
+		this.linearDamping = 0;
+		this.angularDamping = 0;
+
+	}
+
+	this.mass = data.readFloat();
+	this.friction = data.readFloat();
+	this.restitution = data.readFloat();
+
+};
+
+SEA3D.RigidBodyBase.prototype = Object.create( SEA3D.Physics.prototype );
+SEA3D.RigidBodyBase.prototype.constructor = SEA3D.RigidBodyBase;
+
+//
+//	Rigidy Body
+//
+
+SEA3D.RigidBody = function ( name, data, sea3d ) {
+
+	SEA3D.RigidBodyBase.call( this, name, data, sea3d );
+
+	data.readTags( this.readTag.bind( this ) );
+
+};
+
+SEA3D.RigidBody.prototype = Object.create( SEA3D.RigidBodyBase.prototype );
+SEA3D.RigidBody.prototype.constructor = SEA3D.RigidBody;
+
+SEA3D.RigidBody.prototype.type = "rb";
+
+//
+//	Car Controller
+//
+
+SEA3D.CarController = function ( name, data, sea3d ) {
+
+	SEA3D.RigidBodyBase.call( this, name, data, sea3d );
+
+	this.suspensionStiffness = data.readFloat();
+	this.suspensionCompression = data.readFloat();
+	this.suspensionDamping = data.readFloat();
+	this.maxSuspensionTravelCm = data.readFloat();
+	this.frictionSlip = data.readFloat();
+	this.maxSuspensionForce = data.readFloat();
+
+	this.dampingCompression = data.readFloat();
+	this.dampingRelaxation = data.readFloat();
+
+	var count = data.readUByte();
+
+	this.wheel = [];
+
+	for ( var i = 0; i < count; i ++ ) {
+
+		this.wheel[ i ] = new SEA3D.CarController.Wheel( data, sea3d );
+
+	}
+
+	data.readTags( this.readTag.bind( this ) );
+
+};
+
+SEA3D.CarController.Wheel = function ( data, sea3d ) {
+
+	this.data = data;
+	this.sea3d = sea3d;
+
+	var attrib = data.readUShort();
+
+	this.isFront = ( attrib & 1 ) != 0,
+
+	this.target = sea3d.getObject( data.readUInt() );
+
+	this.pos = data.readVector3();
+	this.dir = data.readVector3();
+	this.axle = data.readVector3();
+
+	this.radius = data.readFloat();
+	this.suspensionRestLength = data.readFloat();
+
+};
+
+SEA3D.CarController.prototype = Object.create( SEA3D.RigidBodyBase.prototype );
+SEA3D.CarController.prototype.constructor = SEA3D.CarController;
+
+SEA3D.CarController.prototype.type = "carc";
+
+//
+//	Constraints
+//
+
+SEA3D.Constraints = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	this.attrib = data.readUShort();
+
+	this.disableCollisionsBetweenBodies = this.attrib & 1 != 0;
+
+	this.targetA = sea3d.getObject( data.readUInt() );
+	this.pointA = data.readVector3();
+
+	if ( this.attrib & 2 ) {
+
+		this.targetB = sea3d.getObject( data.readUInt() );
+		this.pointB = data.readVector3();
+
+	}
+
+};
+
+//
+//	P2P Constraint
+//
+
+SEA3D.P2PConstraint = function ( name, data, sea3d ) {
+
+	this.name = name;
+	this.data = data;
+	this.sea3d = sea3d;
+
+	SEA3D.Constraints.call( this, name, data, sea3d );
+
+};
+
+SEA3D.P2PConstraint.prototype = Object.create( SEA3D.Constraints.prototype );
+SEA3D.P2PConstraint.prototype.constructor = SEA3D.P2PConstraint;
+
+SEA3D.P2PConstraint.prototype.type = "p2pc";
+
+//
+//	Hinge Constraint
+//
+
+SEA3D.HingeConstraint = function ( name, data, sea3d ) {
+
+	SEA3D.Constraints.call( this, name, data, sea3d );
+
+	this.axisA = data.readVector3();
+
+	if ( this.attrib & 1 ) {
+
+		this.axisB = data.readVector3();
+
+	}
+
+	if ( this.attrib & 4 ) {
+
+		this.limit = {
+			low: data.readFloat(),
+			high: data.readFloat(),
+			softness: data.readFloat(),
+			biasFactor: data.readFloat(),
+			relaxationFactor: data.readFloat()
+		};
+
+	}
+
+	if ( this.attrib & 8 ) {
+
+		this.angularMotor = {
+			velocity: data.readFloat(),
+			impulse: data.readFloat()
+		};
+
+	}
+
+};
+
+SEA3D.HingeConstraint.prototype = Object.create( SEA3D.Constraints.prototype );
+SEA3D.HingeConstraint.prototype.constructor = SEA3D.HingeConstraint;
+
+SEA3D.HingeConstraint.prototype.type = "hnec";
+
+//
+//	Cone Twist Constraint
+//
+
+SEA3D.ConeTwistConstraint = function ( name, data, sea3d ) {
+
+	SEA3D.Constraints.call( this, name, data, sea3d );
+
+	this.axisA = data.readVector3();
+
+	if ( this.attrib & 1 ) {
+
+		this.axisB = data.readVector3();
+
+	}
+
+	if ( this.attrib & 4 ) {
+
+		this.limit = {
+			swingSpan1: data.readFloat(),
+			swingSpan2: data.readFloat(),
+			twistSpan: data.readFloat(),
+			softness: data.readFloat(),
+			biasFactor: data.readFloat(),
+			relaxationFactor: data.readFloat()
+		};
+
+	}
+
+};
+
+SEA3D.ConeTwistConstraint.prototype = Object.create( SEA3D.Constraints.prototype );
+SEA3D.ConeTwistConstraint.prototype.constructor = SEA3D.ConeTwistConstraint;
+
+SEA3D.ConeTwistConstraint.prototype.type = "ctwc";
+
+//
+//	Extension
+//
+
+SEA3D.File.setExtension( function () {
+
+	// PHYSICS
+	this.addClass( SEA3D.Sphere );
+	this.addClass( SEA3D.Box );
+	this.addClass( SEA3D.Cone );
+	this.addClass( SEA3D.Capsule );
+	this.addClass( SEA3D.Cylinder );
+	this.addClass( SEA3D.ConvexGeometry );
+	this.addClass( SEA3D.TriangleGeometry );
+	this.addClass( SEA3D.Compound );
+	this.addClass( SEA3D.RigidBody );
+	this.addClass( SEA3D.P2PConstraint );
+	this.addClass( SEA3D.HingeConstraint );
+	this.addClass( SEA3D.ConeTwistConstraint );
+	this.addClass( SEA3D.CarController );
+
+} );

+ 1 - 1
examples/js/nodes/TempNode.js

@@ -51,7 +51,7 @@ THREE.TempNode.prototype.build = function( builder, output, uuid, ns ) {
 
 		} else if ( isUnique ) {
 
-			data.name = data.name || THREE.GLNode.prototype.build.call( this, builder, output, uuid )
+			data.name = data.name || THREE.GLNode.prototype.build.call( this, builder, output, uuid );
 
 			return data.name;
 

BIN
examples/models/sea3d/car.sea


BIN
examples/models/sea3d/car.tjs.sea


+ 2 - 0
examples/webgl_loader_sea3d.html

@@ -54,6 +54,8 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
+			console.log("Visit https://github.com/sunag/sea3d to all codes and builds under development.");
+
 			var container, stats;
 
 			var camera, scene, renderer, composer, controls;

+ 3 - 1
examples/webgl_loader_sea3d_hierarchy.html

@@ -50,7 +50,7 @@
 		<script src="js/loaders/sea3d/SEA3DLoader.js"></script>
 		
 		<script src="js/libs/o3dgc.js"></script>
-		<script src="js/loaders/sea3d/SEA3DGC.js"></script>
+		<script src="js/loaders/sea3d/o3dgc/SEA3DGC.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
@@ -59,6 +59,8 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
+			console.log("Visit https://github.com/sunag/sea3d to all codes and builds under development.");
+
 			var container, stats;
 
 			var camera, scene, renderer, composer, controls;

+ 2 - 0
examples/webgl_loader_sea3d_keyframe.html

@@ -56,6 +56,8 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
+			console.log("Visit https://github.com/sunag/sea3d to all codes and builds under development.");
+
 			var container, stats;
 
 			var camera, scene, renderer, composer, controls, demoAt = -1;

+ 2 - 0
examples/webgl_loader_sea3d_morph.html

@@ -56,6 +56,8 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
+			console.log("Visit https://github.com/sunag/sea3d to all codes and builds under development.");
+
 			var container, stats;
 
 			var camera, scene, renderer, composer, controls, teapot;

+ 223 - 0
examples/webgl_loader_sea3d_physics.html

@@ -0,0 +1,223 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - sea3d / keyframe</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				font-family: Monospace;
+				background-color: #000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				z-index: 100;
+				display:block;
+
+			}
+
+			a { color: white }
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank">Three.JS</a> - Ammo Physics Example - Exported by <a href="https://github.com/sunag/sea3d" style="color:#FFFFFF" target="_blank">SEA3D Exporter</a> edited by <a href="https://github.com/sunag/sea3d" style="color:#FFFFFF" target="_blank">SEA3D Studio</a>
+			<br/>
+			<br/><div id="description">Right click to clone</div>
+		</div>
+
+		<script src="../build/three.js"></script>
+
+		<script src="js/controls/OrbitControls.js"></script>
+
+		<script src="js/postprocessing/EffectComposer.js"></script>
+		<script src="js/postprocessing/RenderPass.js"></script>
+		<script src="js/postprocessing/ShaderPass.js"></script>
+		<script src="js/postprocessing/MaskPass.js"></script>
+		<script src="js/shaders/CopyShader.js"></script>
+		<script src="js/shaders/ColorCorrectionShader.js"></script>
+		<script src="js/shaders/VignetteShader.js"></script>
+
+		<script src="js/loaders/sea3d/SEA3D.js"></script>
+		<script src="js/loaders/sea3d/SEA3DLZMA.js"></script>
+		<script src="js/loaders/sea3d/SEA3DLoader.js"></script>
+
+		<script src="js/libs/ammo.js"></script>
+		<script src="js/loaders/sea3d/physics/SEA3DRigidBody.js"></script>
+		<script src="js/loaders/sea3d/physics/SEA3DAmmo.js"></script>
+		<script src="js/loaders/sea3d/physics/SEA3DAmmoLoader.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			console.log("Visit https://github.com/sunag/sea3d to all codes and builds under development.");
+
+			var container, stats;
+
+			var camera, scene, renderer, composer, controls, demoAt = -1;
+
+			var loader;
+
+			// Initialize Three.JS
+
+			init();
+			
+			// Initialize Physics Engine
+			
+			SEA3D.AMMO.init(); 
+
+			//
+			// SEA3D Loader
+			//
+
+			loader = new THREE.SEA3D( {
+
+				container : scene // Container to add models
+
+			} );
+
+			loader.onComplete = function( e ) {
+
+				controls = new THREE.OrbitControls( camera );
+
+				// events
+
+				window.addEventListener( 'contextmenu', function(e) { 
+
+					e.preventDefault(); 
+
+					cloneAsset(); 
+
+				} );
+
+				animate();
+
+			};
+
+			loader.load( './models/sea3d/car.tjs.sea' );
+
+			var cloneAsset = function() {
+
+				var offset = 0;
+
+				return function() {
+
+					var domain = this.loader.clone( { lights : false, runScripts : false, autoPlay: false, enabledPhysics : false } );
+
+					offset += 180;
+
+					domain.container.position.x += offset;
+					domain.applyContainerTransform();
+					domain.enabledPhysics( true );
+					domain.runScripts();
+
+					this.scene.add( domain.container );
+
+				}
+
+			}();
+
+			//
+
+			function init() {
+
+				scene = new THREE.Scene();
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 15000 );
+				camera.position.set( -300, 200, 300 );
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setClearColor( 0x333333, 1 );
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				container.appendChild( stats.dom );
+
+				// post-processing
+
+				composer = new THREE.EffectComposer( renderer );
+
+				var renderPass = new THREE.RenderPass( scene, camera );
+				var copyPass = new THREE.ShaderPass( THREE.CopyShader );
+				composer.addPass( renderPass );
+
+				var vh = 1.4, vl = 1.2;
+
+				var colorCorrectionPass = new THREE.ShaderPass( THREE.ColorCorrectionShader );
+				colorCorrectionPass.uniforms[ "powRGB" ].value = new THREE.Vector3( vh, vh, vh );
+				colorCorrectionPass.uniforms[ "mulRGB" ].value = new THREE.Vector3( vl, vl, vl );
+				composer.addPass( colorCorrectionPass );
+
+				var vignettePass = new THREE.ShaderPass( THREE.VignetteShader );
+				vignettePass.uniforms[ "darkness" ].value = 1.0;
+				composer.addPass( vignettePass );
+
+				composer.addPass( copyPass );
+				copyPass.renderToScreen = true;
+
+				// events
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				composer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			//
+
+			var clock = new THREE.Clock();
+
+			function animate() {
+
+				var delta = clock.getDelta();
+
+				requestAnimationFrame( animate );
+
+				// Update Physics Engine
+
+				SEA3D.AMMO.update( delta );
+
+				// Update SEA3D Animations
+
+				THREE.SEA3D.AnimationHandler.update( delta );
+
+				render( delta );
+
+				stats.update();
+
+			}
+
+			function render( dlt ) {
+
+				//renderer.render( scene, camera );
+				composer.render( dlt );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 2 - 0
examples/webgl_loader_sea3d_skinning.html

@@ -58,6 +58,8 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
+			console.log("Visit https://github.com/sunag/sea3d to all codes and builds under development.");
+
 			var container, stats;
 
 			var camera, scene, renderer, composer, controls, player, hat;

+ 2 - 0
examples/webgl_loader_sea3d_sound.html

@@ -103,6 +103,8 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
+			console.log("Visit https://github.com/sunag/sea3d to all codes and builds under development.");
+
 			var container, raycaster, stats;
 
 			var camera, scene, renderer, composer, controls, velocity;