From 72cec5fb833c6c714a90a1d755c461f45f40a3c1 Mon Sep 17 00:00:00 2001 From: Momchil Atanasov Date: Sat, 5 Jun 2021 17:57:23 +0300 Subject: [PATCH] Use ecs framework from lacking --- cmd/rallymka/internal/ecs/manager.go | 39 ------ cmd/rallymka/internal/ecs/renderer.go | 36 ------ cmd/rallymka/internal/ecscomp/camera.go | 27 ++++ cmd/rallymka/internal/ecscomp/identifiers.go | 13 ++ cmd/rallymka/internal/ecscomp/physics.go | 22 ++++ cmd/rallymka/internal/ecscomp/player.go | 17 +++ cmd/rallymka/internal/ecscomp/render.go | 22 ++++ .../{ecs/entity.go => ecscomp/vehicle.go} | 35 ++---- cmd/rallymka/internal/ecssys/render.go | 45 +++++++ .../internal/{ecs => ecssys}/stand.go | 36 ++++-- .../internal/{ecs => ecssys}/vehicle.go | 37 +++--- cmd/rallymka/internal/scene/car/chassis.go | 21 ++-- cmd/rallymka/internal/scene/car/wheel.go | 21 ++-- cmd/rallymka/internal/scene/stage.go | 118 ++++++++++-------- go.mod | 2 +- go.sum | 4 +- 16 files changed, 291 insertions(+), 204 deletions(-) delete mode 100644 cmd/rallymka/internal/ecs/manager.go delete mode 100644 cmd/rallymka/internal/ecs/renderer.go create mode 100644 cmd/rallymka/internal/ecscomp/camera.go create mode 100644 cmd/rallymka/internal/ecscomp/identifiers.go create mode 100644 cmd/rallymka/internal/ecscomp/physics.go create mode 100644 cmd/rallymka/internal/ecscomp/player.go create mode 100644 cmd/rallymka/internal/ecscomp/render.go rename cmd/rallymka/internal/{ecs/entity.go => ecscomp/vehicle.go} (51%) create mode 100644 cmd/rallymka/internal/ecssys/render.go rename cmd/rallymka/internal/{ecs => ecssys}/stand.go (68%) rename cmd/rallymka/internal/{ecs => ecssys}/vehicle.go (82%) diff --git a/cmd/rallymka/internal/ecs/manager.go b/cmd/rallymka/internal/ecs/manager.go deleted file mode 100644 index ab50722..0000000 --- a/cmd/rallymka/internal/ecs/manager.go +++ /dev/null @@ -1,39 +0,0 @@ -package ecs - -// FIXME: This whole manager is suboptimal and open to bugs -// (for example: deleting an entity while iterating) - -func NewManager() *Manager { - return &Manager{ - entities: make([]*Entity, 0), - } -} - -type Manager struct { - entities []*Entity -} - -func (m *Manager) Entities() []*Entity { - return m.entities -} - -func (m *Manager) CreateEntity() *Entity { - entity := &Entity{} - m.entities = append(m.entities, entity) - return entity -} - -func (m *Manager) DeleteEntity(entity *Entity) { - index := -1 - for i, candidate := range m.entities { - if candidate == entity { - index = i - break - } - } - if index != -1 { - count := len(m.entities) - m.entities[index] = m.entities[count-1] - m.entities = m.entities[:count-1] - } -} diff --git a/cmd/rallymka/internal/ecs/renderer.go b/cmd/rallymka/internal/ecs/renderer.go deleted file mode 100644 index fe0f9ae..0000000 --- a/cmd/rallymka/internal/ecs/renderer.go +++ /dev/null @@ -1,36 +0,0 @@ -package ecs - -import ( - "github.com/mokiat/gomath/sprec" - "github.com/mokiat/lacking/render" -) - -func NewRenderer(ecsManager *Manager, scene *render.Scene) *Renderer { - return &Renderer{ - ecsManager: ecsManager, - scene: scene, - } -} - -type Renderer struct { - ecsManager *Manager - scene *render.Scene -} - -func (r *Renderer) Update() { - for _, entity := range r.ecsManager.Entities() { - renderComp := entity.Render - physicsComp := entity.Physics - if renderComp == nil || physicsComp == nil { - continue - } - body := physicsComp.Body - renderComp.Renderable.Matrix = sprec.TransformationMat4( - body.Orientation().OrientationX(), - body.Orientation().OrientationY(), - body.Orientation().OrientationZ(), - body.Position(), - ) - r.scene.Layout().InvalidateRenderable(renderComp.Renderable) - } -} diff --git a/cmd/rallymka/internal/ecscomp/camera.go b/cmd/rallymka/internal/ecscomp/camera.go new file mode 100644 index 0000000..33ebe39 --- /dev/null +++ b/cmd/rallymka/internal/ecscomp/camera.go @@ -0,0 +1,27 @@ +package ecscomp + +import ( + "github.com/mokiat/gomath/sprec" + "github.com/mokiat/lacking/game/ecs" + "github.com/mokiat/lacking/render" +) + +func SetCameraStand(entity *ecs.Entity, component *CameraStand) { + entity.SetComponent(CameraStandComponentID, component) +} + +func GetCameraStand(entity *ecs.Entity) *CameraStand { + component := entity.Component(CameraStandComponentID) + if component == nil { + return nil + } + return component.(*CameraStand) +} + +type CameraStand struct { + Target *ecs.Entity + AnchorPosition sprec.Vec3 + AnchorDistance float32 + CameraDistance float32 + Camera *render.Camera +} diff --git a/cmd/rallymka/internal/ecscomp/identifiers.go b/cmd/rallymka/internal/ecscomp/identifiers.go new file mode 100644 index 0000000..91a516c --- /dev/null +++ b/cmd/rallymka/internal/ecscomp/identifiers.go @@ -0,0 +1,13 @@ +package ecscomp + +import ( + "github.com/mokiat/lacking/game/ecs" +) + +const ( + PhysicsComponentID ecs.ComponentTypeID = iota + RenderComponentID + VehicleComponentID + PlayerControlComponentID + CameraStandComponentID +) diff --git a/cmd/rallymka/internal/ecscomp/physics.go b/cmd/rallymka/internal/ecscomp/physics.go new file mode 100644 index 0000000..ed5a78e --- /dev/null +++ b/cmd/rallymka/internal/ecscomp/physics.go @@ -0,0 +1,22 @@ +package ecscomp + +import ( + "github.com/mokiat/lacking/game/ecs" + "github.com/mokiat/lacking/game/physics" +) + +type Physics struct { + Body *physics.Body +} + +func SetPhysics(entity *ecs.Entity, component *Physics) { + entity.SetComponent(PhysicsComponentID, component) +} + +func GetPhysics(entity *ecs.Entity) *Physics { + component := entity.Component(PhysicsComponentID) + if component == nil { + return nil + } + return component.(*Physics) +} diff --git a/cmd/rallymka/internal/ecscomp/player.go b/cmd/rallymka/internal/ecscomp/player.go new file mode 100644 index 0000000..94a40b5 --- /dev/null +++ b/cmd/rallymka/internal/ecscomp/player.go @@ -0,0 +1,17 @@ +package ecscomp + +import "github.com/mokiat/lacking/game/ecs" + +func SetPlayerControl(entity *ecs.Entity, component *PlayerControl) { + entity.SetComponent(PlayerControlComponentID, component) +} + +func GetPlayerControl(entity *ecs.Entity) *PlayerControl { + component := entity.Component(PlayerControlComponentID) + if component == nil { + return nil + } + return component.(*PlayerControl) +} + +type PlayerControl struct{} diff --git a/cmd/rallymka/internal/ecscomp/render.go b/cmd/rallymka/internal/ecscomp/render.go new file mode 100644 index 0000000..c49fac6 --- /dev/null +++ b/cmd/rallymka/internal/ecscomp/render.go @@ -0,0 +1,22 @@ +package ecscomp + +import ( + "github.com/mokiat/lacking/game/ecs" + "github.com/mokiat/lacking/render" +) + +func SetRender(entity *ecs.Entity, component *Render) { + entity.SetComponent(RenderComponentID, component) +} + +func GetRender(entity *ecs.Entity) *Render { + component := entity.Component(RenderComponentID) + if component == nil { + return nil + } + return component.(*Render) +} + +type Render struct { + Renderable *render.Renderable +} diff --git a/cmd/rallymka/internal/ecs/entity.go b/cmd/rallymka/internal/ecscomp/vehicle.go similarity index 51% rename from cmd/rallymka/internal/ecs/entity.go rename to cmd/rallymka/internal/ecscomp/vehicle.go index 7603de9..b801252 100644 --- a/cmd/rallymka/internal/ecs/entity.go +++ b/cmd/rallymka/internal/ecscomp/vehicle.go @@ -1,29 +1,22 @@ -package ecs +package ecscomp import ( "github.com/mokiat/gomath/sprec" + "github.com/mokiat/lacking/game/ecs" "github.com/mokiat/lacking/game/physics" "github.com/mokiat/lacking/game/physics/solver" - "github.com/mokiat/lacking/render" ) -type Entity struct { - Physics *PhysicsComponent - Render *RenderComponent - Vehicle *Vehicle - CameraStand *CameraStand - PlayerControl *PlayerControl +func SetVehicle(entity *ecs.Entity, component *Vehicle) { + entity.SetComponent(VehicleComponentID, component) } -type PhysicsComponent struct { - Body *physics.Body -} - -type RenderComponent struct { - Renderable *render.Renderable -} - -type PlayerControl struct { +func GetVehicle(entity *ecs.Entity) *Vehicle { + component := entity.Component(VehicleComponentID) + if component == nil { + return nil + } + return component.(*Vehicle) } type Vehicle struct { @@ -47,11 +40,3 @@ type Wheel struct { AccelerationVelocity float32 DecelerationVelocity float32 } - -type CameraStand struct { - Target *Entity - AnchorPosition sprec.Vec3 - AnchorDistance float32 - CameraDistance float32 - Camera *render.Camera -} diff --git a/cmd/rallymka/internal/ecssys/render.go b/cmd/rallymka/internal/ecssys/render.go new file mode 100644 index 0000000..efe428b --- /dev/null +++ b/cmd/rallymka/internal/ecssys/render.go @@ -0,0 +1,45 @@ +package ecssys + +import ( + "github.com/mokiat/gomath/sprec" + "github.com/mokiat/lacking/game/ecs" + "github.com/mokiat/lacking/render" + "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecscomp" +) + +func NewRenderer(ecsScene *ecs.Scene, scene *render.Scene) *Renderer { + return &Renderer{ + ecsScene: ecsScene, + scene: scene, + } +} + +type Renderer struct { + ecsScene *ecs.Scene + scene *render.Scene +} + +func (r *Renderer) Update() { + result := r.ecsScene.Find(ecs. + Having(ecscomp.PhysicsComponentID). + And(ecscomp.RenderComponentID)) + defer result.Close() + + for result.HasNext() { + entity := result.Next() + + physicsComp := ecscomp.GetPhysics(entity) + body := physicsComp.Body + + renderComp := ecscomp.GetRender(entity) + renderable := renderComp.Renderable + + renderable.Matrix = sprec.TransformationMat4( + body.Orientation().OrientationX(), + body.Orientation().OrientationY(), + body.Orientation().OrientationZ(), + body.Position(), + ) + r.scene.Layout().InvalidateRenderable(renderable) + } +} diff --git a/cmd/rallymka/internal/ecs/stand.go b/cmd/rallymka/internal/ecssys/stand.go similarity index 68% rename from cmd/rallymka/internal/ecs/stand.go rename to cmd/rallymka/internal/ecssys/stand.go index e3d8474..c004484 100644 --- a/cmd/rallymka/internal/ecs/stand.go +++ b/cmd/rallymka/internal/ecssys/stand.go @@ -1,37 +1,47 @@ -package ecs +package ecssys import ( "time" "github.com/mokiat/gomath/sprec" "github.com/mokiat/lacking/app" + "github.com/mokiat/lacking/game/ecs" + "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecscomp" ) -func NewCameraStandSystem(ecsManager *Manager) *CameraStandSystem { +func NewCameraStandSystem(ecsScene *ecs.Scene) *CameraStandSystem { return &CameraStandSystem{ - ecsManager: ecsManager, + ecsScene: ecsScene, } } type CameraStandSystem struct { - ecsManager *Manager + ecsScene *ecs.Scene } func (s *CameraStandSystem) Update(elapsedTime time.Duration, gamepad *app.GamepadState) { - for _, entity := range s.ecsManager.Entities() { - if cameraStand := entity.CameraStand; cameraStand != nil { - s.updateCameraStand(cameraStand, elapsedTime, gamepad) - } + result := s.ecsScene.Find(ecs.Having(ecscomp.CameraStandComponentID)) + defer result.Close() + + for result.HasNext() { + entity := result.Next() + cameraStand := ecscomp.GetCameraStand(entity) + s.updateCameraStand(cameraStand, elapsedTime, gamepad) } } -func (s *CameraStandSystem) updateCameraStand(cameraStand *CameraStand, elapsedTime time.Duration, gamepad *app.GamepadState) { +func (s *CameraStandSystem) updateCameraStand(cameraStand *ecscomp.CameraStand, elapsedTime time.Duration, gamepad *app.GamepadState) { + var ( + targetPhysicsComp = ecscomp.GetPhysics(cameraStand.Target) + targetRenderComp = ecscomp.GetRender(cameraStand.Target) + ) + var targetPosition sprec.Vec3 switch { - case cameraStand.Target.Physics != nil: - targetPosition = cameraStand.Target.Physics.Body.Position() - case cameraStand.Target.Render != nil: - targetPosition = cameraStand.Target.Render.Renderable.Matrix.Translation() + case targetPhysicsComp != nil: + targetPosition = targetPhysicsComp.Body.Position() + case targetRenderComp != nil: + targetPosition = targetRenderComp.Renderable.Matrix.Translation() } // we use a camera anchor to achieve the smooth effect of a // camera following the target diff --git a/cmd/rallymka/internal/ecs/vehicle.go b/cmd/rallymka/internal/ecssys/vehicle.go similarity index 82% rename from cmd/rallymka/internal/ecs/vehicle.go rename to cmd/rallymka/internal/ecssys/vehicle.go index 07214f7..032d833 100644 --- a/cmd/rallymka/internal/ecs/vehicle.go +++ b/cmd/rallymka/internal/ecssys/vehicle.go @@ -1,10 +1,12 @@ -package ecs +package ecssys import ( "time" "github.com/mokiat/gomath/sprec" "github.com/mokiat/lacking/app" + "github.com/mokiat/lacking/game/ecs" + "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecscomp" ) const ( @@ -12,14 +14,14 @@ const ( steeringRestoreSpeed = steeringSpeed * 2 ) -func NewVehicleSystem(ecsManager *Manager) *VehicleSystem { +func NewVehicleSystem(ecsScene *ecs.Scene) *VehicleSystem { return &VehicleSystem{ - ecsManager: ecsManager, + ecsScene: ecsScene, } } type VehicleSystem struct { - ecsManager *Manager + ecsScene *ecs.Scene isSteerLeft bool isSteerRight bool @@ -51,21 +53,24 @@ func (s *VehicleSystem) OnKeyboardEvent(event app.KeyboardEvent) bool { } func (s *VehicleSystem) Update(elapsedTime time.Duration, gamepad *app.GamepadState) { - for _, entity := range s.ecsManager.Entities() { - if vehicle := entity.Vehicle; vehicle != nil { - if entity.PlayerControl != nil { - if gamepad != nil { - s.updateVehicleControlGamepad(vehicle, elapsedTime, gamepad) - } else { - s.updateVehicleControlKeyboard(vehicle, elapsedTime) - } + result := s.ecsScene.Find(ecs.Having(ecscomp.VehicleComponentID)) + defer result.Close() + + for result.HasNext() { + entity := result.Next() + vehicle := ecscomp.GetVehicle(entity) + if ecscomp.GetPlayerControl(entity) != nil { + if gamepad != nil { + s.updateVehicleControlGamepad(vehicle, elapsedTime, gamepad) + } else { + s.updateVehicleControlKeyboard(vehicle, elapsedTime) } - s.updateVehiclePhysics(vehicle, elapsedTime) } + s.updateVehiclePhysics(vehicle, elapsedTime) } } -func (s *VehicleSystem) updateVehicleControlGamepad(vehicle *Vehicle, elapsedTime time.Duration, gamepad *app.GamepadState) { +func (s *VehicleSystem) updateVehicleControlGamepad(vehicle *ecscomp.Vehicle, elapsedTime time.Duration, gamepad *app.GamepadState) { steeringAmount := gamepad.LeftStickX * sprec.Abs(gamepad.LeftStickX) vehicle.SteeringAngle = -sprec.Degrees(steeringAmount * vehicle.MaxSteeringAngle.Degrees()) vehicle.Acceleration = gamepad.RightTrigger @@ -73,7 +78,7 @@ func (s *VehicleSystem) updateVehicleControlGamepad(vehicle *Vehicle, elapsedTim vehicle.Recover = gamepad.LeftBumper } -func (s *VehicleSystem) updateVehicleControlKeyboard(vehicle *Vehicle, elapsedTime time.Duration) { +func (s *VehicleSystem) updateVehicleControlKeyboard(vehicle *ecscomp.Vehicle, elapsedTime time.Duration) { elapsedSeconds := float32(elapsedTime.Seconds()) vehicle.Recover = s.isRecover @@ -116,7 +121,7 @@ func (s *VehicleSystem) updateVehicleControlKeyboard(vehicle *Vehicle, elapsedTi } } -func (s *VehicleSystem) updateVehiclePhysics(vehicle *Vehicle, elapsedTime time.Duration) { +func (s *VehicleSystem) updateVehiclePhysics(vehicle *ecscomp.Vehicle, elapsedTime time.Duration) { elapsedSeconds := float32(elapsedTime.Seconds()) if vehicle.Recover { diff --git a/cmd/rallymka/internal/scene/car/chassis.go b/cmd/rallymka/internal/scene/car/chassis.go index 1aafb6a..221702a 100644 --- a/cmd/rallymka/internal/scene/car/chassis.go +++ b/cmd/rallymka/internal/scene/car/chassis.go @@ -2,11 +2,12 @@ package car import ( "github.com/mokiat/gomath/sprec" + "github.com/mokiat/lacking/game/ecs" "github.com/mokiat/lacking/game/physics" "github.com/mokiat/lacking/render" "github.com/mokiat/lacking/resource" "github.com/mokiat/lacking/shape" - "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecs" + "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecscomp" ) const ( @@ -31,19 +32,21 @@ type ChassisBuilder struct { func (b *ChassisBuilder) WithName(name string) *ChassisBuilder { b.modifiers = append(b.modifiers, func(entity *ecs.Entity) { - entity.Physics.Body.SetName(name) + physicsComponent := ecscomp.GetPhysics(entity) + physicsComponent.Body.SetName(name) }) return b } func (b *ChassisBuilder) WithPosition(position sprec.Vec3) *ChassisBuilder { b.modifiers = append(b.modifiers, func(entity *ecs.Entity) { - entity.Physics.Body.SetPosition(position) + physicsComponent := ecscomp.GetPhysics(entity) + physicsComponent.Body.SetPosition(position) }) return b } -func (b *ChassisBuilder) Build(ecsManager *ecs.Manager, scene *render.Scene, physicsScene *physics.Scene) *ecs.Entity { +func (b *ChassisBuilder) Build(ecsScene *ecs.Scene, scene *render.Scene, physicsScene *physics.Scene) *ecs.Entity { bodyNode, _ := b.model.FindNode("Chassis") physicsBody := physicsScene.CreateBody() @@ -62,17 +65,17 @@ func (b *ChassisBuilder) Build(ecsManager *ecs.Manager, scene *render.Scene, phy }, }) - entity := ecsManager.CreateEntity() - entity.Physics = &ecs.PhysicsComponent{ + entity := ecsScene.CreateEntity() + ecscomp.SetPhysics(entity, &ecscomp.Physics{ Body: physicsBody, - } - entity.Render = &ecs.RenderComponent{ + }) + ecscomp.SetRender(entity, &ecscomp.Render{ Renderable: scene.Layout().CreateRenderable(sprec.IdentityMat4(), 100.0, &resource.Model{ Nodes: []*resource.Node{ bodyNode, }, }), - } + }) for _, modifier := range b.modifiers { modifier(entity) diff --git a/cmd/rallymka/internal/scene/car/wheel.go b/cmd/rallymka/internal/scene/car/wheel.go index 0c9d1bd..155f6a9 100644 --- a/cmd/rallymka/internal/scene/car/wheel.go +++ b/cmd/rallymka/internal/scene/car/wheel.go @@ -4,11 +4,12 @@ import ( "fmt" "github.com/mokiat/gomath/sprec" + "github.com/mokiat/lacking/game/ecs" "github.com/mokiat/lacking/game/physics" "github.com/mokiat/lacking/render" "github.com/mokiat/lacking/resource" "github.com/mokiat/lacking/shape" - "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecs" + "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecscomp" ) const ( @@ -44,19 +45,21 @@ type WheelBuilder struct { func (b *WheelBuilder) WithName(name string) *WheelBuilder { b.modifiers = append(b.modifiers, func(entity *ecs.Entity) { - entity.Physics.Body.SetName(name) + physicsComponent := ecscomp.GetPhysics(entity) + physicsComponent.Body.SetName(name) }) return b } func (b *WheelBuilder) WithPosition(position sprec.Vec3) *WheelBuilder { b.modifiers = append(b.modifiers, func(entity *ecs.Entity) { - entity.Physics.Body.SetPosition(position) + physicsComponent := ecscomp.GetPhysics(entity) + physicsComponent.Body.SetPosition(position) }) return b } -func (b *WheelBuilder) Build(ecsManager *ecs.Manager, scene *render.Scene, physicsScene *physics.Scene) *ecs.Entity { +func (b *WheelBuilder) Build(ecsScene *ecs.Scene, scene *render.Scene, physicsScene *physics.Scene) *ecs.Entity { modelNode, _ := b.model.FindNode(fmt.Sprintf("%sWheel", b.location)) physicsBody := physicsScene.CreateBody() @@ -76,17 +79,17 @@ func (b *WheelBuilder) Build(ecsManager *ecs.Manager, scene *render.Scene, physi }, }) - entity := ecsManager.CreateEntity() - entity.Physics = &ecs.PhysicsComponent{ + entity := ecsScene.CreateEntity() + ecscomp.SetPhysics(entity, &ecscomp.Physics{ Body: physicsBody, - } - entity.Render = &ecs.RenderComponent{ + }) + ecscomp.SetRender(entity, &ecscomp.Render{ Renderable: scene.Layout().CreateRenderable(sprec.IdentityMat4(), 100.0, &resource.Model{ Nodes: []*resource.Node{ modelNode, }, }), - } + }) for _, modifier := range b.modifiers { modifier(entity) } diff --git a/cmd/rallymka/internal/scene/stage.go b/cmd/rallymka/internal/scene/stage.go index 96e2e23..57a635b 100644 --- a/cmd/rallymka/internal/scene/stage.go +++ b/cmd/rallymka/internal/scene/stage.go @@ -6,12 +6,14 @@ import ( "github.com/mokiat/gomath/sprec" "github.com/mokiat/lacking/app" "github.com/mokiat/lacking/async" + "github.com/mokiat/lacking/game/ecs" "github.com/mokiat/lacking/game/physics" "github.com/mokiat/lacking/game/physics/solver" "github.com/mokiat/lacking/graphics" "github.com/mokiat/lacking/render" "github.com/mokiat/lacking/resource" - "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecs" + "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecscomp" + "github.com/mokiat/rally-mka/cmd/rallymka/internal/ecssys" "github.com/mokiat/rally-mka/cmd/rallymka/internal/scene/car" ) @@ -41,15 +43,16 @@ type CarInput struct { func NewStage() *Stage { scene := render.NewScene() - ecsManager := ecs.NewManager() + ecsEngine := ecs.NewEngine() + ecsScene := ecsEngine.CreateScene() physicsEngine := physics.NewEngine() stage := &Stage{ scene: scene, camera: render.NewCamera(), - ecsManager: ecsManager, - ecsRenderer: ecs.NewRenderer(ecsManager, scene), - ecsVehicleSystem: ecs.NewVehicleSystem(ecsManager), - ecsCameraStandSystem: ecs.NewCameraStandSystem(ecsManager), + ecsScene: ecsScene, + ecsRenderer: ecssys.NewRenderer(ecsScene, scene), + ecsVehicleSystem: ecssys.NewVehicleSystem(ecsScene), + ecsCameraStandSystem: ecssys.NewCameraStandSystem(ecsScene), physicsScene: physicsEngine.CreateScene(0.015), } return stage @@ -58,10 +61,10 @@ func NewStage() *Stage { type Stage struct { scene *render.Scene camera *render.Camera - ecsManager *ecs.Manager - ecsRenderer *ecs.Renderer - ecsVehicleSystem *ecs.VehicleSystem - ecsCameraStandSystem *ecs.CameraStandSystem + ecsScene *ecs.Scene + ecsRenderer *ecssys.Renderer + ecsVehicleSystem *ecssys.VehicleSystem + ecsCameraStandSystem *ecssys.CameraStandSystem physicsScene *physics.Scene } @@ -109,50 +112,54 @@ func (s *Stage) Init(gfxWorker *async.Worker, data *Data) { carModel := data.CarModel targetEntity := s.setupCarDemo(carModel, sprec.NewVec3(0.0, 3.0, 0.0)) standTarget := targetEntity - standEntity := s.ecsManager.CreateEntity() - standEntity.CameraStand = &ecs.CameraStand{ + standEntity := s.ecsScene.CreateEntity() + ecscomp.SetCameraStand(standEntity, &ecscomp.CameraStand{ Target: standTarget, Camera: s.camera, - AnchorPosition: sprec.Vec3Sum(standTarget.Physics.Body.Position(), sprec.NewVec3(0.0, 0.0, -cameraDistance)), + AnchorPosition: sprec.Vec3Sum(ecscomp.GetPhysics(standTarget).Body.Position(), sprec.NewVec3(0.0, 0.0, -cameraDistance)), AnchorDistance: anchorDistance, CameraDistance: cameraDistance, - } + }) } func (s *Stage) setupCarDemo(model *resource.Model, position sprec.Vec3) *ecs.Entity { + const ( + suspensionEnabled = true + suspensionStart = float32(-0.25) + suspensionEnd = float32(-0.6) + suspensionWidth = float32(1.0) + suspensionLength = float32(0.25) + suspensionFrequencyHz = float32(3.0) + suspensionDampingRatio = float32(1.0) + ) + chasis := car.Chassis(model). WithName("chasis"). WithPosition(position). - Build(s.ecsManager, s.scene, s.physicsScene) - - suspensionEnabled := true - suspensionStart := float32(-0.25) - suspensionEnd := float32(-0.6) - suspensionWidth := float32(1.0) - suspensionLength := float32(0.25) - suspensionFrequencyHz := float32(3.0) - suspensionDampingRatio := float32(1.0) + Build(s.ecsScene, s.scene, s.physicsScene) + chasisPhysics := ecscomp.GetPhysics(chasis) flWheelRelativePosition := sprec.NewVec3(suspensionWidth, suspensionStart-suspensionLength, 1.07) flWheel := car.Wheel(model, car.FrontLeftWheelLocation). WithName("front-left-wheel"). WithPosition(sprec.Vec3Sum(position, flWheelRelativePosition)). - Build(s.ecsManager, s.scene, s.physicsScene) + Build(s.ecsScene, s.scene, s.physicsScene) + flWheelPhysics := ecscomp.GetPhysics(flWheel) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, flWheel.Physics.Body, + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, flWheelPhysics.Body, solver.NewMatchTranslation(). SetPrimaryAnchor(flWheelRelativePosition). SetIgnoreY(suspensionEnabled), ) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, flWheel.Physics.Body, &solver.LimitTranslation{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, flWheelPhysics.Body, &solver.LimitTranslation{ MaxY: suspensionStart, MinY: suspensionEnd, }) flRotation := solver.NewMatchAxis(). SetPrimaryAxis(sprec.BasisXVec3()). SetSecondaryAxis(sprec.BasisXVec3()) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, flWheel.Physics.Body, flRotation) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, flWheel.Physics.Body, &solver.Coilover{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, flWheelPhysics.Body, flRotation) + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, flWheelPhysics.Body, &solver.Coilover{ PrimaryAnchor: flWheelRelativePosition, FrequencyHz: suspensionFrequencyHz, DampingRatio: suspensionDampingRatio, @@ -162,21 +169,22 @@ func (s *Stage) setupCarDemo(model *resource.Model, position sprec.Vec3) *ecs.En frWheel := car.Wheel(model, car.FrontRightWheelLocation). WithName("front-right-wheel"). WithPosition(sprec.Vec3Sum(position, frWheelRelativePosition)). - Build(s.ecsManager, s.scene, s.physicsScene) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, frWheel.Physics.Body, + Build(s.ecsScene, s.scene, s.physicsScene) + frWheelPhysics := ecscomp.GetPhysics(frWheel) + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, frWheelPhysics.Body, solver.NewMatchTranslation(). SetPrimaryAnchor(frWheelRelativePosition). SetIgnoreY(suspensionEnabled), ) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, frWheel.Physics.Body, &solver.LimitTranslation{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, frWheelPhysics.Body, &solver.LimitTranslation{ MaxY: suspensionStart, MinY: suspensionEnd, }) frRotation := solver.NewMatchAxis(). SetPrimaryAxis(sprec.BasisXVec3()). SetSecondaryAxis(sprec.BasisXVec3()) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, frWheel.Physics.Body, frRotation) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, frWheel.Physics.Body, &solver.Coilover{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, frWheelPhysics.Body, frRotation) + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, frWheelPhysics.Body, &solver.Coilover{ PrimaryAnchor: frWheelRelativePosition, FrequencyHz: suspensionFrequencyHz, DampingRatio: suspensionDampingRatio, @@ -186,22 +194,23 @@ func (s *Stage) setupCarDemo(model *resource.Model, position sprec.Vec3) *ecs.En blWheel := car.Wheel(model, car.BackLeftWheelLocation). WithName("back-left-wheel"). WithPosition(sprec.Vec3Sum(position, blWheelRelativePosition)). - Build(s.ecsManager, s.scene, s.physicsScene) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, blWheel.Physics.Body, + Build(s.ecsScene, s.scene, s.physicsScene) + blWheelPhysics := ecscomp.GetPhysics(blWheel) + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, blWheelPhysics.Body, solver.NewMatchTranslation(). SetPrimaryAnchor(blWheelRelativePosition). SetIgnoreY(suspensionEnabled), ) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, blWheel.Physics.Body, &solver.LimitTranslation{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, blWheelPhysics.Body, &solver.LimitTranslation{ MaxY: suspensionStart, MinY: suspensionEnd, }) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, blWheel.Physics.Body, + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, blWheelPhysics.Body, solver.NewMatchAxis(). SetPrimaryAxis(sprec.BasisXVec3()). SetSecondaryAxis(sprec.BasisXVec3()), ) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, blWheel.Physics.Body, &solver.Coilover{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, blWheelPhysics.Body, &solver.Coilover{ PrimaryAnchor: blWheelRelativePosition, FrequencyHz: suspensionFrequencyHz, DampingRatio: suspensionDampingRatio, @@ -211,61 +220,62 @@ func (s *Stage) setupCarDemo(model *resource.Model, position sprec.Vec3) *ecs.En brWheel := car.Wheel(model, car.BackRightWheelLocation). WithName("back-right-wheel"). WithPosition(sprec.Vec3Sum(position, brWheelRelativePosition)). - Build(s.ecsManager, s.scene, s.physicsScene) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, brWheel.Physics.Body, + Build(s.ecsScene, s.scene, s.physicsScene) + brWheelPhysics := ecscomp.GetPhysics(brWheel) + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, brWheelPhysics.Body, solver.NewMatchTranslation(). SetPrimaryAnchor(brWheelRelativePosition). SetIgnoreY(suspensionEnabled), ) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, brWheel.Physics.Body, &solver.LimitTranslation{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, brWheelPhysics.Body, &solver.LimitTranslation{ MaxY: suspensionStart, MinY: suspensionEnd, }) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, brWheel.Physics.Body, solver.NewMatchAxis(). + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, brWheelPhysics.Body, solver.NewMatchAxis(). SetPrimaryAxis(sprec.BasisXVec3()). SetSecondaryAxis(sprec.BasisXVec3()), ) - s.physicsScene.CreateDoubleBodyConstraint(chasis.Physics.Body, brWheel.Physics.Body, &solver.Coilover{ + s.physicsScene.CreateDoubleBodyConstraint(chasisPhysics.Body, brWheelPhysics.Body, &solver.Coilover{ PrimaryAnchor: brWheelRelativePosition, FrequencyHz: suspensionFrequencyHz, DampingRatio: suspensionDampingRatio, }) - car := s.ecsManager.CreateEntity() - car.Vehicle = &ecs.Vehicle{ + car := s.ecsScene.CreateEntity() + ecscomp.SetVehicle(car, &ecscomp.Vehicle{ MaxSteeringAngle: sprec.Degrees(carMaxSteeringAngle), SteeringAngle: sprec.Degrees(0.0), Acceleration: 0.0, Deceleration: 0.0, - Chassis: &ecs.Chassis{ - Body: chasis.Physics.Body, + Chassis: &ecscomp.Chassis{ + Body: chasisPhysics.Body, }, - Wheels: []*ecs.Wheel{ + Wheels: []*ecscomp.Wheel{ { - Body: flWheel.Physics.Body, + Body: flWheelPhysics.Body, RotationConstraint: flRotation, AccelerationVelocity: carFrontAcceleration, DecelerationVelocity: carFrontDeceleration, }, { - Body: frWheel.Physics.Body, + Body: frWheelPhysics.Body, RotationConstraint: frRotation, AccelerationVelocity: carFrontAcceleration, DecelerationVelocity: carFrontDeceleration, }, { - Body: blWheel.Physics.Body, + Body: blWheelPhysics.Body, AccelerationVelocity: carRearAcceleration, DecelerationVelocity: carRearDeceleration, }, { - Body: brWheel.Physics.Body, + Body: brWheelPhysics.Body, AccelerationVelocity: carRearAcceleration, DecelerationVelocity: carRearDeceleration, }, }, - } - car.PlayerControl = &ecs.PlayerControl{} + }) + ecscomp.SetPlayerControl(car, &ecscomp.PlayerControl{}) return chasis } diff --git a/go.mod b/go.mod index df538ab..e41c7bf 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.16 require ( github.com/mokiat/gomath v0.1.0 - github.com/mokiat/lacking v0.1.1-0.20210602184749-78725fb3f0b0 + github.com/mokiat/lacking v0.1.1-0.20210605144919-30a470105a07 ) diff --git a/go.sum b/go.sum index 32cf622..4bbe0fc 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,8 @@ github.com/mdouchement/hdr v0.2.3 h1:IxzxLgEarv9VPsk17DGIWnhA60MA5ASbekCU8YSFmaY github.com/mdouchement/hdr v0.2.3/go.mod h1:2Yb3JAST9c66wTLZ1vQrejU5sDeOC+ukXVs1pFAUtPo= github.com/mokiat/gomath v0.1.0 h1:wSBt+R4mT+9ndA3iPGKxWRAI+G/8Nmdic2xiCFC6hvc= github.com/mokiat/gomath v0.1.0/go.mod h1:KWlJ2no76F4c6nrnJ7VFwdMKtzbmQXfYuDzwJsm/Xng= -github.com/mokiat/lacking v0.1.1-0.20210602184749-78725fb3f0b0 h1:VNXH6m1mypqXGrDOMUSouQEjdyEbVAuNqXkxrxrqejI= -github.com/mokiat/lacking v0.1.1-0.20210602184749-78725fb3f0b0/go.mod h1:GF61qQ47jiL3QepaCn5bGwHwRyb1YZupUyHbspzFVQI= +github.com/mokiat/lacking v0.1.1-0.20210605144919-30a470105a07 h1:M32CDX4oX8tpzkvgs9oQrqkFRTRjTJGan30l0g/FoGY= +github.com/mokiat/lacking v0.1.1-0.20210605144919-30a470105a07/go.mod h1:GF61qQ47jiL3QepaCn5bGwHwRyb1YZupUyHbspzFVQI= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=