|
|
@@ -0,0 +1,155 @@
|
|
|
+// Copyright 2016 The G3N Authors. All rights reserved.
|
|
|
+// Use of this source code is governed by a BSD-style
|
|
|
+// license that can be found in the LICENSE file.
|
|
|
+
|
|
|
+package physics
|
|
|
+
|
|
|
+import "github.com/g3n/engine/math32"
|
|
|
+
|
|
|
+// ForceField represents a force field. A force is defined for every point.
|
|
|
+type ForceField interface {
|
|
|
+ ForceAt(pos *math32.Vector3) *math32.Vector3
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// Constant is a constant force field.
|
|
|
+// It can be used to simulate surface gravity.
|
|
|
+//
|
|
|
+type Constant struct {
|
|
|
+ force math32.Vector3
|
|
|
+}
|
|
|
+
|
|
|
+// NewConstant creates and returns a pointer to a new Constant force field.
|
|
|
+func NewConstant(acceleration float32) *Constant {
|
|
|
+
|
|
|
+ g := new(Constant)
|
|
|
+ g.force = math32.Vector3{0,0,-acceleration}
|
|
|
+ return g
|
|
|
+}
|
|
|
+
|
|
|
+// SetForce sets the force of the force field.
|
|
|
+func (g *Constant) SetForce(newDirection *math32.Vector3) {
|
|
|
+
|
|
|
+ g.force = *newDirection
|
|
|
+}
|
|
|
+
|
|
|
+// Force returns the force of the force field.
|
|
|
+func (g *Constant) Force() *math32.Vector3 {
|
|
|
+
|
|
|
+ return &g.force
|
|
|
+}
|
|
|
+
|
|
|
+// ForceAt satisfies the ForceField interface and returns the force at the specified position.
|
|
|
+func (g *Constant) ForceAt(pos *math32.Vector3) *math32.Vector3 {
|
|
|
+
|
|
|
+ return &g.force
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// PointAttractor is a force field where all forces point to a single point.
|
|
|
+// The force strength changes with the inverse distance squared.
|
|
|
+// This can be used to model planetary attractions.
|
|
|
+//
|
|
|
+type PointAttractor struct {
|
|
|
+ position math32.Vector3
|
|
|
+ mass float32
|
|
|
+}
|
|
|
+
|
|
|
+// NewPointAttractor creates and returns a pointer to a new PointAttractor force field.
|
|
|
+func NewPointAttractor(position *math32.Vector3, mass float32) *PointAttractor {
|
|
|
+
|
|
|
+ pa := new(PointAttractor)
|
|
|
+ pa.position = *position
|
|
|
+ pa.mass = mass
|
|
|
+ return pa
|
|
|
+}
|
|
|
+
|
|
|
+// SetPosition sets the position of the PointAttractor.
|
|
|
+func (pa *PointAttractor) SetPosition(newPosition *math32.Vector3) {
|
|
|
+
|
|
|
+ pa.position = *newPosition
|
|
|
+}
|
|
|
+
|
|
|
+// Position returns the position of the PointAttractor.
|
|
|
+func (pa *PointAttractor) Position() *math32.Vector3 {
|
|
|
+
|
|
|
+ return &pa.position
|
|
|
+}
|
|
|
+
|
|
|
+// SetMass sets the mass of the PointAttractor.
|
|
|
+func (pa *PointAttractor) SetMass(newMass float32) {
|
|
|
+
|
|
|
+ pa.mass = newMass
|
|
|
+}
|
|
|
+
|
|
|
+// Mass returns the mass of the PointAttractor.
|
|
|
+func (pa *PointAttractor) Mass() float32 {
|
|
|
+
|
|
|
+ return pa.mass
|
|
|
+}
|
|
|
+
|
|
|
+// ForceAt satisfies the ForceField interface and returns the force at the specified position.
|
|
|
+func (pa *PointAttractor) ForceAt(pos *math32.Vector3) *math32.Vector3 {
|
|
|
+
|
|
|
+ dir := pos
|
|
|
+ dir.Negate()
|
|
|
+ dir.Add(&pa.position)
|
|
|
+ dist := dir.Length()
|
|
|
+ dir.Normalize()
|
|
|
+ dir.MultiplyScalar(pa.mass/(dist*dist))
|
|
|
+ return dir
|
|
|
+}
|
|
|
+
|
|
|
+//
|
|
|
+// PointRepeller is a force field where all forces point away from a single point.
|
|
|
+// The force strength changes with the inverse distance squared.
|
|
|
+//
|
|
|
+type PointRepeller struct {
|
|
|
+ position math32.Vector3
|
|
|
+ mass float32
|
|
|
+}
|
|
|
+
|
|
|
+// NewPointRepeller creates and returns a pointer to a new PointRepeller force field.
|
|
|
+func NewPointRepeller(position *math32.Vector3, mass float32) *PointRepeller {
|
|
|
+
|
|
|
+ pr := new(PointRepeller)
|
|
|
+ pr.position = *position
|
|
|
+ pr.mass = mass
|
|
|
+ return pr
|
|
|
+}
|
|
|
+
|
|
|
+// SetPosition sets the position of the PointRepeller.
|
|
|
+func (pr *PointRepeller) SetPosition(newPosition *math32.Vector3) {
|
|
|
+
|
|
|
+ pr.position = *newPosition
|
|
|
+}
|
|
|
+
|
|
|
+// Position returns the position of the PointRepeller.
|
|
|
+func (pr *PointRepeller) Position() *math32.Vector3 {
|
|
|
+
|
|
|
+ return &pr.position
|
|
|
+}
|
|
|
+
|
|
|
+// SetMass sets the mass of the PointRepeller.
|
|
|
+func (pr *PointRepeller) SetMass(newMass float32) {
|
|
|
+
|
|
|
+ pr.mass = newMass
|
|
|
+}
|
|
|
+
|
|
|
+// Mass returns the mass of the PointRepeller.
|
|
|
+func (pr *PointRepeller) Mass() float32 {
|
|
|
+
|
|
|
+ return pr.mass
|
|
|
+}
|
|
|
+
|
|
|
+// ForceAt satisfies the ForceField interface and returns the force at the specified position.
|
|
|
+func (pr *PointRepeller) ForceAt(pos *math32.Vector3) *math32.Vector3 {
|
|
|
+
|
|
|
+ dir := pr.position
|
|
|
+ dir.Negate()
|
|
|
+ dir.Add(pos)
|
|
|
+ dist := dir.Length()
|
|
|
+ dir.Normalize()
|
|
|
+ dir.MultiplyScalar(pr.mass/(dist*dist))
|
|
|
+ return &dir
|
|
|
+}
|