love.scene (yet another scene graph library)

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: love.scene (yet another scene graph library)

Post by ivan »

Hello and thank you for the feedback. Upon more testing I found a few minor issues with the transformation functions so please update your code with the latest version from GitHub. Thanks for your patience.

The way to transform coordinates is different based on your scene setup. You have two ways of drawing the scene: with cameras or without cameras.

1. If you do NOT use cameras the transformations are much simpler. In this case the root layer is parented by the view.

Code: Select all

function love.load()
  Scene = require('scene')
  view = Scene.newView()

  local gw, gh = love.graphics.getDimensions()
  view:setDimensions(300, 300)
  view:setPosition(gw/2 - 300/2, gh/2 - 300/2)
  view:setBackground(0, 1, 1)

  root = view:newLayer(0, 0)
  sprite = root:newSprite(0, 0)
  sprite:setGraphic(love.graphics.newImage('icon.png'))
end

function love.update(dt)
  local mx, my = love.mouse.getPosition()

  local lx, ly = sprite:windowToLocal(mx, my)
  local px, py = sprite:localToParent(lx, ly)
  sprite:setPosition(px, py)
end

function love.draw()
  view:draw()
end
2. If you do use cameras, then make sure that your root layer does NOT have a parent. This will save you a lot of confusion later.

Code: Select all

function love.load()
  Scene = require('scene')
  view = Scene.newView()

  local gw, gh = love.graphics.getDimensions()
  view:setDimensions(300, 300)
  view:setPosition(gw/2 - 300/2, gh/2 - 300/2)
  view:setBackground(0, 1, 1)

  local w, h = view:getDimensions()
  root = Scene.newLayer(0, 0) -- no parent

  camera = root:newCamera(w/2, h/2)
  camera:setRotation(math.pi/8)

  sprite = root:newSprite(0, 0)
  sprite:setGraphic(love.graphics.newImage('icon.png'))
end

function love.update(dt)
  local mx, my = love.mouse.getPosition()

  -- convert the mouse to local view coordinates
  -- the camera coords are the same as the local view coords!
  local x, y = view:windowToLocal(mx, my)
  local px, py = camera:localToRoot(x, y)
  sprite:setPosition(px, py)
end

function love.draw()
  view:draw(camera)
end
I will try to do additional testing and promise to provide more updates if I found any other issues.
User avatar
yetneverdone
Party member
Posts: 448
Joined: Sat Sep 24, 2016 11:20 am
Contact:

Re: love.scene (yet another scene graph library)

Post by yetneverdone »

Hi, thanks for the explanation! I used the camera example, but it seems that it's inverted. The sprite follows the mouse in an inverted way.
lovec_UwZdCP9Xya.gif
lovec_UwZdCP9Xya.gif (1.56 MiB) Viewed 7846 times
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: love.scene (yet another scene graph library)

Post by ivan »

With the introduction of the camera objects you have the option to render the same camera across multiple views. Therefore, when using cameras the functions sprite:localToWindow(x,y) and sprite:windowToLocal(x, y) will return nil. The root object must be a "View" if you want to use sprite:localToWindow or sprite:windowToLocal.

I made some adjustments to the library which should make it somewhat easier to use cameras. The basic idea is to use view:setCamera(cam) and then view:windowToRoot(mx, my) to convert your mouse coords to scene coords.
Here is the gist of it:

Code: Select all

function love.load()
  -- setup the view
  Scene = require('scene')
  view = Scene.newView()
  local gw, gh = love.graphics.getDimensions()
  view:setDimensions(300, 300)
  view:setPosition(gw/2 - 300/2, gh/2 - 300/2)
  view:setBackground(0, 1, 1)
  -- scene and camera
  local w, h = view:getDimensions()
  root = Scene.newLayer(0, 0) -- no parent
  camera = root:newCamera(0, 0)
  view:setCamera(camera)
  camera:setRotation(math.pi/8)
  -- sprite and graphic
  sprite = root:newSprite(0, 0)
  local img = love.graphics.newImage('icon.png')
  local iw, ih = img:getDimensions()
  sprite:setGraphic(img, -iw/2, -ih/2)
end

function love.update(dt)
  -- convert the mouse to scene and move the sprite under it
  local mx, my = love.mouse.getPosition()
  local rx, ry = view:windowToRoot(mx, my)
  sprite:setPosition(rx, ry)
end

function love.draw()
  view:draw()
end
Thank you again for the feedback. I think the library has become much better thanks to your suggestions.
Attachments
nocam.love
(11.1 KiB) Downloaded 160 times
cam.love
(11.18 KiB) Downloaded 142 times
User avatar
yetneverdone
Party member
Posts: 448
Joined: Sat Sep 24, 2016 11:20 am
Contact:

Re: love.scene (yet another scene graph library)

Post by yetneverdone »

Awesome! It works correctly now! Thanks a lot. I'll post here again if I have a question or suggestion :)
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: love.scene (yet another scene graph library)

Post by ivan »

4-7% increase in speed when drawing and transforming sprites through the use of local variables in conjunction with the debug registry
https://github.com/2dengine/love.scene/ ... r=2dengine
User avatar
yetneverdone
Party member
Posts: 448
Joined: Sat Sep 24, 2016 11:20 am
Contact:

Re: love.scene (yet another scene graph library)

Post by yetneverdone »

Question, given this node structure/hierarchy.

Code: Select all

- root layer
- layer 1
  - sprite1 node
  - sprite2 node
  
shouldn't the sprite nodes follow the layer 1 position when the layer 1 moves?

Also, shouldn't the `sprite1:getRoot()` return the `layer 1` instead of the `root layer`? Right now it returns the `root layer`. I think getting the nearest parent is useful
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: love.scene (yet another scene graph library)

Post by ivan »

yetneverdone wrote: Mon Jan 23, 2023 1:00 pm shouldn't the sprite nodes follow the layer 1 position when the layer 1 moves?
Yes they should! Please provide code examples if you have come across a bug.
yetneverdone wrote: Mon Jan 23, 2023 1:00 pm Also, shouldn't the `sprite1:getRoot()` return the `layer 1` instead of the `root layer`? Right now it returns the `root layer`. I think getting the nearest parent is useful
Just a small clarification: is "layer 1" a child of "root layer" or its sibling?
I have just added "node:getParent()" which was missing from the library.
User avatar
yetneverdone
Party member
Posts: 448
Joined: Sat Sep 24, 2016 11:20 am
Contact:

Re: love.scene (yet another scene graph library)

Post by yetneverdone »

Just a small clarification: is "layer 1" a child of "root layer" or its sibling?
oh I missed that, layer 1 is child of root layer.
I have just added "node:getParent()" which was missing from the library.
thank you! will check again and see if i just missed something on my end
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: love.scene (yet another scene graph library)

Post by ivan »

By avoiding metatables we achieved 5-10% increase in performance for most games depending on the total number of sprites. Please use scene.cache to adjust how this works.
https://github.com/2dengine/love.scene/ ... ce46297ebb
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 2 guests