Beispiel #1
0
//Optimized applyCachedImpulse
func (arb *Arbiter) applyCachedImpulse(dt_coef vect.Float) {
	if arb.state == arbiterStateFirstColl && arb.NumContacts > 0 {
		return
	}
	//println("asd")
	a := arb.ShapeA.Body
	b := arb.ShapeB.Body
	var j vect.Vect

	for _, con := range arb.Contacts {
		//transform.RotateVect(con.n, transform.Rotation{con.jnAcc, con.jtAcc})
		j.X = ((con.n.X * con.jnAcc) - (con.n.Y * con.jtAcc)) * dt_coef
		j.Y = ((con.n.X * con.jtAcc) + (con.n.Y * con.jnAcc)) * dt_coef

		//apply_impulses(a, b, con.r1, con.r2, vect.Mult(j, dt_coef))
		a.v.X = (-j.X * a.m_inv) + a.v.X
		a.v.Y = (-j.Y * a.m_inv) + a.v.Y
		a.w += a.i_inv * ((con.r1.X * -j.Y) - (con.r1.Y * -j.X))

		b.v.X = (j.X * b.m_inv) + b.v.X
		b.v.Y = (j.Y * b.m_inv) + b.v.Y

		b.w += b.i_inv * ((con.r2.X * j.Y) - (con.r2.Y * j.X))
	}
}
Beispiel #2
0
/*
Todo: make this an interface.
*/
func (ui *UIText) UpdateCollider() {
	//if ui.GameObject().Physics.Body.Enabled {
	if ui.GameObject().Physics == nil {
		return
	}
	b := ui.GameObject().Physics.Box
	body := ui.GameObject().Physics.Body
	if b != nil {
		h := vect.Float(float64(ui.height) * float64(ui.GameObject().Transform().WorldScale().Y))
		w := vect.Float(float64(ui.width) * float64(ui.GameObject().Transform().WorldScale().X))
		update := false
		if h != b.Height || w != b.Width {
			b.Width = w
			b.Height = h
			update = true
		}

		c := ui.align.Vector()
		center := vect.Vect{vect.Float(c.X), vect.Float(c.Y)}
		center.X = (center.X * w)
		center.Y = (center.Y * h)

		if b.Position.X != center.X || b.Position.Y != center.Y {
			update = true
			b.Position.X, b.Position.Y = center.X, center.Y
		}

		if update {
			b.UpdatePoly()
			if !body.MomentIsInf() && h != 0 && w != 0 {
				body.SetMoment(vect.Float(b.Moment(float32(body.Mass()))))
			}
		}
	}
	//log.Println(b.Height, b.Width, ui.GameObject().Transform().Scale().X, ui.GameObject().Name())
	//}
}
Beispiel #3
0
/*
Todo: make this an interface.
*/
func (sp *Sprite) UpdateShape() {
	if sp.GameObject().Physics != nil {
		ph := sp.GameObject().Physics
		box := ph.Box
		cir := ph.Shape.GetAsCircle()

		scale := sp.Transform().WorldScale()
		ratio := sp.UVs[int(sp.animation)].Ratio
		scale.X *= ratio

		if box != nil {
			update := false
			if vect.Float(scale.Y) != box.Height || vect.Float(scale.X) != box.Width {
				box.Height = vect.Float(scale.Y)
				box.Width = vect.Float(scale.X)
				//box.Position = Vect{box.Width/2, box.Height/2}
				update = true
			}

			c := sp.align.Vector()
			center := vect.Vect{vect.Float(c.X), vect.Float(c.Y)}
			center.X *= vect.Float(scale.X)
			center.Y *= vect.Float(scale.Y)

			if box.Position.X != center.X || box.Position.Y != center.Y {
				update = true
				box.Position.X, box.Position.Y = center.X, center.Y
			}

			if update {
				box.UpdatePoly()
				if !ph.Body.MomentIsInf() && box.Height != 0 && box.Width != 0 {
					ph.Body.SetMoment(vect.Float(box.Moment(float32(ph.Body.Mass()))))
				}
			}
		} else if cir != nil {
			update := false
			s := float32(0)
			if scale.X > scale.Y {
				s = scale.X
			} else {
				s = scale.Y
			}
			if float32(cir.Radius) != s/2 {
				cir.Radius = vect.Float(s / 2)
				update = true
			}

			c := sp.align.Vector()
			center := vect.Vect{vect.Float(c.X), vect.Float(c.Y)}
			center.X *= vect.Float(s)
			center.Y *= vect.Float(s)

			if cir.Position.X != center.X || cir.Position.Y != center.Y {
				update = true
				cir.Position.X, cir.Position.Y = center.X, center.Y
			}

			if update {
				sp.GameObject().Physics.Body.UpdateShapes()
				if !ph.Body.MomentIsInf() && cir.Radius != 0 {
					//log.Println(sp.gameObject.name, cir.Radius, cir.Moment(float32(ph.Body.Mass())), scale.X, scale.Y, ph.Body.Mass(), cir.Position)
					ph.Body.SetMoment(vect.Float(cir.Moment(float32(ph.Body.Mass()))))
				}
			}
		}
	}
}
Beispiel #4
0
//Optimized applyImpulse
func (arb *Arbiter) applyImpulse() {
	a := arb.ShapeA.Body
	b := arb.ShapeB.Body
	vr := vect.Vect{}

	for _, con := range arb.Contacts {
		n := con.n
		r1 := con.r1
		r2 := con.r2

		vr.X = (-r2.Y*b.w + b.v.X) - (-r1.Y*a.w + a.v.X)
		vr.Y = (r2.X*b.w + b.v.Y) - (r1.X*a.w + a.v.Y)

		// Calculate and clamp the bias impulse.
		jbnOld := con.jBias
		con.jBias = jbnOld + (con.bias-(((((-r2.Y*b.w_bias)+b.v_bias.X)-((-r1.Y*a.w_bias)+a.v_bias.X))*n.X)+((((r2.X*b.w_bias)+b.v_bias.Y)-((r1.X*a.w_bias)+a.v_bias.Y))*n.Y)))*con.nMass
		if 0 > con.jBias {
			con.jBias = 0
		}

		// Calculate and clamp the normal impulse.
		jnOld := con.jnAcc
		con.jnAcc = jnOld - (con.bounce+(vr.X*n.X)+(vr.Y*n.Y))*con.nMass
		if 0 > con.jnAcc {
			con.jnAcc = 0
		}

		// Calculate and clamp the friction impulse.
		jtMax := arb.u * con.jnAcc
		jtOld := con.jtAcc
		con.jtAcc = jtOld - (((vr.X+arb.Surface_vr.X)*-n.Y)+((vr.Y+arb.Surface_vr.Y)*n.X))*con.tMass
		if con.jtAcc > jtMax {
			con.jtAcc = jtMax
		} else if con.jtAcc < -jtMax {
			con.jtAcc = -jtMax
		}

		jbnOld = (con.jBias - jbnOld)
		vr.X = n.X * jbnOld
		vr.Y = n.Y * jbnOld

		a.v_bias.X = (-vr.X * a.m_inv) + a.v_bias.X
		a.v_bias.Y = (-vr.Y * a.m_inv) + a.v_bias.Y
		a.w_bias += a.i_inv * ((r1.X * -vr.Y) - (r1.Y * -vr.X))

		b.v_bias.X = (vr.X * b.m_inv) + b.v_bias.X
		b.v_bias.Y = (vr.Y * b.m_inv) + b.v_bias.Y
		b.w_bias += b.i_inv * ((r2.X * vr.Y) - (r2.Y * vr.X))

		jnOld = con.jnAcc - jnOld
		jtOld = con.jtAcc - jtOld

		vr.X = (n.X * jnOld) - (n.Y * jtOld)
		vr.Y = (n.X * jtOld) + (n.Y * jnOld)

		a.v.X = (-vr.X * a.m_inv) + a.v.X
		a.v.Y = (-vr.Y * a.m_inv) + a.v.Y
		a.w += a.i_inv * ((r1.X * -vr.Y) - (r1.Y * -vr.X))

		b.v.X = (vr.X * b.m_inv) + b.v.X
		b.v.Y = (vr.Y * b.m_inv) + b.v.Y

		b.w += b.i_inv * ((r2.X * vr.Y) - (r2.Y * vr.X))
	}
}