Przeglądaj źródła

Update dependencies and clean up

Daniel Salvadori 4 lat temu
rodzic
commit
de78e3c420
72 zmienionych plików z 460 dodań i 460 usunięć
  1. 4 3
      app/app-desktop.go
  2. 6 24
      audio/al/al.go
  3. 3 2
      audio/audio_file.go
  4. 1 4
      audio/ov/vorbisfile.go
  5. 4 3
      audio/player.go
  6. 2 1
      camera/orbit_control.go
  7. 1 1
      experimental/collision/collision.go
  8. 9 9
      experimental/collision/matrix_test.go
  9. 2 1
      experimental/collision/raycaster.go
  10. 0 1
      experimental/collision/shape/capsule.go
  11. 0 1
      experimental/collision/shape/cone.go
  12. 7 10
      experimental/collision/shape/convexhull.go
  13. 0 1
      experimental/collision/shape/cylinder.go
  14. 0 1
      experimental/collision/shape/heightfield.go
  15. 1 1
      experimental/collision/shape/plane.go
  16. 2 2
      experimental/collision/shape/sphere.go
  17. 2 2
      experimental/physics/broadphase.go
  18. 1 1
      experimental/physics/constraint/conetwist.go
  19. 2 2
      experimental/physics/constraint/distance.go
  20. 2 2
      experimental/physics/constraint/hinge.go
  21. 1 1
      experimental/physics/constraint/lock.go
  22. 5 5
      experimental/physics/constraint/pointtopoint.go
  23. 3 3
      experimental/physics/equation/cone.go
  24. 7 7
      experimental/physics/equation/contact.go
  25. 7 7
      experimental/physics/equation/equation.go
  26. 3 3
      experimental/physics/equation/friction.go
  27. 1 1
      experimental/physics/equation/rotational.go
  28. 1 1
      experimental/physics/equation/rotationalmotor.go
  29. 2 2
      experimental/physics/forcefield.go
  30. 116 118
      experimental/physics/narrowphase.go
  31. 18 18
      experimental/physics/object/body.go
  32. 6 6
      experimental/physics/solver/gs.go
  33. 2 1
      geometry/cone-cylinder.go
  34. 2 1
      geometry/disk.go
  35. 3 2
      geometry/morph.go
  36. 2 1
      geometry/sphere.go
  37. 2 1
      geometry/torus.go
  38. 39 38
      geometry/tube.go
  39. 1 1
      gls/build.go
  40. 2 1
      gls/gls.go
  41. 1 1
      gls/shaderdefines.go
  42. 3 3
      go.mod
  43. 8 7
      go.sum
  44. 2 1
      graphic/rigged_mesh.go
  45. 1 1
      graphic/skeleton.go
  46. 9 9
      gui/assets/data.go
  47. 75 75
      gui/assets/icon/icodes.go
  48. 2 1
      gui/chart.go
  49. 3 2
      gui/edit.go
  50. 2 1
      gui/image.go
  51. 2 1
      gui/itemscroller.go
  52. 2 1
      loader/collada/animation.go
  53. 3 2
      loader/collada/collada.go
  54. 3 2
      loader/collada/geometry.go
  55. 3 2
      loader/collada/material.go
  56. 2 1
      loader/collada/scene.go
  57. 6 5
      loader/gltf/gltf.go
  58. 3 3
      loader/gltf/material_pbr.go
  59. 22 25
      math32/curves.go
  60. 5 5
      math32/quaternion.go
  61. 2 2
      math32/vector2.go
  62. 7 7
      math32/vector3.go
  63. 2 1
      renderer/renderer.go
  64. 2 1
      renderer/shaman.go
  65. 2 1
      text/atlas.go
  66. 5 4
      text/font.go
  67. 2 1
      texture/animator.go
  68. 2 1
      texture/texture2D.go
  69. 1 1
      tools/g3nshaders/main.go
  70. 2 1
      util/stats/stats.go
  71. 3 2
      util/wasm/wasm.go
  72. 1 0
      window/window.go

+ 4 - 3
app/app-desktop.go

@@ -8,11 +8,12 @@ package app
 
 import (
 	"fmt"
+	"time"
+
 	"github.com/g3n/engine/audio/al"
 	"github.com/g3n/engine/audio/vorbis"
 	"github.com/g3n/engine/renderer"
 	"github.com/g3n/engine/window"
-	"time"
 )
 
 // Desktop application defaults
@@ -67,7 +68,7 @@ func (a *Application) Run(update func(rend *renderer.Renderer, deltaTime time.Du
 	a.frameStart = time.Now()
 
 	// Set up recurring calls to user's update function
-	for true {
+	for {
 		// If Exit() was called or there was an attempt to close the window dispatch OnExit event for subscribers.
 		// If no subscriber cancelled the event, terminate the application.
 		if a.IWindow.(*window.GlfwWindow).ShouldClose() {
@@ -121,7 +122,7 @@ func (a *Application) KeyState() *window.KeyState {
 // RunTime returns the elapsed duration since the call to Run().
 func (a *Application) RunTime() time.Duration {
 
-	return time.Now().Sub(a.startTime)
+	return time.Since(a.startTime)
 }
 
 // openDefaultAudioDevice opens the default audio device setting it to the current context

+ 6 - 24
audio/al/al.go

@@ -375,10 +375,7 @@ func CtxIsExtensionPresent(dev *Device, extname string) bool {
 	cname := (*C.ALCchar)(C.CString(extname))
 	defer C.free(unsafe.Pointer(cname))
 	cres := C.alcIsExtensionPresent(dev.cdev, cname)
-	if cres == C.AL_TRUE {
-		return true
-	}
-	return false
+	return cres == C.AL_TRUE
 }
 
 func CtxGetEnumValue(dev *Device, enumName string) uint32 {
@@ -457,10 +454,7 @@ func Disable(capability uint) {
 func IsEnabled(capability uint) bool {
 
 	cres := C.alIsEnabled(C.ALenum(capability))
-	if cres == C.AL_TRUE {
-		return true
-	}
-	return false
+	return cres == C.AL_TRUE
 }
 
 func GetString(param uint32) string {
@@ -500,10 +494,7 @@ func GetDoublev(param uint32, values []float64) {
 func GetBoolean(param uint32) bool {
 
 	cres := C.alGetBoolean(C.ALenum(param))
-	if cres == C.AL_TRUE {
-		return true
-	}
-	return false
+	return cres == C.AL_TRUE
 }
 
 func GetInteger(param uint32) int32 {
@@ -538,10 +529,7 @@ func IsExtensionPresent(extName string) bool {
 	cstr := (*C.ALchar)(C.CString(extName))
 	defer C.free(unsafe.Pointer(cstr))
 	cres := C.alIsExtensionPresent(cstr)
-	if cres == 0 {
-		return false
-	}
-	return true
+	return cres != 0
 }
 
 func GetEnumValue(enam string) uint32 {
@@ -656,10 +644,7 @@ func DeleteSources(sources []uint32) {
 func IsSource(source uint32) bool {
 
 	cres := C.alIsSource(C.ALuint(source))
-	if cres == C.AL_TRUE {
-		return true
-	}
-	return false
+	return cres == C.AL_TRUE
 }
 
 func Sourcef(source uint32, param uint32, value float32) {
@@ -812,10 +797,7 @@ func DeleteBuffers(buffers []uint32) {
 func IsBuffer(buffer uint32) bool {
 
 	cres := C.alIsBuffer(C.ALuint(buffer))
-	if cres == C.AL_TRUE {
-		return true
-	}
-	return false
+	return cres == C.AL_TRUE
 }
 
 func BufferData(buffer uint32, format uint32, data unsafe.Pointer, size uint32, freq uint32) {

+ 3 - 2
audio/audio_file.go

@@ -8,11 +8,12 @@ package audio
 
 import (
 	"fmt"
-	"github.com/g3n/engine/audio/al"
-	"github.com/g3n/engine/audio/ov"
 	"io"
 	"os"
 	"unsafe"
+
+	"github.com/g3n/engine/audio/al"
+	"github.com/g3n/engine/audio/ov"
 )
 
 const (

+ 1 - 4
audio/ov/vorbisfile.go

@@ -138,10 +138,7 @@ func Info(f *File, link int, info *VorbisInfo) error {
 func Seekable(f *File) bool {
 
 	cres := C.ov_seekable(f.vf)
-	if cres == 0 {
-		return false
-	}
-	return true
+	return cres != 0
 }
 
 // Seek seeks to the offset specified (in number pcm samples) within the physical bitstream.

+ 4 - 3
audio/player.go

@@ -10,13 +10,14 @@ package audio
 import "C"
 
 import (
+	"io"
+	"time"
+	"unsafe"
+
 	"github.com/g3n/engine/audio/al"
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
-	"io"
-	"time"
-	"unsafe"
 )
 
 const (

+ 2 - 1
camera/orbit_control.go

@@ -5,11 +5,12 @@
 package camera
 
 import (
+	"math"
+
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gui"
 	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/window"
-	"math"
 )
 
 // OrbitEnabled specifies which control types are enabled.

+ 1 - 1
experimental/collision/collision.go

@@ -13,4 +13,4 @@ import "github.com/g3n/engine/geometry"
 func CheckConvex(g1, g2 *geometry.Geometry) bool {
 
 	return true
-}
+}

+ 9 - 9
experimental/collision/matrix_test.go

@@ -13,24 +13,24 @@ func Test(t *testing.T) {
 
 	// m.Get(1, 1) // panics with "runtime error: index out of range" as expected
 
-	m.Set(2,4, true)
-	m.Set(3,2, true)
-	if m.Get(1,1) != false {
+	m.Set(2, 4, true)
+	m.Set(3, 2, true)
+	if m.Get(1, 1) != false {
 		t.Error("Get failed")
 	}
-	if m.Get(2,4) != true {
+	if m.Get(2, 4) != true {
 		t.Error("Get failed")
 	}
-	if m.Get(3,2) != true {
+	if m.Get(3, 2) != true {
 		t.Error("Get failed")
 	}
 
-	m.Set(2,4, false)
-	m.Set(3,2, false)
-	if m.Get(2,4) != false {
+	m.Set(2, 4, false)
+	m.Set(3, 2, false)
+	if m.Get(2, 4) != false {
 		t.Error("Get failed")
 	}
-	if m.Get(3,2) != false {
+	if m.Get(3, 2) != false {
 		t.Error("Get failed")
 	}
 

+ 2 - 1
experimental/collision/raycaster.go

@@ -5,13 +5,14 @@
 package collision
 
 import (
+	"sort"
+
 	"github.com/g3n/engine/camera"
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/graphic"
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/math32"
-	"sort"
 )
 
 // Raycaster represents an empty object that can cast rays and check for ray intersections.

+ 0 - 1
experimental/collision/shape/capsule.go

@@ -3,4 +3,3 @@
 // license that can be found in the LICENSE file.
 
 package shape
-

+ 0 - 1
experimental/collision/shape/cone.go

@@ -3,4 +3,3 @@
 // license that can be found in the LICENSE file.
 
 package shape
-

+ 7 - 10
experimental/collision/shape/convexhull.go

@@ -5,9 +5,9 @@
 package shape
 
 import (
+	"github.com/g3n/engine/experimental/collision"
 	"github.com/g3n/engine/geometry"
 	"github.com/g3n/engine/math32"
-	"github.com/g3n/engine/experimental/collision"
 )
 
 // ConvexHull is a convex triangle-based geometry used for collision detection and contact resolution.
@@ -20,7 +20,6 @@ type ConvexHull struct {
 	worldFaceNormals []math32.Vector3
 	uniqueEdges      []math32.Vector3
 	worldUniqueEdges []math32.Vector3
-
 }
 
 func NewConvexHull(geom *geometry.Geometry) *ConvexHull {
@@ -357,7 +356,6 @@ func (ch *ConvexHull) clipFaceAgainstHull(posA, penAxis *math32.Vector3, quatA *
 		}
 	}
 
-
 	worldClosestFaceA := ch.WorldFace(closestFaceA, posA, quatA)
 	// DEBUGGING
 	//if n.debugging {
@@ -386,7 +384,7 @@ func (ch *ConvexHull) clipFaceAgainstHull(posA, penAxis *math32.Vector3, quatA *
 		connFaceNormal := worldFaceNormalsA[cfidx]
 		// Choose a vertex in the connected face and use it to find the plane constant
 		worldFirstVertex := connFace[0].Clone().ApplyQuaternion(quatA).Add(posA)
-		planeDelta := - worldFirstVertex.Dot(&connFaceNormal)
+		planeDelta := -worldFirstVertex.Dot(&connFaceNormal)
 		clippedFace = ch.clipFaceAgainstPlane(clippedFace, connFaceNormal.Clone(), planeDelta)
 	}
 
@@ -397,7 +395,7 @@ func (ch *ConvexHull) clipFaceAgainstHull(posA, penAxis *math32.Vector3, quatA *
 	//}
 
 	closestFaceAnormal := worldFaceNormalsA[closestFaceAidx]
-	worldFirstVertex := worldClosestFaceA[0].Clone()//.ApplyQuaternion(quatA).Add(&posA)
+	worldFirstVertex := worldClosestFaceA[0].Clone() //.ApplyQuaternion(quatA).Add(&posA)
 	planeDelta := -worldFirstVertex.Dot(&closestFaceAnormal)
 
 	// For each vertex in the clipped face resolve its depth (relative to the closestFaceA) and create a contact
@@ -410,9 +408,9 @@ func (ch *ConvexHull) clipFaceAgainstHull(posA, penAxis *math32.Vector3, quatA *
 		if depth <= maxDist {
 			if depth <= 0 {
 				contacts = append(contacts, collision.Contact{
-					Point: vertex,
+					Point:  vertex,
 					Normal: closestFaceAnormal,
-					Depth: depth,
+					Depth:  depth,
 				})
 			}
 		}
@@ -422,7 +420,6 @@ func (ch *ConvexHull) clipFaceAgainstHull(posA, penAxis *math32.Vector3, quatA *
 	return contacts
 }
 
-
 // clipFaceAgainstPlane clips the specified face against the back of the specified plane.
 // This is used multiple times when finding the portion of a face of one convex hull that is inside another convex hull.
 // planeNormal and planeConstant satisfy the plane equation n*x = p where n is the planeNormal and p is the planeConstant (and x is a point on the plane).
@@ -447,12 +444,12 @@ func (ch *ConvexHull) clipFaceAgainstPlane(face []math32.Vector3, planeNormal *m
 			if dotLast < 0 { // Start < 0, end < 0, so output lastVertex
 				clippedFace = append(clippedFace, lastVertex)
 			} else { // Start < 0, end >= 0, so output intersection
-				newv := firstVertex.Clone().Lerp(&lastVertex, dotFirst / (dotFirst - dotLast))
+				newv := firstVertex.Clone().Lerp(&lastVertex, dotFirst/(dotFirst-dotLast))
 				clippedFace = append(clippedFace, *newv)
 			}
 		} else { // Outside hull
 			if dotLast < 0 { // Start >= 0, end < 0 so output intersection and end
-				newv := firstVertex.Clone().Lerp(&lastVertex, dotFirst / (dotFirst - dotLast))
+				newv := firstVertex.Clone().Lerp(&lastVertex, dotFirst/(dotFirst-dotLast))
 				clippedFace = append(clippedFace, *newv)
 				clippedFace = append(clippedFace, lastVertex)
 			}

+ 0 - 1
experimental/collision/shape/cylinder.go

@@ -3,4 +3,3 @@
 // license that can be found in the LICENSE file.
 
 package shape
-

+ 0 - 1
experimental/collision/shape/heightfield.go

@@ -3,4 +3,3 @@
 // license that can be found in the LICENSE file.
 
 package shape
-

+ 1 - 1
experimental/collision/shape/plane.go

@@ -16,7 +16,7 @@ type Plane struct {
 func NewPlane() *Plane {
 
 	p := new(Plane)
-	p.normal = *math32.NewVector3(0,0,1) //*normal
+	p.normal = *math32.NewVector3(0, 0, 1) //*normal
 	return p
 }
 

+ 2 - 2
experimental/collision/shape/sphere.go

@@ -54,13 +54,13 @@ func (s *Sphere) Area() float32 {
 // Volume computes and returns the volume of the analytical collision sphere.
 func (s *Sphere) Volume() float32 {
 
-	return (4/3) * math32.Pi * s.radius * s.radius * s.radius
+	return (4 / 3) * math32.Pi * s.radius * s.radius * s.radius
 }
 
 // RotationalInertia computes and returns the rotational inertia of the analytical collision sphere.
 func (s *Sphere) RotationalInertia(mass float32) math32.Matrix3 {
 
-	v := (2/5) * mass * s.radius * s.radius
+	v := (2 / 5) * mass * s.radius * s.radius
 	return *math32.NewMatrix3().Set(
 		v, 0, 0,
 		0, v, 0,

+ 2 - 2
experimental/physics/broadphase.go

@@ -16,7 +16,7 @@ type CollisionPair struct {
 }
 
 // Broadphase is the base class for broadphase implementations.
-type Broadphase struct {}
+type Broadphase struct{}
 
 // NewBroadphase creates and returns a pointer to a new Broadphase.
 func NewBroadphase() *Broadphase {
@@ -28,7 +28,7 @@ func NewBroadphase() *Broadphase {
 // FindCollisionPairs (naive implementation)
 func (b *Broadphase) FindCollisionPairs(objects []*object.Body) []CollisionPair {
 
-	pairs := make([]CollisionPair,0)
+	pairs := make([]CollisionPair, 0)
 
 	for iA, bodyA := range objects {
 		for _, bodyB := range objects[iA+1:] {

+ 1 - 1
experimental/physics/constraint/conetwist.go

@@ -5,8 +5,8 @@
 package constraint
 
 import (
-	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/experimental/physics/equation"
+	"github.com/g3n/engine/math32"
 )
 
 // ConeTwist constraint.

+ 2 - 2
experimental/physics/constraint/distance.go

@@ -12,8 +12,8 @@ import (
 // Constrains two bodies to be at a constant distance from each others center of mass.
 type Distance struct {
 	Constraint
-	distance   float32 // Distance
-	equation   *equation.Contact
+	distance float32 // Distance
+	equation *equation.Contact
 }
 
 // NewDistance creates and returns a pointer to a new Distance constraint object.

+ 2 - 2
experimental/physics/constraint/hinge.go

@@ -14,8 +14,8 @@ import (
 // It tries to keep the door in the correct place and with the correct orientation.
 type Hinge struct {
 	PointToPoint
-	axisA   *math32.Vector3           // Rotation axis, defined locally in bodyA.
-	axisB   *math32.Vector3           // Rotation axis, defined locally in bodyB.
+	axisA   *math32.Vector3 // Rotation axis, defined locally in bodyA.
+	axisB   *math32.Vector3 // Rotation axis, defined locally in bodyB.
 	rotEq1  *equation.Rotational
 	rotEq2  *equation.Rotational
 	motorEq *equation.RotationalMotor

+ 1 - 1
experimental/physics/constraint/lock.go

@@ -43,7 +43,7 @@ func NewLock(bodyA, bodyB IBody, maxForce float32) *Lock {
 	lc.initialize(bodyA, bodyB, &pivotA, &pivotB, maxForce)
 
 	// Store initial rotation of the bodies as unit vectors in the local body spaces
-	UnitX := math32.NewVector3(1,0,0)
+	UnitX := math32.NewVector3(1, 0, 0)
 
 	localA := bodyA.VectorToLocal(UnitX)
 	localB := bodyB.VectorToLocal(UnitX)

+ 5 - 5
experimental/physics/constraint/pointtopoint.go

@@ -13,8 +13,8 @@ import (
 // Connects two bodies at the specified offset points.
 type PointToPoint struct {
 	Constraint
-	pivotA *math32.Vector3   // Pivot, defined locally in bodyA.
-	pivotB *math32.Vector3   // Pivot, defined locally in bodyB.
+	pivotA *math32.Vector3 // Pivot, defined locally in bodyA.
+	pivotB *math32.Vector3 // Pivot, defined locally in bodyB.
 	eqX    *equation.Contact
 	eqY    *equation.Contact
 	eqZ    *equation.Contact
@@ -40,9 +40,9 @@ func (ptpc *PointToPoint) initialize(bodyA, bodyB IBody, pivotA, pivotB *math32.
 	ptpc.eqY = equation.NewContact(bodyA, bodyB, -maxForce, maxForce)
 	ptpc.eqZ = equation.NewContact(bodyA, bodyB, -maxForce, maxForce)
 
-	ptpc.eqX.SetNormal(&math32.Vector3{1,0,0})
-	ptpc.eqY.SetNormal(&math32.Vector3{0,1,0})
-	ptpc.eqZ.SetNormal(&math32.Vector3{0,0,1})
+	ptpc.eqX.SetNormal(&math32.Vector3{1, 0, 0})
+	ptpc.eqY.SetNormal(&math32.Vector3{0, 1, 0})
+	ptpc.eqZ.SetNormal(&math32.Vector3{0, 0, 1})
 
 	ptpc.AddEquation(&ptpc.eqX.Equation)
 	ptpc.AddEquation(&ptpc.eqY.Equation)

+ 3 - 3
experimental/physics/equation/cone.go

@@ -12,9 +12,9 @@ import (
 // Works to keep the given body world vectors aligned, or tilted within a given angle from each other.
 type Cone struct {
 	Equation
-	axisA    *math32.Vector3 // Local axis in A
-	axisB    *math32.Vector3 // Local axis in B
-	angle    float32         // The "cone angle" to keep
+	axisA *math32.Vector3 // Local axis in A
+	axisB *math32.Vector3 // Local axis in B
+	angle float32         // The "cone angle" to keep
 }
 
 // NewCone creates and returns a pointer to a new Cone equation object.

+ 7 - 7
experimental/physics/equation/contact.go

@@ -25,9 +25,9 @@ func NewContact(bodyA, bodyB IBody, minForce, maxForce float32) *Contact {
 	// minForce default should be 0.
 
 	ce.restitution = 0.5
-	ce.rA = &math32.Vector3{0,0,0}
-	ce.rB = &math32.Vector3{0,0,0}
-	ce.nA = &math32.Vector3{0,0,0}
+	ce.rA = &math32.Vector3{0, 0, 0}
+	ce.rB = &math32.Vector3{0, 0, 0}
+	ce.nA = &math32.Vector3{0, 0, 0}
 
 	ce.Equation.initialize(bodyA, bodyB, minForce, maxForce)
 
@@ -44,7 +44,7 @@ func (ce *Contact) Restitution() float32 {
 	return ce.restitution
 }
 
-func (ce *Contact) SetNormal(newNormal *math32.Vector3)  {
+func (ce *Contact) SetNormal(newNormal *math32.Vector3) {
 
 	ce.nA = newNormal
 }
@@ -54,7 +54,7 @@ func (ce *Contact) Normal() math32.Vector3 {
 	return *ce.nA
 }
 
-func (ce *Contact) SetRA(newRa *math32.Vector3)  {
+func (ce *Contact) SetRA(newRa *math32.Vector3) {
 
 	ce.rA = newRa
 }
@@ -64,7 +64,7 @@ func (ce *Contact) RA() math32.Vector3 {
 	return *ce.rA
 }
 
-func (ce *Contact) SetRB(newRb *math32.Vector3)  {
+func (ce *Contact) SetRB(newRb *math32.Vector3) {
 
 	ce.rB = newRb
 }
@@ -103,7 +103,7 @@ func (ce *Contact) ComputeB(h float32) float32 {
 
 	// Compute iteration
 	ePlusOne := ce.restitution + 1
-	GW := ePlusOne * vB.Dot(ce.nA) - ePlusOne * vA.Dot(ce.nA) + wB.Dot(rnB) - wA.Dot(rnA)
+	GW := ePlusOne*vB.Dot(ce.nA) - ePlusOne*vA.Dot(ce.nA) + wB.Dot(rnB) - wA.Dot(rnA)
 	GiMf := ce.ComputeGiMf()
 
 	return -g*ce.a - GW*ce.b - h*GiMf

+ 7 - 7
experimental/physics/equation/equation.go

@@ -45,13 +45,13 @@ type IEquation interface {
 // Equation is a SPOOK constraint equation.
 type Equation struct {
 	id         int
-	minForce   float32       // Minimum (read: negative max) force to be applied by the constraint.
-	maxForce   float32       // Maximum (read: positive max) force to be applied by the constraint.
-	bA         IBody // Body "i"
-	bB         IBody // Body "j"
-	a          float32       // SPOOK parameter
-	b          float32       // SPOOK parameter
-	eps        float32       // SPOOK parameter
+	minForce   float32 // Minimum (read: negative max) force to be applied by the constraint.
+	maxForce   float32 // Maximum (read: positive max) force to be applied by the constraint.
+	bA         IBody   // Body "i"
+	bB         IBody   // Body "j"
+	a          float32 // SPOOK parameter
+	b          float32 // SPOOK parameter
+	eps        float32 // SPOOK parameter
 	jeA        JacobianElement
 	jeB        JacobianElement
 	enabled    bool

+ 3 - 3
experimental/physics/equation/friction.go

@@ -31,7 +31,7 @@ func NewFriction(bodyA, bodyB IBody, slipForce float32) *Friction {
 	return fe
 }
 
-func (fe *Friction) SetTangent(newTangent *math32.Vector3)  {
+func (fe *Friction) SetTangent(newTangent *math32.Vector3) {
 
 	fe.t = newTangent
 }
@@ -41,7 +41,7 @@ func (fe *Friction) Tangent() math32.Vector3 {
 	return *fe.t
 }
 
-func (fe *Friction) SetRA(newRa *math32.Vector3)  {
+func (fe *Friction) SetRA(newRa *math32.Vector3) {
 
 	fe.rA = newRa
 }
@@ -51,7 +51,7 @@ func (fe *Friction) RA() math32.Vector3 {
 	return *fe.rA
 }
 
-func (fe *Friction) SetRB(newRb *math32.Vector3)  {
+func (fe *Friction) SetRB(newRb *math32.Vector3) {
 
 	fe.rB = newRb
 }

+ 1 - 1
experimental/physics/equation/rotational.go

@@ -14,7 +14,7 @@ type Rotational struct {
 	Equation
 	axisA    *math32.Vector3 // Local axis in A
 	axisB    *math32.Vector3 // Local axis in B
-	maxAngle float32        // Max angle
+	maxAngle float32         // Max angle
 }
 
 // NewRotational creates and returns a pointer to a new Rotational equation object.

+ 1 - 1
experimental/physics/equation/rotationalmotor.go

@@ -11,7 +11,7 @@ import (
 // RotationalMotor is a rotational motor constraint equation.
 // Tries to keep the relative angular velocity of the bodies to a given value.
 type RotationalMotor struct {
-	Equation // TODO maybe this should embed Rotational instead ?
+	Equation                    // TODO maybe this should embed Rotational instead ?
 	axisA       *math32.Vector3 // World oriented rotational axis
 	axisB       *math32.Vector3 // World oriented rotational axis
 	targetSpeed float32         // Target speed

+ 2 - 2
experimental/physics/forcefield.go

@@ -99,7 +99,7 @@ func (pa *AttractorForceField) ForceAt(pos *math32.Vector3) math32.Vector3 {
 	var val float32
 	//log.Error("dist %v", dist)
 	if dist > 0 {
-		val = pa.mass/(dist*dist)
+		val = pa.mass / (dist * dist)
 	} else {
 		val = 0
 	}
@@ -159,6 +159,6 @@ func (pr *RepellerForceField) ForceAt(pos *math32.Vector3) math32.Vector3 {
 	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
+	dir.MultiplyScalar(pr.mass / (dist * dist)) // TODO multiply by gravitational constant: 6.673×10−11 (N–m2)/kg2
 	return dir
 }

+ 116 - 118
experimental/physics/narrowphase.go

@@ -5,10 +5,10 @@
 package physics
 
 import (
-	"github.com/g3n/engine/experimental/physics/object"
+	"github.com/g3n/engine/experimental/collision/shape"
 	"github.com/g3n/engine/experimental/physics/equation"
+	"github.com/g3n/engine/experimental/physics/object"
 	"github.com/g3n/engine/math32"
-	"github.com/g3n/engine/experimental/collision/shape"
 )
 
 // Narrowphase
@@ -159,9 +159,9 @@ func (n *Narrowphase) GenerateEquations(pairs []CollisionPair) ([]*equation.Cont
 			allContactEqs = append(allContactEqs, contactEqs...)
 			allFrictionEqs = append(allFrictionEqs, frictionEqs...)
 		}
-   }
+	}
 
-   return allContactEqs, allFrictionEqs
+	return allContactEqs, allFrictionEqs
 }
 
 // ResolveCollision figures out which implementation of collision detection and contact resolution to use depending on the shapes involved.
@@ -216,7 +216,7 @@ func (n *Narrowphase) SphereSphere(bodyA, bodyB *object.Body, sphereA, sphereB *
 	radiusA := sphereA.Radius()
 	radiusB := sphereB.Radius()
 
-	if posA.DistanceToSquared(posB) > math32.Pow(radiusA + radiusB, 2) {
+	if posA.DistanceToSquared(posB) > math32.Pow(radiusA+radiusB, 2) {
 		// No collision
 		return contactEqs, frictionEqs
 	}
@@ -263,8 +263,8 @@ func (n *Narrowphase) SpherePlane(bodyA, bodyB *object.Body, sphereA *shape.Sphe
 		// We will have one contact in this case
 		contactEq := equation.NewContact(bodyA, bodyB, 0, 1e6)
 		contactEq.SetSpookParams(1e6, 3, n.simulation.dt)
-		contactEq.SetNormal(normal) // Normalize() might not be needed
-		contactEq.SetRA(normal.Clone().MultiplyScalar(sphereRadius)) // Vector from sphere center to contact point
+		contactEq.SetNormal(normal)                                                                   // Normalize() might not be needed
+		contactEq.SetRA(normal.Clone().MultiplyScalar(sphereRadius))                                  // Vector from sphere center to contact point
 		contactEq.SetRB(math32.NewVec3().SubVectors(point_on_plane_to_sphere, plane_to_sphere_ortho)) // The sphere position projected to plane
 		contactEqs = append(contactEqs, contactEq)
 
@@ -285,13 +285,13 @@ func (n *Narrowphase) SphereConvex(bodyA, bodyB *object.Body, sphereA *shape.Sph
 	// TODO
 	//v3pool := this.v3pool
 	//convex_to_sphere := math32.NewVec3().SubVectors(posA, posB)
-    //normals := sj.faceNormals
-    //faces := sj.faces
-    //verts := sj.vertices
-    //R :=     si.radius
-    //penetrating_sides := []
+	//normals := sj.faceNormals
+	//faces := sj.faces
+	//verts := sj.vertices
+	//R :=     si.radius
+	//penetrating_sides := []
 
-    // COMMENTED OUT
+	// COMMENTED OUT
 	// if(convex_to_sphere.norm2() > si.boundingSphereRadius + sj.boundingSphereRadius){
 	//     return;
 	// }
@@ -302,7 +302,7 @@ func (n *Narrowphase) SphereConvex(bodyA, bodyB *object.Body, sphereA *shape.Sph
 	convexB.Geometry.ReadVertices(func(vertex math32.Vector3) bool {
 		worldVertex := vertex.ApplyQuaternion(quatA).Add(posB)
 		sphereToCorner := math32.NewVec3().SubVectors(worldVertex, posA)
-		if sphereToCorner.LengthSq() < sphereRadius * sphereRadius {
+		if sphereToCorner.LengthSq() < sphereRadius*sphereRadius {
 			// Colliding! worldVertex is inside sphere.
 
 			// Create contact equation
@@ -329,30 +329,30 @@ func (n *Narrowphase) SphereConvex(bodyA, bodyB *object.Body, sphereA *shape.Sph
 	}
 
 	//Check side (plane) intersections TODO NOTE THIS IS UNTESTED
-    convexFaces := convexB.Faces()
-    convexWorldFaceNormals := convexB.WorldFaceNormals()
-    for i := 0; i < len(convexFaces); i++ {
+	convexFaces := convexB.Faces()
+	convexWorldFaceNormals := convexB.WorldFaceNormals()
+	for i := 0; i < len(convexFaces); i++ {
 		worldNormal := convexWorldFaceNormals[i]
-     	face := convexFaces[i]
-     	// Get a world vertex from the face
-     	var worldPoint = face[0].Clone().ApplyQuaternion(quatB).Add(posB)
-     	// Get a point on the sphere, closest to the face normal
-     	var worldSpherePointClosestToPlane = worldNormal.Clone().MultiplyScalar(-sphereRadius).Add(posA)
-     	// Vector from a face point to the closest point on the sphere
-     	var penetrationVec = math32.NewVec3().SubVectors(worldSpherePointClosestToPlane, worldPoint)
-     	// The penetration. Negative value means overlap.
-     	var penetration = penetrationVec.Dot(&worldNormal)
-     	var worldPointToSphere = math32.NewVec3().SubVectors(posA, worldPoint)
-     	if penetration < 0 && worldPointToSphere.Dot(&worldNormal) > 0 {
-         	// Intersects plane. Now check if the sphere is inside the face polygon
-         	worldFace := convexB.WorldFace(face, posB, quatB)
-         	if n.pointBehindFace(worldFace, &worldNormal, posA) { // Is the sphere center behind the face (inside the convex polygon?
+		face := convexFaces[i]
+		// Get a world vertex from the face
+		var worldPoint = face[0].Clone().ApplyQuaternion(quatB).Add(posB)
+		// Get a point on the sphere, closest to the face normal
+		var worldSpherePointClosestToPlane = worldNormal.Clone().MultiplyScalar(-sphereRadius).Add(posA)
+		// Vector from a face point to the closest point on the sphere
+		var penetrationVec = math32.NewVec3().SubVectors(worldSpherePointClosestToPlane, worldPoint)
+		// The penetration. Negative value means overlap.
+		var penetration = penetrationVec.Dot(&worldNormal)
+		var worldPointToSphere = math32.NewVec3().SubVectors(posA, worldPoint)
+		if penetration < 0 && worldPointToSphere.Dot(&worldNormal) > 0 {
+			// Intersects plane. Now check if the sphere is inside the face polygon
+			worldFace := convexB.WorldFace(face, posB, quatB)
+			if n.pointBehindFace(worldFace, &worldNormal, posA) { // Is the sphere center behind the face (inside the convex polygon?
 				// TODO NEVER GETTING INSIDE THIS IF STATEMENT!
-				ShowWorldFace(n.simulation.Scene(), worldFace[:], &math32.Color{0,0,2})
+				ShowWorldFace(n.simulation.Scene(), worldFace[:], &math32.Color{0, 0, 2})
 
 				// if justTest {
-             	//    return true
-             	//}
+				//    return true
+				//}
 
 				// Create contact equation
 				contactEq := equation.NewContact(bodyA, bodyB, 0, 1e6)
@@ -368,31 +368,31 @@ func (n *Narrowphase) SphereConvex(bodyA, bodyB *object.Body, sphereA *shape.Sph
 				fEq1, fEq2 := n.createFrictionEquationsFromContact(contactEq)
 				frictionEqs = append(frictionEqs, fEq1, fEq2)
 				// Exit method (we only expect *one* face contact)
-             	return contactEqs, frictionEqs
-         	} else {
+				return contactEqs, frictionEqs
+			} else {
 				// Edge?
-             	for j := 0; j < len(worldFace); j++ {
-             		// Get two world transformed vertices
-                	v1 := worldFace[(j+1)%3].Clone()//.ApplyQuaternion(quatB).Add(posB)
-                	v2 := worldFace[(j+2)%3].Clone()//.ApplyQuaternion(quatB).Add(posB)
-                	// Construct edge vector
-                	edge := math32.NewVec3().SubVectors(v2, v1)
-                	// Construct the same vector, but normalized
-                	edgeUnit := edge.Clone().Normalize()
-                	// p is xi projected onto the edge
-                	v1ToPosA := math32.NewVec3().SubVectors(posA, v1)
-                	dot := v1ToPosA.Dot(edgeUnit)
+				for j := 0; j < len(worldFace); j++ {
+					// Get two world transformed vertices
+					v1 := worldFace[(j+1)%3].Clone() //.ApplyQuaternion(quatB).Add(posB)
+					v2 := worldFace[(j+2)%3].Clone() //.ApplyQuaternion(quatB).Add(posB)
+					// Construct edge vector
+					edge := math32.NewVec3().SubVectors(v2, v1)
+					// Construct the same vector, but normalized
+					edgeUnit := edge.Clone().Normalize()
+					// p is xi projected onto the edge
+					v1ToPosA := math32.NewVec3().SubVectors(posA, v1)
+					dot := v1ToPosA.Dot(edgeUnit)
 					p := edgeUnit.Clone().MultiplyScalar(dot).Add(v1)
-                	// Compute a vector from p to the center of the sphere
-                	var posAtoP = math32.NewVec3().SubVectors(p, posA)
-                	// Collision if the edge-sphere distance is less than the radius AND if p is in between v1 and v2
-                	edgeL2 := edge.LengthSq()
-                	patp2 := posAtoP.LengthSq()
-                	if (dot > 0) && (dot*dot < edgeL2) && (patp2 < sphereRadius*sphereRadius) { // Collision if the edge-sphere distance is less than the radius
-                	   // Edge contact!
-                	   //if justTest {
-                	   //    return true
-                	   //}
+					// Compute a vector from p to the center of the sphere
+					var posAtoP = math32.NewVec3().SubVectors(p, posA)
+					// Collision if the edge-sphere distance is less than the radius AND if p is in between v1 and v2
+					edgeL2 := edge.LengthSq()
+					patp2 := posAtoP.LengthSq()
+					if (dot > 0) && (dot*dot < edgeL2) && (patp2 < sphereRadius*sphereRadius) { // Collision if the edge-sphere distance is less than the radius
+						// Edge contact!
+						//if justTest {
+						//    return true
+						//}
 						// Create contact equation
 						contactEq := equation.NewContact(bodyA, bodyB, 0, 1e6)
 						contactEq.SetSpookParams(1e6, 3, n.simulation.dt)
@@ -407,11 +407,11 @@ func (n *Narrowphase) SphereConvex(bodyA, bodyB *object.Body, sphereA *shape.Sph
 						//frictionEqs = append(frictionEqs, fEq1, fEq2)
 						// Exit method (we only expect *one* edge contact)
 						return contactEqs, frictionEqs
-                	}
-             	}
+					}
+				}
 			}
-     	}
-    }
+		}
+	}
 
 	return contactEqs, frictionEqs
 }
@@ -517,7 +517,6 @@ func (n *Narrowphase) ConvexConvex(bodyA, bodyB *object.Body, convexA, convexB *
 	return contactEqs, frictionEqs
 }
 
-
 //// TODO ?
 //func (n *Narrowphase) GetAveragePointLocal(target) {
 //
@@ -531,7 +530,6 @@ func (n *Narrowphase) ConvexConvex(bodyA, bodyB *object.Body, convexA, convexB *
 //   return target
 //}
 
-
 // Checks whether p is inside the polyhedra. Must be in local coords.
 // The point lies outside of the convex hull of the other points if and only if
 // the direction of all the vectors from it to those other points are on less than one half of a sphere around it.
@@ -585,59 +583,59 @@ func (n *Narrowphase) PlaneConvex(bodyA, bodyB *object.Body, planeA *shape.Plane
 	//si,
 	//sj,
 	//justTest) {
-   //
+	//
 	//// Simply return the points behind the plane.
-   //worldVertex := planeConvex_v
-   //worldNormal := planeConvex_normal
-   //worldNormal.set(0,0,1)
-   //planeQuat.vmult(worldNormal,worldNormal) // Turn normal according to plane orientation
-   //
-   //var numContacts = 0
-   //var relpos = planeConvex_relpos
-   //for i := 0; i < len(convexShape.vertices); i++ {
-   //
-   //    // Get world convex vertex
-   //    worldVertex.copy(convexShape.vertices[i])
-   //    convexQuat.vmult(worldVertex, worldVertex)
-   //    convexPosition.vadd(worldVertex, worldVertex)
-   //    worldVertex.vsub(planePosition, relpos)
-   //
-   //    var dot = worldNormal.dot(relpos)
-   //    if dot <= 0.0 {
-   //        if justTest {
-   //            return true
-   //        }
-   //
-   //        var r = this.createContactEquation(planeBody, convexBody, planeShape, convexShape, si, sj)
-   //
-   //        // Get vertex position projected on plane
-   //        var projected = planeConvex_projected
-   //        worldNormal.mult(worldNormal.dot(relpos),projected)
-   //        worldVertex.vsub(projected, projected)
-   //        projected.vsub(planePosition, r.ri) // From plane to vertex projected on plane
-   //
-   //        r.ni.copy(worldNormal) // Contact normal is the plane normal out from plane
-   //
-   //        // rj is now just the vector from the convex center to the vertex
-   //        worldVertex.vsub(convexPosition, r.rj)
-   //
-   //        // Make it relative to the body
-   //        r.ri.vadd(planePosition, r.ri)
-   //        r.ri.vsub(planeBody.position, r.ri)
-   //        r.rj.vadd(convexPosition, r.rj)
-   //        r.rj.vsub(convexBody.position, r.rj)
-   //
-   //        this.result.push(r)
-   //        numContacts++
-   //        if !this.enableFrictionReduction {
-   //            this.createFrictionEquationsFromContact(r, this.frictionResult)
-   //        }
-   //    }
-   //}
-   //
-   //if this.enableFrictionReduction && numContacts {
-   //    this.createFrictionFromAverage(numContacts)
-   //}
-
-   return contactEqs, frictionEqs
-}
+	//worldVertex := planeConvex_v
+	//worldNormal := planeConvex_normal
+	//worldNormal.set(0,0,1)
+	//planeQuat.vmult(worldNormal,worldNormal) // Turn normal according to plane orientation
+	//
+	//var numContacts = 0
+	//var relpos = planeConvex_relpos
+	//for i := 0; i < len(convexShape.vertices); i++ {
+	//
+	//    // Get world convex vertex
+	//    worldVertex.copy(convexShape.vertices[i])
+	//    convexQuat.vmult(worldVertex, worldVertex)
+	//    convexPosition.vadd(worldVertex, worldVertex)
+	//    worldVertex.vsub(planePosition, relpos)
+	//
+	//    var dot = worldNormal.dot(relpos)
+	//    if dot <= 0.0 {
+	//        if justTest {
+	//            return true
+	//        }
+	//
+	//        var r = this.createContactEquation(planeBody, convexBody, planeShape, convexShape, si, sj)
+	//
+	//        // Get vertex position projected on plane
+	//        var projected = planeConvex_projected
+	//        worldNormal.mult(worldNormal.dot(relpos),projected)
+	//        worldVertex.vsub(projected, projected)
+	//        projected.vsub(planePosition, r.ri) // From plane to vertex projected on plane
+	//
+	//        r.ni.copy(worldNormal) // Contact normal is the plane normal out from plane
+	//
+	//        // rj is now just the vector from the convex center to the vertex
+	//        worldVertex.vsub(convexPosition, r.rj)
+	//
+	//        // Make it relative to the body
+	//        r.ri.vadd(planePosition, r.ri)
+	//        r.ri.vsub(planeBody.position, r.ri)
+	//        r.rj.vadd(convexPosition, r.rj)
+	//        r.rj.vsub(convexBody.position, r.rj)
+	//
+	//        this.result.push(r)
+	//        numContacts++
+	//        if !this.enableFrictionReduction {
+	//            this.createFrictionEquationsFromContact(r, this.frictionResult)
+	//        }
+	//    }
+	//}
+	//
+	//if this.enableFrictionReduction && numContacts {
+	//    this.createFrictionFromAverage(numContacts)
+	//}
+
+	return contactEqs, frictionEqs
+}

+ 18 - 18
experimental/physics/object/body.go

@@ -5,19 +5,19 @@
 package object
 
 import (
+	"github.com/g3n/engine/experimental/collision/shape"
 	"github.com/g3n/engine/graphic"
-	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/material"
-	"github.com/g3n/engine/experimental/collision/shape"
+	"github.com/g3n/engine/math32"
 )
 
 // Body represents a physics-driven body.
 type Body struct {
 	*graphic.Graphic // TODO future - embed core.Node instead and calculate properties recursively
 
-	material             *material.Material   // Physics material specifying friction and restitution
-	index int
-	name string
+	material *material.Material // Physics material specifying friction and restitution
+	index    int
+	name     string
 
 	// Mass properties
 	mass       float32 // Total mass
@@ -61,12 +61,12 @@ type Body struct {
 	angularFactor  *math32.Vector3 // Use this property to limit the rotational motion along any world axis. (1,1,1) will allow rotation along all axes while (0,0,0) allows none.
 
 	// Body type and sleep settings
-	bodyType        BodyType
-	sleepState      BodySleepState // Current sleep state.
-	allowSleep      bool           // If true, the body will automatically fall to sleep.
-	sleepSpeedLimit float32        // If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy.
-	sleepTimeLimit  float32        // If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping.
-	timeLastSleepy  float32
+	bodyType               BodyType
+	sleepState             BodySleepState // Current sleep state.
+	allowSleep             bool           // If true, the body will automatically fall to sleep.
+	sleepSpeedLimit        float32        // If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy.
+	sleepTimeLimit         float32        // If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping.
+	timeLastSleepy         float32
 	wakeUpAfterNarrowphase bool
 
 	// Collision settings
@@ -79,7 +79,7 @@ type Body struct {
 	boundingRadius  float32      // Total bounding radius of the body (TODO including its shapes, relative to body.position.)
 
 	// Cached geometry properties
-	faces            [][3]math32.Vector3
+	faces [][3]math32.Vector3
 
 	faceNormals      []math32.Vector3
 	worldFaceNormals []math32.Vector3
@@ -140,13 +140,13 @@ const (
 
 // TODO
 type HullType int
+
 const (
 	Sphere = HullType(iota)
 	Capsule
 	Mesh // use mesh itself
 )
 
-
 // NewBody creates and returns a pointer to a new RigidBody.
 // The igraphic's geometry *must* be convex.
 func NewBody(igraphic graphic.IGraphic) *Body {
@@ -231,7 +231,7 @@ func (b *Body) Shape() shape.IShape {
 func (b *Body) BoundingBox() math32.Box3 {
 
 	// TODO future allow multiple shapes
-	mat4 := math32.NewMatrix4().Compose(b.position, b.quaternion, math32.NewVector3(1,1,1))
+	mat4 := math32.NewMatrix4().Compose(b.position, b.quaternion, math32.NewVector3(1, 1, 1))
 	localBB := b.shape.BoundingBox()
 	worldBB := localBB.ApplyMatrix4(mat4)
 	return *worldBB
@@ -327,7 +327,7 @@ func (b *Body) SetBodyType(bodyType BodyType) {
 
 func (b *Body) BodyType() BodyType {
 
-	return b. bodyType
+	return b.bodyType
 }
 
 func (b *Body) SetWakeUpAfterNarrowphase(state bool) {
@@ -426,8 +426,8 @@ func (b *Body) AngularDamping() float32 {
 
 func (b *Body) ApplyDamping(dt float32) {
 
-	b.velocity.MultiplyScalar(math32.Pow(1.0 - b.linearDamping, dt))
-	b.angularVelocity.MultiplyScalar(math32.Pow(1.0 - b.angularDamping, dt))
+	b.velocity.MultiplyScalar(math32.Pow(1.0-b.linearDamping, dt))
+	b.angularVelocity.MultiplyScalar(math32.Pow(1.0-b.angularDamping, dt))
 }
 
 func (b *Body) SetLinearFactor(factor *math32.Vector3) {
@@ -581,7 +581,7 @@ func (b *Body) UpdateMassProperties() {
 		b.invRotInertia.Zero()
 	} else {
 		*b.rotInertia = b.GetGeometry().RotationalInertia(b.mass)
-		b.rotInertia.MultiplyScalar(10) // multiply by high density // TODO remove this ?
+		b.rotInertia.MultiplyScalar(10)          // multiply by high density // TODO remove this ?
 		b.invRotInertia.GetInverse(b.rotInertia) // Note: rotInertia is always positive definite and thus always invertible
 	}
 

+ 6 - 6
experimental/physics/solver/gs.go

@@ -65,13 +65,13 @@ func (gs *GaussSeidel) Solve(dt float32, nBodies int) *Solution {
 	// Things that do not change during iteration can be computed once
 	for i := 0; i < nEquations; i++ {
 		eq := gs.equations[i]
-		gs.solveInvCs = append(gs.solveInvCs, 1.0 / eq.ComputeC())
+		gs.solveInvCs = append(gs.solveInvCs, 1.0/eq.ComputeC())
 		gs.solveBs = append(gs.solveBs, eq.ComputeB(h))
 		gs.solveLambda = append(gs.solveLambda, 0.0)
 	}
 
 	if nEquations > 0 {
-		tolSquared := gs.tolerance*gs.tolerance
+		tolSquared := gs.tolerance * gs.tolerance
 
 		// Iterate over equations
 		for iter = 0; iter < gs.maxIter; iter++ {
@@ -96,12 +96,12 @@ func (gs *GaussSeidel) Solve(dt float32, nBodies int) *Solution {
 				jeB := eq.JeB()
 				GWlambda := jeA.MultiplyVectors(&vA, &wA) + jeB.MultiplyVectors(&vB, &wB)
 
-				deltaLambda := gs.solveInvCs[j] * ( gs.solveBs[j]  - GWlambda - eq.Eps() *lambdaJ)
+				deltaLambda := gs.solveInvCs[j] * (gs.solveBs[j] - GWlambda - eq.Eps()*lambdaJ)
 
 				// Clamp if we are outside the min/max interval
-				if lambdaJ + deltaLambda < eq.MinForce() {
+				if (lambdaJ + deltaLambda) < eq.MinForce() {
 					deltaLambda = eq.MinForce() - lambdaJ
-				} else if lambdaJ + deltaLambda > eq.MaxForce() {
+				} else if (lambdaJ + deltaLambda) > eq.MaxForce() {
 					deltaLambda = eq.MaxForce() - lambdaJ
 				}
 				gs.solveLambda[j] += deltaLambda
@@ -136,4 +136,4 @@ func (gs *GaussSeidel) Solve(dt float32, nBodies int) *Solution {
 	gs.Iterations = iter
 
 	return &gs.Solution
-}
+}

+ 2 - 1
geometry/cone-cylinder.go

@@ -5,9 +5,10 @@
 package geometry
 
 import (
+	"math"
+
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
-	"math"
 )
 
 // NewCone creates a cone geometry with the specified base radius, height,

+ 2 - 1
geometry/disk.go

@@ -5,9 +5,10 @@
 package geometry
 
 import (
+	"math"
+
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
-	"math"
 )
 
 // NewDisk creates a disk (filled circle) geometry with the specified

+ 3 - 2
geometry/morph.go

@@ -5,10 +5,11 @@
 package geometry
 
 import (
-	"github.com/g3n/engine/gls"
-	"github.com/g3n/engine/math32"
 	"sort"
 	"strconv"
+
+	"github.com/g3n/engine/gls"
+	"github.com/g3n/engine/math32"
 )
 
 // MorphGeometry represents a base geometry and its morph targets.

+ 2 - 1
geometry/sphere.go

@@ -5,9 +5,10 @@
 package geometry
 
 import (
+	"math"
+
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
-	"math"
 )
 
 // NewSphere creates a sphere geometry with the specified radius and number of radial segments in each dimension.

+ 2 - 1
geometry/torus.go

@@ -5,9 +5,10 @@
 package geometry
 
 import (
+	"math"
+
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
-	"math"
 )
 
 // NewTorus creates a torus geometry with the specified revolution radius, tube radius,

+ 39 - 38
geometry/tube.go

@@ -6,23 +6,24 @@
 package geometry
 
 import (
-	"github.com/g3n/engine/math32"
-	"github.com/g3n/engine/gls"
 	"math"
+
+	"github.com/g3n/engine/gls"
+	"github.com/g3n/engine/math32"
 )
 
 func CalculateNormals(indices math32.ArrayU32, positions, normals math32.ArrayF32) math32.ArrayF32 {
 	var x1x2, y1y2, z1z2, x3x2, y3y2, z3z2, x, y, z, l float32
 	var x1, y1, z1, x2, y2, z2, x3, y3, z3 int // position indexes
 
-	for i := 0; i < len(indices) / 3; i++ {
-		x1 = int(indices[i * 3] * uint32(3))
+	for i := 0; i < len(indices)/3; i++ {
+		x1 = int(indices[i*3] * uint32(3))
 		y1 = x1 + 1
 		z1 = x1 + 2
-		x2 = int(indices[i * 3 + 1] * uint32(3))
+		x2 = int(indices[i*3+1] * uint32(3))
 		y2 = x2 + 1
 		z2 = x2 + 2
-		x3 = int(indices[i * 3 + 2] * uint32(3))
+		x3 = int(indices[i*3+2] * uint32(3))
 		y3 = x3 + 1
 		z3 = x3 + 2
 
@@ -33,11 +34,11 @@ func CalculateNormals(indices math32.ArrayU32, positions, normals math32.ArrayF3
 		y3y2 = positions[y3] - positions[y2]
 		z3z2 = positions[z3] - positions[z2]
 
-		x = y1y2 * z3z2 - z1z2 * y3y2
-		y = z1z2 * x3x2 - x1x2 * z3z2
-		z = x1x2 * y3y2 - y1y2 * x3x2
+		x = y1y2*z3z2 - z1z2*y3y2
+		y = z1z2*x3x2 - x1x2*z3z2
+		z = x1x2*y3y2 - y1y2*x3x2
 
-		l = float32(math.Sqrt(float64(x) * float64(x) + float64(y) * float64(y) + float64(z) * float64(z)))
+		l = float32(math.Sqrt(float64(x)*float64(x) + float64(y)*float64(y) + float64(z)*float64(z)))
 		if l == 0 {
 			l = 1.0
 		}
@@ -52,26 +53,26 @@ func CalculateNormals(indices math32.ArrayU32, positions, normals math32.ArrayF3
 		normals[y3] += y / l
 		normals[z3] += z / l
 	}
-	for i := 0; i < len(normals) / 3; i++ {
-		x = normals[i * 3]
-		y = normals[i * 3 + 1]
-		z = normals[i * 3 + 2]
-		l = float32(math.Sqrt(float64(x) * float64(x) + float64(y) * float64(y) + float64(z) * float64(z)))
+	for i := 0; i < len(normals)/3; i++ {
+		x = normals[i*3]
+		y = normals[i*3+1]
+		z = normals[i*3+2]
+		l = float32(math.Sqrt(float64(x)*float64(x) + float64(y)*float64(y) + float64(z)*float64(z)))
 		if l == 0 {
 			l = 1.0
 		}
-		normals[i * 3] = x / l
-		normals[i * 3 + 1] = y / l
-		normals[i * 3 + 2] = z / l
+		normals[i*3] = x / l
+		normals[i*3+1] = y / l
+		normals[i*3+2] = z / l
 	}
 	return normals
 }
 
 func NewRibbon(paths [][]math32.Vector3, close bool) *Geometry {
 	/*
-	if len(paths) < 3 {
-		close = false
-	}
+		if len(paths) < 3 {
+			close = false
+		}
 	*/
 	c := NewGeometry()
 
@@ -99,8 +100,8 @@ func NewRibbon(paths [][]math32.Vector3, close bool) *Geometry {
 	}
 	p := 0
 	i = 0
-	for i <= min && p < len(ls) - 1 {
-		t := is[p+1] - is[p] 
+	for i <= min && p < len(ls)-1 {
+		t := is[p+1] - is[p]
 
 		indices.Append(uint32(i), uint32(i+t), uint32(i+1))
 		indices.Append(uint32(i+t+1), uint32(i+1), uint32(i+t))
@@ -111,7 +112,7 @@ func NewRibbon(paths [][]math32.Vector3, close bool) *Geometry {
 				indices.Append(uint32(is[p]+t), uint32(is[p]), uint32(i+t))
 			}
 			p++
-			if p == len(ls) - 1 {
+			if p == len(ls)-1 {
 				break
 			}
 			l1 = ls[p] - 1
@@ -149,11 +150,11 @@ func NewTube(path []math32.Vector3, radius float32, radialSegments int, close bo
 	tangents[l-1].Normalize()
 
 	var tmpVertex *math32.Vector3
-	if (tangents[0].X != 1) {
+	if tangents[0].X != 1 {
 		tmpVertex = math32.NewVector3(1, 0, 0)
-	} else if (tangents[0].Y != 1) {
+	} else if tangents[0].Y != 1 {
 		tmpVertex = math32.NewVector3(0, 1, 0)
-	} else if (tangents[0].Z != 1) {
+	} else if tangents[0].Z != 1 {
 		tmpVertex = math32.NewVector3(0, 0, 1)
 	}
 
@@ -161,14 +162,14 @@ func NewTube(path []math32.Vector3, radius float32, radialSegments int, close bo
 	normals[0].Normalize()
 	binormals[0] = *tangents[0].Clone().Cross(&normals[0])
 	binormals[0].Normalize()
-	
+
 	for i := 1; i < l; i++ {
 		prev := *path[i].Clone().Sub(&path[i-1])
-		if (i < l-1) {
-		  cur := *path[i+1].Clone().Sub(&path[i])
-		  tangents[i] = *prev.Clone().Add(&cur)
-		  tangents[i].Normalize()
-		  
+		if i < l-1 {
+			cur := *path[i+1].Clone().Sub(&path[i])
+			tangents[i] = *prev.Clone().Add(&cur)
+			tangents[i].Normalize()
+
 		}
 		normals[i] = *binormals[i-1].Clone().Cross(&tangents[i])
 		normals[i].Normalize()
@@ -190,11 +191,11 @@ func NewTube(path []math32.Vector3, radius float32, radialSegments int, close bo
 			x := normals[i].X
 			y := normals[i].Y
 			z := normals[i].Z
-			rw := 1 / (x * matrix[3] + y * matrix[7] + z * matrix[11] + matrix[15])
-			newX := (x * matrix[0] + y * matrix[4] + z * matrix[8] + matrix[12]) * rw
-			newY := (x * matrix[1] + y * matrix[5] + z * matrix[9] + matrix[13]) * rw
-			newZ := (x * matrix[2] + y * matrix[6] + z * matrix[10] + matrix[14]) * rw
-			
+			rw := 1 / (x*matrix[3] + y*matrix[7] + z*matrix[11] + matrix[15])
+			newX := (x*matrix[0] + y*matrix[4] + z*matrix[8] + matrix[12]) * rw
+			newY := (x*matrix[1] + y*matrix[5] + z*matrix[9] + matrix[13]) * rw
+			newZ := (x*matrix[2] + y*matrix[6] + z*matrix[10] + matrix[14]) * rw
+
 			rotated := math32.NewVector3(newX, newY, newZ).MultiplyScalar(radius).Add(&path[i])
 			radialPath = append(radialPath, *rotated)
 		}

+ 1 - 1
gls/build.go

@@ -9,7 +9,7 @@ package gls
 
 // // Platform build flags
 // #cgo freebsd CFLAGS:  -DGL_GLEXT_PROTOTYPES
-// #cgo freebsd LDFLAGS: 
+// #cgo freebsd LDFLAGS:
 //
 // #cgo linux   CFLAGS:  -DGL_GLEXT_PROTOTYPES
 // #cgo linux   LDFLAGS: -ldl

+ 2 - 1
gls/gls.go

@@ -13,9 +13,10 @@
 package gls
 
 import (
-	"github.com/g3n/engine/util/logger"
 	"math"
 	"unsafe"
+
+	"github.com/g3n/engine/util/logger"
 )
 
 // Package logger

+ 1 - 1
gls/shaderdefines.go

@@ -29,7 +29,7 @@ func (sd *ShaderDefines) Unset(name string) {
 // Add adds to this ShaderDefines all the key-value pairs in the specified ShaderDefines.
 func (sd *ShaderDefines) Add(other *ShaderDefines) {
 
-	for k, v := range map[string]string(*other){
+	for k, v := range map[string]string(*other) {
 		(*sd)[k] = v
 	}
 }

+ 3 - 3
go.mod

@@ -3,8 +3,8 @@ module github.com/g3n/engine
 go 1.13
 
 require (
-	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2
+	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb
 	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
-	golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a
-	gopkg.in/yaml.v2 v2.2.2
+	golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9
+	gopkg.in/yaml.v2 v2.4.0
 )

+ 8 - 7
go.sum

@@ -1,11 +1,12 @@
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2 h1:Ac1OEHHkbAZ6EUnJahF0GKcU0FjPc/V8F1DvjhKngFE=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb h1:T6gaWBvRzJjuOrdCtg8fXXjKai2xSDqWTcKFUPuw8Tw=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
-golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a h1:gHevYm0pO4QUbwy8Dmdr01R5r1BuKtfYqRqF0h/Cbh0=
-golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9 h1:D0iM1dTCbD5Dg1CbuvLC/v/agLc79efSj/L35Q3Vqhs=
+golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

+ 2 - 1
graphic/rigged_mesh.go

@@ -5,9 +5,10 @@
 package graphic
 
 import (
-	"github.com/g3n/engine/gls"
 	"strconv"
+
 	"github.com/g3n/engine/core"
+	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
 )
 

+ 1 - 1
graphic/skeleton.go

@@ -7,7 +7,7 @@ package graphic
 import (
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/math32"
-	)
+)
 
 // Skeleton contains armature information.
 type Skeleton struct {

+ 9 - 9
gui/assets/data.go

@@ -243,12 +243,12 @@ func AssetNames() []string {
 
 // _bindata is a table, holding each asset generator, mapped to its name.
 var _bindata = map[string]func() (*asset, error){
-	"fonts/FreeMono.ttf": fontsFreemonoTtf,
-	"fonts/FreeSans.ttf": fontsFreesansTtf,
-	"fonts/FreeSansBold.ttf": fontsFreesansboldTtf,
+	"fonts/FreeMono.ttf":              fontsFreemonoTtf,
+	"fonts/FreeSans.ttf":              fontsFreesansTtf,
+	"fonts/FreeSansBold.ttf":          fontsFreesansboldTtf,
 	"fonts/MaterialIcons-Regular.ttf": fontsMaterialiconsRegularTtf,
-	"cursors/diag1.png": cursorsDiag1Png,
-	"cursors/diag2.png": cursorsDiag2Png,
+	"cursors/diag1.png":               cursorsDiag1Png,
+	"cursors/diag2.png":               cursorsDiag2Png,
 }
 
 // AssetDir returns the file names below a certain
@@ -290,15 +290,16 @@ type bintree struct {
 	Func     func() (*asset, error)
 	Children map[string]*bintree
 }
+
 var _bintree = &bintree{nil, map[string]*bintree{
 	"cursors": &bintree{nil, map[string]*bintree{
 		"diag1.png": &bintree{cursorsDiag1Png, map[string]*bintree{}},
 		"diag2.png": &bintree{cursorsDiag2Png, map[string]*bintree{}},
 	}},
 	"fonts": &bintree{nil, map[string]*bintree{
-		"FreeMono.ttf": &bintree{fontsFreemonoTtf, map[string]*bintree{}},
-		"FreeSans.ttf": &bintree{fontsFreesansTtf, map[string]*bintree{}},
-		"FreeSansBold.ttf": &bintree{fontsFreesansboldTtf, map[string]*bintree{}},
+		"FreeMono.ttf":              &bintree{fontsFreemonoTtf, map[string]*bintree{}},
+		"FreeSans.ttf":              &bintree{fontsFreesansTtf, map[string]*bintree{}},
+		"FreeSansBold.ttf":          &bintree{fontsFreesansboldTtf, map[string]*bintree{}},
 		"MaterialIcons-Regular.ttf": &bintree{fontsMaterialiconsRegularTtf, map[string]*bintree{}},
 	}},
 }}
@@ -349,4 +350,3 @@ func _filePath(dir, name string) string {
 	cannonicalName := strings.Replace(name, "\\", "/", -1)
 	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
 }
-

+ 75 - 75
gui/assets/icon/icodes.go

@@ -1808,79 +1808,79 @@ var name2Codepoint = map[string]string{
 	"Traffic":                               string(0xe565),
 	"Train":                                 string(0xe570),
 	"Tram":                                  string(0xe571),
-	"TransferWithinAStation": string(0xe572),
-	"Transform":              string(0xe428),
-	"Translate":              string(0xe8e2),
-	"TrendingDown":           string(0xe8e3),
-	"TrendingFlat":           string(0xe8e4),
-	"TrendingUp":             string(0xe8e5),
-	"Tune":                   string(0xe429),
-	"TurnedIn":               string(0xe8e6),
-	"TurnedInNot":            string(0xe8e7),
-	"Tv":                     string(0xe333),
-	"Unarchive":              string(0xe169),
-	"Undo":                   string(0xe166),
-	"UnfoldLess":             string(0xe5d6),
-	"UnfoldMore":             string(0xe5d7),
-	"Update":                 string(0xe923),
-	"Usb":                    string(0xe1e0),
-	"VerifiedUser":           string(0xe8e8),
-	"VerticalAlignBottom":    string(0xe258),
-	"VerticalAlignCenter":    string(0xe259),
-	"VerticalAlignTop":       string(0xe25a),
-	"Vibration":              string(0xe62d),
-	"VideoCall":              string(0xe070),
-	"VideoLabel":             string(0xe071),
-	"VideoLibrary":           string(0xe04a),
-	"Videocam":               string(0xe04b),
-	"VideocamOff":            string(0xe04c),
-	"VideogameAsset":         string(0xe338),
-	"ViewAgenda":             string(0xe8e9),
-	"ViewArray":              string(0xe8ea),
-	"ViewCarousel":           string(0xe8eb),
-	"ViewColumn":             string(0xe8ec),
-	"ViewComfy":              string(0xe42a),
-	"ViewCompact":            string(0xe42b),
-	"ViewDay":                string(0xe8ed),
-	"ViewHeadline":           string(0xe8ee),
-	"ViewList":               string(0xe8ef),
-	"ViewModule":             string(0xe8f0),
-	"ViewQuilt":              string(0xe8f1),
-	"ViewStream":             string(0xe8f2),
-	"ViewWeek":               string(0xe8f3),
-	"Vignette":               string(0xe435),
-	"Visibility":             string(0xe8f4),
-	"VisibilityOff":          string(0xe8f5),
-	"VoiceChat":              string(0xe62e),
-	"Voicemail":              string(0xe0d9),
-	"VolumeDown":             string(0xe04d),
-	"VolumeMute":             string(0xe04e),
-	"VolumeOff":              string(0xe04f),
-	"VolumeUp":               string(0xe050),
-	"VpnKey":                 string(0xe0da),
-	"VpnLock":                string(0xe62f),
-	"Wallpaper":              string(0xe1bc),
-	"Warning":                string(0xe002),
-	"Watch":                  string(0xe334),
-	"WatchLater":             string(0xe924),
-	"WbAuto":                 string(0xe42c),
-	"WbCloudy":               string(0xe42d),
-	"WbIncandescent":         string(0xe42e),
-	"WbIridescent":           string(0xe436),
-	"WbSunny":                string(0xe430),
-	"Wc":                     string(0xe63d),
-	"Web":                    string(0xe051),
-	"WebAsset":               string(0xe069),
-	"Weekend":                string(0xe16b),
-	"Whatshot":               string(0xe80e),
-	"Widgets":                string(0xe1bd),
-	"Wifi":                   string(0xe63e),
-	"WifiLock":               string(0xe1e1),
-	"WifiTethering":          string(0xe1e2),
-	"Work":                   string(0xe8f9),
-	"WrapText":               string(0xe25b),
-	"YoutubeSearchedFor":     string(0xe8fa),
-	"ZoomIn":                 string(0xe8ff),
-	"ZoomOut":                string(0xe900),
-	"ZoomOutMap":             string(0xe56b),
+	"TransferWithinAStation":                string(0xe572),
+	"Transform":                             string(0xe428),
+	"Translate":                             string(0xe8e2),
+	"TrendingDown":                          string(0xe8e3),
+	"TrendingFlat":                          string(0xe8e4),
+	"TrendingUp":                            string(0xe8e5),
+	"Tune":                                  string(0xe429),
+	"TurnedIn":                              string(0xe8e6),
+	"TurnedInNot":                           string(0xe8e7),
+	"Tv":                                    string(0xe333),
+	"Unarchive":                             string(0xe169),
+	"Undo":                                  string(0xe166),
+	"UnfoldLess":                            string(0xe5d6),
+	"UnfoldMore":                            string(0xe5d7),
+	"Update":                                string(0xe923),
+	"Usb":                                   string(0xe1e0),
+	"VerifiedUser":                          string(0xe8e8),
+	"VerticalAlignBottom":                   string(0xe258),
+	"VerticalAlignCenter":                   string(0xe259),
+	"VerticalAlignTop":                      string(0xe25a),
+	"Vibration":                             string(0xe62d),
+	"VideoCall":                             string(0xe070),
+	"VideoLabel":                            string(0xe071),
+	"VideoLibrary":                          string(0xe04a),
+	"Videocam":                              string(0xe04b),
+	"VideocamOff":                           string(0xe04c),
+	"VideogameAsset":                        string(0xe338),
+	"ViewAgenda":                            string(0xe8e9),
+	"ViewArray":                             string(0xe8ea),
+	"ViewCarousel":                          string(0xe8eb),
+	"ViewColumn":                            string(0xe8ec),
+	"ViewComfy":                             string(0xe42a),
+	"ViewCompact":                           string(0xe42b),
+	"ViewDay":                               string(0xe8ed),
+	"ViewHeadline":                          string(0xe8ee),
+	"ViewList":                              string(0xe8ef),
+	"ViewModule":                            string(0xe8f0),
+	"ViewQuilt":                             string(0xe8f1),
+	"ViewStream":                            string(0xe8f2),
+	"ViewWeek":                              string(0xe8f3),
+	"Vignette":                              string(0xe435),
+	"Visibility":                            string(0xe8f4),
+	"VisibilityOff":                         string(0xe8f5),
+	"VoiceChat":                             string(0xe62e),
+	"Voicemail":                             string(0xe0d9),
+	"VolumeDown":                            string(0xe04d),
+	"VolumeMute":                            string(0xe04e),
+	"VolumeOff":                             string(0xe04f),
+	"VolumeUp":                              string(0xe050),
+	"VpnKey":                                string(0xe0da),
+	"VpnLock":                               string(0xe62f),
+	"Wallpaper":                             string(0xe1bc),
+	"Warning":                               string(0xe002),
+	"Watch":                                 string(0xe334),
+	"WatchLater":                            string(0xe924),
+	"WbAuto":                                string(0xe42c),
+	"WbCloudy":                              string(0xe42d),
+	"WbIncandescent":                        string(0xe42e),
+	"WbIridescent":                          string(0xe436),
+	"WbSunny":                               string(0xe430),
+	"Wc":                                    string(0xe63d),
+	"Web":                                   string(0xe051),
+	"WebAsset":                              string(0xe069),
+	"Weekend":                               string(0xe16b),
+	"Whatshot":                              string(0xe80e),
+	"Widgets":                               string(0xe1bd),
+	"Wifi":                                  string(0xe63e),
+	"WifiLock":                              string(0xe1e1),
+	"WifiTethering":                         string(0xe1e2),
+	"Work":                                  string(0xe8f9),
+	"WrapText":                              string(0xe25b),
+	"YoutubeSearchedFor":                    string(0xe8fa),
+	"ZoomIn":                                string(0xe8ff),
+	"ZoomOut":                               string(0xe900),
+	"ZoomOutMap":                            string(0xe56b),
 }

+ 2 - 1
gui/chart.go

@@ -6,6 +6,8 @@ package gui
 
 import (
 	"fmt"
+	"math"
+
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/geometry"
 	"github.com/g3n/engine/gls"
@@ -13,7 +15,6 @@ import (
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/renderer/shaders"
-	"math"
 )
 
 func init() {

+ 3 - 2
gui/edit.go

@@ -5,11 +5,12 @@
 package gui
 
 import (
+	"strings"
+	"time"
+
 	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/text"
 	"github.com/g3n/engine/window"
-	"strings"
-	"time"
 )
 
 // Edit represents a text edit box GUI element

+ 2 - 1
gui/image.go

@@ -5,8 +5,9 @@
 package gui
 
 import (
-	"github.com/g3n/engine/texture"
 	"image"
+
+	"github.com/g3n/engine/texture"
 )
 
 // Image is a Panel which contains a single Image

+ 2 - 1
gui/itemscroller.go

@@ -5,8 +5,9 @@
 package gui
 
 import (
-	"github.com/g3n/engine/window"
 	"math"
+
+	"github.com/g3n/engine/window"
 )
 
 // ItemScroller is the GUI element that allows scrolling of IPanels

+ 2 - 1
loader/collada/animation.go

@@ -6,9 +6,10 @@ package collada
 
 import (
 	"fmt"
+	"strings"
+
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/math32"
-	"strings"
 )
 
 // AnimationTarget contains all animation channels for an specific target node

+ 3 - 2
loader/collada/collada.go

@@ -8,11 +8,12 @@ package collada
 import (
 	"encoding/xml"
 	"fmt"
+	"io"
+	"os"
+
 	"github.com/g3n/engine/geometry"
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/texture"
-	"io"
-	"os"
 )
 
 // Decoder contains all decoded data from collada file

+ 3 - 2
loader/collada/geometry.go

@@ -6,11 +6,12 @@ package collada
 
 import (
 	"fmt"
+	"reflect"
+	"strings"
+
 	"github.com/g3n/engine/geometry"
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/math32"
-	"reflect"
-	"strings"
 )
 
 // GetGeometry returns a pointer to an instance of the geometry

+ 3 - 2
loader/collada/material.go

@@ -6,11 +6,12 @@ package collada
 
 import (
 	"fmt"
+	"path/filepath"
+	"strings"
+
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/texture"
-	"path/filepath"
-	"strings"
 )
 
 // GetMaterial returns a pointer to an instance of the material

+ 2 - 1
loader/collada/scene.go

@@ -6,12 +6,13 @@ package collada
 
 import (
 	"fmt"
+	"strings"
+
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/graphic"
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/math32"
-	"strings"
 )
 
 // NewScene returns a new collada empty scene

+ 6 - 5
loader/gltf/gltf.go

@@ -6,14 +6,15 @@
 package gltf
 
 import (
+	"image"
+
 	"github.com/g3n/engine/animation"
 	"github.com/g3n/engine/camera"
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gls"
+	"github.com/g3n/engine/graphic"
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/math32"
-	"image"
-	"github.com/g3n/engine/graphic"
 )
 
 // glTF Extensions.
@@ -325,9 +326,9 @@ type Sparse struct {
 type Target struct {
 	Node int    // The index of the node to target. Not required.
 	Path string // The name of the node's TRS property to modify, or the "weights" of the Morph Targets it instantiates. Required.
-	            // For the "translation" property, the values that are provided by the sampler are the translation along the x, y, and z axes.
-	            // For the "rotation" property, the values are a quaternion in the order (x, y, z, w), where w is the scalar.
-	            // For the "scale" property, the values are the scaling factors along the x, y, and z axes.
+	// For the "translation" property, the values that are provided by the sampler are the translation along the x, y, and z axes.
+	// For the "rotation" property, the values are a quaternion in the order (x, y, z, w), where w is the scalar.
+	// For the "scale" property, the values are the scaling factors along the x, y, and z axes.
 	Extensions map[string]interface{} // Dictionary object with extension-specific objects. Not required.
 	Extras     interface{}            // Application-specific data. Not required.
 }

+ 3 - 3
loader/gltf/material_pbr.go

@@ -26,7 +26,7 @@ func (g *GLTF) loadMaterialPBR(m *Material) (material.IMaterial, error) {
 	}
 
 	var alphaMode string
-	if len(m.AlphaMode) > 0{
+	if len(m.AlphaMode) > 0 {
 		alphaMode = m.AlphaMode
 	} else {
 		alphaMode = "OPAQUE"
@@ -47,7 +47,7 @@ func (g *GLTF) loadMaterialPBR(m *Material) (material.IMaterial, error) {
 	if pbr.BaseColorFactor != nil {
 		baseColorFactor = math32.Color4{pbr.BaseColorFactor[0], pbr.BaseColorFactor[1], pbr.BaseColorFactor[2], pbr.BaseColorFactor[3]}
 	} else {
-		baseColorFactor = math32.Color4{1,1,1,1}
+		baseColorFactor = math32.Color4{1, 1, 1, 1}
 	}
 	pm.SetBaseColorFactor(&baseColorFactor)
 
@@ -81,7 +81,7 @@ func (g *GLTF) loadMaterialPBR(m *Material) (material.IMaterial, error) {
 		if m.EmissiveTexture != nil {
 			emissiveFactor = math32.Color{1, 1, 1}
 		} else {
-			emissiveFactor = math32.Color{0,0,0}
+			emissiveFactor = math32.Color{0, 0, 0}
 		}
 	}
 	pm.SetEmissiveFactor(&emissiveFactor)

+ 22 - 25
math32/curves.go

@@ -23,7 +23,7 @@ func (c *Curve) SetLength() {
 	l := float32(0.0)
 	for i := 1; i < len(points); i++ {
 		p0 := points[i].Clone()
-		p1 := points[i - 1].Clone()
+		p1 := points[i-1].Clone()
 		l += (p0.Sub(p1)).Length()
 	}
 	c.length = l
@@ -33,7 +33,7 @@ func (c *Curve) SetLength() {
 // creates and returns a pointer to a new curve
 // combined curves are unaffected
 func (c *Curve) Continue(other *Curve) *Curve {
-	last := c.points[len(c.points) - 1].Clone()
+	last := c.points[len(c.points)-1].Clone()
 	first := other.points[0].Clone()
 
 	var continued, otherpoints []Vector3
@@ -61,10 +61,10 @@ func NewBezierQuadratic(origin, control, destination *Vector3, npoints int) *Cur
 	if npoints <= 2 {
 		npoints = 3
 	}
-	var equation func(float32, float32, float32, float32) float32
-	equation = func(t, v0, v1, v2 float32) float32 {
+
+	var equation = func(t, v0, v1, v2 float32) float32 {
 		a0 := 1.0 - t
-		result := a0 * a0 * v0 + 2.0 * t * a0 * v1 + t * t * v2
+		result := a0*a0*v0 + 2.0*t*a0*v1 + t*t*v2
 		return result
 	}
 	var bezier []Vector3
@@ -92,11 +92,10 @@ func NewBezierCubic(origin, control1, control2, destination *Vector3, npoints in
 	if npoints <= 3 {
 		npoints = 4
 	}
-	
-	var equation func(float32, float32, float32, float32, float32) float32
-	equation = func(t, v0, v1, v2, v3 float32) float32 {
+
+	var equation = func(t, v0, v1, v2, v3 float32) float32 {
 		a0 := 1.0 - t
-		result := a0 * a0 * a0 * v0 + 3.0 * t * a0 * a0 * v1 + 3.0 * t * t * a0 * v2 + t * t * t * v3
+		result := a0*a0*a0*v0 + 3.0*t*a0*a0*v1 + 3.0*t*t*a0*v2 + t*t*t*v3
 		return result
 	}
 	var bezier []Vector3
@@ -121,8 +120,7 @@ func NewBezierCubic(origin, control1, control2, destination *Vector3, npoints in
 func NewHermiteSpline(origin, tangent1, destination, tangent2 *Vector3, npoints int) *Curve {
 	c := new(Curve)
 
-	var equation func(float32, *Vector3, *Vector3, *Vector3, *Vector3) *Vector3
-	equation = func(t float32, v0, tan0, v1, tan1 *Vector3) *Vector3 {
+	var equation = func(t float32, v0, tan0, v1, tan1 *Vector3) *Vector3 {
 		t2 := t * t
 		t3 := t * t2
 		p0 := (2.0 * t3) - (3.0 * t2) + 1.0
@@ -138,7 +136,7 @@ func NewHermiteSpline(origin, tangent1, destination, tangent2 *Vector3, npoints
 	step := float32(1.0) / float32(npoints)
 	var hermite []Vector3
 	for i := 0; i <= npoints; i++ {
-		vect := equation(float32(i) * step, origin, tangent1, destination, tangent2)
+		vect := equation(float32(i)*step, origin, tangent1, destination, tangent2)
 		hermite = append(hermite, *vect)
 	}
 	c.points = hermite
@@ -152,20 +150,19 @@ func NewHermiteSpline(origin, tangent1, destination, tangent2 *Vector3, npoints
 func NewCatmullRomSpline(points []*Vector3, npoints int, closed bool) *Curve {
 	c := new(Curve)
 
-	var equation func(float32, *Vector3, *Vector3, *Vector3, *Vector3) *Vector3
-	equation = func(t float32, v0, v1, v2, v3 *Vector3) *Vector3 {
-		t2 := t * t;
-		t3 := t * t2;
+	var equation = func(t float32, v0, v1, v2, v3 *Vector3) *Vector3 {
+		t2 := t * t
+		t3 := t * t2
 		x := 0.5 * ((((2.0 * v1.X) + ((-v0.X + v2.X) * t)) +
 			(((((2.0 * v0.X) - (5.0 * v1.X)) + (4.0 * v2.X)) - v3.X) * t2)) +
-			((((-v0.X + (3.0 * v1.X)) - (3.0 * v2.X)) + v3.X) * t3));
+			((((-v0.X + (3.0 * v1.X)) - (3.0 * v2.X)) + v3.X) * t3))
 		y := 0.5 * ((((2.0 * v1.Y) + ((-v0.Y + v2.Y) * t)) +
 			(((((2.0 * v0.Y) - (5.0 * v1.Y)) + (4.0 * v2.Y)) - v3.Y) * t2)) +
-			((((-v0.Y + (3.0 * v1.Y)) - (3.0 * v2.Y)) + v3.Y) * t3));
+			((((-v0.Y + (3.0 * v1.Y)) - (3.0 * v2.Y)) + v3.Y) * t3))
 		z := 0.5 * ((((2.0 * v1.Z) + ((-v0.Z + v2.Z) * t)) +
 			(((((2.0 * v0.Z) - (5.0 * v1.Z)) + (4.0 * v2.Z)) - v3.Z) * t2)) +
-			((((-v0.Z + (3.0 * v1.Z)) - (3.0 * v2.Z)) + v3.Z) * t3));
-		return NewVector3(x, y, z);
+			((((-v0.Z + (3.0 * v1.Z)) - (3.0 * v2.Z)) + v3.Z) * t3))
+		return NewVector3(x, y, z)
 	}
 
 	step := float32(1.0) / float32(npoints)
@@ -176,7 +173,7 @@ func NewCatmullRomSpline(points []*Vector3, npoints int, closed bool) *Curve {
 		for i := 0; i < count; i++ {
 			t = 0.0
 			for n := 0; n < npoints; n++ {
-				vect := equation(t, points[i % count], points[(i + 1) % count], points[(i + 2) % count], points[(i + 3) % count])
+				vect := equation(t, points[i%count], points[(i+1)%count], points[(i+2)%count], points[(i+3)%count])
 				catmull = append(catmull, *vect)
 				t += step
 			}
@@ -185,18 +182,18 @@ func NewCatmullRomSpline(points []*Vector3, npoints int, closed bool) *Curve {
 	} else {
 		total := []*Vector3{points[0].Clone()}
 		total = append(total, points...)
-		total = append(total, points[len(points) - 1].Clone())
+		total = append(total, points[len(points)-1].Clone())
 		var i int
-		for i = 0; i < len(total) - 3; i++ {
+		for i = 0; i < len(total)-3; i++ {
 			t = 0
 			for n := 0; n < npoints; n++ {
-				vect := equation(t, total[i], total[i + 1], total[i + 2], total[i + 3])
+				vect := equation(t, total[i], total[i+1], total[i+2], total[i+3])
 				catmull = append(catmull, *vect)
 				t += step
 			}
 		}
 		i--
-		vect := equation(t, total[i], total[i + 1], total[i + 2], total[i + 3])
+		vect := equation(t, total[i], total[i+1], total[i+2], total[i+3])
 		catmull = append(catmull, *vect)
 	}
 	c.points = catmull

+ 5 - 5
math32/quaternion.go

@@ -265,7 +265,7 @@ func (q *Quaternion) Normalize() *Quaternion {
 // Returns pointer to this updated quaternion.
 func (q *Quaternion) NormalizeFast() *Quaternion {
 
-	f := (3.0-(q.X*q.X + q.Y*q.Y + q.Z*q.Z + q.W*q.W))/2.0
+	f := (3.0 - (q.X*q.X + q.Y*q.Y + q.Z*q.Z + q.W*q.W)) / 2.0
 	if f == 0 {
 		q.X = 0
 		q.Y = 0
@@ -346,9 +346,9 @@ func (q *Quaternion) Slerp(other *Quaternion, t float32) *Quaternion {
 		return q
 	}
 
-	sqrSinHalfTheta := 1.0 - cosHalfTheta * cosHalfTheta
+	sqrSinHalfTheta := 1.0 - cosHalfTheta*cosHalfTheta
 	if sqrSinHalfTheta < 0.001 {
-		s := 1-t
+		s := 1 - t
 		q.W = s*w + t*q.W
 		q.X = s*x + t*q.X
 		q.Y = s*y + t*q.Y
@@ -356,8 +356,8 @@ func (q *Quaternion) Slerp(other *Quaternion, t float32) *Quaternion {
 		return q.Normalize()
 	}
 
-	sinHalfTheta := Sqrt( sqrSinHalfTheta )
-	halfTheta := Atan2( sinHalfTheta, cosHalfTheta )
+	sinHalfTheta := Sqrt(sqrSinHalfTheta)
+	halfTheta := Atan2(sinHalfTheta, cosHalfTheta)
 	ratioA := Sin((1-t)*halfTheta) / sinHalfTheta
 	ratioB := Sin(t*halfTheta) / sinHalfTheta
 

+ 2 - 2
math32/vector2.go

@@ -414,8 +414,8 @@ func (v *Vector2) InTriangle(p0, p1, p2 *Vector2) bool {
 // AlmostEquals returns whether the vector is almost equal to another vector within the specified tolerance.
 func (v *Vector2) AlmostEquals(other *Vector2, tolerance float32) bool {
 
-	if (Abs(v.X - other.X) < tolerance) &&
-		(Abs(v.Y - other.Y) < tolerance) {
+	if (Abs(v.X-other.X) < tolerance) &&
+		(Abs(v.Y-other.Y) < tolerance) {
 		return true
 	}
 	return false

+ 7 - 7
math32/vector3.go

@@ -642,12 +642,12 @@ func (v *Vector3) SetFromQuaternion(q *Quaternion) *Vector3 {
 // RandomTangents computes and returns two arbitrary tangents to the vector.
 func (v *Vector3) RandomTangents() (*Vector3, *Vector3) {
 
-	t1 := NewVector3(0,0,0)
-	t2 := NewVector3(0,0,0)
+	t1 := NewVector3(0, 0, 0)
+	t2 := NewVector3(0, 0, 0)
 	length := v.Length()
 	if length > 0 {
 		n := NewVector3(v.X/length, v.Y/length, v.Z/length)
-		randVec := NewVector3(0,0,0)
+		randVec := NewVector3(0, 0, 0)
 		if Abs(n.X) < 0.9 {
 			randVec.SetX(1)
 			t1.CrossVectors(n, randVec)
@@ -671,10 +671,10 @@ func (v *Vector3) RandomTangents() (*Vector3, *Vector3) {
 // AlmostEquals returns whether the vector is almost equal to another vector within the specified tolerance.
 func (v *Vector3) AlmostEquals(other *Vector3, tolerance float32) bool {
 
-	if (Abs(v.X - other.X) < tolerance) &&
-		(Abs(v.Y - other.Y) < tolerance) &&
-		(Abs(v.Z - other.Z) < tolerance) {
-			return true
+	if (Abs(v.X-other.X) < tolerance) &&
+		(Abs(v.Y-other.Y) < tolerance) &&
+		(Abs(v.Z-other.Z) < tolerance) {
+		return true
 	}
 	return false
 }

+ 2 - 1
renderer/renderer.go

@@ -6,6 +6,8 @@
 package renderer
 
 import (
+	"sort"
+
 	"github.com/g3n/engine/camera"
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gls"
@@ -15,7 +17,6 @@ import (
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/math32"
 	"github.com/g3n/engine/util/logger"
-	"sort"
 )
 
 // Package logger

+ 2 - 1
renderer/shaman.go

@@ -9,10 +9,11 @@ import (
 	"regexp"
 	"strings"
 
+	"strconv"
+
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/renderer/shaders"
-	"strconv"
 )
 
 // Regular expression to parse #include <name> [quantity] directive

+ 2 - 1
text/atlas.go

@@ -7,11 +7,12 @@ package text
 import (
 	"bufio"
 	"fmt"
-	"github.com/g3n/engine/math32"
 	"image"
 	"image/png"
 	"os"
 	"unicode/utf8"
+
+	"github.com/g3n/engine/math32"
 )
 
 // CharInfo contains the information to locate a character in an Atlas

+ 5 - 4
text/font.go

@@ -5,15 +5,16 @@
 package text
 
 import (
-	"github.com/g3n/engine/math32"
-	"github.com/golang/freetype/truetype"
-	"golang.org/x/image/font"
-	"golang.org/x/image/math/fixed"
 	"image"
 	"image/color"
 	"image/draw"
 	"io/ioutil"
 	"strings"
+
+	"github.com/g3n/engine/math32"
+	"github.com/golang/freetype/truetype"
+	"golang.org/x/image/font"
+	"golang.org/x/image/math/fixed"
 )
 
 // Font represents a TrueType font face.

+ 2 - 1
texture/animator.go

@@ -5,8 +5,9 @@
 package texture
 
 import (
-	"github.com/g3n/engine/gls"
 	"time"
+
+	"github.com/g3n/engine/gls"
 )
 
 // Animator can generate a texture animation based on a texture sheet

+ 2 - 1
texture/texture2D.go

@@ -7,7 +7,6 @@ package texture
 
 import (
 	"fmt"
-	"github.com/g3n/engine/util/logger"
 	"image"
 	"image/draw"
 	_ "image/gif"
@@ -15,6 +14,8 @@ import (
 	_ "image/png"
 	"os"
 
+	"github.com/g3n/engine/util/logger"
+
 	"github.com/g3n/engine/gls"
 )
 

+ 1 - 1
tools/g3nshaders/main.go

@@ -123,7 +123,7 @@ func main() {
 	flag.Parse()
 
 	// If requested, print version and exits
-	if *oVersion == true {
+	if *oVersion {
 		fmt.Fprintf(os.Stderr, "%s v%d.%d\n", PROGNAME, VMAJOR, VMINOR)
 		return
 	}

+ 2 - 1
util/stats/stats.go

@@ -1,9 +1,10 @@
 package stats
 
 import (
-	"github.com/g3n/engine/gls"
 	"runtime"
 	"time"
+
+	"github.com/g3n/engine/gls"
 )
 
 // Stats contains several statistics useful for performance evaluation

+ 3 - 2
util/wasm/wasm.go

@@ -1,3 +1,4 @@
+// +build wasm
 // +build go1.13
 
 package wasm
@@ -62,7 +63,7 @@ func sliceToByteSlice(s interface{}) []byte {
 }
 
 func SliceToTypedArray(s interface{}) (val js.Value, free func()) {
-	free = func(){}
+	free = func() {}
 	switch s := s.(type) {
 	case []int8:
 		a := js.Global().Get("Uint8Array").New(len(s))
@@ -118,4 +119,4 @@ func SliceToTypedArray(s interface{}) (val js.Value, free func()) {
 
 func Equal(a, b js.Value) bool {
 	return a.Equal(b)
-}
+}

+ 1 - 0
window/window.go

@@ -8,6 +8,7 @@ package window
 
 import (
 	"fmt"
+
 	"github.com/g3n/engine/core"
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/util/logger"