Created
May 20, 2012 14:33
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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