UNPKG

webgl-3d-animation

Version:

Interactive 3D animation using WebGL showing a 2D predator prey ecology on a grid which is real-time mapped onto the surface of a 3D torus. node.js server side gives access to WAV format files which are rendered using Web Audio API

574 lines (339 loc) 19.2 kB
var communication_sockets_obj = function() { // http://www.websocket.org/aboutwebsocket.html // http://caniuse.com/websockets // for binary types (WebSockets supports raw frames using ArrayBuffers and Blobs) // var WebSocket; // --- function show_buffer(given_audio_buffer, given_buffer_size, limit_to_see) { console.log('about to show buffer of size ', given_buffer_size); var max_visible_index = (given_buffer_size > limit_to_see) ? limit_to_see : given_buffer_size; for (var curr_index = 0; curr_index < max_visible_index; curr_index++) { console.log(curr_index, given_audio_buffer[curr_index]); } console.log('end of show buffer of size ', given_buffer_size); } // --- var socket; function connect_client_socket() { if ("WebSocket" in window) { console.log('client in browser says ... WebSocket is supported by your browser.'); // return; // stens TODO - remove this when live 20140729 // var chosen_port_client = process.env.PORT; // OK prior to nodejitsu // var chosen_port_client = 80; // change for nodejitsu // var chosen_port_client = 8801; // OK prior to nodejitsu // var chosen_port_client = 8888; // var chosen_port_client = 8800; // console.log("process.env.HOSTING_VENDOR ", process.env.HOSTING_VENDOR); // console.log("process.env.NODE_ENV ", process.env.NODE_ENV); // console.log("process.env.SUBDOMAIN ", process.env.SUBDOMAIN); // console.log("process.env.PORT ", process.env.PORT); // console.log("chosen_port_client ", chosen_port_client); console.log("version: 0.0.27 "); var serviceUrl; // if (process.env.NODE_ENV && process.env.NODE_ENV == "production") { // serviceUrl = "ws://webgl-3d-animation.jit.su:" + chosen_port_client + '/'; // serviceUrl = "ws://gentle-cliffs-8200.herokuapp.com:" + chosen_port_client + '/'; serviceUrl = location.origin.replace(/^http/, 'ws'); // } else { // serviceUrl = 'ws://localhost:' + chosen_port_client + '/'; // } // var serviceUrl = 'ws://localhost:8800/'; // var serviceUrl = 'ws://localhost:' + chosen_port_client + '/'; var protocol = 'Chat-1.0'; // http://webgl-3d-animation.jit.su/ console.log('serviceUrl ', serviceUrl); // var socket = new WebSocket(serviceUrl, protocol); // socket = new WebSocket(serviceUrl); // WebSocket = require('ws'); socket = new WebSocket(serviceUrl); socket.binaryType = "arraybuffer"; // stens TODO - added April 30 2014 socket.onopen = function() { console.log('Connection Established!'); }; socket.onclose = function() { console.log('Connection Closed!'); }; socket.onerror = function(error) { console.log('Error Occured: ' + error); }; socket.onmessage = function(e) { var binary_bytes = null; if (typeof e.data === "string") { console.log('String message received: ' + e.data); } else if (e.data instanceof ArrayBuffer) { console.log("ArrayBuffer received: " + e.data, " received size ", e.data.size, " size ", e.size); // var binary_bytes = new ArrayBuffer(e.data); binary_bytes = new Uint8Array(e.data); for (var i = 0; i < 200; i++) { console.log(binary_bytes[i]); } } else if (e.data instanceof Blob) { // binary bbb // console.log('Blob received on client browser side of length ', e.data.length); // console.log('Blob received on client browser side of length size ', e.size); console.log('Blob received on client browser side of length data.size ', e.data.size); var size_buffer = e.data.size; // var binary_bytes = new Uint8Array(e.data); // var binary_bytes = new ArrayBuffer(e.data); binary_bytes = new Blob(e.data); // var image = context.createImageData(canvas.width, canvas.height); // for (var i = 0; i < 200; i++) { // console.log(binary_bytes[i]); // } // context.drawImage(image, 0, 0); /* var audio_buffer = new Uint8Array(e.data, 0, size_buffer); show_buffer(audio_buffer, size_buffer, 20); */ // --- // bbb for (var property in Blob) { console.log("Blob property ", property, " value ", Blob[property]); } } }; // socket.send("Hello WebSocket!"); // socket.close(); } else { var error_msg = "ERROR - failed to find WebSocket in client"; console.log(error_msg); alert(error_msg); } } function pop_monster(given_data_blob) { var curr_value; var inneri = 0; var index_int_from_float = 0; var one_float = new Float32Array(1); var one_float_in_four_bytes_int; var size_monster = given_data_blob.size_buffer; for (var index = 0; index < size_monster; index++) { if (given_data_blob.datatype == 'int') { // big_monster_data_int8[index] = Common_Utils.get_random_in_range_inclusive_int(0, 255); given_data_blob.buffer[index] = Common_Utils.get_random_in_range_inclusive_int(0, 255); console.log(index, ' value ', given_data_blob.buffer[index]); } else if (given_data_blob.datatype == 'float') { // big_monster_data_float32[index] = Common_Utils.get_random_in_range_inclusive_float( -0.9999, 0.9999); // big_monster_data_float32[index] = 0.0; // big_monster_data_float32[index] = 1.0; one_float[0] = Common_Utils.get_random_in_range_inclusive_float(-0.9999, 0.9999); one_float_in_four_bytes_int = new Uint8Array(one_float.buffer, 0, Float32Array.BYTES_PER_ELEMENT); // First float of fa. console.log(index, ' this array size should be 4 ', one_float_in_four_bytes_int.length, ' originally value as a float ', one_float[0]); for (inneri = 0; inneri < 4; inneri++) { console.log(inneri, ' int value ', one_float_in_four_bytes_int[inneri]); given_data_blob.buffer[index_int_from_float++] = one_float_in_four_bytes_int[inneri]; } // big_monster_data_int8_from_float32[index] = 1.0; console.log(index, ' value ', one_float[0]); } else { var error_msg = 'ERROR - failed to find data type in given_data_blob'; console.log(error_msg); alert(error_msg); } // if (index % 200000 == 0) { // console.log(index, ' value ', big_monster_data[index]); // } } // var size_monster = 10; // var big_monster_data = new Uint8Array(size_monster); } // communication_sockets_obj.socket_client(1); // function convert_32bit_float_typed_array_into_4_bytes_ints_typed_array(given_data_blob, given_binary_data) { function convert_32bit_float_typed_array_into_4_bytes_ints_typed_array(data_input, data_output) { /* given binary data can be either int or float typed array, output will be Uint8Array which can be handles OK by web socket */ var curr_value; var inneri = 0; var index_int_from_float = 0; var one_float = new Float32Array(1); var one_float_in_four_bytes_int; var size_monster = data_output.buffer.length; console.log(' big data blog datatype ', data_output.datatype, " size ", size_monster); for (var index = 0; index < size_monster; index++) { if (data_output.datatype == 'int') { // big_monster_data_int8[index] = Common_Utils.get_random_in_range_inclusive_int(0, 255); data_output.buffer[index] = Common_Utils.get_random_in_range_inclusive_int(0, 255); } else if (data_output.datatype == 'float') { // one_float[0] = Common_Utils.get_random_in_range_inclusive_float( -0.9999, 0.9999); // one_float[0] = data_input[index]; one_float[0] = data_input.buffer[index]; one_float_in_four_bytes_int = new Uint8Array(one_float.buffer, 0, Float32Array.BYTES_PER_ELEMENT); // First float of fa. // console.log(index, ' as float ', one_float[0], " as int ", one_float_in_four_bytes_int); // console.log(index, ' this array size should be 4 ', one_float_in_four_bytes_int.length, // ' originally value as a float ', one_float[0]); // bbb for (inneri = 0; inneri < 4; inneri++) { // console.log(inneri, ' int value ', one_float_in_four_bytes_int[inneri]); data_output.buffer[index_int_from_float++] = one_float_in_four_bytes_int[inneri]; } if (index_int_from_float % 20000 === 0) { console.log(index, ' currated sampled every 200 float value ', one_float[0]); } } else { var error_msg = 'ERROR - failed to find data type in data_output'; console.log(error_msg); alert(error_msg); } // if (index % 200000 == 0) { // console.log(index, ' value ', big_monster_data[index]); // } } } // convert_32bit_float_typed_array_into_4_bytes_ints_typed_array function socket_client(given_mode, given_binary_data) { // function socket_client(given_mode) { // http://www.html5rocks.com/en/tutorials/webgl/typed_arrays/ // http://www.codeproject.com/Articles/531698/Introduction-to-HTML-WebSocket console.log('inside socket_client with given_mode ', given_mode); console.log('about to probe socket '); if (typeof socket !== 'undefined') { console.log('OK OK OK socket is defined'); } else { console.log('Boo Boo Boo socket is NOT NOT NOT defined'); } if (given_mode == 1) { connect_client_socket(); } else if (given_mode == 2) { socket.send("Hello WebSocket!"); // socket.close(); } else if (given_mode == 3 || given_mode == 4 || given_mode == 5) { console.log("socket_client given_mode ", given_mode); // typed arrays : 3 = ints 4 = floats 5 = elephant roar // binary typed array // stens TODO - below does NOTHING - has NO impact on sending typed arrays // socket.binaryType = 'arraybuffer'; // tell socket to get into Binary node // if (given_binary_data) { if (typeof given_binary_data !== 'undefined') { console.log("cool was given binary data to send to server side length ", given_binary_data.size_buffer); switch (given_mode) { case 4: { // genetic synth on server side console.log('... bundling genetic synth data '); for (var property in given_binary_data) { if (property == "buffer") { console.log("seeing property property Genetic will skip over"); // console.log("here is big buffer ", big_data_blob.buffer); } else { console.log("socket_client EEEEEEEEnetiCCCCC ", property, given_binary_data[property]); socket.send(property + "=" + given_binary_data[property]); // socket.send("request_flavor=elephant_roar"); } } // --- must send actual binary audio buffer AFTER above parms are sent over // socket.send(big_data_blob.buffer); // no binary in this direction break; } case 3: { // elephant roar console.log('... bundling elephant roar data '); var big_data_blob = {}; // parent object for big data var blob_property = null; for (blob_property in given_binary_data) { // copy over from source to target if (blob_property != "buffer") { big_data_blob[blob_property] = given_binary_data[blob_property]; } } // --- big_data_blob.datatype = 'float'; var size_int_buff = given_binary_data.buffer.length * Float32Array.BYTES_PER_ELEMENT; console.log("output big buffer size ", size_int_buff); // big_data_blob.buffer = new Uint8Array(given_binary_data.buffer.length * Float32Array.BYTES_PER_ELEMENT); big_data_blob.buffer = new Uint8Array(size_int_buff); convert_32bit_float_typed_array_into_4_bytes_ints_typed_array(given_binary_data, big_data_blob); big_data_blob.size_buffer = big_data_blob.buffer.length; big_data_blob.size = big_data_blob.buffer.length; big_data_blob.data_type_buffer = "Uint8Array"; // descriptive buffer typeof console.log("ssss elephant roar POST float to int has buffer length ", big_data_blob.buffer.length); for (blob_property in big_data_blob) { if (blob_property == "buffer") { console.log("seeing property property SSSSSSSOOO will skip over"); console.log("here is big buffer ", big_data_blob.buffer); } else { console.log("socket_client TTTTTTT ", blob_property, big_data_blob[blob_property]); socket.send(blob_property + "=" + big_data_blob[blob_property]); } } // --- must send actual binary audio buffer AFTER above parms are sent over socket.send(big_data_blob.buffer); break; } case 0: { // console.log('... OK synth from sample is available so render is progressing 341 '); // chosen_buff_obj.buffer = synth_from_sample_buffer; // chosen_buff_obj.size = desired_synth_buff_size; // return chosen_buff_obj; break; } // --- default - catch all if not identifed above // socket.send(big_data_blob.buffer); break; } // socket.send(big_data_blob.buffer); // socket.send(big_data_blob); } else { console.log('inside socket_client about to pop_monster '); var monster_blob = {}; // parent object for big data monster_blob.size_buffer = 3; // number of elements in numeric array if (given_mode == 3) { monster_blob.datatype = 'int'; monster_blob.buffer = new Uint8Array(monster_blob.size_buffer); } else if (given_mode == 4) { monster_blob.datatype = 'float'; monster_blob.buffer = new Uint8Array(monster_blob.size_buffer * Float32Array.BYTES_PER_ELEMENT); } pop_monster(monster_blob); socket.send(monster_blob.buffer); // --- /* if (big_data_blob.datatype == 'int') { // socket.send(big_monster_data_int8); socket.send(big_data_blob.buffer); // socket.send(big_monster_data_int8, {binary: true, mask: true}); // ws.send(array, {binary: true, mask: true}); } else if (big_data_blob.datatype == 'float') { // socket.send(big_monster_data_float32, {binary: true, mask: true}); // socket.send(big_monster_data_float32); var size_mm = big_data_blob.buffer.buffer.length; console.log('showing each int element of array prior to socket send '); for (var index = 0; index < size_mm; index++) { // console.log(index, big_monster_data_int8_from_float32[index]); console.log(index, big_data_blob.buffer[index]); } // socket.send(big_monster_data_int8_from_float32); socket.send(big_data_blob.buffer); // ws.send(array, {binary: true, mask: true}); } else { var error_msg = 'ERROR - failed to find data type in pop_monster'; console.log(error_msg); alert(error_msg); } */ } } else if (given_mode == 5) { console.log("cool about to send elephant roar data to nodejs server side file"); // socket.send(big_data_blob.buffer); } else { var error_msg = "ERROR - did not recognize given_mode sent to socket_client"; console.log(error_msg); alert(error_msg); } } // socket_client // https://stackoverflow.com/questions/19462705/nodejs-websocket-server-http-trigger // communication_sockets_obj.socket_server // --------------------------------------- return { // to make visible to calling reference frame list function here comma delimited, socket_client: socket_client // socket_server: socket_server // get_size_buffer: get_size_buffer, // get_sampled_buffer: get_sampled_buffer, // get_size_sampled_buffer: get_size_sampled_buffer }; }(); // communication_sockets_obj = function()