# HG changeset patch # User Sam # Date 1687799860 -25200 # Node ID a4c757f5d17f4712e889c6a33cc0bda463d3d1f9 # Parent 4f991bc3613ace11917995548c3a2eee3dabefd3 did: change API for ECS diff -r 4f991bc3613a -r a4c757f5d17f examples/E01_hello_triangle.nim --- a/examples/E01_hello_triangle.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/examples/E01_hello_triangle.nim Tue Jun 27 00:17:40 2023 +0700 @@ -27,10 +27,10 @@ var triangle = newScene("scene", newEntity( "triangle", - newMesh( + {"mesh": Component(newMesh( [newVec3f(-0.5, 0.5), newVec3f(0, -0.5), newVec3f(0.5, 0.5)], [newVec4f(1, 0, 0, 1), newVec4f(0, 1, 0, 1), newVec4f(0, 0, 1, 1)], - ) + ))} )) myengine = initEngine("Hello triangle") renderPass = myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode) diff -r 4f991bc3613a -r a4c757f5d17f examples/E02_squares.nim --- a/examples/E02_squares.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/examples/E02_squares.nim Tue Jun 27 00:17:40 2023 +0700 @@ -81,7 +81,7 @@ var myengine = initEngine("Squares") myengine.setRenderer(myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode)) - var scene = newScene("scene", newEntity("scene", newEntity("squares", squaremesh))) + var scene = newScene("scene", newEntity("scene", [], newEntity("squares", {"mesh": Component(squaremesh)}))) myengine.addScene(scene, vertexInput, @[], transformAttribute="") scene.addShaderGlobal("time", 0.0'f32) while myengine.updateInputs() == Running and not myengine.keyWasPressed(Escape): diff -r 4f991bc3613a -r a4c757f5d17f examples/E03_hello_cube.nim --- a/examples/E03_hello_cube.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/examples/E03_hello_cube.nim Tue Jun 27 00:17:40 2023 +0700 @@ -78,7 +78,7 @@ main="color = outcolor;" ) myengine.setRenderer(myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode)) - var cube = newScene("scene", newEntity("cube", newMesh(positions=cube_pos, indices=tris, colors=cube_color))) + var cube = newScene("scene", newEntity("cube", {"mesh": Component(newMesh(positions=cube_pos, indices=tris, colors=cube_color))})) cube.addShaderGlobal("projection", Unit4f32) cube.addShaderGlobal("view", Unit4f32) cube.addShaderGlobal("model", Unit4f32) diff -r 4f991bc3613a -r a4c757f5d17f examples/E04_input.nim --- a/examples/E04_input.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/examples/E04_input.nim Tue Jun 27 00:17:40 2023 +0700 @@ -135,15 +135,15 @@ # define mesh objects scene = newScene("scene", newEntity("scene")) - scene.root.add newEntity("background", backgroundmesh) - let keyboard = newEntity("keyboard", keyboardmesh) + scene.root.add newEntity("background", {"mesh": Component(backgroundmesh)}) + let keyboard = newEntity("keyboard", {"mesh": Component(keyboardmesh)}) keyboard.transform = translate3d( -float32(rowWidth) / 2'f32, -float32(tupleLen(keyRows) * (keyDimension + keyGap) - keyGap) / 2'f32, 0'f32 ) - scene.root.add newEntity("keyboard-center", keyboard) - scene.root.add newEntity("cursor", cursormesh) + scene.root.add newEntity("keyboard-center", [], keyboard) + scene.root.add newEntity("cursor", {"mesh": Component(cursormesh)}) # shaders const @@ -194,7 +194,7 @@ let mousePos = translate3d(myengine.mousePosition().x + 20, myengine.mousePosition().y + 20, 0'f32) scene.root.firstWithName("cursor").transform = mousePos - var mesh = Mesh(scene.root.firstWithName("keyboard").components[0]) + var mesh = Mesh(scene.root.firstWithName("keyboard")["mesh"]) for (index, key) in enumerate(keyIndices): if myengine.keyWasPressed(key): let baseIndex = uint32(index * 4) diff -r 4f991bc3613a -r a4c757f5d17f examples/E10_pong.nim --- a/examples/E10_pong.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/examples/E10_pong.nim Tue Jun 27 00:17:40 2023 +0700 @@ -19,14 +19,14 @@ var myengine = initEngine("Pong") level = newScene("scene", newEntity("Level")) var playerbarmesh = rect(color=barcolor) - var playerbar = newEntity("playerbar", playerbarmesh) + var playerbar = newEntity("playerbar", {"mesh": Component(playerbarmesh)}) playerbar.transform = scale3d(barWidth, barSize, 1'f) * translate3d(0.5'f, 0'f, 0'f) - var player = newEntity("player", playerbar) + var player = newEntity("player", [], playerbar) player.transform = translate3d(0'f, 0.3'f, 0'f) level.root.add player var ballmesh = circle(color=ballcolor) - var ball = newEntity("ball", ballmesh) + var ball = newEntity("ball", {"mesh": Component(ballmesh)}) ball.transform = scale3d(ballSize, ballSize, 1'f) * translate3d(10'f, 10'f, 0'f) level.root.add ball diff -r 4f991bc3613a -r a4c757f5d17f src/semicongine/animation.nim --- a/src/semicongine/animation.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/src/semicongine/animation.nim Tue Jun 27 00:17:40 2023 +0700 @@ -4,7 +4,6 @@ import std/strformat import std/algorithm -import ./scene import ./core/matrix type diff -r 4f991bc3613a -r a4c757f5d17f src/semicongine/core/matrix.nim --- a/src/semicongine/core/matrix.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/src/semicongine/core/matrix.nim Tue Jun 27 00:17:40 2023 +0700 @@ -2,6 +2,7 @@ import std/macros import std/random import std/strutils +import std/strformat import std/typetraits import ./vector diff -r 4f991bc3613a -r a4c757f5d17f src/semicongine/resources/mesh.nim --- a/src/semicongine/resources/mesh.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/src/semicongine/resources/mesh.nim Tue Jun 27 00:17:40 2023 +0700 @@ -237,7 +237,7 @@ # mesh if node.hasKey("mesh"): - result.add loadMesh(root, root["meshes"][node["mesh"].getInt()], mainBuffer) + result[name & "_mesh"] = loadMesh(root, root["meshes"][node["mesh"].getInt()], mainBuffer) proc loadScene(root: JsonNode, scenenode: JsonNode, mainBuffer: var seq[uint8]): Scene = var rootEntity = newEntity("") diff -r 4f991bc3613a -r a4c757f5d17f src/semicongine/scene.nim --- a/src/semicongine/scene.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/src/semicongine/scene.nim Tue Jun 27 00:17:40 2023 +0700 @@ -29,7 +29,7 @@ internal_transform: Mat4 # todo: cache transform + only update VBO when transform changed parent*: Entity children*: seq[Entity] - components*: seq[Component] + components*: Table[string, Component] EntityAnimation* = ref object of Component player: AnimationPlayer[Mat4] @@ -53,7 +53,7 @@ func transform*(entity: Entity): Mat4 = result = entity.internal_transform - for component in entity.components.mitems: + for component in entity.components.mvalues: if component of EntityAnimation and EntityAnimation(component).player.playing: result = result * EntityAnimation(component).player.currentValue @@ -129,41 +129,25 @@ proc add*(entity: Entity, child: Entity) = child.parent = entity entity.children.add child -proc add*(entity: Entity, component: Component) = +proc `[]=`*(entity: Entity, index: int, child: Entity) = + child.parent = entity + entity.children[index] = child +proc `[]`*(entity: Entity, index: int): Entity = + entity.children[index] + +proc `[]=`*(entity: Entity, name: string, component: Component) = component.entity = entity - entity.components.add component -proc add*(entity: Entity, children: seq[Entity]) = - for child in children: - child.parent = entity - entity.children.add child -proc add*(entity: Entity, components: seq[Component]) = - for component in components: - component.entity = entity - entity.components.add component + entity.components[name] = component +proc `[]`*(entity: Entity, name: string): Component = + entity.components[name] -func newEntity*(name: string = ""): Entity = +func newEntity*(name: string, components: openArray[(string, Component)] = [], children: varargs[Entity]): Entity = result = new Entity - result.name = name - result.internal_transform = Unit4 - if result.name == "": - result.name = &"Entity[{$(cast[ByteAddress](result))}]" - -func newEntity*(name: string, firstChild: Entity, children: varargs[Entity]): Entity = - result = new Entity - result.add firstChild for child in children: result.add child result.name = name - result.internal_transform = Unit4 - if result.name == "": - result.name = &"Entity[{$(cast[ByteAddress](result))}]" - -proc newEntity*(name: string, firstComponent: Component, components: varargs[Component]): Entity = - result = new Entity - result.name = name - result.add firstComponent - for component in components: - result.add component + for (name, comp) in components: + result[name] = comp if result.name == "": result.name = &"Entity[{$(cast[ByteAddress](result))}]" result.internal_transform = Unit4 @@ -181,7 +165,7 @@ var queue = @[root] while queue.len > 0: let entity = queue.pop - for component in entity.components.mitems: + for component in entity.components.mvalues: if component of T: yield T(component) for i in countdown(entity.children.len - 1, 0): @@ -240,8 +224,8 @@ proc prettyRecursive*(entity: Entity): seq[string] = var compList: seq[string] - for comp in entity.components: - compList.add $comp + for (name, comp) in entity.components.pairs: + compList.add name & ": " & $comp var trans = entity.transform.col(3) var pos = entity.getModelTransform().col(3) diff -r 4f991bc3613a -r a4c757f5d17f src/semicongine/settings.nim --- a/src/semicongine/settings.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/src/semicongine/settings.nim Tue Jun 27 00:17:40 2023 +0700 @@ -2,7 +2,6 @@ import std/streams import std/parsecfg import std/strutils -import std/sequtils import std/parseutils import std/strformat import std/tables diff -r 4f991bc3613a -r a4c757f5d17f src/semicongine/text.nim --- a/src/semicongine/text.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/src/semicongine/text.nim Tue Jun 27 00:17:40 2023 +0700 @@ -88,7 +88,7 @@ Entity(result).transform = Unit4F32 # wrap the text mesh in a new entity to preserve the font-scaling - var box = newEntity("box", result.mesh) + var box = newEntity("box", {"mesh": Component(result.mesh)}) # box.transform = scale3d(font.fontscale * 0.002, font.fontscale * 0.002) box.transform = scale3d(1 / font.resolution, 1 / font.resolution) result.add box diff -r 4f991bc3613a -r a4c757f5d17f tests/test_materials.nim --- a/tests/test_materials.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/tests/test_materials.nim Tue Jun 27 00:17:40 2023 +0700 @@ -4,7 +4,7 @@ import semicongine proc main() = - var scene = newScene("main", root=newEntity("rect", rect())) + var scene = newScene("main", root=newEntity("rect", {"mesh": Component(rect())})) let (RT, WT, PT) = (hexToColorAlpha("A51931").asPixel, hexToColorAlpha("F4F5F8").asPixel, hexToColorAlpha("2D2A4A").asPixel) let # image from memory diff -r 4f991bc3613a -r a4c757f5d17f tests/test_mesh.nim --- a/tests/test_mesh.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/tests/test_mesh.nim Tue Jun 27 00:17:40 2023 +0700 @@ -1,8 +1,8 @@ import semicongine proc main() = - var ent1 = newEntity("hoho", rect()) - var ent2 = newEntity("hehe", ent1) + var ent1 = newEntity("hoho", {"mesh": Component(rect())}) + var ent2 = newEntity("hehe", [], ent1) var myScene = newScene("hi", ent2) myScene.root.transform = translate3d(0.2'f32, 0'f32, 0'f32) myScene.root.children[0].transform = translate3d(0'f32, 0.2'f32, 0'f32) diff -r 4f991bc3613a -r a4c757f5d17f tests/test_vulkan_wrapper.nim --- a/tests/test_vulkan_wrapper.nim Tue Jun 27 00:01:36 2023 +0700 +++ b/tests/test_vulkan_wrapper.nim Tue Jun 27 00:17:40 2023 +0700 @@ -3,37 +3,37 @@ import semicongine proc scene_different_mesh_types(): Entity = - result = newEntity("root", - newEntity("triangle1", newMesh( + result = newEntity("root", [], + newEntity("triangle1", {"mesh": Component(newMesh( positions=[newVec3f(0.0, -0.5), newVec3f(0.5, 0.5), newVec3f(-0.5, 0.5)], colors=[newVec4f(1.0, 0.0, 0.0, 1), newVec4f(0.0, 1.0, 0.0, 1), newVec4f(0.0, 0.0, 1.0, 1)], - )), - newEntity("triangle1b", newMesh( + ))}), + newEntity("triangle1b", {"mesh": Component(newMesh( positions=[newVec3f(0.0, -0.4), newVec3f(0.4, 0.4), newVec3f(-0.4, 0.5)], colors=[newVec4f(1.0, 0.0, 0.0, 1), newVec4f(0.0, 1.0, 0.0, 1), newVec4f(0.0, 0.0, 1.0, 1)], - )), - newEntity("triangle2a", newMesh( + ))}), + newEntity("triangle2a", {"mesh": Component(newMesh( positions=[newVec3f(0.0, 0.5), newVec3f(0.5, -0.5), newVec3f(-0.5, -0.5)], colors=[newVec4f(1.0, 0.0, 0.0, 1), newVec4f(0.0, 1.0, 0.0, 1), newVec4f(0.0, 0.0, 1.0, 1)], indices=[[0'u16, 2'u16, 1'u16]] - )), - newEntity("triangle2b", newMesh( + ))}), + newEntity("triangle2b", {"mesh": Component(newMesh( positions=[newVec3f(0.0, 0.4), newVec3f(0.4, -0.4), newVec3f(-0.4, -0.4)], colors=[newVec4f(1.0, 0.0, 0.0, 1), newVec4f(0.0, 1.0, 0.0, 1), newVec4f(0.0, 0.0, 1.0, 1)], indices=[[0'u16, 2'u16, 1'u16]] - )), - newEntity("triangle3a", newMesh( + ))}), + newEntity("triangle3a", {"mesh": Component(newMesh( positions=[newVec3f(0.4, 0.5), newVec3f(0.9, -0.3), newVec3f(0.0, -0.3)], colors=[newVec4f(1.0, 1.0, 0.0, 1), newVec4f(1.0, 1.0, 0.0, 1), newVec4f(1.0, 1.0, 0.0, 1)], indices=[[0'u32, 2'u32, 1'u32]], autoResize=false - )), - newEntity("triangle3b", newMesh( + ))}), + newEntity("triangle3b", {"mesh": Component(newMesh( positions=[newVec3f(0.4, 0.5), newVec3f(0.9, -0.3), newVec3f(0.0, -0.3)], colors=[newVec4f(1.0, 1.0, 0.0, 1), newVec4f(1.0, 1.0, 0.0, 1), newVec4f(1.0, 1.0, 0.0, 1)], indices=[[0'u32, 2'u32, 1'u32]], autoResize=false - )), + ))}), ) for mesh in allComponentsOfType[Mesh](result): mesh.setInstanceData("translate", @[newVec3f()]) @@ -63,7 +63,7 @@ mymesh2.setInstanceData("translate", @[newVec3f(0.0, 0.3)]) mymesh3.setInstanceData("translate", @[newVec3f(-0.3, 0.0)]) mymesh4.setInstanceData("translate", @[newVec3f(0.0, -0.3), newVec3f(0.0, 0.5)]) - result = newEntity("root", newEntity("triangle", mymesh4, mymesh3, mymesh2, mymesh1)) + result = newEntity("root", [], newEntity("triangle", {"mesh1": Component(mymesh4), "mesh2": Component(mymesh3), "mesh3": Component(mymesh2), "mesh4": Component(mymesh1)})) proc scene_primitives(): Entity = var r = rect(color="ff0000") @@ -73,12 +73,12 @@ r.setInstanceData("translate", @[newVec3f(0.5, -0.3)]) t.setInstanceData("translate", @[newVec3f(0.3, 0.3)]) c.setInstanceData("translate", @[newVec3f(-0.3, 0.1)]) - result = newEntity("root", t, r, c) + result = newEntity("root", {"mesh1": Component(t), "mesh1": Component(r), "mesh1": Component(c)}) proc scene_flag(): Entity = var r = rect(color="ff0000") r.updateMeshData("color", @[newVec4f(0, 0), newVec4f(1, 0), newVec4f(1, 1), newVec4f(0, 1)]) - result = newEntity("root", r) + result = newEntity("root", {"mesh": Component(r)}) proc main() = var engine = initEngine("Test")