Skip to content

Instantly share code, notes, and snippets.

@suma
Created May 20, 2012 14:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save suma/2758316 to your computer and use it in GitHub Desktop.
Save suma/2758316 to your computer and use it in GitHub Desktop.
creating spike for CTF visualizer with WebGL(three.js) base on three.js examples (MIT lisence)
<!doctype html>
<html lang="en">
<head>
<title>ctf watcher</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 {
/* background:#000; */
background:#000;
color: #eee;
padding:0;
margin:0;
font-weight:bold;
overflow:hidden;
font-family:Monospace;
font-size:13px;
text-align:center;
}
#info {
position: absolute;
top: 0px; width: 100%;
padding: 5px;
z-index:100;
}
</style>
</head>
<body>
<div id="info">
<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - earth [fly camera]<br/><br/>
<b>WASD</b> move, <b>R|F</b> up | down, <b>Q|E</b> roll, <b>up|down</b> pitch, <b>left|right</b> yaw<br/>
</div>
<script src="./build/Three.js"></script>
<script src="./examples/js/Stats.js"></script>
<script>
function include(arr,obj) {
return (arr.indexOf(obj) != -1);
}
// websocket
if (!("WebSocket" in window)) {
alert('WebSocket not supported on this browser');
} else {
//init_ws();
}
// TODO: describe or input describe from server
var problems = []
problems.push("hoge");
problems.push("hoge");
problems.push("hoge");
problems.push("hoge");
var problem_mesh = []
var teams = []
var clock, controls;
var container, stats;
var camera, scene, projector, renderer;
var geometry;
var floor_frame = 0, deltaSum = 0;
// for Particles floor
var floor_group;
var SEPARATION = 100;
var AMOUNT_X = 50;
var AMOUNT_Y = 50;
var PI2 = Math.PI * 2;
var particles = [];
// base
var vertex1, vertex2, line;
// packet
var packets = []
var mouse = { x: 0, y: 0 }, INTERSECTED;
var mouseDown = false;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
//document.addEventListener( 'mouseup', onDocumentMouseUp, false );
//document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
init();
init_base();
init_data(problems);
init_floor();
animate();
function init_ws() {
ws = new WebSocket("ws://localhost:8080/chat");
ws.onmessage = function(event) {
var obj = jQuery.parseJSON(event.data);
if (obj.type == 'update') {
// init or update object
// target: { name => problem, type => type }
// sender: { team => teamname, ip => ip }
} else if (obj.type == 'packet') {
// receive packet event
// EV_ACCESS GET/POST
// EV_ANSWER POST answer form
// EV_CLEAR ANSWER successful
packet_received(obj.to);
}
}
ws.onopen = function(event) {
output("connected");
}
ws.onclose = function(event) {
output("disconnected");
}
}
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
//scene.fog = new THREE.FogExp2( 0x003366, 0.0095 );
clock = new THREE.Clock();
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
controls = new THREE.FlyControls( camera );
controls.movementSpeed = 1000;
controls.domElement = container;
controls.rollSpeed = Math.PI / 24;
controls.autoForward = false;
controls.dragToLook = true;
//camera.position.x = 100;
camera.position.y = 100;
camera.position.z = 1000;
camera.target = new THREE.Vector3();
scene.add( camera );
projector = new THREE.Projector();
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
}
function init_floor() {
// floor
var floor_group= new THREE.Object3D();
var material = new THREE.ParticleCanvasMaterial( {
color: 0xfffffff,
program: function (context) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
} );
var SEP2 = ( ( AMOUNT_X * SEPARATION ) / 2 );
for (var ix = 0; ix < AMOUNT_X; ix++) {
for (var iy = 0; iy < AMOUNT_Y; iy++) {
var particle = new THREE.Particle( material );
particle.position.x = ix * SEPARATION - SEP2;
particle.position.z = iy * SEPARATION - SEP2;
floor_group.add( particle );
particles.push(particle);
}
scene.add( floor_group );
}
}
function init_base() {
var geometry = new THREE.Geometry();
var r = 30;
for (var i = 0; i < 500; i++) {
vertex1 = new THREE.Vector3();
vertex1.x = Math.random() * 2 - 1;
vertex1.y = Math.random() * 2 - 1;
vertex1.z = Math.random() * 2 - 1;
vertex1.normalize();
vertex1.multiplyScalar( r );
vertex2 = vertex1.clone();
vertex2.multiplyScalar( Math.random() * 0.09 + 1 );
geometry.vertices.push( vertex1 );
geometry.vertices.push( vertex2 );
}
var p = [ 1, 0xff7700, 1, 2 ];
var material = new THREE.LineBasicMaterial( { color: p[ 1 ], opacity: p[ 2 ], linewidth: p[ 3 ] } );
line = new THREE.Line( geometry, material, THREE.LinePieces );
line.scale.x = line.scale.y = line.scale.z = p[ 0 ];
line.originalScale = p[ 0 ];
line.rotation.y = Math.random() * Math.PI;
line.updateMatrix();
line.position.y = 20;
line.position.z = 800;
scene.add( line );
}
function init_data(problems) {
var geometry = new THREE.CubeGeometry( 100, 100, 10 );
for ( var i = 0; i < problems.length; i ++ ) {
var material = new THREE.MeshBasicMaterial({color: 0xff00f0, opacity: 0.5});
var mesh = new THREE.Mesh( geometry, material );
// TODO: mapping to any position
mesh.position.x = 500 - 155 * i;
mesh.position.y = 300;
mesh.position.z = 10;
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
problem_mesh.push( mesh );
scene.add( mesh );
}
}
function packet_received(target) {
//
var material = new THREE.ParticleCanvasMaterial( {
color: 0x00ff00,
program: function (context) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
} );
var tama;
var particle = new THREE.Particle( material );
tama.particle = particle;
tama.target = problem_mesh[target];
//tama.orient = ;
scene.add(particle);
packets.push(tama);
}
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function onDocumentMouseDown(event) {
// find intersections
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );
if ( intersects.length > 0 && include(problem_mesh, intersects[0].object)) {
// move to object
var old = camera.position.z;
camera.position = intersects[0].object.position;
camera.position.z = old - 10;
}
}
function onDocumentMouseUp(event) {
mouseDown = false;
}
function onDocumentMouseWheel(event) {
mouseDown = false;
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
var ANIMATION = 15;
function render() {
var delta = clock.getDelta();
deltaSum += delta;
if (deltaSum > .07) {
floor_frame = (floor_frame + 1) % ANIMATION;
deltaSum = deltaSum % .07;
var MOV = SEPARATION / ANIMATION;
var SEP2 = ( ( AMOUNT_X * SEPARATION ) / 2 );
for (var ix = 0, i = 0; ix < AMOUNT_X; ix++) {
for (var iy = 0; iy < AMOUNT_Y; iy++, i++) {
var particle = particles[i];
if (floor_frame == 0) {
// reset floor position
particle.position.z = iy * SEPARATION - SEP2;
} else {
particle.position.z -= MOV;
}
}
}
}
// find intersections
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );
if ( intersects.length > 0 && include(problem_mesh, intersects[0].object)) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED = intersects[0].object;
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
INTERSECTED.material.color.setHex(0xff0000);
}
} else {
if ( INTERSECTED ) INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
INTERSECTED = null;
}
// process
var remove = [];
for (var i = 0; i < packets.length; i++) {
var p = packets[i];
}
for (var i = 0; i < remove.length; i++) {
// remove objects
}
controls.update( delta );
renderer.render( scene, camera );
}
</script>
</body>
</html>
require 'em-websocket'
require 'json'
class CTFServer
def initialize(ch)
@channel = ch
end
def event(input)
@channel.push(input)
end
end
svr = nil
EventMachine.run {
# TODO: prepare reciver for CTF Monitor
@channel = EM::Channel.new
# hit Control + C to stop
Signal.trap("INT") { EventMachine.stop }
Signal.trap("TERM") { EventMachine.stop }
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
ws.onopen {
puts "WebSocket connection open"
# publish message to the client
res = { 'msg' => "Server: Hello Client" }.to_json
ws.send res
sid = @channel.subscribe { |msg|
ws.send msg
}
ws.onclose {
@channel.unsubscribe(sid)
puts "Connection closed"
}
ws.onmessage { |msg|
puts "Recieved message: #{msg}"
res = { 'msg' => "Server: received #{msg}" }.to_json
@channel.push res
#ws.send res
}
ws.onping { |value|
}
ws.onpong { |value|
}
ws.onerror { |e|
puts "Error: #{e.inspect}"
}
}
end
puts "server started"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment