summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2014-11-03 12:44:23 -0500
committerJules Laplace <jules@okfoc.us>2014-11-03 12:44:23 -0500
commit6b9cf0e41c4e0c09a715e59c162380b5fad42cba (patch)
tree99bec285665859236b23a2ec5234c7adcce5ac7c
parent4cd1bf2ab9944c1f0782e95b51b0da132909a189 (diff)
different collision algo for mobile movement
-rw-r--r--public/assets/javascripts/rectangles/engine/rooms/mover.js179
-rw-r--r--public/assets/test/intersect3.html19
2 files changed, 147 insertions, 51 deletions
diff --git a/public/assets/javascripts/rectangles/engine/rooms/mover.js b/public/assets/javascripts/rectangles/engine/rooms/mover.js
index 69e821f..5682be8 100644
--- a/public/assets/javascripts/rectangles/engine/rooms/mover.js
+++ b/public/assets/javascripts/rectangles/engine/rooms/mover.js
@@ -5,6 +5,7 @@ Rooms.mover = new function(){
base.noclip = false
var cursor = base.cursor = new Rect (0,0,0,0)
+ var cursor_copy = new Rect (0,0,0,0)
var wall_vec = new Rect (0,0,0,0)
var intersect = new vec2(0,0)
@@ -28,6 +29,7 @@ Rooms.mover = new function(){
}
base.update = function(pos){
+ var intersect, collision, distance
var radius = scene.camera.radius
cam.y = pos.y
@@ -41,23 +43,38 @@ Rooms.mover = new function(){
return
}
- var intersect = base.intersect(pos)
+ distance = sqrt(pow(cam.x-pos.x, 2), pow(cam.z-pos.z, 2))
+
+ // check if we've breached one of the walls.. clamp position if so.
+ // there are two algorithms for this now, ridiculously..
+ // - the first one is smoother, best for keyboard use
+ // but if the distance travelled is greater than the min. distance from the wall,
+ // then there is a possibility of ejection from the room. so is bad for phone/mousewheel.
- if (intersect && ! base.noclip) {
- cam.x = intersect.a
- cam.z = intersect.b
- return
+ // - the second one determines fortuitously if we have breached any of the walls
+ // however it can get jumpy if you run into a wall.. thus it is best for devices like phone or mousewheel
+ // the benefit is you will never leave the room.
+ if (base.noclip) {
+ // in no-clip mode we walk through walls.
}
-/*
- // check if we've breached one of the walls.. clamp position if so
- var collision = base.room.collidesDisc(cam, pos, radius)
+ else if (distance < radius) {
+ collision = base.room.collidesDisc(cam, pos, radius)
+
+ if (collision) {
+ cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x
+ cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z
+ return
+ }
+ }
+ else {
+ intersect = base.intersect(pos)
+ if (intersect) {
+ cam.x = intersect.a
+ cam.z = intersect.b
+ return
+ }
+ }
- if (collision && ! base.noclip) {
- cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x
- 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()
@@ -83,39 +100,30 @@ Rooms.mover = new function(){
}
}
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 closest_intersect, closest_wall, new_t, wall_t, t, min_t = 1
+
+ cursor_copy.x.a = cursor.x.a = cam.x
+ cursor_copy.x.b = cursor.x.b = cam.z
+ cursor_copy.y.a = cursor.y.a = pos.x
+ cursor_copy.y.b = 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)
+ cursor_copy.extend_ends(scene.camera.radius)
+
+ origins.x = cursor_copy.x
+ origins.y = wall_vec.x
Walls.list.forEach(function(wall, i){
- var actually_intersects, intersecting_face
+ var actually_intersects = false, intersecting_face
+
+ wall.get_points(wall_vec)
- 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 )
+ t = perp(origins, wall_vec) / ( perp(cursor_copy, 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
+ intersect.a = cursor_copy.x.a + ( cursor_copy.y.a - cursor_copy.x.a ) * t
+ intersect.b = cursor_copy.x.b + ( cursor_copy.y.b - cursor_copy.x.b ) * t
if ( ! is_collinear( intersect, wall_vec ) ) return
@@ -128,24 +136,76 @@ Rooms.mover = new function(){
actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0)
if (actually_intersects) {
- closest_intersect = intersect.clone()
+ closest_intersect = intersect.clone()
+ closest_wall = wall_vec.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)
+ if (closest_intersect) {
+
+ var aw, len, dd
+ aw = angle(closest_wall)
+ wall_vec.assign(closest_wall)
+ wall_vec.x.a -= scene.camera.radius * sin(aw)
+ wall_vec.x.b += scene.camera.radius * cos(aw)
+ wall_vec.y.a -= scene.camera.radius * sin(aw)
+ wall_vec.y.b += scene.camera.radius * cos(aw)
+
+ origins.x = cursor.x
+ origins.y = wall_vec.x
+
+ new_t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 )
+ wall_t = perp(origins, cursor) / ( perp(wall_vec, cursor) || 0.0000001 )
+
+ intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * new_t
+ intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * new_t
+
+ // here compare len to the length of the wall in the direction we are travelling
+ dd = dot2(diff(closest_wall), diff(cursor))
+ len = sqrt(dot(wall_vec, wall_vec))
+
+ if (dd > 0) {
+ len *= 1-abs(wall_t)
+ }
+ else {
+ len *= abs(wall_t)
+ aw += PI
+ }
+
+ len = clamp(len, 0, (1-min_t) * sqrt(dot(cursor, cursor)))
+
+ intersect.a += len * cos(aw)
+ intersect.b += len * sin(aw)
+
+ wall_vec.normalize()
+ intersect.a = clamp(intersect.a, wall_vec.x.a, wall_vec.y.a)
+ intersect.b = clamp(intersect.b, wall_vec.x.b, wall_vec.y.b)
+
+ return intersect
+ }
+ else {
+ return cursor.y
}
- return closest_intersect
}
+ function diff (v) {
+ return new vec2(v.y.a - v.x.a, v.y.b - v.x.b)
+ }
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 angle2 (pa, pb) {
+ return atan2(pb.b - pa.b, pb.a - pa.a)
+ }
+ function normal (va) {
+ return atan2(va.x.a - va.y.a, va.y.b - va.x.b)
+ }
+ 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 dot2 (pa, pb) {
+ return pa.a * pb.a + pa.b * pb.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)
}
@@ -169,4 +229,27 @@ Rooms.mover = new function(){
return !! (on_x && on_y)
}
+ cursor_copy.extend_ends = function(n){
+ var a = angle(this)
+ this.x.a -= n*cos(a)
+ this.x.b -= n*sin(a)
+ this.y.a += n*cos(a)
+ this.y.b += n*sin(a)
+ return this
+ }
+ wall_vec.normalize = function(){
+ var carry
+ if (this.x.a > this.y.a) {
+ console.log("SWAP X")
+ carry = this.x.a
+ this.x.a = this.y.a
+ this.y.a = carry
+ }
+ if (this.x.b > this.y.b) {
+ console.log("SWAP Y")
+ carry = this.x.b
+ this.x.b = this.y.b
+ this.y.b = carry
+ }
+ }
}
diff --git a/public/assets/test/intersect3.html b/public/assets/test/intersect3.html
index ed81346..5440a76 100644
--- a/public/assets/test/intersect3.html
+++ b/public/assets/test/intersect3.html
@@ -217,8 +217,9 @@ function draw (time) {
end_of_ray.a += len * cos(aw)
end_of_ray.b += len * sin(aw)
-// end_of_ray.a = clamp(end_of_ray.a, wall_vec.x.a, wall_vec.y.a)
-// end_of_ray.b = clamp(end_of_ray.b, wall_vec.x.b, wall_vec.y.b)
+ wall_vec.normalize()
+ end_of_ray.a = clamp(end_of_ray.a, wall_vec.x.a, wall_vec.y.a)
+ end_of_ray.b = clamp(end_of_ray.b, wall_vec.x.b, wall_vec.y.b)
drawPoint(end_of_ray)
drawLine(closest_intersect2, end_of_ray, "#00f")
@@ -295,7 +296,19 @@ cursor.extend_ends = function(n){
clone.y.b += n*sin(a)
return clone
}
-
+wall_vec.normalize = function(){
+ var carry
+ if (this.x.a > this.y.a) {
+ carry = this.x.a
+ this.x.a = this.y.a
+ this.y.a = carry
+ }
+ if (this.x.b > this.y.b) {
+ carry = this.x.b
+ this.x.b = this.y.b
+ this.y.b = carry
+ }
+}
function animate(time){
requestAnimationFrame(animate)
draw(time)