Skip to content

Commit

Permalink
Fix matrix update, add globaltransform
Browse files Browse the repository at this point in the history
  • Loading branch information
SpectralDragon committed Jun 6, 2024
1 parent 79e425e commit 01766e2
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 66 deletions.
2 changes: 1 addition & 1 deletion Sources/AdaEditor/AdaEditorApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct AdaEditorApp: App {

var scene: some AppScene {
GameAppScene {
SpaceInvaders()
ManySpritesExampleScene()
}
.windowMode(.windowed)
.windowTitle("AdaEngine")
Expand Down
100 changes: 100 additions & 0 deletions Sources/AdaEditor/Scenes/BunnyExampleScene.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// StressExampleScene.swift
//
//
// Created by Vladislav Prusakov on 06.06.2024.
//

import AdaEngine

class ManySpritesExampleScene: Scene {
override func sceneDidMove(to view: SceneView) {
let tilesImage = try! ResourceManager.loadSync("Assets/tiles_packed.png", from: Bundle.editor) as Image

let characterAtlas = TextureAtlas(from: tilesImage, size: [18, 18])

self.spawnEntityes(atlas: characterAtlas)

let cameraEntity = OrthographicCamera()
cameraEntity.camera.backgroundColor = Color(135/255, 206/255, 235/255, 1)
cameraEntity.camera.clearFlags = .solid
cameraEntity.camera.orthographicScale = 20

self.addEntity(cameraEntity)
self.addSystem(CamMovementSystem.self)
}

func spawnEntityes(atlas: TextureAtlas) {
let mapSize = Vector2(50)

let halfX = Int(mapSize.x / 2.0)
let halfY = Int(mapSize.y / 2.0)

var entities: Int = 0

for y in -halfY..<halfY {
for x in -halfX..<halfX {
let position = Vector2(x: Float(x), y: Float(y))
let translation = Vector3(position, 1)
let rotation = Quat(axis: Vector3(x: 0, y: 0, z: 1), angle: .random(in: 0..<2))
let scale = Vector3(.random(in: 0.3..<1))

let ent = Entity {
Transform(rotation: rotation, scale: scale, position: translation)
SpriteComponent(texture: atlas[Int.random(in: 0..<20), Int.random(in: 0..<9)])
NoFrustumCulling()
}

self.addEntity(ent)

entities += 1
}
}

print("Spawned entities", entities)
}

struct CamMovementSystem: System {

static let cameraQuery = EntityQuery(where: .has(Camera.self) && .has(Transform.self))

init(scene: Scene) { }

func update(context: UpdateContext) {
let cameraEntity: Entity = context.scene.performQuery(Self.cameraQuery).first!

var (camera, cameraTransform) = cameraEntity.components[Camera.self, Transform.self]

let speed: Float = Input.isKeyPressed(.space) ? 13 : 7
let speedNormalized: Float = speed * context.deltaTime

if Input.isKeyPressed(.w) {
cameraTransform.position.y += speedNormalized
}

if Input.isKeyPressed(.s) {
cameraTransform.position.y -= speedNormalized
}

if Input.isKeyPressed(.a) {
cameraTransform.position.x -= speedNormalized
}

if Input.isKeyPressed(.d) {
cameraTransform.position.x += speedNormalized
}

if Input.isKeyPressed(.arrowUp) {
camera.orthographicScale -= speedNormalized
}

if Input.isKeyPressed(.arrowDown) {
camera.orthographicScale += speedNormalized
}

cameraEntity.components += cameraTransform
cameraEntity.components += camera
}
}

}
8 changes: 4 additions & 4 deletions Sources/AdaEditor/Scenes/TilemapScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,11 @@ struct CamMovementSystem: System {

func update(context: UpdateContext) {
let cameraEntity: Entity = context.scene.performQuery(Self.cameraQuery).first!
let tileEntity: Entity = context.scene.performQuery(Self.tileMap).first!
// let tileEntity: Entity = context.scene.performQuery(Self.tileMap).first!

if Input.isKeyPressed(.m) {
tileEntity.components[TileMapComponent.self]!.tileMap.layers[0].isEnabled.toggle()
}
// if Input.isKeyPressed(.m) {
// tileEntity.components[TileMapComponent.self]!.tileMap.layers[0].isEnabled.toggle()
// }

var (camera, cameraTransform) = cameraEntity.components[Camera.self, Transform.self]

Expand Down
10 changes: 5 additions & 5 deletions Sources/AdaEngine/Scene/2D/Sprite/SpriteRenderSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ public struct SpriteRenderSystem: System {

public init(scene: Scene) { }

public func update(context: UpdateContext) async {
public func update(context: UpdateContext) {
let extractedSprites = context.scene.performQuery(Self.extractedSprites)

await context.scene.performQuery(Self.cameras).concurrent.forEach { entity in
context.scene.performQuery(Self.cameras).forEach { entity in
let visibleEntities = entity.components[VisibleEntities.self]!
var renderItems = entity.components[RenderItems<Transparent2DRenderItem>.self]!

Expand Down Expand Up @@ -221,7 +221,7 @@ public struct ExtractSpriteSystem: System {

public static let dependencies: [SystemDependency] = [.after(VisibilitySystem.self)]

static let sprites = EntityQuery(where: .has(SpriteComponent.self) && .has(Transform.self) && .has(Visibility.self))
static let sprites = EntityQuery(where: .has(SpriteComponent.self) && .has(GlobalTransform.self) && .has(Transform.self) && .has(Visibility.self))

public init(scene: Scene) { }

Expand All @@ -230,7 +230,7 @@ public struct ExtractSpriteSystem: System {
var extractedSprites = ExtractedSprites(sprites: [])

context.scene.performQuery(Self.sprites).forEach { entity in
let (sprite, transform, visible) = entity.components[SpriteComponent.self, Transform.self, Visibility.self]
let (sprite, globalTransform, transform, visible) = entity.components[SpriteComponent.self, GlobalTransform.self, Transform.self, Visibility.self]

if !visible.isVisible {
return
Expand All @@ -242,7 +242,7 @@ public struct ExtractSpriteSystem: System {
texture: sprite.texture,
tintColor: sprite.tintColor,
transform: transform,
worldTransform: transform.matrix
worldTransform: globalTransform.matrix
)
)
}
Expand Down
46 changes: 25 additions & 21 deletions Sources/AdaEngine/Scene/Components/Transform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// Created by v.prusakov on 11/1/21.
//

import Math

/// A component that defines the scale, rotation, and translation of an entity.
@Component
public struct Transform: Codable, Hashable {
Expand Down Expand Up @@ -37,27 +39,6 @@ public struct Transform: Codable, Hashable {
}
}

public extension Transform {

/// The transform represented as a Transform3D aka 4x4 matrix.
/// - Note: Getter of this property is compute.
var matrix: Transform3D {
get {
Transform3D(
translation: self.position,
rotation: self.rotation,
scale: self.scale
)
}

set {
self.scale = newValue.scale
self.rotation = newValue.rotation
self.position = newValue.origin
}
}
}

public extension ScriptableComponent {

/// Return transform component for current entity.
Expand All @@ -70,4 +51,27 @@ public extension ScriptableComponent {
return self.components[Transform.self] = newValue
}
}

/// Return global transform component for current entity.
var globalTransform: GlobalTransform {
return self.components[GlobalTransform.self]!
}
}

/// A component that describe global transform of an entity
///
/// - Note: To update position, scale or rotation of an entity, use ``Transform`` component.
@Component
public struct GlobalTransform {
public internal(set) var matrix: Transform3D
}

public extension GlobalTransform {
func getTransform() -> Transform {
Transform(
rotation: self.matrix.rotation,
scale: self.matrix.scale,
position: self.matrix.origin
)
}
}
6 changes: 3 additions & 3 deletions Sources/AdaEngine/Scene/Components/VisibleEntities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ public struct VisibilitySystem: System {
var bounds: BoundingComponent.Bounds?

if entity.components.has(SpriteComponent.self) || entity.components.has(Circle2DComponent.self) {
let transform = entity.components[Transform.self]!

if !entity.components.isComponentChanged(transform) && entity.components.has(BoundingComponent.self) {
if !entity.components.isComponentChanged(Transform.self) && entity.components.has(BoundingComponent.self) {
return
}

let transform = entity.components[Transform.self]!

let position = transform.position
let scale = transform.scale
Expand Down
8 changes: 6 additions & 2 deletions Sources/AdaEngine/Scene/ECS/Entity/Entity+ComponentSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,18 @@ public extension Entity {
public var isEmpty: Bool {
return self.buffer.isEmpty
}

public func isComponentChanged<T: Component>(_ component: T) -> Bool {
public func isComponentChanged<T: Component>(_ componentType: T.Type) -> Bool {
guard let entity = self.entity else {
return false
}

return world?.isComponentChanged(T.identifier, for: entity) ?? false
}

public func isComponentChanged<T: Component>(_ component: T) -> Bool {
return self.isComponentChanged(T.self)
}
}
}

Expand Down
14 changes: 7 additions & 7 deletions Sources/AdaEngine/Scene/Resources/Texture/TextureAtlas.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,20 @@ public final class TextureAtlas: Texture2D {
// MARK: - Slices

/// Create a slice of the texture.
public subscript(x: Float, y: Float) -> Slice {
return self.textureSlice(at: Vector2(x: x, y: y))
public subscript(x: Int, y: Int) -> Slice {
return self.textureSlice(at: PointInt(x: x, y: y))
}

/// Create a slice of the texture.
public func textureSlice(at position: Vector2) -> Slice {
public func textureSlice(at position: PointInt) -> Slice {
let min = Vector2(
(position.x * Float((spriteSize.width + margin.width))) / Float(self.width),
(position.y * Float((spriteSize.height + margin.height))) / Float(self.height)
(Float(position.x) * Float((spriteSize.width + margin.width))) / Float(self.width),
(Float(position.y) * Float((spriteSize.height + margin.height))) / Float(self.height)
)

let max = Vector2(
((position.x + 1) * Float((spriteSize.width + margin.width))) / Float(self.width),
((position.y + 1) * Float((spriteSize.height + margin.height))) / Float(self.height)
(Float(position.x + 1) * Float((spriteSize.width + margin.width))) / Float(self.width),
(Float(position.y + 1) * Float((spriteSize.height + margin.height))) / Float(self.height)
)

return Slice(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ public class TextureAtlasTileSource: TileSource {
let alignment = tileData.animationColumnsAlignment

for index in 0..<tileData.animationFrameColumns {
let x = Float(atlasCoordinates.x + (alignment == .horizontal ? index : 0))
let y = Float(atlasCoordinates.y + (alignment == .vertical ? index : 0))
let x = atlasCoordinates.x + (alignment == .horizontal ? index : 0)
let y = atlasCoordinates.y + (alignment == .vertical ? index : 0)

let slice = self.textureAtlas.textureSlice(at: [x, y])
animatedTexture[index] = slice
Expand All @@ -96,7 +96,7 @@ public class TextureAtlasTileSource: TileSource {
return animatedTexture
}

return self.textureAtlas.textureSlice(at: Vector2(Float(atlasCoordinates.x), Float(atlasCoordinates.y)))
return self.textureAtlas.textureSlice(at: [atlasCoordinates.x, atlasCoordinates.y])
}

@discardableResult
Expand Down
2 changes: 1 addition & 1 deletion Sources/AdaEngine/Scene/Scene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ public extension Scene {
transform = self.worldTransformMatrix(for: parent)
}

guard let entityTransform = entity.components[Transform.self] else {
guard let entityTransform = entity.components[GlobalTransform.self] else {
return transform
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
struct TransformPlugin: ScenePlugin {
func setup(in scene: Scene) async {
scene.addSystem(TransformSystem.self)
scene.addSystem(ChildTransformSystem.self)
}
}
Loading

0 comments on commit 01766e2

Please sign in to comment.