func newBody(shape Shape) *body { b := &body{} b.shape = shape b.imass = 0 // no mass, static body by default b.friction = 0.5 // good to have some friction b.world = lin.NewT().SetI() // world transform b.guess = lin.NewT().SetI() // predicted world transform // allocate linear and angular motion data b.lvel = lin.NewV3() b.lfor = lin.NewV3() b.avel = lin.NewV3() b.afor = lin.NewV3() b.iitw = lin.NewM3().Set(lin.M3I) b.iit = lin.NewV3() // allocate scratch variables b.coi = &C.BoxBoxInput{} b.cor = &C.BoxBoxResults{} b.m0 = &lin.M3{} b.m1 = &lin.M3{} b.v0 = &lin.V3{} b.t0 = lin.NewT() // create a unique body identifier bodyUuidMutex.Lock() b.bid = bodyUuid if bodyUuid++; bodyUuid == 0 { log.Printf("Overflow: dev error. Unique body id wrapped.") } bodyUuidMutex.Unlock() return b }
// newSolverBody allocates space for body specific solver information. // This is expected to be called for a movable body, ie. one that has mass // and can have velocity. func newSolverBody(bod *body) *solverBody { sb := &solverBody{} sb.oBody = bod // reference sb.world = lin.NewT().Set(bod.world) sb.linearVelocity = lin.NewV3().Set(bod.lvel) sb.angularVelocity = lin.NewV3().Set(bod.avel) sb.deltaLinearVelocity = lin.NewV3() sb.deltaAngularVelocity = lin.NewV3() sb.pushVelocity = lin.NewV3() sb.turnVelocity = lin.NewV3() sb.invMass = lin.NewV3().SetS(bod.imass, bod.imass, bod.imass) sb.t0 = lin.NewT() sb.v0 = lin.NewV3() return sb }
func TestSphereAabb(t *testing.T) { sp := Shape(NewSphere(1)) ab := sp.Aabb(lin.NewT().SetI(), &Abox{}, 0.01) if ab.Sx != -1.01 || ab.Sy != -1.01 || ab.Sz != -1.01 || ab.Lx != 1.01 || ab.Ly != 1.01 || ab.Lz != 1.01 { t.Error("Invalid bounding box for Sphere") } }
func TestBoxAabb(t *testing.T) { bx := Shape(NewBox(1, 1, 1)) ab := bx.Aabb(lin.NewT().SetI(), &Abox{}, 0.01) if ab.Sx != -1.01 || ab.Sy != -1.01 || ab.Sz != -1.01 || ab.Lx != 1.01 || ab.Ly != 1.01 || ab.Lz != 1.01 { t.Error("Invalid bounding box for Box") } }
// fixedSolverBody lazy initializes and returns the single fixed // solver body that is used by all static solver bodies. func fixedSolverBody() *solverBody { if fsb == nil { fsb = &solverBody{} fsb.oBody = nil fsb.world = lin.NewT().SetI() fsb.linearVelocity = lin.NewV3() fsb.angularVelocity = lin.NewV3() fsb.deltaLinearVelocity = lin.NewV3() fsb.deltaAngularVelocity = lin.NewV3() fsb.pushVelocity = lin.NewV3() fsb.turnVelocity = lin.NewV3() fsb.invMass = lin.NewV3() fsb.t0 = lin.NewT() fsb.v0 = lin.NewV3() } return fsb }
// newPov allocates and initialzes a point of view transform. func newPov(eng *engine, eid uint64) *pov { p := &pov{eng: eng, eid: eid, visible: true} p.at = lin.NewT() p.scale = &lin.V3{X: 1, Y: 1, Z: 1} // allocate scratch variables. p.rot = lin.NewQ() p.mm = &lin.M4{} return p }
// newCamera creates a default point of view that is looking down // the positive Z axis. func newCamera() *camera { c := &camera{depth: true} c.vt = VP c.at = lin.NewT() c.vm = &lin.M4{} c.ivm = (&lin.M4{}).Set(lin.M4I) c.pm = &lin.M4{} c.ipm = &lin.M4{} c.q0 = &lin.Q{} c.xrot = lin.NewQ().SetAa(1, 0, 0, 0) c.yrot = lin.NewQ().SetAa(0, 1, 0, 0) c.v0 = &lin.V4{} c.ray = &lin.V3{} return c }
func (b *body) World() *lin.T { if b.world == nil { b.world = lin.NewT().SetI() } return b.world }