How to use AutoGeometry
-
- Posts: 56
- Joined: Mon Mar 25, 2013 11:57 pm
- Contact:
How to use AutoGeometry
I'm fairly new to Chipmunk, but I chose it because of the Obj-C wrapper. I have been through all the example projects, and while there are a few that use AutoGeometry, I can't find any examples of what I want to do.
I am trying to figure out the workflow for creating physics objects from image files. With Box2d, the workflow was:
- import the image into PhysicsEditor
- trace the image, add vertexes if necessary
- save out a Box2d .plist file
- import the plist into Xcode
- use GB2ShapeCache to retrieve the physics data and assign it to a physics sprite
So what is the workflow in Obj-Chipmunk? I notice there is a Chipmunk PLIST output (BETA) in Physics Editor. Do I even need to use Physics Editor for AutoGeometry?
Say I have an image that looks like a star. I simply need to create a physics object in the shape of the star so that it has the correct physics body. I'm using Cocos2D.
Could someone please describe the process with specific code examples? I'm assuming that AutoGeometry makes this process simple (that's why we have to pay for it right?), but again, I can't find any clear examples on how to use it.
I am trying to figure out the workflow for creating physics objects from image files. With Box2d, the workflow was:
- import the image into PhysicsEditor
- trace the image, add vertexes if necessary
- save out a Box2d .plist file
- import the plist into Xcode
- use GB2ShapeCache to retrieve the physics data and assign it to a physics sprite
So what is the workflow in Obj-Chipmunk? I notice there is a Chipmunk PLIST output (BETA) in Physics Editor. Do I even need to use Physics Editor for AutoGeometry?
Say I have an image that looks like a star. I simply need to create a physics object in the shape of the star so that it has the correct physics body. I'm using Cocos2D.
Could someone please describe the process with specific code examples? I'm assuming that AutoGeometry makes this process simple (that's why we have to pay for it right?), but again, I can't find any clear examples on how to use it.
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: How to use AutoGeometry
So there are two snippets from the examples that are apropos here.
The first was probably easily missed because it was just sort of tacked onto Space Patrol. The car's main shape was generated from the alpha of a PNG file at runtime here:
https://github.com/slembcke/SpacePatrol ... ggy.m#L107
The second is from Gemeralds Pinball. It uses the render buffer sampler class included in the project to get the geometry directly from the alpha of a Cocos2D sprite. It is a little bit slower though since it needs to render the sprite to an offscreen buffer in order to get at it's pixel data. This is useful though because it means that you can be using sprite atlases or a weird texture format that can't easily be loaded into a bitmap in memory.
https://github.com/slembcke/Gemeralds/b ... rySprite.m
Both of them generate a single convex hull, but you can use toConvexHulls_BETA: instead of toConvexHull if you want to decompose a concave poly for you. (Note that the method is "beta" because it doesn't yet handle self intersecting polygons.) Let me know if either of those are what you are looking for.
The first was probably easily missed because it was just sort of tacked onto Space Patrol. The car's main shape was generated from the alpha of a PNG file at runtime here:
https://github.com/slembcke/SpacePatrol ... ggy.m#L107
The second is from Gemeralds Pinball. It uses the render buffer sampler class included in the project to get the geometry directly from the alpha of a Cocos2D sprite. It is a little bit slower though since it needs to render the sprite to an offscreen buffer in order to get at it's pixel data. This is useful though because it means that you can be using sprite atlases or a weird texture format that can't easily be loaded into a bitmap in memory.
https://github.com/slembcke/Gemeralds/b ... rySprite.m
Both of them generate a single convex hull, but you can use toConvexHulls_BETA: instead of toConvexHull if you want to decompose a concave poly for you. (Note that the method is "beta" because it doesn't yet handle self intersecting polygons.) Let me know if either of those are what you are looking for.
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: 56
- Joined: Mon Mar 25, 2013 11:57 pm
- Contact:
Re: How to use AutoGeometry
The GeometrySprite example would be great if it was a standalone class that wasn't so coupled with the project. It has a lot of extraneous code specific to Gemeralds and CocosBuilder. What would be perfect is a generic GeometrySprite class where you could instantiate a physics object from any sprite, with it's geometry automatically traced out.
Since I don't know Chipmunk well enough to do that yet, I'm trying to use the Space Patrol example. I've never seen PSD files used as resources in Xcode before so this is a bit confusing:
There is no ChassisOutline.png file, only ChassisOutline.psd, so I'm not sure how the png resource is getting loaded, and I don't see how to handle retina/non-retina images when using the ChipmunkBitmapSampler.
Since I don't know Chipmunk well enough to do that yet, I'm trying to use the Space Patrol example. I've never seen PSD files used as resources in Xcode before so this is a bit confusing:
Code: Select all
NSURL *url = [[NSBundle mainBundle] URLForResource:@"ChassisOutline" withExtension:@"png"];
ChipmunkBitmapSampler *sampler = [ChipmunkImageSampler samplerWithImageFile:url isMask:FALSE];
-
- Posts: 56
- Joined: Mon Mar 25, 2013 11:57 pm
- Contact:
Re: How to use AutoGeometry
Here is a weak attempt at a generic GeometrySprite class. It doesn't work. The sprite image gets added to the screen, but it has no physics properties and other objects do not interact with it. Any help fixing this class would be appreciated.
CMGeometrySprite.h:
CMGeometrySprite.m:
CMGeometrySprite.h:
Code: Select all
#import "ObjectiveChipmunk.h"
@interface CMGeometrySprite : NSObject <ChipmunkObject>
@property(nonatomic, assign) cpVect pos;
@property(nonatomic, strong) ChipmunkShape *shape;
@property(nonatomic, strong) NSArray *sprites;
@property(nonatomic, strong) NSArray *chipmunkObjects;
@property(nonatomic, strong) ChipmunkBody *physicsBody;
+(id)physicsObjectFromResource:(NSString*)filename;
@end
Code: Select all
#import "CMGeometrySprite.h"
#import "ChipmunkAutoGeometry.h"
@implementation CMGeometrySprite
-(cpVect)pos
{
return self.physicsBody.pos;
}
-(void)setPos:(cpVect)pos
{
self.physicsBody.pos = pos;
}
-(id) initWithResource:(NSString*)filename
{
if((self = [super init])){
NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:@"png"];
ChipmunkBitmapSampler *sampler = [ChipmunkImageSampler samplerWithImageFile:url isMask:FALSE];
// Set a border of 0.0 to ensure the outline will be closed even if the pixels butt up against the image edge.
[sampler setBorderValue:0.0];
// March the image and grab the outline.
ChipmunkPolylineSet *lines = [sampler marchAllWithBorder:TRUE hard:FALSE];
ChipmunkPolyline *line = [lines lineAtIndex:0];
// Double check that we only have one and that it has the correct winding.
// You can handle multiple outlines easily enough, but will need to change the moment calculation so that it's properly area weighted.
NSAssert(lines.count == 1 && line.area > 0.0, @"Degenerate image hull.");
CCSprite *sprite = [CCSprite spriteWithFile:[NSString stringWithFormat:@"%@.png", filename]];
// Calculate the moment of inertia from the polyline.
// The center of gravity of the body will match up with the sprite's anchor point, so use that as the offset.
cpFloat moment = [line momentForMass:1.0 offset:cpvneg(sprite.anchorPointInPoints)];
self.physicsBody = [ChipmunkBody bodyWithMass:1.0 andMoment:moment];
// Simplify the outline and make a convex hull out of it.
ChipmunkPolyline *hull = [[line simplifyCurves:1.0] toConvexHull:1.0];
self.shape = [hull asChipmunkPolyShapeWithBody:self.physicsBody offset:cpvneg(sprite.anchorPointInPoints)];
self.shape.friction = 0.3;
//shape.group = PhysicsIdentifier(BUGGY);
//shape.layers = COLLISION_LAYERS_BUGGY;
self.chipmunkObjects = @[self.physicsBody, self.shape];
self.sprites = @[sprite];
}
return self;
}
+(id)physicsObjectFromResource:(NSString*)filename
{
return [[self alloc] initWithResource:filename];
}
@end
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: How to use AutoGeometry
Looks fine as far as I can tell. Can you post the code where you are adding it to your scene?
edit: Also, try putting a logging statement or breakpoint to check the number of vertexes in the convex hull it's generating.
edit: Also, try putting a logging statement or breakpoint to check the number of vertexes in the convex hull it's generating.
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: 56
- Joined: Mon Mar 25, 2013 11:57 pm
- Contact:
Re: How to use AutoGeometry
Actually I have it working if I do this:
Is that the best way to add a static shape to a space? Seems cleaner to me to be able to set the shape as static and just do the usual space:add method but that doesn't seem possible.
Anyway, like you said though, it only creates a convex outline around the outermost points of an object. So if I have a star image it doesn't really work like I need it to. How exactly do I get a concave poly with toConvexHulls_BETA?
How do I set this as the shape?
Code: Select all
[self.space addStaticShape:myGeometrySprite.shape];
for(CCNode *node in myGeometrySprite.sprites){
[self addChild:node z:z_FOREGROUND];
}
Anyway, like you said though, it only creates a convex outline around the outermost points of an object. So if I have a star image it doesn't really work like I need it to. How exactly do I get a concave poly with toConvexHulls_BETA?
Code: Select all
ChipmunkPolylineSet *hull = [[line simplifyCurves:1.0] toConvexHulls_BETA:1.0];
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: How to use AutoGeometry
So that is the old deprecated way of working with static shapes. I guess I should add the deprecated attribute to the headers so it actually warns you.
When I added the sleeping algorithm back in 5.something I made it so that bodies were marked as static. Any shaped attached to a static body is static. You don't need to use a special add method anymore. You can either use the static body provided by the space as a convenience or make your own using one of the static body constructor methods of ChipmunkBody.
When I added the sleeping algorithm back in 5.something I made it so that bodies were marked as static. Any shaped attached to a static body is static. You don't need to use a special add method anymore. You can either use the static body provided by the space as a convenience or make your own using one of the static body constructor methods of ChipmunkBody.
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: 56
- Joined: Mon Mar 25, 2013 11:57 pm
- Contact:
Re: How to use AutoGeometry
So I tried this in CMGeometrySprite.m:
Along with this in the main layer.m file:
And I get this error:
Maybe I'm misunderstanding what a static body is. Sometimes I just need physics bodies to stay in the same place on the screen, and not be affected by gravity or other forces. Objects should just bounce off of them. I was thinking that's the definition of a static body (coming from box2d).
Also, any tips on my other question? I need to make a star shape for example.
How do I set this as the shape?
Code: Select all
self.physicsBody = [ChipmunkBody staticBody];
Code: Select all
[self.space add:myGeometrySprite];
Code: Select all
Aborting due to Chipmunk error: Static bodies cannot be added to a space as they are not meant to be simulated.
Failed condition: !cpBodyIsStatic(body)
Also, any tips on my other question? I need to make a star shape for example.
Code: Select all
ChipmunkPolylineSet *hull = [[line simplifyCurves:1.0] toConvexHulls_BETA:1.0];
- slembcke
- Site Admin
- Posts: 4166
- Joined: Tue Aug 14, 2007 7:13 pm
- Contact:
Re: How to use AutoGeometry
So this is something that tends to confuse people about Chipmunk I guess. Adding a body to a space means that you want the body to be updated each frame (be affected by gravity, update it's position with it's velocity, etc). Since static bodies do not move, they cannot be added to a space to be simulated. This completely made sense to me when I was first writing Chipmunk, but it definitely confuses a lot of people. I've been pondering what I can do to make that more clear in the next major version of Chipmunk.
Anyway, what you are supposed to do is simply leave the static body out of your chipmunkObjects array since that is the Chipmunk objects that you want added to the space when adding your object.
Anyway, what you are supposed to do is simply leave the static body out of your chipmunkObjects array since that is the Chipmunk objects that you want added to the space when adding your object.
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: 56
- Joined: Mon Mar 25, 2013 11:57 pm
- Contact:
Re: How to use AutoGeometry
Thanks for the explanation on static bodies. Leaving the body out of the chipmunkObjects array works.
I still don't have a solution for my original question though, which was creating shapes from an image.
So far I can only create a convex outline around the outermost points of an object using this:
So if I have a star image it doesn't really work like I need it to. How exactly do I get a concave poly with toConvexHulls_BETA?
I still don't have a solution for my original question though, which was creating shapes from an image.
So far I can only create a convex outline around the outermost points of an object using this:
Code: Select all
ChipmunkPolyline *hull = [[line simplifyCurves:1.0] toConvexHull:1.0];
self.shape = [hull asChipmunkPolyShapeWithBody:self.physicsBody offset:cpvneg(sprite.anchorPointInPoints)];
Code: Select all
ChipmunkPolylineSet *hull = [[line simplifyCurves:1.0] toConvexHulls_BETA:1.0];
self.shape = ?????
Who is online
Users browsing this forum: No registered users and 12 guests