// see if any of the rigid bodys contact func generateContacts(delta float64) (bool, []*cubez.Contact) { var returnFound bool var found bool var contacts []*cubez.Contact for _, cube := range cubes { // see if we have a collision with the ground found, contacts = cube.Collider.CheckAgainstHalfSpace(groundPlane, contacts) if found == true { returnFound = true } // check it against the other cubes. yes this is O(n^2) and not good practice for _, otherCube := range cubes { if cube == otherCube { continue } found, contacts = cubez.CheckForCollisions(cube.Collider, otherCube.Collider, contacts) if found == true { returnFound = true } } } return returnFound, contacts }
// see if any of the rigid bodys contact func generateContacts(delta float64) (bool, []*cubez.Contact) { var returnFound bool // create the ground plane groundPlane := cubez.NewCollisionPlane(m.Vector3{0.0, 1.0, 0.0}, 0.0) // see if we have a collision with the ground found, contacts := cubez.CheckForCollisions(cube.Collider, groundPlane, nil) if found { returnFound = true } // see if there's a collision against the backboard found, contacts = cubez.CheckForCollisions(cube.Collider, backboard.Collider, contacts) if found { returnFound = true } // run collision checks on bullets for _, bullet := range bullets { // check against the ground found, contacts = cubez.CheckForCollisions(bullet.Collider, groundPlane, contacts) if found { returnFound = true } // check against the cube found, contacts = cubez.CheckForCollisions(cube.Collider, bullet.Collider, contacts) if found { returnFound = true } // check against the backboard found, contacts = cubez.CheckForCollisions(backboard.Collider, bullet.Collider, contacts) if found { returnFound = true } // check against other bullets for _, bullet2 := range bullets { if bullet2 == bullet { continue } found, contacts = cubez.CheckForCollisions(bullet2.Collider, bullet.Collider, contacts) if found { returnFound = true } } } return returnFound, contacts }
// 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 }