Streaming data from Blender into Three.js (WebGL+Websockets)


(goathead) #1

Three.js rocks! Best WebGL library I have used so far.
-brett-


(Daccy) #2

That looks pretty impressive. How does it handle complex scenes?


(aermartin) #3

neat :slight_smile: one step closer to have a blender webgl game engine.
three.js and mrdoob rocks indeed.


(goathead) #4

@Daccy, i haven’t tried a complex scene yet, but i expect it would perform well as long as not too many dynamic meshes are streamed. Three.js is very fast, so the bottleneck is not there.


(cekuhnen) #5

hey this is very interesting - the ability of streaming is I think the most fascinating aspect of this!

Aermartin nice wish man - I think we are still a long way away from this but getting close :wink:


(BenDansie) #6

It would be a massive stress test for sure, but I wonder how this would hold up in the future for BConf presentations? Obviously not all of them, but it would certainly be interesting to see.


(goathead) #7

Anybody know how to solve this rotation bug?

Transform from Blender is streamed to a Three.js webclient, the data is in world space. Position and scale are correct. Rotation is correct if only the X axis is rotated. Rotation goes haywire when Y and Z are rotated. The video shows the affects of changing the client-side code to swap Y,Z - this gives better but still incorrect results.

Here is my javscript function that takes the message from blender and updates Three.js

function on_message(e) {
var data = ws.rQshiftStr();
var msg = JSON.parse( data );
dbugmsg = msg;

for (var name in msg['FX']) {
	var fx = FX[ name ];
	fx.enabled = msg['FX'][name][0];
	var uniforms = msg['FX'][name][1];
	if (fx.uniforms) {
		for (var n in uniforms) { fx.uniforms[ n ].value = uniforms[ n ]; }
	}
	else {	// BloomPass
		for (var n in uniforms) { fx.screenUniforms[ n ].value = uniforms[ n ]; }
	}
}

for (var name in msg['lights']) {
	var light;
	var ob = msg['lights'][ name ];
	name = name.replace('.', '_');

	if ( name in LIGHTS == false ) {	// Three.js bug, new lights are not added to old materials
		console.log('>> new light');
		LIGHTS[ name ] = light = new THREE.PointLight( 0xffffff );
		scene.add( light );
	}
	light = LIGHTS[ name ];
	light.color.r = ob.color[0];
	light.color.g = ob.color[1];
	light.color.b = ob.color[2];
	light.distance = ob.dist;
	light.intensity = ob.energy;

	light.position.x = ob.pos[0];
	light.position.y = ob.pos[2];
	light.position.z = -ob.pos[1];

}

for (var name in msg['meshes']) {
	var ob = msg['meshes'][ name ];
	var raw_name = name;
	name = name.replace('.', '_');

	if (name in Objects && Objects[name]) {
		m = Objects[ name ];
		if (ob.selected) { SELECTED = m; }

		/*
		var mat = new THREE.Matrix4(
			ob.mat[0],
			ob.mat[1],
			ob.mat[2],
			ob.mat[3],
			ob.mat[4],
			ob.mat[5],
			ob.mat[6],
			ob.mat[7],
			ob.mat[8],
			ob.mat[9],
			ob.mat[10],
			ob.mat[11],
			ob.mat[12],
			ob.mat[13],
			ob.mat[14],
			ob.mat[15]
		);
		var props = mat.decompose( m.position, m.quaternion, m.scale );
		*/
		//m.position = props[ 0 ];
		//m.quaternion = props[ 1 ];
		//m.scale = props[ 2 ];

		m.position.x = ob.pos[0];
		m.position.y = ob.pos[2];
		m.position.z = -ob.pos[1];

		m.scale.x = ob.scl[0];
		m.scale.y = ob.scl[2];
		m.scale.z = ob.scl[1];

		m.rotation.x = ob.rot[0];
		m.rotation.y = ob.rot[2];
		m.rotation.z = -ob.rot[1];
		/*
		m.quaternion.w = ob.rot[0];
		m.quaternion.x = ob.rot[1];
		m.quaternion.y = ob.rot[2];
		m.quaternion.z = ob.rot[3];
		*/

		if (ob.color) {
			m._material.color.r = ob.color[0];
			m._material.color.g = ob.color[1];
			m._material.color.b = ob.color[2];
		}
		m._material.shininess = ob.spec;

		if (ob.verts) {
			m.dirty_modifiers = true;
			m.subsurf = ob.subsurf;
			m.geometry_base.computeCentroids();
			//m.geometry_base.computeFaceNormals();
			//m.geometry_base.computeVertexNormals();
			var vidx=0;
			for (var i=0; i <= ob.verts.length-3; i += 3) {
				var v = m.geometry_base.vertices[ vidx ].position;
				v.x = ob.verts[ i ];
				v.y = ob.verts[ i+2 ];
				v.z = -ob.verts[ i+1 ];
				vidx++;
			}
		}
	}
	else if (name in Objects == false) {
		console.log( '>> loading new collada' );
		Objects[ name ] = null;
		var loader = new THREE.ColladaLoader();
		loader.options.convertUpAxis = true;
		loader.load( '/objects/'+raw_name+'.dae', on_collada_ready );

	}
}

}


(goathead) #8

Testing 2D Three.js effects overlays and random camera changes triggered by sound input.


(goathead) #9

Testing progressive image baking. Automated baking of diffuse, AO, and normal maps, with progressively higher resolution.


(gonchar) #10

Cool!
For rotations use Quaternions only. Because multiply of rotation matrices are not commutative. I see in your code, quaternions commented.


(Hyzhak) #11

i think to solve this problem you need to use Quaternions


(rectalogic) #12

Blenders euler order is ‘XYZ’, but the equivalent euler rotation order in Three.js is ‘ZYX’ (they are just named the reverse) So try this:

m.rotation.x = ob.rot[0];
m.rotation.y = ob.rot[1];
m.rotation.z = ob.rot[2];
m.eulerOrder = ‘ZYX’;


(X3DModels) #13

Looks interesting. Where is the sourcecode of this?


(X3DModels) #14

no answer? Hm =(


(goathead) #15

Hi X3D, the source is hosted on google code.
http://code.google.com/p/pyppet/


(Meta-Androcto) #16

new video by goathead