Having gamera, hump.camera and STALKER-X around, one may wonder, does the world really need yet another camera library?
No, it really doesn't. Unless... ok, ok, not that either. Or, well, maybe a little, if you are like me, and prefer that the guts of your libraries are as optimal as they can be. And that's what this library is. It isn't really full of features, but what it does, it does well, and fast, by leveraging the new built-in Transform object, and a lazy evaluation technique. At the time of writing this, none of the aforementioned libraries has been updated to use this new 11.0 feature.
It can also serve as an engine for a more powerful camera. While I have plans to build a more sophisticated camera library on top of it, these plans may not be realized until I actually have a need for something like that.
Not everything is advantages, though. The LÖVE Transform object uses single-precision floats internally, therefore the results incur a precision penalty with respect to libraries that perform the transformations in pure Lua.
NotABug repo and docs: https://notabug.org/pgimeno/cam11
cam11 - Yet another camera library
cam11 - Yet another camera library
Last edited by pgimeno on Mon Nov 11, 2019 10:13 pm, edited 1 time in total.
- zorg
- Party member
- Posts: 3468
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: cam11 - Yet another camera library
Hi!
Apart from this one tiny documentation bug i found: (should be corner or position instead, no?)
Also, i do sincerely believe that yes, the world indeed does need more camera libraries.
Apart from this one tiny documentation bug i found: (should be corner or position instead, no?)
This looks to be a neat lib; i'm guessing you tested its efficiency against the other 3 libs you mentioned?viewport_x and viewport_y are the coordinates of the top left -->angle<-- of the viewport where the camera will be rendered, in screen coordinates. The default is 0 for both.
Also, i do sincerely believe that yes, the world indeed does need more camera libraries.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: cam11 - Yet another camera library
Thanks zorg, that's a false friend that slipped in "ángulo" also means "corner" in Spanish.
To be honest, I hadn't tested them. Now I have. Here's the test program:
And here are the results: UPDATE: The results for Screen to World and World to Screen are outdated! See two posts below for updated results that include the new performance improvements.
Note that they are not entirely fair because of the different feature sets of each library. STALKER-X does not support camera rotation, and does not support clipping. gamera does not have attach/detach methods, therefore the comparison had to be done against artificially created draw() methods which have the potential of offsetting the comparison.
The big surprise came with the point transformation functions. gamera's technique of caching the sine and cosine of the angle pays off, outperforming all others by a wide margin. STALKER-X's lack of support for rotation makes the comparison with cam11 a bit unfair, beating cam11 by a tight margin. I imagine that the overhead of crossing the C++ boundary is what makes the performance of cam11 drop under the expectations. hump.camera is handicapped by its calls to love.graphics.getWidth and love.graphics.getHeight on each call to the transformation functions. It supports undocumented parameters that could solve that, but calling it with undocumented values sounded unfair.
I added the comparison of setAngle() to highlight the caching performed by gamera, but it's not really an important metric for measuring the performance of the lib. It's more usual to need to transform many points than to need to call setAngle() many times.
To be honest, I hadn't tested them. Now I have. Here's the test program:
Code: Select all
local cam11 = require 'cam11'
local stalker = require 'stalker-x'
local gamera = require 'gamera'
local humpcamera = require 'hump_camera'
local getTime = love.timer.getTime
function love.keypressed(k)
return k == "escape" and love.event.quit()
end
local ntimes = 1e7
--[.[
print('draw() test')
print('===========')
print()
local function dummy() end
local function test(cam, suite)
local start = getTime()
for i = 1, ntimes do
cam:drawtest(dummy)
end
local finish = getTime()
print(suite .. ': '.. finish - start)
end
local cam
-- Monkey-patch the objects to add a draw function to those that don't have
-- one, avoiding naming conflicts (stalker.draw is very different to
-- humpcamera.draw and gamera.draw)
cam11.drawtest = function (cam, fn)
cam:attach(false)
fn()
cam:detach()
end
test(cam11.new(), 'cam11 (no clipping)', false)
cam = stalker.new()
getmetatable(cam).__index.drawtest = cam11.drawtest
test(cam, 'STALKER-X (no clipping)')
cam = humpcamera.new()
getmetatable(cam).__index.drawtest = function (cam, fn)
cam:draw(0,0,0,0, false, fn)
end
test(humpcamera(), 'hump.camera (no clipping)')
print()
cam11.drawtest = function (cam, fn)
cam:attach(true)
fn()
cam:detach()
end
test(cam11.new(), 'cam11 (clipping)', true)
gamera.drawtest = function(cam, fn)
cam:draw(fn)
end
test(gamera.new(0, 0, 8192, 8192), 'gamera (clipping)')
humpcamera.drawtest = function (cam, fn)
cam:draw(0,0,0,0, true, fn)
end
test(humpcamera(), 'hump.camera (clipping)')
print()
print()
--]]
print('Screen to World coords conversion test')
print('======================================')
print()
test = function (cam, fn, suite)
local start = getTime()
for i = 1, ntimes do
fn(cam, i, i)
end
local finish = getTime()
print(suite .. ': '.. finish - start)
end
cam = cam11()
test(cam, cam.toWorld, 'cam11')
cam = stalker()
test(cam, cam.toWorldCoords, 'stalker')
cam = gamera.new(0, 0, 8192, 8192)
test(cam, cam.toWorld, 'gamera')
cam = humpcamera()
test(cam, cam.worldCoords, 'hump.camera')
print()
print()
print('World to Screen coords conversion test')
print('======================================')
print()
cam = cam11()
test(cam, cam.toScreen, 'cam11')
cam = stalker()
test(cam, cam.toCameraCoords, 'stalker')
cam = gamera.new(0, 0, 8192, 8192)
test(cam, cam.toScreen, 'gamera')
cam = humpcamera()
test(cam, cam.cameraCoords, 'hump.camera')
print()
print()
print('setAngle test')
print('=============')
print()
cam = cam11()
test(cam, cam.setAngle, 'cam11')
cam = gamera.new(0, 0, 8192, 8192)
test(cam, cam.setAngle, 'gamera')
cam = humpcamera()
test(cam, cam.rotateTo, 'hump.camera')
love.event.quit()
Code: Select all
draw() test
===========
cam11 (no clipping): 1.7323464825749
STALKER-X (no clipping): 4.054413462989
hump.camera (no clipping): 8.8572070803493
cam11 (clipping): 5.0095141148195
gamera (clipping): 7.060666478239
hump.camera (clipping): 8.8429979169741
Screen to World coords conversion test
======================================
cam11: 0.57571997307241
stalker: 0.53201641887426
gamera: 0.19846635125577
hump.camera: 1.7385331876576
World to Screen coords conversion test
======================================
cam11: 0.56872890982777
stalker: 0.53778914362192
gamera: 0.19814178906381
hump.camera: 1.726593574509
setAngle test
=============
cam11: 0.13578468654305
gamera: 0.92074527684599
hump.camera: 0.13101442158222
The big surprise came with the point transformation functions. gamera's technique of caching the sine and cosine of the angle pays off, outperforming all others by a wide margin. STALKER-X's lack of support for rotation makes the comparison with cam11 a bit unfair, beating cam11 by a tight margin. I imagine that the overhead of crossing the C++ boundary is what makes the performance of cam11 drop under the expectations. hump.camera is handicapped by its calls to love.graphics.getWidth and love.graphics.getHeight on each call to the transformation functions. It supports undocumented parameters that could solve that, but calling it with undocumented values sounded unfair.
I added the comparison of setAngle() to highlight the caching performed by gamera, but it's not really an important metric for measuring the performance of the lib. It's more usual to need to transform many points than to need to call setAngle() many times.
Last edited by pgimeno on Mon Nov 11, 2019 10:11 pm, edited 1 time in total.
- zorg
- Party member
- Posts: 3468
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: cam11 - Yet another camera library
And funnily enough, corner is synonymous with ankle here...
One more question; i've been working on a pretty complex camera lib as well (based on both the Scroll Back talk/article on gamasutra, and the tech demo of the dev who made Insanely Twisted Shadow Planet); i've already asked the other cam. lib. authors if they were fine with me adapting some ideas from their libraries, so i wanted to do the same and ask you as well. (Due credit given, of course)
One more question; i've been working on a pretty complex camera lib as well (based on both the Scroll Back talk/article on gamasutra, and the tech demo of the dev who made Insanely Twisted Shadow Planet); i've already asked the other cam. lib. authors if they were fine with me adapting some ideas from their libraries, so i wanted to do the same and ask you as well. (Due credit given, of course)
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: cam11 - Yet another camera library
Yeah, sure thing. Feel free to grab any ideas you find interesting.
I've updated the library to make the speed be more on par with gamera. I had to disable hump testing, as it seems to interrupt tracing (because of the love.graphics.getWidth/Height call I presume).
JIT off:
JIT on:
[Edit: I consider the latter results identical, as they are within the noise level]
I'll update the OP and the benchmark post.
I've updated the library to make the speed be more on par with gamera. I had to disable hump testing, as it seems to interrupt tracing (because of the love.graphics.getWidth/Height call I presume).
JIT off:
Code: Select all
Screen to World coords conversion test
======================================
cam11: 0.93761968333274
stalker: 1.3281588135287
gamera: 0.75724026188254
World to Screen coords conversion test
======================================
cam11: 0.78163079824299
stalker: 1.3142171455547
gamera: 0.76074439007789
Code: Select all
Screen to World coords conversion test
======================================
cam11: 0.0028397468850017
stalker: 0.0028160996735096
gamera: 0.0028035007417202
World to Screen coords conversion test
======================================
cam11: 0.0028062574565411
stalker: 0.0028091045096517
gamera: 0.0027997028082609
I'll update the OP and the benchmark post.
Re: cam11 - Yet another camera library
You are forgetting Brady. It's made by the same guy who made Walt and mlib!
My Github- your contribution is highly appreciated
Who is online
Users browsing this forum: No registered users and 3 guests