Просмотр исходного кода

physics dev (simulation, forcefield, particle)

danaugrs 7 лет назад
Родитель
Сommit
57d8c6deab
4 измененных файлов с 244 добавлено и 0 удалено
  1. 155 0
      physics/forcefield.go
  2. 17 0
      physics/particle.go
  3. 3 0
      physics/rigidbody.go
  4. 69 0
      physics/simulation.go

+ 155 - 0
physics/forcefield.go

@@ -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
+}

+ 17 - 0
physics/particle.go

@@ -0,0 +1,17 @@
+// 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
+
+// Particle represents a physics-driven particle.
+type Particle struct {
+	// TODO :)
+}
+
+// NewParticle creates and returns a pointer to a new Particle.
+func NewParticle() *Particle {
+
+	b := new(Particle)
+	return b
+}

+ 3 - 0
physics/rigidbody.go

@@ -4,9 +4,12 @@
 
 package physics
 
+import "github.com/g3n/engine/math32"
+
 // RigidBody represents a physics-driven solid body.
 type RigidBody struct {
 	// TODO :)
+	position math32.Vector3 // World position of the center of gravity
 }
 
 // NewRigidBody creates and returns a pointer to a new RigidBody.

+ 69 - 0
physics/simulation.go

@@ -0,0 +1,69 @@
+// 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
+
+type ICollidable interface {
+
+}
+
+// Simulation represents a physics simulation.
+type Simulation struct {
+	forceFields []*ForceField
+	rigidBodies []*RigidBody
+	particles   []*Particle
+
+}
+
+// NewSimulation creates and returns a pointer to a new physics simulation.
+func NewSimulation() *Simulation {
+
+	b := new(Simulation)
+	return b
+}
+
+// AddForceField adds a force field to the simulation.
+func (s *Simulation) AddForceField(ff *ForceField) {
+
+	s.forceFields = append(s.forceFields, ff)
+}
+
+// RemoveForceField removes the specified force field from the simulation.
+// Returns true if found or false otherwise.
+func (s *Simulation) RemoveForceField(ff *ForceField) bool {
+
+	for pos, current := range s.forceFields {
+		if current == ff {
+			copy(s.forceFields[pos:], s.forceFields[pos+1:])
+			s.forceFields[len(s.forceFields)-1] = nil
+			s.forceFields = s.forceFields[:len(s.forceFields)-1]
+			return true
+		}
+	}
+	return false
+}
+
+func (s *Simulation) CollisionBroadphase() {
+
+}
+
+func (s *Simulation) CheckCollisions(collidables []ICollidable) {
+
+}
+
+// Step steps the simulation.
+func (s *Simulation) Step() {
+
+	// Check for collisions (broad phase)
+	//s.CollisionBroadphase()
+
+	// Check for collisions (narrow phase)
+	//s.CheckCollisions()
+
+	// Apply forces/inertia/impulses
+
+
+	// Update visual representation
+
+}