cubez

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2016 License: BSD-2-Clause Imports: 2 Imported by: 0

README

Cubez v0.1.0

Cubez is a 3d physics library written in the Go programming language. It is mostly a port of cyclone-physics by Ian Millington and using his book "Game Physics Engine Design" as a reference.

Current Features

  • Full 3d rigid body real-time physics simulation suitable for games; meaning both linear velocity as well as angular velocity are calculated.
  • Collision detection between collider primitives.
  • Primitives supported: planes, spheres, cubes.
  • Math library defaults to 64-bit floats but can easily be tuned down to 32-bit.

Examples

Ballistic: shoot spheres at a cube by pressing the space bar.

ballistic

Cubedrop: hit the space bar to drop some cubes onto the ground

cubedrop

OS Support

Cubez is known to work on the following:

  • Windows 7 x64 with mingw-w64 (see this tutorial if necessary)
  • Linux (Ubuntu 14.04)

At present, I suspect it should work on any Windows or Linux 64-bit system for which there is an acceptable Go x64 and gcc x64 compiler set available.

Support for 32-bit systems is untested.

Dependencies

The only dependency on the core cubez package is the math package included in cubez.

For the examples, you will need GLFW 3.1.x installed on your system, and you will need to install the go-gl project's gl, glfw and mathgl libraries. Your system will also need to be OpenGL 3.3 capable.

The examples use a basic OpenGL framework-in-a-file inspired by my graphics engine called fizzle. This way the full fizzle library is not a dependency.

Installation

If you don't have the dependencies for the examples and wish to install them, you can do so with the following commands:

go get github.com/go-gl/gl/v3.3-core/gl
go get github.com/go-gl/mathgl/mgl32
go get github.com/go-gl/glfw/v3.1/glfw

The library itself can be installed with the following command:

go get github.com/tbogdala/cubez

To build the examples, run the following in a shell:

 cd $GOPATH/src/github.com/tbogdala/cubez/examples
./build.sh

Documentation

Currently, you'll have to use godoc to read the API documentation and check out the examples to figure out how to use the library.

Known Limitations

  • slim down the public interface to the library to only export what's needed
  • introduce a way to set the restitution and friction for contacts

Roadmap

  • more benchmarks
  • unit tests for collisions
  • more collision primitives
  • include some coarse collision detection to ease the O(n^2) pain with resolving contacts in one big slice

License

Cubez is released under the BSD license. See the LICENSE file for more details.

Release History

No tagged releases yet.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ResolveContacts

func ResolveContacts(maxIterations int, contacts []*Contact, duration m.Real)

ResolveContacts results a set of contacts for both penetration and velocity.

NOTE: Contacts that cannot interact with each other should be passed to separate calls of ResolveContacts for performance reasons.

Types

type Collider

type Collider interface {
	Clone() Collider
	CalculateDerivedData()
	GetBody() *RigidBody
	GetTransform() m.Matrix3x4
	CheckAgainstHalfSpace(plane *CollisionPlane, existingContacts []*Contact) (bool, []*Contact)
	CheckAgainstSphere(sphere *CollisionSphere, existingContacts []*Contact) (bool, []*Contact)
	CheckAgainstCube(secondCube *CollisionCube, existingContacts []*Contact) (bool, []*Contact)
}

Collider is an interface for collision primitive objects to make calculating collisions amongst a heterogenous set of objects easier.

This interface can be used in conjuection with CheckForCollisions() to check for collision between two primitives without having to switch on types in client code.

type CollisionCube

type CollisionCube struct {
	// Body is the RigidBody that is represented by this collision object.
	Body *RigidBody

	// Offset is the matrix that gives the offset of this primitive from Body.
	Offset m.Matrix3x4

	// Halfsize holds the cube's half-sizes along each of its local axes.
	HalfSize m.Vector3
	// contains filtered or unexported fields
}

CollisionCube is a rigid body that can be considered an axis-alligned cube for contact collision.

func NewCollisionCube

func NewCollisionCube(optBody *RigidBody, halfSize m.Vector3) *CollisionCube

NewCollisionCube creates a new CollisionCube object with the dimensions specified for a given RigidBody. If a RigidBody is not specified, then a new RigidBody object is created for the new collider object.

func (*CollisionCube) CalculateDerivedData

func (cube *CollisionCube) CalculateDerivedData()

CalculateDerivedData internal data from public data members.

Constructs a transform matrix based on the RigidBody's transform and the collision object's offset.

func (*CollisionCube) CheckAgainstCube

func (cube *CollisionCube) CheckAgainstCube(secondCube *CollisionCube, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstCube checks for collisions against another cube.

func (*CollisionCube) CheckAgainstHalfSpace

func (cube *CollisionCube) CheckAgainstHalfSpace(plane *CollisionPlane, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstHalfSpace does a collision test on a collision box and a plane representing a half-space (i.e. the normal of the plane points out of the half-space).

func (*CollisionCube) CheckAgainstSphere

func (cube *CollisionCube) CheckAgainstSphere(sphere *CollisionSphere, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstSphere checks the cube against a sphere to see if there's a collision.

func (*CollisionCube) Clone

func (cube *CollisionCube) Clone() Collider

Clone makes a new copy of the CollisionCube object

func (*CollisionCube) GetBody

func (cube *CollisionCube) GetBody() *RigidBody

GetBody returns the rigid body associated with the cube.

func (*CollisionCube) GetTransform

func (cube *CollisionCube) GetTransform() m.Matrix3x4

GetTransform returns a copy of the transform matrix for the collider object.

type CollisionPlane

type CollisionPlane struct {
	// Normal is the plane's normal vector
	Normal m.Vector3

	// Offset is the distance of the plane from the origin
	Offset m.Real
}

CollisionPlane represents a plane in space for collisions but doesn't have an associated rigid body and is considered to be infinite. It's primarily useful for rerepresenting immovable world geometry like a giant ground plane.

func NewCollisionPlane

func NewCollisionPlane(n m.Vector3, o m.Real) *CollisionPlane

NewCollisionPlane creates a new CollisionPlane object with the normal and offset specified.

func (*CollisionPlane) CalculateDerivedData

func (p *CollisionPlane) CalculateDerivedData()

CalculateDerivedData currently doesn't do anything for planes.

func (*CollisionPlane) CheckAgainstCube

func (p *CollisionPlane) CheckAgainstCube(cube *CollisionCube, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstCube checks for collisions against a cube.

func (*CollisionPlane) CheckAgainstHalfSpace

func (p *CollisionPlane) CheckAgainstHalfSpace(plane *CollisionPlane, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstHalfSpace doesn't return collisions against another plane, so this implementation is empty.

func (*CollisionPlane) CheckAgainstSphere

func (p *CollisionPlane) CheckAgainstSphere(sphere *CollisionSphere, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstSphere checks for collisions against a sphere.

func (*CollisionPlane) Clone

func (p *CollisionPlane) Clone() Collider

Clone makes a new copy of the CollisionPlane object

func (*CollisionPlane) GetBody

func (p *CollisionPlane) GetBody() *RigidBody

GetBody returns nil since the plane doesn't have a rigid body associated with it

func (*CollisionPlane) GetTransform

func (p *CollisionPlane) GetTransform() m.Matrix3x4

GetTransform returns an identity transform since the collision plane doesn't use transform matrixes.

type CollisionSphere

type CollisionSphere struct {
	// Body is the RigidBody that is represented by this collision object.
	Body *RigidBody

	// Offset is the matrix that gives the offset of this primitive from Body.
	Offset m.Matrix3x4

	// Radius is the radius of the sphere.
	Radius m.Real
	// contains filtered or unexported fields
}

CollisionSphere is a rigid body that can be considered a sphere for collision detection.

func NewCollisionSphere

func NewCollisionSphere(optBody *RigidBody, radius m.Real) *CollisionSphere

NewCollisionSphere creates a new CollisionSphere object with the radius specified for a given RigidBody. If a RigidBody is not specified, then a new RigidBody object is created for the new collider object.

func (*CollisionSphere) CalculateDerivedData

func (s *CollisionSphere) CalculateDerivedData()

CalculateDerivedData internal data from public data members.

Constructs a transform matrix based on the RigidBody's transform and the collision object's offset.

func (*CollisionSphere) CheckAgainstCube

func (s *CollisionSphere) CheckAgainstCube(cube *CollisionCube, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstCube checks the sphere against collision with a cube.

func (*CollisionSphere) CheckAgainstHalfSpace

func (s *CollisionSphere) CheckAgainstHalfSpace(plane *CollisionPlane, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstHalfSpace does a collision test on a collision sphere and a plane representing a half-space (i.e. the normal of the plane points out of the half-space).

func (*CollisionSphere) CheckAgainstSphere

func (s *CollisionSphere) CheckAgainstSphere(secondSphere *CollisionSphere, existingContacts []*Contact) (bool, []*Contact)

CheckAgainstSphere checks the sphere against collision with another sphere.

func (*CollisionSphere) Clone

func (s *CollisionSphere) Clone() Collider

Clone makes a new copy of the CollisionSphere object

func (*CollisionSphere) GetBody

func (s *CollisionSphere) GetBody() *RigidBody

GetBody returns the rigid body associated with the sphere.

func (*CollisionSphere) GetTransform

func (s *CollisionSphere) GetTransform() m.Matrix3x4

GetTransform returns a copy of the transform matrix for the collider object.

type Contact

type Contact struct {
	// Bodies holds 1 or 2 bodies involved in the contact; second body can be nil
	Bodies [2]*RigidBody

	// Friction holds the lateral friction coefficient at the contact
	Friction m.Real

	// Restitution holdes the normal restitution coefficient at the contact
	Restitution m.Real

	// ContactPoint is the position of the contact in World Space
	ContactPoint m.Vector3

	// ContactNormal is the direction of the contact in World Space
	ContactNormal m.Vector3

	// Penetration is the depth of penetration at the contact point. If
	// both Bodies are set, then this should be midway between the
	// inter-penetrating points.
	Penetration m.Real
	// contains filtered or unexported fields
}

Contact holds all of the data associated with a contact between two collider primitives.

func CheckForCollisions

func CheckForCollisions(one Collider, two Collider, existingContacts []*Contact) (bool, []*Contact)

CheckForCollisions will check one collider primitive against another and update the contact slice if there were any contacts (as well as returning a bool indicating if contacts were found).

func NewContact

func NewContact() *Contact

NewContact returns a new Contact object.

type RigidBody

type RigidBody struct {
	// LinearDamping holds the amount of damping applied to the linear motion
	// of the RigidBody. This is required to remove energy that might get
	// added due to the numerical instability of floating point operations.
	LinearDamping m.Real

	// AngularDamping holds the amount of damping applied to angular modtion
	// of the RigidBody. Damping is required to remove energy added through
	// numerical instability in the integrator.
	AngularDamping m.Real

	// Position is the position of the RigidBody in World Space.
	Position m.Vector3

	// Orientation is the angular orientation of the RigidBody.
	Orientation m.Quat

	// Velocity is the linear velocity of the RigidBody in World Space.
	Velocity m.Vector3

	// Acceleration is the acceleration of the RigidBody and can be
	// used to set acceleration due to gravity or any other constant
	// acceleration desired.
	Acceleration m.Vector3

	// Rotation holds the angular velocity, or rotation, of the rigid body in World Space.
	Rotation m.Vector3

	// InverseInertiaTensor holds the inverse of the rigid body's inertia tensor.
	// The inertia tensor provided must not be degenerate (that would mean the
	// body had zero inertia for spinning along one axis). As long as the tensor
	// is finite, it will be invertible. The inverse tensor is used for similar
	// reasons to the use of the inverse mass.
	// NOTE: this is given in Body Space.
	InverseInertiaTensor m.Matrix3

	// IsAwake indicates if the RigidBody is awake and should be updated
	// upon integration.
	// Defaults to true.
	IsAwake bool

	// CanSleep indicates if the RigidBody is allowed to 'sleep' or
	// if it should always be awake.
	// Defaults to true.
	CanSleep bool
	// contains filtered or unexported fields
}

RigidBody is the main data structure represending an object that can cause collisions and move around in the physics simulation.

func NewRigidBody

func NewRigidBody() *RigidBody

NewRigidBody creates a new RigidBody object and returns it.

func (*RigidBody) AddRotation

func (body *RigidBody) AddRotation(v *m.Vector3)

AddRotation adds the vector to the RigidBody's Rotation property.

func (*RigidBody) AddVelocity

func (body *RigidBody) AddVelocity(v *m.Vector3)

AddVelocity adds the vector to the RigidBody's Velocity property.

func (*RigidBody) CalculateDerivedData

func (body *RigidBody) CalculateDerivedData()

CalculateDerivedData internal data from public data members.

NOTE: This should be called after the RigidBody's state is alterted directly by client code; it is called automatically during integration.

Particularly, call this after modifying:

Position, Orientation

func (*RigidBody) ClearAccumulators

func (body *RigidBody) ClearAccumulators()

ClearAccumulators resets all of the stored linear and torque forces stored in the body.

func (*RigidBody) Clone

func (body *RigidBody) Clone() *RigidBody

Clone makes a new RigidBody object with the current data of the RigidBody this is called on.

func (*RigidBody) GetInverseInertiaTensorWorld

func (body *RigidBody) GetInverseInertiaTensorWorld() m.Matrix3

GetInverseInertiaTensorWorld returns a copy of the RigidBody's inverse inertia tensor in World Space.

func (*RigidBody) GetInverseMass

func (body *RigidBody) GetInverseMass() m.Real

GetInverseMass gets the inverse mass of the RigidBody object.

func (*RigidBody) GetLastFrameAccelleration

func (body *RigidBody) GetLastFrameAccelleration() m.Vector3

GetLastFrameAccelleration returns a copy of the RigidBody's linear accelleration for the last frame.

func (*RigidBody) GetMass

func (body *RigidBody) GetMass() m.Real

GetMass gets the mass of the RigidBody object.

func (*RigidBody) GetTransform

func (body *RigidBody) GetTransform() m.Matrix3x4

GetTransform returns a copy of the RigidBody's calculated transform matrix

func (*RigidBody) HasFiniteMass

func (body *RigidBody) HasFiniteMass() bool

HasFiniteMass returns true if the RigidBody has a finite mass (not infinite).

func (*RigidBody) Integrate

func (body *RigidBody) Integrate(duration m.Real)

Integrate takes all of the forces accumulated in the RigidBody and change the Position and Orientation of the object.

func (*RigidBody) SetAwake

func (body *RigidBody) SetAwake(awake bool)

SetAwake sets the IsAwake property of the RigidBody. NOTE: this function doesn't respect CanSleep.

func (*RigidBody) SetInertiaTensor

func (body *RigidBody) SetInertiaTensor(m *m.Matrix3)

SetInertiaTensor sets the InverseInertiaTensor member of the RigidBody by calculating the inverse of the matrix supplied.

func (*RigidBody) SetInfiniteMass

func (body *RigidBody) SetInfiniteMass()

SetInfiniteMass sets the mass of the RigidBody object to be 'infinite' ... which actually just sets the inverse mass to 0.0.

func (*RigidBody) SetMass

func (body *RigidBody) SetMass(mass m.Real)

SetMass sets the mass of the RigidBody object.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL