| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- // 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
- }
- //
- // ConstantForceField is a constant force field.
- // It can be used to simulate surface gravity.
- //
- type ConstantForceField struct {
- force math32.Vector3
- }
- // NewConstantForceField creates and returns a pointer to a new ConstantForceField.
- func NewConstantForceField(force *math32.Vector3) *ConstantForceField {
- g := new(ConstantForceField)
- g.force = *force
- return g
- }
- // SetForce sets the force of the force field.
- func (g *ConstantForceField) SetForce(newDirection *math32.Vector3) {
- g.force = *newDirection
- }
- // Force returns the force of the force field.
- func (g *ConstantForceField) Force() *math32.Vector3 {
- return &g.force
- }
- // ForceAt satisfies the ForceField interface and returns the force at the specified position.
- func (g *ConstantForceField) ForceAt(pos *math32.Vector3) math32.Vector3 {
- return g.force
- }
- //
- // AttractorForceField 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 AttractorForceField struct {
- position math32.Vector3
- mass float32
- }
- // NewAttractorForceField creates and returns a pointer to a new AttractorForceField.
- func NewAttractorForceField(position *math32.Vector3, mass float32) *AttractorForceField {
- pa := new(AttractorForceField)
- pa.position = *position
- pa.mass = mass
- return pa
- }
- // SetPosition sets the position of the AttractorForceField.
- func (pa *AttractorForceField) SetPosition(newPosition *math32.Vector3) {
- pa.position = *newPosition
- }
- // Position returns the position of the AttractorForceField.
- func (pa *AttractorForceField) Position() *math32.Vector3 {
- return &pa.position
- }
- // SetMass sets the mass of the AttractorForceField.
- func (pa *AttractorForceField) SetMass(newMass float32) {
- pa.mass = newMass
- }
- // Mass returns the mass of the AttractorForceField.
- func (pa *AttractorForceField) Mass() float32 {
- return pa.mass
- }
- // ForceAt satisfies the ForceField interface and returns the force at the specified position.
- func (pa *AttractorForceField) ForceAt(pos *math32.Vector3) math32.Vector3 {
- dir := pos
- dir.Negate()
- dir.Add(&pa.position)
- dist := dir.Length()
- dir.Normalize()
- var val float32
- //log.Error("dist %v", dist)
- if dist > 0 {
- val = pa.mass/(dist*dist)
- } else {
- val = 0
- }
- val = math32.Min(val, 100) // TODO deal with instability
- //log.Error("%v", val)
- dir.MultiplyScalar(val) // TODO multiply by gravitational constant: 6.673×10−11 (N–m2)/kg2
- return *dir
- }
- //
- // RepellerForceField is a force field where all forces point away from a single point.
- // The force strength changes with the inverse distance squared.
- //
- type RepellerForceField struct {
- position math32.Vector3
- mass float32
- }
- // NewRepellerForceField creates and returns a pointer to a new RepellerForceField.
- func NewRepellerForceField(position *math32.Vector3, mass float32) *RepellerForceField {
- pr := new(RepellerForceField)
- pr.position = *position
- pr.mass = mass
- return pr
- }
- // SetPosition sets the position of the RepellerForceField.
- func (pr *RepellerForceField) SetPosition(newPosition *math32.Vector3) {
- pr.position = *newPosition
- }
- // Position returns the position of the RepellerForceField.
- func (pr *RepellerForceField) Position() *math32.Vector3 {
- return &pr.position
- }
- // SetMass sets the mass of the RepellerForceField.
- func (pr *RepellerForceField) SetMass(newMass float32) {
- pr.mass = newMass
- }
- // Mass returns the mass of the RepellerForceField.
- func (pr *RepellerForceField) Mass() float32 {
- return pr.mass
- }
- // ForceAt satisfies the ForceField interface and returns the force at the specified position.
- func (pr *RepellerForceField) 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)) // TODO multiply by gravitational constant: 6.673×10−11 (N–m2)/kg2
- return dir
- }
|