Permalink
Browse files

basics working

  • Loading branch information...
1 parent ef6dfd6 commit 74c5fd914b0c3d9f5ac21d0a164a653d5db74376 @slembcke committed Dec 21, 2012
Showing with 233 additions and 0 deletions.
  1. +2 −0 Demo/ChipmunkDemo.c
  2. +227 −0 Demo/Shatter.c
  3. +4 −0 xcode/Chipmunk6.xcodeproj/project.pbxproj
View
@@ -563,6 +563,7 @@ extern ChipmunkDemo Crane;
extern ChipmunkDemo Buoyancy;
extern ChipmunkDemo ContactGraph;
extern ChipmunkDemo Slice;
+extern ChipmunkDemo Shatter;
extern ChipmunkDemo Convex;
extern ChipmunkDemo Unicycle;
extern ChipmunkDemo Sticky;
@@ -574,6 +575,7 @@ int
main(int argc, const char **argv)
{
ChipmunkDemo demo_list[] = {
+ Shatter,
LogoSmash,
PyramidStack,
Plink,
View
@@ -0,0 +1,227 @@
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "chipmunk.h"
+#include "constraints/util.h"
+
+#include "ChipmunkDemo.h"
+
+#define DENSITY (1.0/10000.0)
+
+//static void
+//ClipPoly(cpSpace *space, cpShape *shape, cpVect n, cpFloat dist)
+//{
+// cpBody *body = cpShapeGetBody(shape);
+//
+// int count = cpPolyShapeGetNumVerts(shape);
+// int clippedCount = 0;
+//
+// cpVect *clipped = (cpVect *)alloca((count + 1)*sizeof(cpVect));
+//
+// for(int i=0, j=count-1; i<count; j=i, i++){
+// cpVect a = cpBodyLocal2World(body, cpPolyShapeGetVert(shape, j));
+// cpFloat a_dist = cpvdot(a, n) - dist;
+//
+// if(a_dist < 0.0){
+// clipped[clippedCount] = a;
+// clippedCount++;
+// }
+//
+// cpVect b = cpBodyLocal2World(body, cpPolyShapeGetVert(shape, i));
+// cpFloat b_dist = cpvdot(b, n) - dist;
+//
+// if(a_dist*b_dist < 0.0f){
+// cpFloat t = cpfabs(a_dist)/(cpfabs(a_dist) + cpfabs(b_dist));
+//
+// clipped[clippedCount] = cpvlerp(a, b, t);
+// clippedCount++;
+// }
+// }
+//}
+
+static cpVect
+WorleyPoint(int i, int j, cpBB bb, int width, int height)
+{
+ return cpv(
+ cpflerp(bb.l, bb.r, ((cpFloat)i + 0.5f)/(cpFloat)width),
+ cpflerp(bb.b, bb.t, ((cpFloat)j + 0.5f)/(cpFloat)height)
+ );
+}
+
+static int
+ClipCell(cpShape *shape, cpVect center, int i, int j, cpBB bb, int width, int height, cpVect *verts, cpVect *clipped, int count)
+{
+ cpVect other = WorleyPoint(i, j, bb, width, height);
+ if(cpShapeNearestPointQuery(shape, other, NULL) > 0.0f){
+ memcpy(clipped, verts, count*sizeof(cpVect));
+ return count;
+ }
+
+ cpVect n = cpvsub(other, center);
+ cpFloat dist = cpvdot(n, cpvlerp(center, other, 0.5f));
+
+ int clipped_count = 0;
+ for(int j=0, i=count-1; j<count; i=j, j++){
+ cpVect a = verts[i];
+ cpFloat a_dist = cpvdot(a, n) - dist;
+
+ if(a_dist <= 0.0){
+ clipped[clipped_count] = a;
+ clipped_count++;
+ }
+
+ cpVect b = verts[j];
+ cpFloat b_dist = cpvdot(b, n) - dist;
+
+ if(a_dist*b_dist < 0.0f){
+ cpFloat t = cpfabs(a_dist)/(cpfabs(a_dist) + cpfabs(b_dist));
+
+ clipped[clipped_count] = cpvlerp(a, b, t);
+ clipped_count++;
+ }
+ }
+
+ return clipped_count;
+}
+
+static void
+ShatterCell(cpSpace *space, cpShape *shape, cpVect cell, int i, int j, cpBB bb, int width, int height)
+{
+ cpBody *body = cpShapeGetBody(shape);
+
+ int count = cpPolyShapeGetNumVerts(shape);
+ cpVect *ping = (cpVect *)alloca((count + 8)*sizeof(cpVect));
+ cpVect *pong = (cpVect *)alloca((count + 8)*sizeof(cpVect));
+
+ for(int i=0; i<count; i++){
+ ping[i] = cpBodyLocal2World(body, cpPolyShapeGetVert(shape, i));
+ }
+
+ count = ClipCell(shape, cell, i - 1, j - 1, bb, width, height, ping, pong, count);
+ count = ClipCell(shape, cell, i , j - 1, bb, width, height, pong, ping, count);
+ count = ClipCell(shape, cell, i + 1, j - 1, bb, width, height, ping, pong, count);
+ count = ClipCell(shape, cell, i - 1, j , bb, width, height, pong, ping, count);
+ count = ClipCell(shape, cell, i + 1, j , bb, width, height, ping, pong, count);
+ count = ClipCell(shape, cell, i - 1, j + 1, bb, width, height, pong, ping, count);
+ count = ClipCell(shape, cell, i , j + 1, bb, width, height, ping, pong, count);
+ count = ClipCell(shape, cell, i + 1, j + 1, bb, width, height, pong, ping, count);
+
+// if(count != 4){
+// printf("weird %d\n", count);
+// return;
+// }
+
+ cpVect centroid = cpCentroidForPoly(count, ping);
+ cpFloat mass = cpAreaForPoly(count, ping)*DENSITY;
+ cpFloat moment = cpMomentForPoly(mass, count, ping, cpvneg(centroid));
+
+ cpBody *new_body = cpSpaceAddBody(space, cpBodyNew(mass, moment));
+ cpBodySetPos(new_body, centroid);
+ cpBodySetVel(new_body, cpBodyGetVelAtWorldPoint(body, centroid));
+ cpBodySetAngVel(new_body, cpBodyGetAngVel(body));
+
+ cpShape *new_shape = cpSpaceAddShape(space, cpPolyShapeNew(new_body, count, ping, cpvneg(centroid)));
+ // Copy whatever properties you have set on the original shape that are important
+ cpShapeSetFriction(new_shape, cpShapeGetFriction(shape));
+}
+
+static void
+ShatterShape(cpSpace *space, cpShape *shape)
+{
+ cpBB bb = cpShapeGetBB(shape);
+ int width = 4;
+ int height = 2;
+
+ for(int i=0; i<width; i++){
+ for(int j=0; j<height; j++){
+ cpVect cell = WorleyPoint(i, j, bb, width, height);
+ if(cpShapeNearestPointQuery(shape, cell, NULL) < 0.0f){
+ ShatterCell(space, shape, cell, i, j, bb, width, height);
+ }
+ }
+ }
+}
+
+static void
+update(cpSpace *space)
+{
+ int steps = 1;
+ cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
+
+ for(int i=0; i<steps; i++){
+ cpSpaceStep(space, dt);
+ }
+}
+
+static cpSpace *
+init(void)
+{
+ ChipmunkDemoMessageString = "Right click something to shatter it.";
+
+ cpSpace *space = cpSpaceNew();
+ cpSpaceSetIterations(space, 30);
+ cpSpaceSetGravity(space, cpv(0, -500));
+ cpSpaceSetSleepTimeThreshold(space, 0.5f);
+ cpSpaceSetCollisionSlop(space, 0.5f);
+
+ cpBody *body, *staticBody = cpSpaceGetStaticBody(space);
+ cpShape *shape;
+
+ // Create segments around the edge of the screen.
+ shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
+ cpShapeSetElasticity(shape, 1.0f);
+ cpShapeSetFriction(shape, 1.0f);
+ cpShapeSetLayers(shape, NOT_GRABABLE_MASK);
+
+ cpFloat width = 200.0f;
+ cpFloat height = 300.0f;
+ cpFloat mass = width*height*DENSITY;
+ cpFloat moment = cpMomentForBox(mass, width, height);
+
+// body = cpSpaceAddBody(space, cpBodyNew(mass, moment));
+//
+// shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height));
+// cpShapeSetFriction(shape, 0.6f);
+
+ body = cpBodyNew(mass, moment);
+ shape = cpBoxShapeNew(body, width, height);
+ cpShapeSetFriction(shape, 0.6f);
+
+ cpShapeCacheBB(shape);
+ ShatterShape(space, shape);
+
+ return space;
+}
+
+static void
+destroy(cpSpace *space)
+{
+ ChipmunkDemoFreeSpaceChildren(space);
+ cpSpaceFree(space);
+}
+
+ChipmunkDemo Shatter = {
+ "Shatter.",
+ init,
+ update,
+ ChipmunkDemoDefaultDrawImpl,
+ destroy,
+};
@@ -63,6 +63,7 @@
D38011630E984FA400A3D7FA /* cpDampedSpring.h in Headers */ = {isa = PBXBuildFile; fileRef = D38011600E984FA400A3D7FA /* cpDampedSpring.h */; };
D38687D30BAFC695008B7008 /* libChipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D34963BB0B56CAA300CAD239 /* libChipmunk.a */; };
D38996A6148B1E72006CFE0B /* Slice.c in Sources */ = {isa = PBXBuildFile; fileRef = D38996A5148B1E72006CFE0B /* Slice.c */; };
+ D38C029916840ED3009F612B /* Shatter.c in Sources */ = {isa = PBXBuildFile; fileRef = D38C029816840ED2009F612B /* Shatter.c */; };
D393275C0EA02C710026F6A2 /* Pump.c in Sources */ = {isa = PBXBuildFile; fileRef = D393275B0EA02C710026F6A2 /* Pump.c */; };
D3AA477512AF0F8900E27AAB /* cpBBTree.c in Sources */ = {isa = PBXBuildFile; fileRef = D3AA477312AF0F8900E27AAB /* cpBBTree.c */; };
D3AA477612AF0F8900E27AAB /* cpSpatialIndex.c in Sources */ = {isa = PBXBuildFile; fileRef = D3AA477412AF0F8900E27AAB /* cpSpatialIndex.c */; };
@@ -170,6 +171,7 @@
D38011600E984FA400A3D7FA /* cpDampedSpring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpDampedSpring.h; path = ../../include/chipmunk/constraints/cpDampedSpring.h; sourceTree = "<group>"; };
D38996A5148B1E72006CFE0B /* Slice.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Slice.c; sourceTree = "<group>"; };
D38BB1D1149933F20000EC41 /* chipmunk-docs.textile */ = {isa = PBXFileReference; lastKnownFileType = text; name = "chipmunk-docs.textile"; path = "../doc-src/chipmunk-docs.textile"; sourceTree = "<group>"; };
+ D38C029816840ED2009F612B /* Shatter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Shatter.c; sourceTree = "<group>"; };
D390FDAD146EF0F8005D1E06 /* VERSION.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = VERSION.txt; path = ../VERSION.txt; sourceTree = "<group>"; };
D393275B0EA02C710026F6A2 /* Pump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Pump.c; sourceTree = "<group>"; };
D39F478A0FD4AB4E00B244CA /* chipmunk_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = chipmunk_types.h; path = ../include/chipmunk/chipmunk_types.h; sourceTree = SOURCE_ROOT; };
@@ -336,6 +338,7 @@
D37282D313C76C1B00FFFA3F /* Buoyancy.c */,
D373FF0F13D0D66E000EDB87 /* ContactGraph.c */,
D38996A5148B1E72006CFE0B /* Slice.c */,
+ D38C029816840ED2009F612B /* Shatter.c */,
D3F6EEDE156D581300A158A8 /* Convex.c */,
D3DFB55C1613765700162F19 /* Sticky.c */,
D3E4867513175AE000A00840 /* Bench.c */,
@@ -633,6 +636,7 @@
D3F2EE2F14F898E9005FD439 /* Unicycle.c in Sources */,
D3F6EEDF156D581300A158A8 /* Convex.c in Sources */,
D3DFB55D1613765700162F19 /* Sticky.c in Sources */,
+ D38C029916840ED3009F612B /* Shatter.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

0 comments on commit 74c5fd9

Please sign in to comment.