summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulie Lala <jules@okfoc.us>2014-10-31 22:38:27 -0400
committerJulie Lala <jules@okfoc.us>2014-10-31 22:38:27 -0400
commita61ad3cea5b7a76777d594d1a6d960943a0e776f (patch)
tree404981bc53e3101ed6081fad3326de5036fb2a56
parentdc4db9d58f9868694d71b697e5351596cadc4054 (diff)
correctly intercepting walls in mover
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/mover.js188
-rw-r--r--public/assets/test/intersect3.html10
2 files changed, 105 insertions, 93 deletions
diff --git a/public/assets/javascripts/rectangles/engine/rooms/mover.js b/public/assets/javascripts/rectangles/engine/rooms/mover.js
index 8ce00fe..69e821f 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/mover.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/mover.js
@@ -4,6 +4,14 @@ Rooms.mover = new function(){
base.room = null
base.noclip = false
+ var cursor = base.cursor = new Rect (0,0,0,0)
+ var wall_vec = new Rect (0,0,0,0)
+ var intersect = new vec2(0,0)
+
+ var origins = new Rect()
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
base.init = function(){
base.bind()
base.update(scene.camera)
@@ -33,6 +41,14 @@ Rooms.mover = new function(){
return
}
+ var intersect = base.intersect(pos)
+
+ if (intersect && ! base.noclip) {
+ cam.x = intersect.a
+ cam.z = intersect.b
+ return
+ }
+/*
// check if we've breached one of the walls.. clamp position if so
var collision = base.room.collidesDisc(cam, pos, radius)
@@ -41,96 +57,13 @@ Rooms.mover = new function(){
cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z
return
}
-
+*/
// in this case, we appear to have left the room..
// $(".face.active").removeClass("active")
Walls.clearBodyColor()
base.room = null
}
-/*
- var dz = new vec2( cam.z, pos.z )
- dz.normalize()
-
- var dx = new vec2( cam.x, pos.x )
- dx.normalize()
-
- // first check if the cam-pos movement intersects the wall.
- // next check if it intersects any of the surface frames
- // if we can pass through the wall at this point, we do not need to clamp.
- // otherwise, get the distance along the cam-pos vector where we would hit the wall and clamp to it.
- Walls.list.forEach(function(wall){
- var t = -1
- switch (wall.side) {
- case FRONT:
- if (cam.z >= wall.edge + radius && wall.edge + radius >= pos.z && wall.vec.intersects(dx) ) {
- t = check_intersection( front_back_intersection, cam, pos, dx, wall, radius )
- }
- break
- case BACK:
- // console.log(cam.z|0, wall.edge-radius, pos.z|0, wall.vec.intersects(dx))
- if (cam.z <= wall.edge - radius && wall.edge - radius <= pos.z && wall.vec.intersects(dx) ) {
- t = check_intersection( front_back_intersection, cam, pos, dx, wall, -radius )
- console.log(t)
- }
- break
- case LEFT:
- if (cam.x >= wall.edge + radius && wall.edge + radius >= pos.x && wall.vec.intersects(dz) ) {
- t = check_intersection( left_right_intersection, cam, pos, dz, wall, radius )
- }
- break
- case RIGHT:
- if (cam.x <= wall.edge - radius && wall.edge - radius <= pos.x && wall.vec.intersects(dz) ) {
- t = check_intersection( left_right_intersection, cam, pos, dz, wall, -radius )
- }
- break
- }
- if (0 <= t && t <= 1) {
- pos.x = cam.x + (pos.x - cam.x) * t
- pos.z = cam.z + (pos.z - cam.z) * t
-
- dz = new vec2( cam.z, pos.z )
- dz.normalize()
-
- dx = new vec2( cam.x, pos.x )
- dx.normalize()
- }
- })
-
- function check_intersection(intersection_function, cam, pos, cam_pos_vector, wall, radius) {
- var t = -1
- wall.surface.faces.some(function(face, i){
- if (face.y.a == 0 && face.x.intersects(cam_pos_vector)) {
- t = intersection_function( cam, pos, wall, face, radius )
- console.log(">>", t)
- if (0 <= t && t <= 1) {
- return true
- }
- else {
- t = -1
- }
- }
- return false
- })
- return t
- }
- function left_right_intersection (cam, pos, wall, face, radius) {
- var perp_n = (face.x.a - face.x.b) * (wall.edge - cam.z + radius)
- var perp_d = (face.x.a - face.x.b) * (pos.z - cam.z)
- if (perp_d == 0) return Infinity
- return perp_n / perp_d
- }
- function front_back_intersection (cam, pos, wall, face, radius) {
- // va.vx*vb.vy - va.vy*vb.vx
- var perp_n = (face.x.b - face.x.a) * (wall.edge - cam.x + radius)
- var perp_d = (face.x.b - face.x.a) * (pos.x - cam.x)
-
- console.log((pos.x - cam.x), wall.edge - cam.x, radius)
-
- if (perp_d == 0) return Infinity
- return perp_n / perp_d
- }
-*/
// collision test failed, so update position
cam.x = pos.x
cam.z = pos.z
@@ -148,7 +81,92 @@ Rooms.mover = new function(){
}
app.tube("change-room", { room: base.room })
}
-
}
+ base.intersect = function(pos){
+ var closest_intersect, t, min_t = 1
+
+ cursor.x.a = cam.x
+ cursor.x.b = cam.z
+ cursor.y.a = pos.x
+ cursor.y.b = pos.z
+
+ var a = angle(cursor)
+ cursor.y.a += scene.camera.radius * cos(a)
+ cursor.y.b += scene.camera.radius * sin(a)
+
+ Walls.list.forEach(function(wall, i){
+ var actually_intersects, intersecting_face
+ if (wall.side & LEFT_RIGHT) {
+ wall_vec.x.a = wall.edge
+ wall_vec.x.b = wall.vec.a
+ wall_vec.y.a = wall.edge
+ wall_vec.y.b = wall.vec.b
+ }
+ else {
+ wall_vec.x.a = wall.vec.a
+ wall_vec.x.b = wall.edge
+ wall_vec.y.a = wall.vec.b
+ wall_vec.y.b = wall.edge
+ }
+
+ t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
+
+ if ( min_t < t || t < 0 || 1 < t ) return
+
+ intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * t
+ intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * t
+
+ if ( ! is_collinear( intersect, wall_vec ) ) return
+
+ if (wall.side & LEFT_RIGHT) {
+ intersecting_face = wall.surface.face_for_x(intersect.b)
+ }
+ else {
+ intersecting_face = wall.surface.face_for_x(intersect.a)
+ }
+
+ actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0)
+ if (actually_intersects) {
+ closest_intersect = intersect.clone()
+ min_t = t
+ }
+ })
+
+ if (min_t < 1) {
+ var a = angle(cursor)
+ closest_intersect.a -= scene.camera.radius * cos(a)
+ closest_intersect.b -= scene.camera.radius * sin(a)
+ }
+ return closest_intersect
+ }
+ function angle (va) {
+ return atan2(va.y.b - va.x.b, va.y.a - va.x.a)
+ }
+ function dot (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.a - vb.x.a) + (va.y.b - va.x.b) * (vb.y.b - vb.x.b)
+ }
+ function perp (va, vb) {
+ return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a)
+ }
+ function is_collinear (p, vec) {
+ var on_x, on_y
+ var pa = round(p.a), pb = round(p.b)
+
+ if (vec.x.a < vec.y.a) {
+ on_x = vec.x.a <= pa && pa <= vec.y.a
+ }
+ else {
+ on_x = vec.x.a >= pa && pa >= vec.y.a
+ }
+
+ if (vec.x.b < vec.y.b) {
+ on_y = vec.x.b <= pb && pb <= vec.y.b
+ }
+ else {
+ on_y = vec.x.b >= pb && pb >= vec.y.b
+ }
+
+ return !! (on_x && on_y)
+ }
}
diff --git a/public/assets/test/intersect3.html b/public/assets/test/intersect3.html
index e897e8a..1e2a1a4 100644
--- a/public/assets/test/intersect3.html
+++ b/public/assets/test/intersect3.html
@@ -167,12 +167,12 @@ function draw () {
}
drawPoint(intersect)
- if (actually_intersects && intersecting_face && t < min_t) {
+ if (actually_intersects && t < min_t) {
min_t = t
hud.innerHTML += t + "<br>"
var clone = intersect.clone()
clone.t = t
- closest_face = intersecting_face
+ closest_intersect = intersecting_face
closest_intersect = clone
}
})
@@ -185,12 +185,6 @@ function draw () {
ctx.fillStyle = "#00f"
drawPoint(closest_intersect)
drawLine(cursor.x, closest_intersect, "#00f")
- // closest_face.vec
-
- // get the closest intersect, i.e. the one with smallest t value
- // get the angle of the cursor
- // move the desired position to pos - 20px
-
}
}
function drawLine (pa, pb, color, headless) {