Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

[FIXED] How can I use graphics.newOutline() with @2x and @4x image substitution?
Started by ksan Feb 09 2014 02:56 PM

23 replies to this topic
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

The new graphics.newOutline() works great in the actual resolution of the png file provided. When I use it with a display.newImageRect I have a problem though. newImageRect substitutes higher resolution assets depending on the device specifics and the outline used in physics.addBody does not seem to follow suit. Is there a way around this issue?

 

I could use display.newImage obviously and not make use of the higher resolution assets but then the visuals are not appealing at all. What is the best strategy to follow in this situation? Thanks for your help.



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,558 posts
  • Enterprise

In what way isn't it working?  The physics body should be relative to your content area so it shouldn't matter which image it grabs.

 

Rob



[TOPIC: post.html]
#3

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

In what way it isn't working? Hybrid mode allows me to verify the physics body drawn vs the actual image and I can see the physics body is following the pixel count of x1 image that was used in creating it. Here's how I do it currently (as per sample app etc)

 

local imageOutline = graphics.newOutline( 2, "myImage.png" ) 
local physicsPiece = display.newImageRect(group, "myImage.png", 60, 512);
physics.addBody(physicsPiece, "static", {bounce = 0, outline=imageOutline});  

So my x1 image is 60x512. The graphics.newOutline works on it and gets me an outline which I then feed into the physics.addBody. The object is created with the newImageRect though so this means it might pull in the @2x (120x1024) or even @4x (240 x 2048) images respectively. The graphics.newOutline does not seem to pull in the @2x or @4x when needed. Does this help clarify my problem?

 

Thanks for your help.



[TOPIC: post.html]
#4

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

A potential workaround could be to detect the resolution we are running in and therefore understand which image will be used by display.newImageRect and feed that version of the image to graphics.newOutline. Short of graphics.newOutline becoming able to  automatically substitute higher-resolution assets on higher-resolution devices this could be a possible way to deal with this issue. Would you agree?



[TOPIC: post.html]
#5

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,558 posts
  • Enterprise

I would think that the values are based on the content area you have defined in your config.lua.  The scaling should not have an effect.

 

Lets say you have a 1x image that generates say a 100x100 square.   That's a 100x100 in your content area.  If we load in the @2x image, even though its 200x200, it's still 100x100 with regards to your content area and that polygon would still be the right shape.  The @4x at 400x400 still takes up 100x100 in content space.

 

What evidence do you have that something is afoot?  Can you produce screen shots showing the physics overlaying the image so I can see where it's off?

 

Thanks

Rob



[TOPIC: post.html]
#6

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Ok. Here it goes. I took the CL falling crate demo app. I upsized the crate to 2x and 4x sizes and marked with text to make sure I know which image is loaded. I then used the following code to define the body : 

	-- make a crate (off-screen), position it, and rotate slightly
	local crate = display.newImageRect( "crate.png", 90, 90 )
	crate.x, crate.y = 160, -100
	crate.rotation = 15
        
        local imageOutline = graphics.newOutline( 2, "crate.png" )         
        
	-- add physics to the crate
	physics.addBody( crate, { density=.1, friction=1, bounce=0.1, outline=imageOutline } )

I put a pause in there somewhere so I can get screenshots. This is with hybrid mode on of course. Take a look at the 1x, 2x & 4x screenshots attached. You can clearly see the physics shape defined by graphics.newOutline keeping to the original 1x size of "crate.png". 

 

Hope this helps. I now have the demo app anyways so I can submit this as a bug if you like. 

Attached Files



[TOPIC: post.html]
#7

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,558 posts
  • Enterprise

Perfect.  That's what I needed to see.  This seems like a bug to me.  Can you file a bug report and make sure to include these screen shots?

 

Thanks

Rob



[TOPIC: post.html]
#8

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Thanks. Case 30296 submitted. Meanwhile I will rely on newImage rather than newImageRect and force my screen to use 1x images so I don't have the problem.

 

If I wanted to implement the other workaround I mentioned above, what would be the easiest way to determine if display.newImageRect is about to use @2x or @4x images? Appreciate your help.



[TOPIC: post.html]
#9

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,558 posts
  • Enterprise

Well a lot depends on your config.lua and the scale values you use before you switch, but it's something like:

 

local sf = display.pixelWidth / display.contentWidth

if sf > 3.0 then

    -- use @4x

elseif sf > 1.5 then

    -- use @2x

else

   -- use 1x

end

 

Where 3.0 and 1.5 are the values you  have in your config.lua.

 

Rob



[TOPIC: post.html]
#10

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Got it. Thanks. That should work well in the meanwhile. 



[TOPIC: post.html]
#11

bjsorrentino

[GLOBAL: userInfoPane.html]
bjsorrentino
  • Veteran

  • 8,506 posts
  • Corona SDK

The display.imageSuffix API is a better way of determining which suffix your app is going to use (or not use). It'll return the suffix, or return nothing if the scale factor is 1:1 (so you have to test for "nil" which means the suffix is actually in the 1:1 ratio).

 

http://docs.coronalabs.com/api/library/display/imageSuffix.html

 

Brent



[TOPIC: post.html]
#12

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Thank you very much! Even better!!! Lets hope graphics.newOutline() gets fixed to deal with this internally in the future but for the time being the display.imageSuffix API will provide a simple workaround. 



[TOPIC: post.html]
#13

albert90

[GLOBAL: userInfoPane.html]
albert90
  • Enthusiast

  • 82 posts
  • Corona Staff

I fixed the problem. Please try tomorrow's daily build and let us know if you have any further issues. Thanks!



[TOPIC: post.html]
#14

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Will do. Thank you very much for the quick turnaround. And I must say this is one very powerful and useful API call. Its a pleasure to watch the outlines it creates it Hybrid mode.



[TOPIC: post.html]
#15

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Albert, additional observation. Not sure if you consider this a bug or a 'feature'...

 

After setting the imageOutline I can use object.rotation and the outline will rotate with the object. This is great! If I use Yscale = -1 to flip the object then imageOutline does not flip with the object. In other words, 

 

Code Snippet A

object.yScale = -1;
object.xScale = -1;  
 
Code Snippet B
object.rotation = 180
 
Code Snippet A and Code Snippet B does exactly the same thing visually but as far as the physics body defined with graphics.newOutline() the outcome is 180 degrees different... I can live with rotation in this project but in some cases we will simply need to flip in one direction which rotate will not do.
 
Thoughts?


[TOPIC: post.html]
#16

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,558 posts
  • Enterprise

I don't believe you can scale physics objects.  You have to remove and re-add the body after changing it's scale.  Usually people are changing scale to make it bigger or smaller, but flipping images won't affect the physics body either.

 

Rob



[TOPIC: post.html]
#17

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Thanks. Remove & add physics body doesn't work in this situation because you can't give graphics.newOutline() the flipped display object to process. You can only give it the original file which is still not flipped. Thankfully rotate works and gets the job done for me in this instance but I can see cases where you might need to supply the flipped image and do away with the X/Yscale = -1 calls. I understand the limitation coming from the Box2D engine. Thanks



[TOPIC: post.html]
#18

bjsorrentino

[GLOBAL: userInfoPane.html]
bjsorrentino
  • Veteran

  • 8,506 posts
  • Corona SDK

Hi Kerem,

I recently created a simple "shape flipper" function, which could potentially be used to flip the coordinates of newOutline()-generated shapes. Do you want me to post it here? It only works for horizontal (y-axis) flipping, not vertical, but in truth a vertical flip is the same as a 180-degree-rotated horizontal flip.

 

Brent



[TOPIC: post.html]
#19

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Hi Brent, thanks for offering that. Indeed would love to have a copy. Maybe a post in Code Exchange for maximum exposure? Thanks in advance. 



[TOPIC: post.html]
#20

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

I fixed the problem. Please try tomorrow's daily build and let us know if you have any further issues. Thanks!

 

Albert, I tried 2174 and I can see graphics.newOutline is doing something different @2x and @4x so thank you very much for your prompt response. There is a problem though and it is not returning the right outline as 1x did against the 1x image. It might be something to do with my images which was not becoming a problem earlier. May I send you 3 images for you to see for yourself?



[TOPIC: post.html]
#21

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Nevermind. graphics.newOutline is working very well. The issue was with my image such that higher resolution version had some very fine gaps / breaks in the outline. These must be compressed when I downshifted the image to 1x so outline for 1x was tracing well. Once I went to 4x suddenly my trace was broken but this has nothing to do with the graphics.newOutline api. All is good. Case closed. 



[TOPIC: post.html]
#22

bjsorrentino

[GLOBAL: userInfoPane.html]
bjsorrentino
  • Veteran

  • 8,506 posts
  • Corona SDK

Hi Kerem,

I just posted my "physics body flipper" in the Code Exchange. Please test it out and let me know if there are any issues.

 

Currently, it only handles horizontal flipping. Adding vertical flipping would probably be easy enough, but I don't have time to tinker with that and test it. As I said above, you can always take the "easy way out" and just rotate the horizontally-flipped body 180 degrees and achieve the same thing. :)

 

http://code.coronalabs.com/code/physics-body-shape-flipper

 

Brent



[TOPIC: post.html]
#23

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

Hi Brent, 

 

Will test as soon as possible. Thank you very much for sharing this solution. I agree, rotate + flip horizontal will cover all possible needs. 

 

Regards,

Kerem



[TOPIC: post.html]
#24

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

I noticed the following in my console while running my app in simulator at 4x res... 

 

The generation of the physics body for this outline had to be cut short. Please provide a simpler input.

 

The resulting physics body still looked and worked ok so I don't know what was cut short but then I reduced the coarsenessInTexels value one at a time from the initial 2 and eventually found a number which still looked and worked great did not generate this error. Thought I should share with others reading this thread about newOutline API and high-res images ... 




[topic_controls]
[/topic_controls]