SHARE
TWEET

Untitled

a guest Aug 19th, 2019 76 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'use strict';
  2.  
  3.  
  4. const minMaxProjection = (axis, object) => {
  5.     let minPr, maxPr;
  6.     minPr = maxPr = object.vertices[0].vectorProjection(axis);
  7.     for (let i = 1; i < 4; i++) {
  8.         let projection = object.vertices[i].vectorProjection(axis);
  9.         if (projection > maxPr) {
  10.             maxPr = projection;
  11.         } else if (projection < minPr) {
  12.             minPr = projection;
  13.         }
  14.     }
  15.     return {
  16.         min: minPr,
  17.         max: maxPr
  18.     };
  19. };
  20.  
  21. const overlap = (pr1, pr2) => {
  22.     let max, min;
  23.  
  24.     if (pr1.max < pr2.max) {
  25.         max = pr1.max;
  26.         min = pr2.min;
  27.     } else {
  28.         max = pr2.max;
  29.         min = pr1.min;
  30.     }
  31.     return min - max;
  32. };
  33.  
  34. const AABBvsCircle=(object,obstacle)=> {
  35.     let axis = obstacle.centre.sub(object.centre, new Vector2d());
  36.     let thisProjection = minMaxProjection(axis, object);
  37.  
  38.     let centreProjection = obstacle.centre.vectorProjection(axis);
  39.  
  40.     let struct = {
  41.         min: centreProjection - obstacle.radius,
  42.         max: centreProjection + obstacle.radius
  43.     };
  44.  
  45.     let depth;
  46.  
  47.     if ((depth = overlap(thisProjection, struct)) < 0) {
  48.         return new Collision(axis.normalize().mul(depth), obstacle);
  49.     }
  50.     return null
  51. }
  52.  
  53. const getCollision=(objectCommon,obstacleCommon)=>{
  54.     let object,obstacle
  55.  
  56.     if (objectCommon instanceof Hitbox ){
  57.         object=objectCommon.hitbox
  58.     }else if (objectCommon instanceof AABB || CircleHitbox){
  59.         object=objectCommon
  60.     }
  61.  
  62.     if (obstacleCommon instanceof Hitbox ){
  63.         obstacle=obstacleCommon.hitbox
  64.     }else if (obstacleCommon instanceof AABB || CircleHitbox){
  65.         obstacle=obstacleCommon
  66.     }
  67.  
  68.     if (object instanceof AABB) {
  69.         if (obstacle instanceof AABB) {
  70.             return object.getCollision(obstacle)
  71.         }else if (obstacle instanceof CircleHitbox){
  72.             return AABBvsCircle(object,obstacle)
  73.         }
  74.     }else if (object instanceof CircleHitbox){
  75.         if (obstacle instanceof AABB){
  76.             let collision=AABBvsCircle(obstacle,object)
  77.             if (collision){
  78.                 collision.distance.mul(-1)
  79.                 collision.obstacle=obstacle
  80.             }
  81.         return collision
  82.         }else if (obstacle instanceof CircleHitbox){
  83.             return object.getCollision(obstacle)
  84.         }
  85.     }
  86.     return null
  87. }
  88.  
  89. class AABB {
  90.     constructor(centre,vertices,id=Game.getUniqId()){
  91.         this.centre=centre;
  92.         this.vertices=vertices;
  93.         let firstSide=this.vertices[1].sub(this.vertices[0],new Vector2d());
  94.         let secondSide=this.vertices[2].sub(this.vertices[1],new Vector2d());
  95.         this.firstAxis=firstSide.normal();
  96.         this.secondAxis=secondSide.normal();
  97.         this.id=id;
  98.     }
  99.  
  100.     getCollision(obstacle) {
  101.         let thisPr1 = minMaxProjection(this.firstAxis, this);
  102.         let thisPr2 = minMaxProjection(this.secondAxis, this);
  103.         let objPr1 = minMaxProjection(this.firstAxis, obstacle);
  104.         let objPr2 = minMaxProjection(this.secondAxis, obstacle);
  105.  
  106.         let secThisPr1 = minMaxProjection(obstacle.firstAxis, this);
  107.         let secThisPr2 = minMaxProjection(obstacle.secondAxis, this);
  108.         let secObjPr1 = minMaxProjection(obstacle.firstAxis, obstacle);
  109.         let secObjPr2 = minMaxProjection(obstacle.secondAxis, obstacle);
  110.  
  111.         let dx, dy, dX, dY;
  112.  
  113.         if ((dx = overlap(thisPr1, objPr1)) < 0 && (dy = overlap(thisPr2, objPr2)) < 0
  114.             && (dX = overlap(secThisPr1, secObjPr1)) < 0 && (dY = overlap(secThisPr2, secObjPr2)) < 0) {
  115.  
  116.             const getMin = (dx, dy, firstAxis, secondAxis) => {
  117.                 let depth, axis;
  118.                 if (dx < dy) {
  119.                     depth = dy;
  120.                     axis = new Vector2d(secondAxis);
  121.                 } else {
  122.                     depth = dx;
  123.                     axis = new Vector2d(firstAxis);
  124.                 }
  125.                 return {
  126.                     depth: depth,
  127.                     axis: axis
  128.                 };
  129.             };
  130.  
  131.             let thisMin = getMin(dx, dy, this.firstAxis, this.secondAxis);
  132.             let objMin = getMin(dX, dY, obstacle.firstAxis, obstacle.secondAxis);
  133.             let res = getMin(thisMin.depth, objMin.depth, thisMin.axis, objMin.axis);
  134.  
  135.             let centre_to_centre = obstacle.centre.sub(this.centre, new Vector2d());
  136.  
  137.             if (centre_to_centre.vectorProjection(res.axis) < 0) res.axis.mul(-1);
  138.  
  139.             return new Collision(res.axis.normalize().mul(res.depth), obstacle);
  140.         }
  141.         return null
  142.     }
  143.  
  144.     changePosition(newCentre){
  145.         let delta=newCentre.sub(this.centre,new Vector2d());
  146.         this.centre.set(newCentre);
  147.         for (let vertex of this.vertices){
  148.             vertex.add(delta);
  149.         }
  150.     }
  151.  
  152.     correctPosition(collision){
  153.         this.changePosition(this.centre.add(collision.distance,new Vector2d()));
  154.     }
  155.  
  156.     getMinMax(x_or_y){
  157.         let min,max;
  158.         min=max=this.vertices[0][x_or_y];
  159.         for (let i=1;i<4;i++){
  160.             if (this.vertices[i][x_or_y]>max){
  161.                 max=this.vertices[i][x_or_y]
  162.             }
  163.             if (this.vertices[i][x_or_y]<min){
  164.                 min=this.vertices[i][x_or_y];
  165.             }
  166.         }
  167.         return {
  168.             max:max,
  169.             min:min
  170.         }
  171.     }
  172.  
  173.     /**
  174.      * @param {AABB} object
  175.      * @return {boolean}
  176.      */
  177.     equals(object){
  178.         return object instanceof AABB && this.id===object.id;
  179.     }
  180.  
  181.     setId(id){
  182.         this.id=id;
  183.         return this;
  184.     }
  185. }
  186.  
  187. class CircleHitbox {
  188.     constructor(centre,radius,id=Game.getUniqId()){
  189.         this.radius=radius;
  190.         this.centre=centre;
  191.         this.id=id;
  192.     }
  193.  
  194.     getCollision(obstacle) {
  195.         let axis = this.centre.sub(obstacle.centre, new Vector2d());
  196.         let dist = axis.length();
  197.         if (this.radius + obstacle.radius > dist) {
  198.             return new Collision(axis.normalize().mul(obstacle.radius + this.radius - dist), obstacle);
  199.         }
  200.         return null;
  201.     }
  202.  
  203.     changePosition(newCentre){
  204.         this.centre.set(newCentre);
  205.     }
  206.     correctPosition(collision){
  207.         this.changePosition(this.centre.add(collision.distance,new Vector2d()));
  208.     }
  209.  
  210.     getMinMax(x_or_y){
  211.         return {
  212.             max:this.centre[x_or_y]+this.radius,
  213.             min:this.centre[x_or_y]-this.radius
  214.         }
  215.     }
  216.  
  217.     /**
  218.      * @param {CircleHitbox} object
  219.      * @return {boolean}
  220.      */
  221.     equals(object){
  222.         return object instanceof CircleHitbox
  223.             && this.id===object.id;
  224.     }
  225.  
  226.     setId(id){
  227.         this.id=id;
  228.         return this;
  229.     }
  230. }
  231.  
  232. class Collision{
  233.     constructor(dist,obstacle){
  234.         this.distance=dist
  235.         this.obstacle=obstacle
  236.     }
  237. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top