Пример #1
0
func (b *body) setMaterial(mass, bounciness float64) *body {
	b.imass = 0 // static unless there is mass.
	if !lin.AeqZ(mass) {
		b.imass = 1.0 / mass                 // only need inverse mass
		b.iit = b.shape.Inertia(mass, b.iit) // shape inertia
		if lin.AeqZ(b.iit.X) {               // inverse shape inertia
			b.iit.X = 0
		} else {
			b.iit.X = 1.0 / b.iit.X
		}
		if lin.AeqZ(b.iit.Y) {
			b.iit.Y = 0
		} else {
			b.iit.Y = 1.0 / b.iit.Y
		}
		if lin.AeqZ(b.iit.Z) {
			b.iit.Z = 0
		} else {
			b.iit.Z = 1.0 / b.iit.Z
		}
	}
	b.restitution = bounciness
	b.movable = b.imass != 0
	return b
}
Пример #2
0
// castRayPlane calculates the point of collision between ray:a and
// plane:b. The contact point is returned if there is an intersection.
func castRayPlane(a, b Body) (hit bool, x, y, z float64) {
	sa, sb := a.Shape().(*ray), b.Shape().(*plane)
	la, lb := a.World().Loc, b.World().Loc
	rdir := b.(*body).v0.SetS(sa.dx, sa.dy, sa.dz).Unit() // ray direction.
	nrm := a.(*body).v0.SetS(sb.nx, sb.ny, sb.nz).Unit()  // plane normal.
	nrm.MultQ(nrm, b.World().Rot)                         // apply world spin to plane normal.
	denom := rdir.Dot(nrm)
	if lin.AeqZ(denom) || denom < 0 {
		return false, 0, 0, 0 // plane is behind ray or ray is parallel to plane.
	}

	// calculate the difference from a point on the plane to the ray origin.
	dx, dy, dz := rdir.X, rdir.Y, rdir.Z
	diff := b.(*body).v0.SetS(lb.X-la.X, lb.Y-la.Y, lb.Z-la.Z)
	dlen := diff.Dot(nrm) / denom
	if dlen < 0 {
		return false, 0, 0, 0
	}

	// Get contact point by scaling the ray direction with the contact distance
	// and adding the ray origin.
	x, y, z = dx*dlen+la.X, dy*dlen+la.Y, dz*dlen+la.Z
	return true, x, y, z
}