physics

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Dec 11, 2022 License: BSD-2-Clause, Zlib Imports: 5 Imported by: 0

Documentation

Overview

Package physics is a real-time simulation of real-world physics. Physics applies simulated forces to virtual 3D objects known as bodies. Physics updates bodies locations and directions based on forces and collisions with other bodies.

Bodies are created using NewBody(shape). For example:

box    := NewBody(NewBox(hx, hy, hz))
sphere := NewBody(NewSphere(radius))

Creating and storing bodies is the responsibility of the calling application. Bodies are moved with frequent and regular calls to Physics.Step(). Regulating the calls to Step() is also the responsibility of the calling application. Once Step() has completed, the bodies updated location and direction are available in Body.World().

Package physics is provided as part of the vu (virtual universe) 3D engine.

Index

Constants

View Source
const (
	SphereShape  = iota // Considered convex (curving outwards).
	BoxShape            // Polyhedral (flat faces, straight edges). Convex.
	VolumeShapes        // Separates shapes with volume from those without.
	PlaneShape          // Area, no volume or mass.
	RayShape            // Points on a line, no area, volume or mass.
	NumShapes           // Keep this last.
)

Enumerate the shapes handled by physics and returned by Shape.Type(). Currently volume shapes are used in physics collision and the non-volume shapes are used in ray-casting.

Variables

This section is empty.

Functions

func Cast

func Cast(ray, b Body) (hit bool, x, y, z float64)

Cast checks if a ray r intersects the given Form f, giving back the nearest point of intersection if there is one. The point of contact x, y, z is valid when hit is true.

func SetPlane

func SetPlane(b Body, x, y, z float64)

SetPlane allows a plane to be updated. Body b is expected to be a plane created from NewPlane().

func SetRay

func SetRay(b Body, x, y, z float64)

SetRay allows a ray direction to be changed. Body b is expected to be a ray created from NewRay().

Types

type Abox

type Abox struct {
	Sx, Sy, Sz float64 // Smallest point.
	Lx, Ly, Lz float64 // Largest point.
}

Abox is an axis aligned bounding box used with the Shape interface. Its primary purpose is to surround arbitrary shapes during broad phase collision detection. Abox is not a primitive shape for collision - use Box instead. Vertices for the full axis aligned box are:

Sx, Sy, Sz -- smallest vertex (left, bottom, back = minimum point)
Sx, Sy, Lz |
Sx, Ly, Sz |
Sx, Ly, Lz |- generate if necessary.
Lx, Sy, Sz |
Lx, Sy, Lz |
Lx, Ly, Sz |
Lx, Ly, Lz -- largest vertex (right, top, front = maximum point)

func (*Abox) Overlaps

func (a *Abox) Overlaps(b *Abox) bool

Overlaps returns true if Abox a and b are intersecting. Returns false if Abox a and b are not intersecting or are just touching along one or more points, edges, or faces.

type Body

type Body interface {
	Shape() Shape          // Physics shape for this form.
	World() *lin.T         // Get the location and direction
	SetWorld(world *lin.T) // ...or set the location and direction.

	Eq(b Body) bool           // True if the two bodies are the same.
	Speed() (x, y, z float64) // Current linear velocity.
	Whirl() (x, y, z float64) // Current angular velocity.
	Push(x, y, z float64)     // Add to the body's linear velocity.
	SetTrigger(value bool)    //Trigger
	Turn(x, y, z float64)     // Add to the body's angular velocity.
	Stop()                    // Stops linear velocity.
	Rest()                    // Stops angular velocity.

	// SetProps associates physical properties with a body. The physical
	// properties are combined with the body's shape to determine its
	// behaviour during collisions. The updated Body is returned.
	//     mass:       use zero mass for unmoving (static/fixed) bodies.
	//     bounciness: total bounciness is the multiplication of the two
	//                 colliding bodies. If one of the bodies has 0
	//                 bounciness then there is no bounce effect.
	SetProps(mass, bounciness float64) Body
}

Body is a single object contained within a physics simulation. Bodies generally relate to a scene node that is displayed to the user. Only add bodies that need to participate in physics. Bodies that are added to physics are expected to have their movement controlled by the physics simulation and not the application.

func NewBody

func NewBody(shape Shape) Body

NewBody returns a new Body structure. The body will be positioned, with no rotation, at the origin.

type PhysAttr

type PhysAttr func(Physics)

PhysAttr defines a physics attribute that can be used in Physics.Set().

func Gravity

func Gravity(g float64) PhysAttr

Gravity changes the physics gravity constant. Attribute expected to be used in Physics.Set().

func Margin

func Margin(collisionMargin float64) PhysAttr

Margin is set so that close enough objects are reported as colliding. Its default value is 0.04. It is an attribute to be used in Physics.Set().

type Physics

type Physics interface {
	// Set changes engine wide attributes. It accepts one or more
	// functions that take an PhysAttr parameter, ie: physics.Gravity(0).
	Set(...PhysAttr) // Update one or more engine attributes.

	// Step the physics simulation one tiny bit forward. This is expected
	// to be called regularly from the main engine loop. At the end of
	// a simulation step, all the bodies positions will be updated based on
	// forces acting upon them and/or collision results. Unmoving/unmoved
	// bodies, or bodies with zero mass are not updated.
	Step(bodies []Body, timestep float64)

	// Collide checks for collision between bodies a, b independent of
	// the current physics simulation. Bodies positions and velocities
	// are not updated. Provided for occasional or one-off checks.
	Collide(a, b Body) bool
}

Physics simulates forces acting on moving bodies. Expected usage is to simulate real-life conditions like air resistance and gravity, or the lack thereof.

func NewPhysics

func NewPhysics() Physics

NewPhysics creates and returns a mover instance. Generally expected to be called once per application that needs a physics simulation.

type Shape

type Shape interface {
	Type() int       // Type returns the shape type.
	Volume() float64 // Volume is useful for mass = density*volume.

	// Aabb updates ab to be the axis aligned bounding box for this shape.
	// The updated Abox ab will be in the space defined by the transform.
	//    ab     : Output structure. Providing a nil Abox will cause a panic.
	//    margin : Optional small positive value that increases the size
	//             of the surrounding box. Use 0 for no margin.
	// The updated Abox ab is returned.
	Aabb(transform *lin.T, ab *Abox, margin float64) *Abox

	// Inertia is needed by collision resolution.
	//    mass   : can be set directly or as density*Volume()
	// The input vector, inertia, is updated and returned.
	Inertia(mass float64, inertia *lin.V3) *lin.V3
}

Shape is a physics collision primitive generally used 3D model collision detection. A Shape is always in local space centered at the origin. Combine a shape with a transform to position the shape anywhere in world space. Shapes do not allocate memory. They expect to be given the necessary structures when doing calculations like filling in bounding boxes.

func NewBox

func NewBox(hx, hy, hz float64) Shape

NewBox creates a Box shape. Negative input values are turned positive. Input values of zero are ignored, but not recommended.

func NewPlane

func NewPlane(x, y, z float64) Shape

NewPlane creates a plane shape using the given plane normal x, y, z.

func NewRay

func NewRay(x, y, z float64) Shape

NewRay creates a ray shape using the given ray direction x, y, z.

func NewSphere

func NewSphere(radius float64) Shape

NewSphere creates a Sphere shape. Negative radius values are turned positive. Input values of zero are ignored, but not recommended.

Jump to

Keyboard shortcuts

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