If you look closely, you will see a problem I call the “Lucky Luke Problem”: when the objects moves/rotates fast the shadow is slower than the object updates it’s position. Don’t know how to solve this, since the shadows get calculated on a Runtime “enterframe” event (it’s not possible doing it faster, isn’t it?)
Any ideas how to solve this? Maybe there is is a way to optimize the time when the shadows gets calculated?
Regarding the Lucky Luke problem, drawing your shapes using the nearest cube corner point “in the middle” of your contact shadow instead of the farthest will help a little already, I think. Are the boxes controlled by a player, or automatically? If the latter, why not move the boxes within the same enterFrame event? Everything in this code block will be drawn together before the frame is updated I believe, so things 'll move more or less in unison.
The big crate gets moved by a transition.to. The vertices at the four corners to calculate the shadow from are child objects of this crate that gets moved with the transition.to method. It seems that the child objects gets updated a bit later after the parent object.
Moving the tranistion.to directly into the shadow update method does not change the Lucky Luke effect
I think I will clean up the code a bit and put it to GitHub. Maybe someone else interested in shadows is able to optimize.
Thanks for sharing this. It works well in the simulator and on hardware (even an older gen1 Nexus 7).
I did have to make some small adjustments however. Lua is case-sensitive and some of your require statements used the wrong cases for file names. I merely updated all directory and file names to camel-case and then modified the code to use the same case.
After that… bingo. No prob.
Again, thanks for sharing this. If I find any optimizations or a solution to the ‘Lucky Luke’ issue I’ll post back.
The Lucky Luke effect does only appear if I use transition.to() to move/rotate the object. I.e. if I drag the object (the crates and lights in the example are draggable) or if I rotate a crate with
crate1.rotation = crate1.rotation + 5
in an update timer then the shadows are fine.
It seems the transition.to() let the objects updates somehow different which leads to the Lucky Luke effect.
This is a fantastic library. Well done and thank you.
I was thinking that perhaps the Lucky Luke (why that name, in particular?) problem is due to the enterFrame executing before the code executed by the transition library, yet before the screen is actually updated. Have you tried using a timer which executes at 120 times a second? (transition.to does not have a per-frame event listener, unfortunately.)
You know the Lucky Luke comic character? Maybe it’s more known in Europe (where are you from?). Lucky Luke is a Western hero that can shoot faster than is own shadow
How about a special “should this be an instant-update light” option that sets the metatable (special setting because setting the metatable results in a slower table)?
Pseudo-code (within shadows library):
[lua]
if thisLightShouldBeInstantUpdate then
local mt = getmetatable(thisLight)
local prevNewIndex = mt.__newindex
mt.__newindex = function(self, k, v)
prevNewIndex(self, k, v) – Use the original newindex function
if k == “x” or k == “y” then
self.update() – Whatever the “update this light” function is named
end
end
end
[/lua]
The above code should listen for setting of the light’s x or y value, then update the light when that happens. That way, the light will update each time it’s moved, not just on an enterFrame basis.
Of course, you probably still want the enterFrame listener to catch other objects moving.
You could expand this idea if the problem is occurring when any object moves, not just the light, and do a __newindex to update the whole scene’s light; I don’t know when this problem is happening, exactly.
Thank you for your idea, Caleb. I will definitely take a look at the metatables approach. But first I have to read about Lua metatables. I does not know anything about it.
In the Corona Geek Show #122 Charles gave me the opportunity to present the 2D shadow system. Now I updated the source code at the BitBucket repo to v1.1 which contains the latest features you can see in that Corona Geek issue.
New features are
Added circle shape support
Added support for multiple shapes per shadow caster
dded support for CodeAndWeb’s PhysicsEditor to create complex shapes
Added support for a shadow length factor. Now shadows can be longer or shorter per light source setting. (Simulates the height of the light source)
Shadows intensity can be changed independently from light source intensity. Per default it is the same, but if you want to make the shadows brighter without changing the appearance of the light.
Support for concave shapes (using multiple convex shapes)
Support for counter clockwise vertex shapes
Fixed a lense flare texture (borders were visible)
Some polishing to background and shadow caster objects (especially for the Corona Geek Show #122
To keep the compatibility to Coronas Starter Edition I implemented a image buffer technique. This means: drawing all shadow stuff on a white background, then capturing this greyscale image as a display object, hide all shadow polygon objects and finally drawing the captured image on to the screen. This might be a bit slower and I could imagine this way I use more texture memory. But at this I time I think it’s the only way to support multi shape objects with Corona Starter Edition.
Please let me know how the performance is going. @roaminggamer Ed, maybe you could use your test scene you showed at Corona Geek (now it is officially a benchmark scene for the shadow system :lol: ) and let me know how it performs.
Oh, and Ed Maurina also found a way to use transition.to() and avoid the Lucky Luke (lagging shadows) problem: do not let the transition change the x and y position of the shadow caster object directly. Instead use some interim variables to do the transition to (yes you can do transitions on variables, it must not be a display object). And then update the shadow caster’s x/y position values to these interim variables in an enterFrame event for example. Good Idea! Thank you Ed.