1 // Copyright 2013 Howling Moon Software. All rights reserved.
2 // See http://chipmunk2d.net/legal.php for more information.
4 #import "ChipmunkPointCloudSampler.h"
7 typedef struct DeformPoint {
14 PointBB(DeformPoint *point)
16 cpVect v = point->pos;
17 cpFloat r = point->radius;
19 return cpBBNew(v.x - r, v.y - r, v.x + r, v.y + r);
24 @implementation ChipmunkPointCloudSampler
27 fuzz(cpVect v, cpVect c, cpFloat r, cpFloat softness)
29 cpFloat distsq = cpvdistsq(v, c);
30 return (distsq < r*r ? 1.0f - cpfclamp01((r - cpfsqrt(distsq))/(softness*r)) : 1.0f);
34 PointQuery(cpVect *v, DeformPoint *point, cpCollisionID id, cpFloat *density)
36 (*density) *= fuzz(*v, point->pos, point->radius, point->fuzz);
40 PointCloudSample(ChipmunkPointCloudSampler *cloud, cpVect pos)
42 cpFloat density = 1.0f;
43 cpSpatialIndexQuery(cloud->_index, &pos, cpBBNewForCircle(pos, 0.0f), (cpSpatialIndexQueryFunc)PointQuery, &density);
48 - (id)initWithCellSize:(cpFloat)cellSize
50 if((self = [super initWithSamplingFunction:(cpMarchSampleFunc)PointCloudSample])){
53 _index = cpSpaceHashNew(cellSize, 1000, (cpSpatialIndexBBFunc)PointBB, NULL);
59 static void freeWrap(void *ptr, void *unused){cpfree(ptr);}
63 cpSpatialIndexEach(_index, (cpSpatialIndexIteratorFunc)freeWrap, NULL);
64 cpSpatialIndexFree(_index);
69 -(cpBB)addPoint:(cpVect)pos radius:(cpFloat)radius fuzz:(cpFloat)fuzz
71 DeformPoint *point = (DeformPoint *)cpcalloc(1, sizeof(DeformPoint));
73 point->radius = radius;
76 cpSpatialIndexInsert(_index, point, (cpHashValue)point);
78 return PointBB(point);