Exemplo n.º 1
0
func updateCallback(delta float64) {
	updateObjects(delta)
	foundContacts, contacts := generateContacts(delta)
	if foundContacts {
		cubez.ResolveContacts(len(contacts)*8, contacts, m.Real(delta))
	}
}
Exemplo n.º 2
0
// 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
}