Autogeometry to create solid object
-
- Posts: 71
- Joined: Mon Sep 06, 2010 1:29 pm
- Contact:
Autogeometry to create solid object
Is it possible to create an autogeometry-object as a solid shape?
Today I use the GeometryNode to create a static object. If I add a non-static "dynamic" object, e.g. long narrow rectangle, partly inside the auto geometry-object it gets stuck on the inside resting on a segment making up the border.
If I do the same with a traditionally created static object, the dynamic object is moved outside as soon as it is added.
Today I use the GeometryNode to create a static object. If I add a non-static "dynamic" object, e.g. long narrow rectangle, partly inside the auto geometry-object it gets stuck on the inside resting on a segment making up the border.
If I do the same with a traditionally created static object, the dynamic object is moved outside as soon as it is added.
-
- Posts: 71
- Joined: Mon Sep 06, 2010 1:29 pm
- Contact:
Re: Autogeometry to create solid object
The problem is that the total shape is made up by smaller segments. Another object can intersect any of these segments without being "evicted" (as the case for solid shapes).
Code: Select all
ChipmunkShape *seg = [ChipmunkSegmentShape segmentWithBody:body from:a to:b radius:1.0f];
seg.friction = self.friction;
seg.elasticity = self.elasticity;
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Autogeometry to create solid object
Hey sorry I missed answering this before. I had left the window open on one of my computers as a reminder and then didn't use that computer. :-\
I created a branch for you here:
https://github.com/slembcke/Gemeralds/tree/solid
You can see the changes I made here:
https://github.com/slembcke/Gemeralds/c ... 82e04008af
There were a few changes made. First, the previous code didn't use a border, so the outlines it generated were open on the edges of the screen. It gave the border a value of 0 (meaning everything outside the screen is empty) so that it would close the edges of the shapes in. Then, instead of looping over the individual line segments and creating segment shapes for each one, I call toConvexHulls_BETA on each of the polylines. This will turn any looped polyline into a set of convex hulls. The last step is a bit annoying since the sampled data can be downsampled. It has to scale it back up in order to match the size on the screen.
There are some important things to keep in mind! Polygons are more complex and a little slower as a collision type than line segments. While they do make the area solid, it's also full of cracks where they are joined together to make concave areas. When a polygon shape pushes an object out of it, it pushes it in the shortest direction to get it out of that specific polygon. That might be towards the surface of the level, or it might be towards one of the cracks. I don't really think this solves your problem. There is no good way to solve overlaps, and the way Chipmunk does it is sort of a necessary hack. I wouldn't generally recommend relying on the behavior of it though.
An alternative is that you can keep the sampler around and query the density of the terrain at different points using the sample: method. That will let you know if a point is inside the terrain before adding a shape.
Oh, and one more thing. The toConvexHulls_BETA method is marked as beta because it only works on simple polygons (ones that don't intersect themselves). It doesn't crash if you give it a non-simple polygon, but the output is somewhat undefined. It might be missing large chunks of geometry or it might look very close. I haven't quite figured out what to do about this yet since simply detecting a non-simple polygon is far more expensive than toConvexHulls_BETA itself. Turning a a non-simple polygon into a set of simple ones is similarly difficult and expensive.
I created a branch for you here:
https://github.com/slembcke/Gemeralds/tree/solid
You can see the changes I made here:
https://github.com/slembcke/Gemeralds/c ... 82e04008af
There were a few changes made. First, the previous code didn't use a border, so the outlines it generated were open on the edges of the screen. It gave the border a value of 0 (meaning everything outside the screen is empty) so that it would close the edges of the shapes in. Then, instead of looping over the individual line segments and creating segment shapes for each one, I call toConvexHulls_BETA on each of the polylines. This will turn any looped polyline into a set of convex hulls. The last step is a bit annoying since the sampled data can be downsampled. It has to scale it back up in order to match the size on the screen.
There are some important things to keep in mind! Polygons are more complex and a little slower as a collision type than line segments. While they do make the area solid, it's also full of cracks where they are joined together to make concave areas. When a polygon shape pushes an object out of it, it pushes it in the shortest direction to get it out of that specific polygon. That might be towards the surface of the level, or it might be towards one of the cracks. I don't really think this solves your problem. There is no good way to solve overlaps, and the way Chipmunk does it is sort of a necessary hack. I wouldn't generally recommend relying on the behavior of it though.
An alternative is that you can keep the sampler around and query the density of the terrain at different points using the sample: method. That will let you know if a point is inside the terrain before adding a shape.
Oh, and one more thing. The toConvexHulls_BETA method is marked as beta because it only works on simple polygons (ones that don't intersect themselves). It doesn't crash if you give it a non-simple polygon, but the output is somewhat undefined. It might be missing large chunks of geometry or it might look very close. I haven't quite figured out what to do about this yet since simply detecting a non-simple polygon is far more expensive than toConvexHulls_BETA itself. Turning a a non-simple polygon into a set of simple ones is similarly difficult and expensive.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
-
- Posts: 71
- Joined: Mon Sep 06, 2010 1:29 pm
- Contact:
Re: Autogeometry to create solid object
Thanks, highly appreciated!
It works great. But we use another coordinate system and transformed the new points. This gives rise to a "Polygon is concave or has a reversed winding." exception. Shouldn't it be possible to flip a shape in any direction?
Example Pseudo code
It works great. But we use another coordinate system and transformed the new points. This gives rise to a "Polygon is concave or has a reversed winding." exception. Shouldn't it be possible to flip a shape in any direction?
Example Pseudo code
Code: Select all
for(int i=0; i<hull.count - 1; i++){
verts[i] = CGPointApplyAffineTransform(hull.verts[i], transform);
verts[i] = CGPointMake(verts[i].x, Y_TRANSFORM - verts[i].y);
}
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: Autogeometry to create solid object
If you flip the coordinates on an axis you need to reverse the winding.
Code: Select all
for(int i=0; i<hull.count - 1; i++){
verts[i] = CGPointApplyAffineTransform(hull.verts[hull.count - i - 1], transform);
verts[i] = CGPointMake(verts[i].x, Y_TRANSFORM - verts[i].y);
}
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
-
- Posts: 71
- Joined: Mon Sep 06, 2010 1:29 pm
- Contact:
Re: Autogeometry to create solid object
To fix the problem with concave shapes to advanced for Autogeometry I bought PhysicsEditor. I am reading all points and creating ChipmunkPolyShapes.
Why am I getting the message "Aborting due to Chipmunk error: Polygon is concave or has a reversed winding. Consider using cpConvexHull() or CP_CONVEX_HULL()" for this code.
The two arrays should be identical?
I am not an expert of c. Most of my code is Objective-C.
If I use p->vertices directly it works but all points are mirrored, left-low is right-high etc. so I need to translate them some how.
Why am I getting the message "Aborting due to Chipmunk error: Polygon is concave or has a reversed winding. Consider using cpConvexHull() or CP_CONVEX_HULL()" for this code.
The two arrays should be identical?
I am not an expert of c. Most of my code is Objective-C.
Code: Select all
int nr = p->numVertices;
cpVect *verts = malloc(sizeof(cpVect) * nr);
for(int i=0; i < nr - 1; i++){
verts[i] = p->vertices[i];
}
ChipmunkPolyShape *poly = [ChipmunkPolyShape polyWithBody:body count:nr verts:verts offset:cpvzero];
-
- Posts: 71
- Joined: Mon Sep 06, 2010 1:29 pm
- Contact:
Re: Autogeometry to create solid object
Bump.
We still haven't solved this problem. The shapes are mirrored and any change to the point array creates the error mentioned above.
We still haven't solved this problem. The shapes are mirrored and any change to the point array creates the error mentioned above.
- AndyKorth
- Site Admin
- Posts: 36
- Joined: Wed Aug 15, 2007 3:56 pm
Re: Autogeometry to create solid object
So a few issues here:
The simplest thing you can do here is run those vertices through the cpConvexHull() method. It will automatically correct the winding for you. You will still need to flip the coordinates like Scott showed in his example to correct for the different coordinate system that is presumably coming from PhysicsEditor.
Secondly, I can explain polygon winding a little bit. Chipmunk 6 requires a clockwise winding. So if you start at the top of a polygon, the next vertex you specify should be the next one to the right- just like how an old analog clock hand moves.
If, for example, you mirror/flip a shape horizontally, that same vertex order is now moving counterclockwise. In order to make that work, you'd need to reorder the vertices.
In your example code you reversed the order of the vertices, but you didn't flip them. So you have made something with an incorrect winding.
Note that if you flip something twice, over x and y axis, you don't have to change the winding. (Or you can change it twice, and it will cancel out).
And again, since all this winding flipping is confusing, you can let cpConvexHull do it for you.
The simplest thing you can do here is run those vertices through the cpConvexHull() method. It will automatically correct the winding for you. You will still need to flip the coordinates like Scott showed in his example to correct for the different coordinate system that is presumably coming from PhysicsEditor.
Secondly, I can explain polygon winding a little bit. Chipmunk 6 requires a clockwise winding. So if you start at the top of a polygon, the next vertex you specify should be the next one to the right- just like how an old analog clock hand moves.
If, for example, you mirror/flip a shape horizontally, that same vertex order is now moving counterclockwise. In order to make that work, you'd need to reorder the vertices.
In your example code you reversed the order of the vertices, but you didn't flip them. So you have made something with an incorrect winding.
Note that if you flip something twice, over x and y axis, you don't have to change the winding. (Or you can change it twice, and it will cancel out).
And again, since all this winding flipping is confusing, you can let cpConvexHull do it for you.
Who is online
Users browsing this forum: No registered users and 6 guests