yea it was going to be one, but i screwed up
(couldn't figure out how to tell if a portal is facing the camera)
since i made this i found the solution so i should probably update this one or something
/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7vMx
*/
package {
import flash.text.TextField;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
// write as3 code here..
vecPort = new Vector.<xPort>(0,false);
var a:xPort;
var m:Number;
var i:int;
var k:int;
var yt:int;
var xz:xZone;
/*
for (i = 0; i < 8; i++)
{
a = new xPort();
m = Math.random() * 6.28;
a.nx = Math.cos(m);
a.ny = Math.sin(m);
a.cx = Math.random()*220+30;
a.cy = Math.random()*220+30;
vecPort.push(a);
}//nexti
*/
var cw:Number = 64;
var ch:Number = 64;
mw = 4;
mh = 4;
vecZone = new Vector.<xZone>(mw*mh, false);
for (i = 0; i < mh; i++)
{
yt = i * mw;
for (k = 0; k < mw; k++)
{
if (i ==1 && k==1) {continue;}
xz = new xZone();
xz.cx = 32+k * cw;
xz.cy = 32+i * ch;
xz.cw = cw;
xz.ch = ch;
vecZone[yt+k] = xz;
}//nextk
}//nexti
for (i = 0; i < mh; i++)
{
yt = i * mw;
for (k = 0; k < mw; k++)
{
xz = vecZone[yt+k];
if (xz == null) { continue; }
// if (i >0 && k >0) {continue;}
if (i > 0)
{
a = new xPort;
a.cx = xz.cx+xz.cw*0.5;
a.cy = xz.cy;
a.nx = 0; a.ny = 1;
a.zone = xz;
a.dest = vecZone[yt+k-mw];
vecPort.push(a);
xz.vecPort.push(a);
}
if (k > 0)
{
a = new xPort;
a.cx = xz.cx;
a.cy = xz.cy+xz.ch*0.5;
a.nx = 1; a.ny = 0;
a.zone = xz;
a.dest = vecZone[yt+k-1];
vecPort.push(a);
xz.vecPort.push(a);
}
if (i < mh-1)
{
a = new xPort;
a.cx = xz.cx+xz.cw*0.5;
a.cy = xz.cy+xz.ch;
a.nx = 0; a.ny = -1;
a.zone = xz;
a.dest = vecZone[yt+k+mw];
vecPort.push(a);
xz.vecPort.push(a);
}
if (k < mw-1)
{
a = new xPort;
a.cx = xz.cx+xz.cw;
a.cy = xz.cy+xz.ch*0.5;
a.nx = -1; a.ny = 0;
a.zone = xz;
a.dest = vecZone[yt+k+1];
vecPort.push(a);
xz.vecPort.push(a);
}
}//nextk
}//nexti
deb = new TextField();
deb.width =320;
deb.height=240;
deb.mouseEnabled=false;
addChild(deb);
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public var vecPort:Vector.<xPort>;
public var vecZone:Vector.<xZone>;
public var mw:int = 0;
public var mh:int = 0;
public var deb:TextField;
public function getZone(wx:Number, wy:Number):xZone
{
var i:int;
var num:int;
var xz:xZone;
num = vecZone.length;
for (i = 0; i < num; i++)
{
xz = vecZone[i];
if (xz==null){continue;}
if (wx < xz.cx) { continue; }
if (wy < xz.cy) { continue; }
if (wx > xz.cx+xz.cw) { continue; }
if (wy > xz.cy+xz.ch) { continue; }
return xz;
}//nexti
return null;
}//xzone
public var curTest:int = 1;
public var tempZone:Vector.<xZone> = new Vector.<xZone>(4096,false);
public function floodZone(start:xZone,cx:Number,cy:Number, nx:Number, ny:Number):void
{
var vzone:Vector.<xZone>;
var it:int;
var safe:int = 0;
var xz:xZone;
it = 0;
vzone = tempZone;
vzone[0] = start;
it = 1;
curTest += 1;
start.test = curTest;
var a:xPort;
var i:int;
var num:int;
var k:int;
var vec:Vector.<xPort>;
var dot:Number;
graphics.moveTo(start.cx,start.cy);
while (it > 0)
{
it -=1;
if (it < 0) {break;}
//avoid infinite loop in case i screw something up
safe +=1;
if (safe > 10000) { return;}
xz = vzone[it];
vec = xz.vecPort;
num = vec.length;
// graphics.lineTo(xz.cx+xz.cw*0.5,xz.cy+xz.ch*0.5);
for (i =0; i<num;i++)
{
a = vec[i];
xz = a.dest;
if (xz ==null) {continue;}
graphics.drawCircle(xz.cx+xz.cw*0.5,xz.cy+xz.ch*0.5,4);
// if (a.dest.test == curTest) { continue; }
var dx:Number;
var dy:Number;
var mag:Number;
dx = cx - a.cx;
dy = cy - a.cy;
mag = Math.sqrt(dx*dx+dy*dy);
if (mag == 0) {mag= 0.00001;}
dx /= mag;
dy /= mag;
dot = (a.nx *dx) +(a.ny*dy);
//not sure where i screw up
//update: now i do
//the camera normal is not needed here
//need a dot product with
//the normalised line the portal to the camera
//and the portal normal
if (dot<0) {continue;}
if (a.dest.frame == curFrame) {continue;}
//cheap (and not really good) way of checking if portal is in frustum
//as wonderfl is acting up again and i cant be bothered
//to make a proper test
dot = (dx*nx)+(dy*ny);
if (dot > 0) {continue;}
a.dest.test = curTest;
a.dest.frame = curFrame;
vzone[it] = a.dest;
it+=1;
}//nexti
}//nextit
}//flood
public var curFrame:int = 1;
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2,0);
var ax:Number;
var ay:Number;
var ang:Number;
var cx:Number;
var cy:Number;
var mag:Number;
var xz:xZone;
cx = 200;
cy = 200;
//cx = 53;
// cy = 53;
mag = 512;
ang = Math.atan2(stage.mouseY-cy,stage.mouseX-cx);
ax = Math.cos(ang);
ay = Math.sin(ang);
// deb.text = " " +ang+"\n " +ax +"\n " +ay+"\n "+(Math.sqrt(ax*ax+ay*ay));
d = (ax*1 + ay*0);
deb.text = " "+d +" \n " + (d>0 ? 1: 0);
graphics.moveTo(cx,cy);
graphics.lineTo(cx+ax*8, cy+ay*8);
graphics.moveTo(cx+ay*-mag,cy+ax*mag);
graphics.lineTo(cx+ay*mag, cy+ax*-mag);
var a2:Number;
var wx:Number;
var wy:Number;
a2 = ang +1.57*0.5;
wx = Math.cos(a2);
wy = Math.sin(a2);
graphics.moveTo(cx,cy);
graphics.lineTo(cx+wx*mag, cy+wy*mag);
a2 = ang -1.57*0.5;
wx = Math.cos(a2);
wy = Math.sin(a2);
graphics.moveTo(cx,cy);
graphics.lineTo(cx+wx*mag, cy+wy*mag);
var a:xPort;
var num:int;
var i:int;
var d:Number;
num = vecPort.length;
for (i = 0; i < num; i++)
{
a = vecPort[i];
//dot product
d = ax*a.nx + ay *a.ny;
if (d < 0.5)
{ graphics.lineStyle(2,0); }
else { graphics.lineStyle(2,0x808080);}
//distance to plane
d = (a.cx-cx)*ax + (a.cy-cy)*ay;
if (d < 0)
{ graphics.lineStyle(2,0xFF0000); }
//graphics.drawCircle(a.cx,a.cy,8);
graphics.moveTo(a.cx,a.cy);
graphics.lineTo(a.cx+a.nx*8,a.cy+a.ny*8);
/*
wx = cx - a.cx;
wy = cy-a.cy;
mag = Math.sqrt(wx*wx+wy*wy);
if (mag == 0) {mag=0.000001;}
wx/=mag;
wy/=mag;
graphics.moveTo(a.cx,a.cy);
graphics.lineTo(a.cx+wx*8,a.cy+wy*8);
*/
}//nexti
curFrame += 1;
xz = getZone(cx,cy);
if (xz != null)
{
xz.frame = curFrame;
floodZone(xz,cx,cy,ax,ay);
}
graphics.lineStyle(1,0x808080);
num = vecZone.length;
for (i = 0; i < num; i++)
{
xz = vecZone[i];
if (xz == null) {continue;}
if (xz.frame == curFrame)
{ graphics.lineStyle(2,0);}
else { graphics.lineStyle(1,0x808080,0.15); }
graphics.drawRect(xz.cx,xz.cy, xz.cw, xz.ch);
}//nexti
}//onenter
}//classend
}
internal class xPort
{
public var nx:Number = 0;
public var ny:Number = 0;
public var cx:Number = 0;
public var cy:Number = 0;
public var zone:xZone = null;
public var dest:xZone = null;
}//xport
internal class xZone
{
public var cx:Number = 0;
public var cy:Number = 0;
public var cw:Number = 0;
public var ch:Number = 0;
public var frame:int = 0;
public var test:int = 0;
public var vecPort:Vector.<xPort> = new Vector.<xPort>;
}//xzone