Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

any luck with flipping physics body ?
Started by edualc Apr 29 2019 03:36 PM

17 replies to this topic
#physics #flip
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

edualc

[GLOBAL: userInfoPane.html]
edualc
  • Enthusiast

  • 72 posts
  • Corona SDK

Hello, in May 2013 Brent Sorrentino said:

 

Hi Hari,

Icy Spark is correct... just note that flipping will not (at this time) flip a physics body, if you're using it that way. It will flip the image, but the physics body will retain its core orientation. I have, however, asked the engineers to look into this and see if we can provide a "true" flip with physics... hopefully it can happen before too long.  :)

 

Brent

 

Any luck with that ? that would be SO good and so much easier than the convoluted workarounds for flipping the physics that go with a body.

 

please please please ! ;-)



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 838 posts
  • Corona SDK

This is actually a lot more trivial than it may seem.

First and foremost, make sure that the shape of your physics body is using relative coordinates from its own centre, i.e. for a 20 by 20 pixels rect, make it {-10,-10,10,-10,10,10,-10,10} and not, for instance {0,0,20,0,20,20,0,20}. There are plenty of simple functions that can do this for you as well.

Now, horizontally or vertically flipping a shape like that is as simple as changing the sign in front of the x or y vertices, i.e. turn positive x/y vertices into negative and vice versa.

Here's the simplest function I could think of for accomplishing it:

 

local physics = require("physics")
physics.start()
physics.setDrawMode( "hybrid" )

local function flip( vertices, direction )
	local t, v, h = {}, 1, 1

	if direction == "v" then -- "v" for "vertical"
		v = -1
	elseif direction == "h" then -- "h" for "horizontal"
		h = -1
	else -- flip both
		v, h = -1, -1
	end

	for i = 1, #vertices, 2 do
		t[i] = vertices[i]*h
		t[i+1] = vertices[i+1]*v
	end

	return t
end


local verticesOriginal = { -70, -40, 20, -60, 70, 60 }
local verticesHorizontalFlip = flip( verticesOriginal, "h" )
local verticesVerticalFlip = flip( verticesOriginal, "v" )
local verticesBothFlip = flip( verticesOriginal )


local polygon1 = display.newPolygon( display.contentCenterX-100, display.contentCenterY-100, verticesOriginal )
physics.addBody( polygon1, "static", {shape=verticesOriginal} )

local polygon2 = display.newPolygon( display.contentCenterX+100, display.contentCenterY-100, verticesHorizontalFlip )
physics.addBody( polygon2, "static", {shape=verticesHorizontalFlip} )

local polygon3 = display.newPolygon( display.contentCenterX-100, display.contentCenterY+100, verticesVerticalFlip )
physics.addBody( polygon3, "static", {shape=verticesVerticalFlip} )

local polygon4 = display.newPolygon( display.contentCenterX+100, display.contentCenterY+100, verticesBothFlip )
physics.addBody( polygon4, "static", {shape=verticesBothFlip} )

Not convoluted at all, right? :D

Now, if you want to update the shapes after they've already been created, then simply remove the body and recreate it afterwards with the flipped vertices.



[TOPIC: post.html]
#3

edualc

[GLOBAL: userInfoPane.html]
edualc
  • Enthusiast

  • 72 posts
  • Corona SDK

yeah, thank you Xedur. 

Thanks to PhysicsEditor I dont have to do this. I get a lua file with the definition of coolCarGoingRight and coolCarGoingLeft then like you say I remove the body and recreate it.

For one shape/car there are quite a few fixtures/elements created by PE (7 or 8 ) so it's not something to do during recess .. takes time (*)

BUT even with PE it is still hard work, I need to create two mirror images, load in PE, create the lua file and everytime it changes direction I have to do:


if not (physics.removeBody(coolCar[i]) ) then
      print ("cant remove physics.removeBody1>",coolCar[i].name)
end
physics.addBody( coolCar[i], physicsData:get("mycoolcarleft") )

so yeah it's still hard work. I would pay $$ to have only one line like physics.flipBody(coolCar[i], "left") 

 

But thank you for your answer. reading this 2013 post I was hoping it would now be a Corona feature. 

 

 

 

 

(*) especially when developing on the fly and characters and things change quite a bit until all the graphics are settled.



[TOPIC: post.html]
#4

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 838 posts
  • Corona SDK

It's been a while since I've used Physics Editor, but you should still be able to use the same principle as I mentioned above, but it would require "a few" extra steps and conditions.

Here's an over simplified sample leaning on the idea from before:
 

local function newRect( x, y, width, height )
	local rect = display.newRect( x, y, width, height )

	function rect:newBody( bodyType, direction )
		if self.bodyType then
			physics.removeBody( self )
		end

		local vertices = {}
		if direction then
			vertices = flip( verticesOriginal, direction )
		else
			vertices = verticesOriginal
		end
		physics.addBody( self, bodyType, { shape=vertices } )
	end

	return rect
end

local object = newRect( display.contentCenterX, display.contentCenterY, 120, 40 )
object:newBody( "static", "v" )

If you created objects with a function like that (a more complex one of course, but with the same idea), then you could have just that one line of code that removes the old body and creates the new one.

This has actually piqued my interest somewhat. I have a few other plugins that will be coming out around next week, but once I'm done with them I could have a go at this. I think that developing something like this shouldn't be too difficult, after all, something like this is almost purely just math.



[TOPIC: post.html]
#5

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 838 posts
  • Corona SDK

Well, I seem to be spamming here a bit now, but I actually solved it already. :D

I had 15 minutes to spare, so I downloaded the Physics Editor sample project from GitHub and wrote a brief function. I'll clean up my code at a later point and make a few adjustments and performance tweaks to it, but you'll be able to flip your shapes horizontally and vertically with a single line of code by next week. :P

Edit: I included an image showing the result. The original shape is the dynamic one below, the flipped shape is the static one above.
Attached File  reference.png   189.22KB   0 downloads


  • sporkfin likes this

[TOPIC: post.html]
#6

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 500 posts
  • Corona SDK

Depending on the shape, you could make two physics bodies (one a mirror image of the other) and weld them together with a joint.  For one of them, set the alpha to 0 and set isSensor = true and the other to alpha 1 and isSensor = false.  When it's time to flip, reverse the alpha and isSensor for the objects.  

 

Caveat: depending on how complex your shapes are and how fast things are moving, you might need to "pre-sense" the flip and apply a little force to the objects in the way so they don't get stuck.  Don't use chain bodies for this.

 

*by flip I was assuming you meant a 180 degree mirror image flip as opposed to a rotational flip



[TOPIC: post.html]
#7

edualc

[GLOBAL: userInfoPane.html]
edualc
  • Enthusiast

  • 72 posts
  • Corona SDK

so Xedur, just to confirm what you will do is actually create the physical description of the image of the duck by a function so we don't need to create this mirror image and trace its physical shape in PE ?

 

and then we'll be able to flip it 'just like that' (the easy part)

 

can't wait ! 



[TOPIC: post.html]
#8

edualc

[GLOBAL: userInfoPane.html]
edualc
  • Enthusiast

  • 72 posts
  • Corona SDK

thanks Sporkfin, that's what i'm really trying to avoid, 'complex solutions' (let's not call them 'convoluted' ;-) ) to do that.

I'm probably more a designer than a programmer and to flip an object reaching a border seems pretty basic and I feel it shouldn't need any special programming. (that's my thought anyway ! :-) )

 

So I already have a solution using PE to get the mirror shape definition and re-adding the body everytime. 

 

But hopefully Xedur will come up with something to improve immensely the Corona Physics engine !



[TOPIC: post.html]
#9

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 500 posts
  • Corona SDK

Are you trying to make this flip during the game or before the game?



[TOPIC: post.html]
#10

edualc

[GLOBAL: userInfoPane.html]
edualc
  • Enthusiast

  • 72 posts
  • Corona SDK

During the game everytime it either hits a border (left or right) or an obstacle half way.



[TOPIC: post.html]
#11

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 838 posts
  • Corona SDK

Yeah, so the "user side" code is minimal. It's just the usual stuff to require the plugin, PE shape definitions and then create the display object, etc.
 

local physicsData = (require "shapedefs").physicsData(1.0)
local spyricMorph = require("spyric.spyricMorph")

local object = display.newImage("Duck.png")
object.x = 160
object.y = 200

spyricMorph.add( object )
object:morph( "dynamic", -1, 1, physicsData:get("Duck") )

After you require the plugin in your code (the plugin will be free btw), then you'll just need first use spyricMorph.add() once on an object and it will set it up for morphing. After that, all you need to do is call :morph() and pass the bodyType (optional), xScale, yScale (required) and the physics definitions, which in this example is from PE.

Here's a sample image of the morph in action (with PE shapes and two simple polygons).
Attached File  Spyric Morph demo.png   71.6KB   0 downloads
 

Edit: Oh, right, once you've actually used :morph() once, to create the initial body, for instance, then you can just keep on using :morph() to change the body. No physics.removeBody() needed.


  • sporkfin likes this

[TOPIC: post.html]
#12

edualc

[GLOBAL: userInfoPane.html]
edualc
  • Enthusiast

  • 72 posts
  • Corona SDK

my goodness. if that works expect a carton of liquid Corona on your doorstep !



[TOPIC: post.html]
#13

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 500 posts
  • Corona SDK

@Xedur - super cool!  What happens to nearby physics objects when you morph the physics body?  I would fear that the Box2D bodies could get stuck together.



[TOPIC: post.html]
#14

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 838 posts
  • Corona SDK

@sporkfin, the answer is: it depends.

The two main variables in this equation are the body types and the amount of overlapping. If the morphed body overlaps with another body, then the two bodies try to first push each other away since they can't occupy the same space.

If both bodies are dynamic, then both bodies will give space and they are less likely to get stuck. However, if one body is dynamic and the other one is static, then the static one will not give at all they are more likely to get stuck.

But, in terms of getting stuck, the more important variable is the amount of overlapping, which needs to be substantial. I don't think I've ever managed to stuck two dynamic bodies together, but it is doable with dynamic and static bodies.


Here's a few images showing the issue with two different morph scales.

First, we have the start setting with two ducks with scales of ( -0.5, 0.5 ) and ( 1, 1 )
Attached File  Picture 0.png   65.25KB   0 downloads

Then, in scenario A, the duck on the left is morphed to scale ( -1, 1.5 ). The two ducks overlap significantly and ~50% of the duck on the left is inside or below the platform. Below is the result on the very frame when the morphing occurs.

Attached File  Picture 1.png   110.13KB   0 downloads

In the next frame, we see that the duck is now stuck inside the platform, but not to the other duck.
Attached File  Picture 2.png   125KB   0 downloads

However, in scenario B, the duck on the left is morphed to scale ( -1, 1.2 ). The overlapping is still significant as can be seen below.
Attached File  Picture 3.png   100.47KB   0 downloads

But in the next frame, the physics engine has pushed the duck out of the platform and the two ducks have knocked each other out. Nothing is stuck.
Attached File  Picture 4.png   107.61KB   0 downloads


So, it completely depends on what kind of morphing is being done and to what types of bodies. If we are talking about something simple like horizontal or vertical mirroring or slight to moderate upscaling, then it is very unlikely to get objects stuck to each other. In scenario A, the duck on the left gets stuck after I make it 3 times taller than it is initially while being 1 pixel away from the platform.

Another potential issue arises if the user tries to make the body too small, e.g. morphing to scale( 0.1, 0.1 ) or something, because the resulting body may be too small and will then be ignored by the physics engine.


  • sporkfin likes this

[TOPIC: post.html]
#15

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 500 posts
  • Corona SDK

@Xedur - well done!  My current projects are to complex to risk a 1 in 1,000 chance of something getting stuck (too many bodies doing too many unpredictable things unpredictable places) but that is a fabulous solution for a more simplified environment.

 

You did this all by manipulating the PE output info?  That's a very impressive quick solve!



[TOPIC: post.html]
#16

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 838 posts
  • Corona SDK

Yeah, this solution works with PE shape definitions as well as Corona's standard physics bodies. It doesn't really matter which is used, or whether you are creating static, dynamic, kinetic bodies, or simple, multibody or chain bodies, etc.

This is really just math and there's not much difficult stuff here. Everything goes according to what I suggested to @edualc as the possible code solutions. :P



[TOPIC: post.html]
#17

edualc

[GLOBAL: userInfoPane.html]
edualc
  • Enthusiast

  • 72 posts
  • Corona SDK

greetings @Xedur , just wondering .. did  you publish the plugin to flip the physical objects ? I'd love to replace my clumsy code with it !



[TOPIC: post.html]
#18

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 838 posts
  • Corona SDK

Hey!

Yeah, sorry about that. The plugin is entirely done and tested, I've created a sample project for it as well. All I needed to do is to just write the documentation page for it, setup a marketplace profile and upload the plugin. The reason why I haven't done that last steps is because I got a rush contract and I've been focusing my time and energy on it.

I'll try to get those remaining steps done tomorrow and then it'll just be a matter of how long it will take for Corona to clear it.




[topic_controls]
[/topic_controls]