func updateCallback(delta float64) { updateObjects(delta) foundContacts, contacts := generateContacts(delta) if foundContacts { cubez.ResolveContacts(len(contacts)*8, contacts, m.Real(delta)) } }
// UpdatePhysics makes sure the physics objects are updated. func (gm *LocalGameManager) UpdatePhysics(frameDelta float32) { if gm.physicsEnabled == false { return } physicsNow := time.Now() physicsDelta := float32(physicsNow.Sub(gm.physicsLastTime).Seconds()) // sync physics to no more than 60 fps if physicsDelta < 1.0/60.0 { return } // conversely, if it's been too long, we just act like nothing happened ... // what's up with that? if physicsDelta > 0.50 { // try again next time to see if we can process the world gm.physicsLastTime = physicsNow groggy.Logsf("INFO", "LGM:UpdatePhycis() had to skip a physics frame due to excessive lag in delta time (%f)", physicsDelta) return } // update the collider in each entity gm.entityManager.Map(func(e *entity.Entity) { if e.Collider != nil { e.RunCollider(physicsDelta) } }) // generate any contacts //groggy.Logsf("DEBUG", "LGM: UpdatePhysics: checking start") var contacts []*physics.Contact gm.entityManager.Map(func(e *entity.Entity) { if e.Collider != nil { // test collisions against other entities // TODO: do better coarse collision detection gm.entityManager.Map(func(otherEnt *entity.Entity) { if e != otherEnt && otherEnt.Collider != nil { //groggy.Logsf("DEBUG", "\tLGM: UpdatePhysics: checking entitys:") //groggy.Logsf("DEBUG", "\t\tentity %d(%s) @ (%v)", e.Id, e.Name, e.Collider.GetTransform()) //groggy.Logsf("DEBUG", "\t\t%v", e.Collider.GetBody()) //groggy.Logsf("DEBUG", "\t\tentity %d(%s) @ (%v)", otherEnt.Id, otherEnt.Name, otherEnt.Collider.GetTransform()) //groggy.Logsf("DEBUG", "\t\t%v", otherEnt.Collider.GetBody()) _, contacts = physics.CheckForCollisions(e.Collider, otherEnt.Collider, contacts) } }) // stop here with the infinite mass, non-movable entities if e.Collider.GetBody().HasFiniteMass() == false { return } // Now check the entity against the landscape chunks // TODO: super lame selections of chunks and very wasteful intX, intZ := int(e.Location[0]), int(e.Location[2]) chunks := gm.landscapeMan.GetChunksFor(intX, intZ) chunks = append(chunks, gm.landscapeMan.GetChunksFor(intX, intZ+1)...) chunks = append(chunks, gm.landscapeMan.GetChunksFor(intX, intZ-1)...) chunks = append(chunks, gm.landscapeMan.GetChunksFor(intX+1, intZ-1)...) chunks = append(chunks, gm.landscapeMan.GetChunksFor(intX-1, intZ-1)...) for _, chunk := range chunks { // check collision against the relevant landscape collisions for _, chunkCollider := range chunk.Colliders { _, contacts = physics.CheckForCollisions(e.Collider, chunkCollider, contacts) } } } }) // resolve the contacts if contacts != nil && len(contacts) > 0 { physics.ResolveContacts(len(contacts)*2, contacts, physmath.Real(physicsDelta)) } gm.physicsLastTime = physicsNow }