Beispiel #1
0
func fire() {
	var mass m.Real = 1.5
	var radius m.Real = 0.2

	// create a test sphere to render
	bullet := CreateSphere(float32(radius), 16, 16)
	bullet.Shader = colorShader
	bullet.Color = mgl.Vec4{0.2, 0.2, 1.0, 1.0}

	// create the collision box for the the bullet
	bulletCollider := cubez.NewCollisionSphere(nil, radius)
	bulletCollider.Body.Position = m.Vector3{0.0, 1.5, 20.0}

	var cubeInertia m.Matrix3
	var coeff m.Real = 0.4 * mass * radius * radius
	cubeInertia.SetInertiaTensorCoeffs(coeff, coeff, coeff, 0.0, 0.0, 0.0)
	bulletCollider.GetBody().SetInertiaTensor(&cubeInertia)

	bulletCollider.Body.SetMass(mass)
	bulletCollider.Body.Velocity = m.Vector3{0.0, 0.0, -40.0}
	bulletCollider.Body.Acceleration = m.Vector3{0.0, -2.5, 0.0}

	bulletCollider.Body.CalculateDerivedData()
	bulletCollider.CalculateDerivedData()

	e := NewEntity(bullet, bulletCollider)
	bullets = append(bullets, e)
}
Beispiel #2
0
func fire() {
	const cubesToMake = 4
	var offset float32 = 0.0
	if len(cubes) > 0 && (len(cubes)/cubesToMake)%2 >= 1 {
		offset = 0.75
	}

	for i := 0; i < cubesToMake; i++ {
		e := new(Entity)
		e.Node = CreateCube(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5)
		e.Node.Shader = diffuseShader
		e.Node.Color = mgl.Vec4{1.0, 1.0, 1.0, 1.0}
		e.Node.Location = mgl.Vec3{float32(i*2.0-cubesToMake/2) - 0.5 + offset, 10.0, 0.0}
		e.Node.Tex0 = crateTexture

		// create the collision box for the the cube
		cubeCollider := cubez.NewCollisionCube(nil, m.Vector3{0.5, 0.5, 0.5})
		cubeCollider.Body.Position = m.Vector3{m.Real(i*2.0-cubesToMake/2) - 0.5 + m.Real(offset), 10.0, 0.0}
		cubeCollider.Body.SetMass(8.0)
		cubeCollider.Body.CanSleep = true

		var cubeInertia m.Matrix3
		cubeInertia.SetBlockInertiaTensor(&cubeCollider.HalfSize, 8.0)
		cubeCollider.Body.SetInertiaTensor(&cubeInertia)

		cubeCollider.Body.CalculateDerivedData()
		cubeCollider.CalculateDerivedData()
		e.Collider = cubeCollider

		cubes = append(cubes, e)
	}
}
Beispiel #3
0
// calculateFrictionImpulse calculates the impulse needed to resolve this contact,
// given that the contact has a non-zero coefficient of friction.
func (c *Contact) calculateFrictionImpulse(inverseInertiaTensors [2]m.Matrix3) (impulseContact m.Vector3) {
	inverseMass := c.Bodies[0].GetInverseMass()

	// the equivalent of a cross product in matrices is multiplication
	// by a skew symmetric matrix - we build the matrix for converting
	// between linear and angular quantities.
	var impulseToTorque m.Matrix3
	setSkewSymmetric(&impulseToTorque, &c.relativeContactPosition[0])

	// build the matrix to convert contact impulse to change in velocity in
	// world coordinates
	deltaVelWorld := impulseToTorque.MulMatrix3(&inverseInertiaTensors[0])
	deltaVelWorld = deltaVelWorld.MulMatrix3(&impulseToTorque)
	deltaVelWorld.MulWith(-1.0)

	// check to see if we need to add the second body's data
	if c.Bodies[1] != nil {
		// set the cross product matrix
		setSkewSymmetric(&impulseToTorque, &c.relativeContactPosition[1])

		// calculate the velocity change matrix
		deltaVelWorld2 := impulseToTorque.MulMatrix3(&inverseInertiaTensors[1])
		deltaVelWorld2 = deltaVelWorld2.MulMatrix3(&impulseToTorque)
		deltaVelWorld2.MulWith(-1.0)

		// add to the total delta velocity
		deltaVelWorld.Add(&deltaVelWorld2)

		// add to the inverse mass
		inverseMass += c.Bodies[1].GetInverseMass()
	}

	// do a change of basis to convert into contact coordinates
	deltaVelocity := c.contactToWorld.Transpose()
	deltaVelocity = deltaVelocity.MulMatrix3(&deltaVelWorld)
	deltaVelocity = deltaVelocity.MulMatrix3(&c.contactToWorld)

	// add in the linear velocity change
	deltaVelocity[0] += inverseMass
	deltaVelocity[4] += inverseMass
	deltaVelocity[8] += inverseMass

	// invert to get the impulse needed per unit velocity
	impulseMatrix := deltaVelocity.Invert()

	// find the target velocities to kill
	velKill := m.Vector3{
		c.desiredDeltaVelocity,
		-c.contactVelocity[1],
		-c.contactVelocity[2],
	}

	// find the impulse to kill target velocities
	impulseContact = impulseMatrix.MulVector3(&velKill)

	// check for exceeding friction
	planarImpulse := m.RealSqrt(impulseContact[1]*impulseContact[1] + impulseContact[2]*impulseContact[2])
	if planarImpulse > impulseContact[0]*c.Friction {
		// we need to use dynamic friction
		impulseContact[1] /= planarImpulse
		impulseContact[2] /= planarImpulse

		impulseContact[0] = deltaVelocity[0] +
			deltaVelocity[3]*c.Friction*impulseContact[1] +
			deltaVelocity[6]*c.Friction*impulseContact[2]
		impulseContact[0] = c.desiredDeltaVelocity / impulseContact[0]
		impulseContact[1] *= c.Friction * impulseContact[0]
		impulseContact[2] *= c.Friction * impulseContact[0]
	}

	return
}
Beispiel #4
0
func main() {
	app = NewApp()
	app.InitGraphics("Ballistic", 800, 600)
	app.SetKeyCallback(keyCallback)
	app.OnRender = renderCallback
	app.OnUpdate = updateCallback
	defer app.Terminate()

	// compile the shaders
	var err error
	colorShader, err = LoadShaderProgram(DiffuseColorVertShader, DiffuseColorFragShader)
	if err != nil {
		panic("Failed to compile the shader! " + err.Error())
	}

	// create the ground plane
	groundPlane = cubez.NewCollisionPlane(m.Vector3{0.0, 1.0, 0.0}, 0.0)

	// make a ground plane to draw
	ground = CreatePlaneXZ(-500.0, 500.0, 500.0, -500.0, 1.0)
	ground.Shader = colorShader
	ground.Color = mgl.Vec4{0.6, 0.6, 0.6, 1.0}

	// create a test cube to render
	cubeNode := CreateCube(-1.0, -1.0, -1.0, 1.0, 1.0, 1.0)
	cubeNode.Shader = colorShader
	cubeNode.Color = mgl.Vec4{1.0, 0.0, 0.0, 1.0}

	// create the collision box for the the cube
	var cubeMass m.Real = 8.0
	var cubeInertia m.Matrix3
	cubeCollider := cubez.NewCollisionCube(nil, m.Vector3{1.0, 1.0, 1.0})
	cubeCollider.Body.Position = m.Vector3{0.0, 5.0, 0.0}
	cubeCollider.Body.SetMass(cubeMass)
	cubeInertia.SetBlockInertiaTensor(&cubeCollider.HalfSize, cubeMass)
	cubeCollider.Body.SetInertiaTensor(&cubeInertia)
	cubeCollider.Body.CalculateDerivedData()
	cubeCollider.CalculateDerivedData()

	// make the entity out of the renerable and collider
	cube = NewEntity(cubeNode, cubeCollider)

	// make a slice of entities for bullets
	bullets = make([]*Entity, 0, 16)

	// make the backboard to bound the bullets off of
	backboardNode := CreateCube(-0.5, -2.0, -0.25, 0.5, 2.0, 0.25)
	backboardNode.Shader = colorShader
	backboardNode.Color = mgl.Vec4{0.25, 0.2, 0.2, 1.0}
	backboardCollider := cubez.NewCollisionCube(nil, m.Vector3{0.5, 2.0, 0.25})
	backboardCollider.Body.Position = m.Vector3{0.0, 2.0, -10.0}
	backboardCollider.Body.SetInfiniteMass()
	backboardCollider.Body.CalculateDerivedData()
	backboardCollider.CalculateDerivedData()
	SetGlVector3(&backboardNode.Location, &backboardCollider.Body.Position)

	// make the backboard entity
	backboard = NewEntity(backboardNode, backboardCollider)

	// setup the camera
	app.CameraPos = mgl.Vec3{-3.0, 3.0, 15.0}
	app.CameraRotation = mgl.QuatLookAtV(
		mgl.Vec3{-3.0, 3.0, 15.0},
		mgl.Vec3{0.0, 1.0, 0.0},
		mgl.Vec3{0.0, 1.0, 0.0})

	gl.Enable(gl.DEPTH_TEST)
	app.RenderLoop()
}
Beispiel #5
0
// SetInertiaTensor sets the InverseInertiaTensor member of the RigidBody
// by calculating the inverse of the matrix supplied.
func (body *RigidBody) SetInertiaTensor(m *m.Matrix3) {
	body.InverseInertiaTensor = m.Invert()
}