I have added the ability to search twitter and re-populate the fish tank. So now you can place a search in like “Tool” or “Toledo” or whatever you query it will pull results from twitter. I have noticed this experiment is resource intensive. In part three of this experiment I will look for ways to tidy up the code make it more reusable and less resource intensive. I also noticed in c3dl they already have a nice random number function built in I will have to try and use that in the future. I am also curious to see if I can’t use this library to augment the Processing.JS library I noticed the same group at Secena is also working on this library I believe they have ported most of the new functions. I also added two sliders with jQuery to control the camera I am currently using an orbitCamera I think I will change this in the future to utilize a free camera and use the animateAxis function to animate around a vector with an angle. Currently I am using the Yaw and Pitch functions of the orbitCamera of course it looks kind of awkward to spin it. I will try to find ways to speed this experiment up, fix the picking result to be more sensitive, clean up the look and feel of it for part three. If there is a part four it will be about making the fish bound to the sphere and maybe making them so the swim back and forth not in a straight line.

I might also be making a similar experiment with away3Dlite and the hype framework with flash this weekend. This has been a fun experiment to play around with. Maybe Adobe should allocate some of their resources to compiling to javascript and using the webGL and DirectX for IE with the canvas tag (Even though It isn’t as fast as flash and doensn’t display the same across browsers). Haxe I believe currently does this to some extent I am not sure how fast the results are but seems to me their are Sandy3D experiments on Google Experiments.

TweetTank WebGL example Created with C3DL

Here is the code for the experiment:

var CANVAS_WIDTH = $(window).width;
var CANVAS_HEIGHT = $(window).height()*2;
$('#tweetTank').width(CANVAS_WIDTH);
$('#tweetTank').height(CANVAS_HEIGHT);
$('#tweetTank').css('display','block');
		var arrayTwit;
        var schooloffish;
        var fishArray = [];
        var bubblesArray = [];
        var bubbles;
		var objectsHit = "";
		var objectSelected;
		var cam;
		var searchInt = 0;
        function mRandom(r) {
            var randomInt = Math.floor(Math.random() * r + 1);
            return randomInt;
        }
        
        c3dl.addModel("fish.dae");
        c3dl.addModel("OceanSphere.dae"); 
        // The program main
        function canvasMain(canvasName) {

            // Create new c3dl.Scene object
            scn = new c3dl.Scene();
            scn.setCanvasTag(canvasName);

            // Create GL context
            renderer = new c3dl.WebGL();
            renderer.addTexture("bubble.jpg");
            renderer.createRenderer(this);

            // Attach renderer to the scene
            scn.setRenderer(renderer);
            scn.init(canvasName);
            //the isReady() function tests whether or not a renderer
            //is attached to a scene.  If the renderer failed to
            //initialize this will return false but only after you
            //try to attach it to a scene.
            if (renderer.isReady()) {
                // Create a Collado object that
                // will contain a imported
                // model of something to put
                // in the scene.
                var schooloffish = mRandom(100);
                var ocean = new c3dl.Collada();
                ocean.init("OceanSphere.dae");
                ocean.setAngularVel(new Array(0, .00005, 0));
                ocean.scale([20.0, 20.0, 20.0]);
                ocean.setPickable(false);
                scn.addObjectToScene(ocean); 
				//console.log(arrayTwit.length);
                for (var i = 0; i < arrayTwit.length; i++) {
					//console.log(arrayTwit[i]);
                    fishArray[i] = new c3dl.Collada();
                    fishArray[i].init("fish.dae");
                    fishArray[i].yaw(45.0);
					fishArray[i].ID = "Fish" + i;
                    //fish.roll(25.0);
                    fishArray[i].pitch(-86.4);
					fishArray[i].setLinearVel([0,0,-2]);
                    fishArray[i].url = "http://twitter.com/" + arrayTwit[i].from_user;
                    //fish.setPosition([1200, 100, 700]);
                    fishArray[i].setPosition([mRandom(1200), mRandom(900), mRandom(1500)]);
                    scn.addObjectToScene(fishArray[i]);
                }
                for (var i = 0; i < 7; i++) {
                    bubblesArray[i] = new c3dl.ParticleSystem();
                    bubblesArray[i].setMinVelocity([-2, 0, -2]);
                    bubblesArray[i].setMaxVelocity([2, 25, 2]);
                    bubblesArray[i].setMinLifetime(5.3);
                    bubblesArray[i].setMaxLifetime(10.7);
                    bubblesArray[i].setMinColor([0, 0, 0.3, 0]);
                    bubblesArray[i].setMaxColor([0, 0.3, 0.5, 1]);
                    bubblesArray[i].setSrcBlend(c3dl.ONE);
                    bubblesArray[i].setDstBlend(c3dl.ONE);
                    bubblesArray[i].setMinSize(0.5);
                    bubblesArray[i].setMaxSize(5.0);
                    bubblesArray[i].setTexture("bubble.gif");
                    bubblesArray[i].setAcceleration([0, 9, 0]);
                    bubblesArray[i].setEmitRate(40);
                    bubblesArray[i].init(150);
                    bubblesArray[i].setPosition([mRandom(1200), mRandom(100), mRandom(700)]);
                    scn.addObjectToScene(bubblesArray[i]);
                }
                // Create a camera
                //var cam = new c3dl.FreeCamera();
                
                
               
               // scn.setCamera(cam);
                cam = new c3dl.OrbitCamera();
                cam.setFarthestDistance(2000);
                //cam.pitch(90);
                cam.setPosition(new Array(3000.0, 300.0, 200.0));
                //cam.setLookAtPoint(new Array(0.0, 0.0, 0.0));
                cam.setOrbitPoint(new Array(800.0, 100.0, 200.0));
                cam.setClosestDistance(200);
                cam.setDistance(900);
                //cam.pitch(1);
                scn.setCamera(cam);
                // Start the scene
                scn.startScene();
                scn.setPickingCallback(goLink);
                //scn.setKeyboardCallback(onKeyUp, onKeyDown);
                scn.setMouseCallback(mouseWheel);
                
            }
        }
		
		function goLink(pickingObj)
		{
 			var objectsHit = pickingObj.getObjects();

 			if( objectsHit.length > 0 )
			 {
 				var sepiaEffect = new c3dl.Effect();
				sepiaEffect.init(c3dl.effects.SEPIA);
 				window.open(objectsHit[0].url, '_blank');
				objectsHit[0].setEffect(sepiaEffect);
 					for(var i = 0; i < arrayTwit.length; i++){
 						if(objectsHit[0].url == scn.getObj(i).url)
 					scn.getObject(i).setEffect(sepiaEffect);
 					}
 				}
		}
        
        function mouseWheel(event) {
            var delta = 0;
			const ZOOM_SENSITIVITY = 3;
            // Chromium
            if (event.wheelDelta) {
                delta = -event.wheelDelta / 20;
            }
            // Minefield
            else if (event.detail) {
                delta = event.detail * 4;
            }

            else {
                if (keyD) {
                    cam.yaw(delta * ZOOM_SENSITIVITY / 100);
                }
                else {

                    // towards user
                    if (-delta * ZOOM_SENSITIVITY < 0) {
                        cam.goFarther(-1 * -delta * ZOOM_SENSITIVITY);
                    }

                    // towards screen
                    else {
                        cam.goCloser(-delta * ZOOM_SENSITIVITY);
                    }
                }
            }
        }


function twitterSearch(searchTag) {
	//console.log(searchTag);
	arrayTwit = "";
	arrayTwit = new Array();
                $.getJSON("http://search.twitter.com/search.json?q=" + searchTag + "&callback=?",
        function(data) {
            $.each(data.results, function(i, item) {
                twitSeach = item;
                arrayTwit.push(twitSeach);
            });
		
			if(searchInt >=1){
				searchInt++;
				$('#TweetTankBowl').html("");
				$('#TweetTankBowl').html('');
				$('#tweetTank').width(CANVAS_WIDTH);
				$('#tweetTank').height(CANVAS_HEIGHT);
				$('#tweetTank').css('display','block');
				canvasMain("tweetTank");
			}else{
				searchInt++;	
				c3dl.addMainCallBack(canvasMain, "tweetTank");
			}
		 });
}
$(document).ready(function() {
            twitterSearch("fishing");
			sliderGo();
        });

function goTwitter(){
var tweet =  $('#tweetSearchTxt').val();
twitterSearch(tweet);	
}

function sliderGo(){
$("#sliderVeritcal").slider({
				step: 0.15,
				min: 0.00,
				max:360.00,
				orientation: 'vertical',
				slide: function(event, ui) {  
					cam.pitch(ui.value);
				}
			});
				$("#sliderHorizontal").slider({
				step: 0.15,
				min: 0.00,
				max:360.00,
				slide: function(event, ui) {  
					cam.yaw(ui.value);
				}
			});	
}

Launch Experiment / Download Code