Page 1 of 1

Resolve collision function?

Posted: Wed Feb 02, 2022 2:56 pm
by Gunroar:Cannon()
I have a function for checking collisions (cough-bump-cough :ehem: ), but I'm looking for a function to resolve them. I already made a working function but it just includes elasticity and no mass or friction. How would I do this?

Not sure this would be helpful but here's what I have:

Code: Select all

function Entity:resolveCollision(col, notDo)
    self:changeVelocityByCollisionNormal(col.normal.x, col.normal.y, nil, col.other)
    if col.normal.y == -1 then
        if not self.isMini and (not self.isPlayer or (self.isPlayer and self.vy>100)) and not self.isDebris then
                --causes puff on land
                if not self.onGround then
                    if not self.noPuff then--self.vy<-15 then
                        self:createPuff(3,5)
                    end
                    self:playSound("punch1")--getValue({"punch1","punch2","punch3"}))
                end
                self.gravity = 0
                self.vy = 0
                self.onGround = true
            
        end
    else
        --self.onGround = false
    end
    
    if notDo then self:changeVelocityByImpulse(col) end
end

 
function Entity:changeVelocityByImpulse(col)
    
        local other = col.other
        if not other.isTile then-- 
            --push
            local xx, yy = self.vx, other.vx
            local y,x = col.normal.y, col.normal.x
            if y<0 and self.vy>other.vy then
                other:applyImpulseY(self.vy)
            elseif y<0 and self.vy<other.vy then
                self:applyImpulseY(other.vy)
            end
            
            if y>0 and self.vy<other.vy then
                other:applyImpulseY(self.vy)
            elseif y>0 and self.vy>other.vy then
                self:applyImpulseY(other.vy)
            end
            
            if x<0 and self.vx>other.vx then
                other:applyImpulseX(self.vx)
            elseif x<0 and self.vx<other.vx then
                self:applyImpulseX(other.vx)
            end
            
            if x>0 and self.vx<other.vx then
                other:applyImpulseX(self.vx)
            elseif x>0 and self.vx>other.vx then
                self:applyImpulseX(other.vx)
            end
         
end

function Entity:changeVelocityByCollisionNormal(nx, ny, bounciness, other)
  local bounciness = bounciness or self.elasticity
  if other.isCrate or (other.isBlock and other.dynamic)
   or self.isBullet or not bounciness or bounciness == 0 then
      return
  end
  local vx, vy = self.vx, self.vy

  if (nx < 0 and vx > 0) or (nx > 0 and vx < 0) then
    vx = -vx * bounciness
    self.bounced.x = true
  end
  
  if (ny < 0 and vy > 0) or (ny > 0 and vy < 0) then
    vy = -vy * bounciness
    self.bounced.y = true
  end
  
  self.vx, self.vy = vx, vy
end


function Entity:move(x,y)
    local actualX, actualY, collisions, len = self.world:move(self,x,y,
    self.checkCollision)
    local col
    for i = 1, len do
        col = collisions[i]
        self:resolveCollision(col)
    end
    
    return actualX, actualY
end

Re: Resolve collision function

Posted: Wed Feb 02, 2022 3:14 pm
by darkfrei
Round objects or squares?

Re: Resolve collision function?

Posted: Wed Feb 02, 2022 3:19 pm
by Gunroar:Cannon()
Squares as that's what bump (collision lib) supports.

Re: Resolve collision function?

Posted: Wed Feb 02, 2022 3:51 pm
by darkfrei
Gunroar:Cannon() wrote: Wed Feb 02, 2022 3:19 pm Squares as that's what bump (collision lib) supports.
Just reverse one of the speeds, vx vor horizontal bounce and vy vor the vertical one.
Multiply both speeds (vx and vy) by 0.5 for friction.

Re: Resolve collision function?

Posted: Wed Feb 02, 2022 5:05 pm
by Gunroar:Cannon()
Already have bounce. I need things like bounce based on mass and no constant variables so things can have different properties.

Re: Resolve collision function?

Posted: Wed Feb 02, 2022 5:11 pm
by darkfrei
I have this two functions for static and dynamic solutions:

Code: Select all

function pushback (collision)
	local particles = collision.particles
	local b1, b2 = particles[1], particles[2]
	local overlap = collision.overlap
	local nx, ny = collision.nx, collision.ny 
	b1.x = b1.x - nx*overlap
	b2.x = b2.x + nx*overlap
	b1.y = b1.y - ny*overlap
	b2.y = b2.y + ny*overlap
end

Code: Select all

function rollback (collision)
	local particles = collision.particles
	local b1, b2 = particles[1], particles[2]
	local nx, ny = collision.nx, collision.ny -- normal
	local tx, ty = -ny, nx -- tangent
	
	local dptan1 = b1.vx*tx + b1.vy*ty
	local dptan2 = b2.vx*tx + b2.vy*ty
	
	local dpnorm1 = b1.vx*nx + b1.vy*ny
	local dpnorm2 = b2.vx*nx + b2.vy*ny
	
	local m1 = (dpnorm1*(b1.mass-b2.mass)+2*b2.mass*dpnorm2)/(b1.mass+b2.mass)
	local m2 = (dpnorm2*(b2.mass-b1.mass)+2*b1.mass*dpnorm1)/(b1.mass+b2.mass)
	
	b1.vx = tx*dptan1 + nx*m1
	b1.vy = ty*dptan1 + ny*m1
	b2.vx = tx*dptan2 + nx*m2
	b2.vy = ty*dptan2 + ny*m2
end

Re: Resolve collision function?

Posted: Wed Feb 02, 2022 5:51 pm
by Gunroar:Cannon()
darkfrei wrote: Wed Feb 02, 2022 5:11 pm I have this two functions for static and dynamic solutions:

Code: Select all

function pushback (collision)
	local particles = collision.particles
	local b1, b2 = particles[1], particles[2]
	local overlap = collision.overlap
	local nx, ny = collision.nx, collision.ny 
	b1.x = b1.x - nx*overlap
	b2.x = b2.x + nx*overlap
	b1.y = b1.y - ny*overlap
	b2.y = b2.y + ny*overlap
end

Code: Select all

function rollback (collision)
	local particles = collision.particles
	local b1, b2 = particles[1], particles[2]
	local nx, ny = collision.nx, collision.ny -- normal
	local tx, ty = -ny, nx -- tangent
	
	local dptan1 = b1.vx*tx + b1.vy*ty
	local dptan2 = b2.vx*tx + b2.vy*ty
	
	local dpnorm1 = b1.vx*nx + b1.vy*ny
	local dpnorm2 = b2.vx*nx + b2.vy*ny
	
	local m1 = (dpnorm1*(b1.mass-b2.mass)+2*b2.mass*dpnorm2)/(b1.mass+b2.mass)
	local m2 = (dpnorm2*(b2.mass-b1.mass)+2*b1.mass*dpnorm1)/(b1.mass+b2.mass)
	
	b1.vx = tx*dptan1 + nx*m1
	b1.vy = ty*dptan1 + ny*m1
	b2.vx = tx*dptan2 + nx*m2
	b2.vy = ty*dptan2 + ny*m2
end
Hmmm, looks closer to what I want. So rollback is for dynamic? Seems I can't use the first function (becuase I don't want to change position variables directly, only velocity).

But this one seems to be missing friction.

Re: Resolve collision function?

Posted: Wed Feb 02, 2022 6:02 pm
by darkfrei
Gunroar:Cannon() wrote: Wed Feb 02, 2022 5:51 pm But this one seems to be missing friction.
Make the normal twice smaller.

Code: Select all

local nx, ny = collision.nx/2, collision.ny/2 -- normal
local tx, ty = -ny, nx -- tangent

Re: Resolve collision function?

Posted: Thu Feb 03, 2022 12:59 pm
by Gunroar:Cannon()
Ok, I got something inspired of your code. Thanks.