[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / chipmunk2d / objectivec / src / ChipmunkAutoGeometry.m
1 // Copyright 2013 Howling Moon Software. All rights reserved.
2 // See http://chipmunk2d.net/legal.php for more information.
3
4 #import <malloc/malloc.h>
5
6 #import "ChipmunkAutoGeometry.h"
7
8 @implementation ChipmunkPolyline
9
10 -(id)initWithPolyline:(cpPolyline *)line
11 {
12         if((self = [super init])){
13                 _line = line;
14         }
15         
16         return self;
17 }
18
19 -(void)dealloc
20 {
21         cpPolylineFree(_line);
22         
23         [super dealloc];
24 }
25
26 +(ChipmunkPolyline *)fromPolyline:(cpPolyline *)line
27 {
28         return [[[self alloc] initWithPolyline:line] autorelease];
29 }
30
31 -(bool)isClosed
32 {
33         return cpPolylineIsClosed(_line);
34 }
35
36 -(cpFloat)area
37 {
38         if(_area == 0.0 && [self isClosed]){
39                 _area = cpAreaForPoly(_line->count - 1, _line->verts, 0.0);
40         }
41         
42         return _area;
43 }
44
45 -(cpVect)centroid
46 {
47         cpAssertHard([self isClosed], "Cannot compute the centroid of a non-looped polyline.");
48         return cpCentroidForPoly(_line->count - 1, _line->verts);
49 }
50
51 -(cpFloat)momentForMass:(cpFloat)mass offset:(cpVect)offset
52 {
53         cpAssertHard([self isClosed], "Cannot compute the moment of a non-looped polyline.");
54         return cpMomentForPoly(mass, _line->count - 1, _line->verts, offset, 0.0);
55 }
56
57 -(NSUInteger)count {return _line->count;}
58 -(const cpVect *)verts {return _line->verts;}
59
60 -(ChipmunkPolyline *)simplifyCurves:(cpFloat)tolerance
61 {
62         return [ChipmunkPolyline fromPolyline:cpPolylineSimplifyCurves(_line, tolerance)];
63 }
64
65 -(ChipmunkPolyline *)simplifyVertexes:(cpFloat)tolerance
66 {
67         return [ChipmunkPolyline fromPolyline:cpPolylineSimplifyVertexes(_line, tolerance)];
68 }
69
70 -(ChipmunkPolyline *)toConvexHull:(cpFloat)tolerance
71 {
72         return [ChipmunkPolyline fromPolyline:cpPolylineToConvexHull(_line, tolerance)];
73 }
74
75 -(ChipmunkPolyline *)toConvexHull
76 {
77         return [self toConvexHull:0.0];
78 }
79
80 -(ChipmunkPolylineSet *)toConvexHulls_BETA:(cpFloat)tolerance
81 {
82         cpPolylineSet *set = cpPolylineConvexDecomposition_BETA(_line, tolerance);
83         ChipmunkPolylineSet *value = [ChipmunkPolylineSet fromPolylineSet:set];
84         cpPolylineSetFree(set, FALSE);
85         
86         return value;
87 }
88
89 -(NSArray *)asChipmunkSegmentsWithBody:(ChipmunkBody *)body radius:(cpFloat)radius offset:(cpVect)offset
90 {
91         NSMutableArray *arr = [NSMutableArray arrayWithCapacity:_line->count];
92         
93         
94         cpVect a = cpvadd(_line->verts[0], offset);
95         for(int i=1; i<_line->count; i++){
96                 cpVect b = cpvadd(_line->verts[i], offset);
97                 [arr addObject:[ChipmunkSegmentShape segmentWithBody:body from:a to:b radius:radius]];
98                 a = b;
99         }
100         
101         return arr;
102 }
103
104 -(ChipmunkPolyShape *)asChipmunkPolyShapeWithBody:(ChipmunkBody *)body transform:(cpTransform)transform radius:(cpFloat)radius
105 {
106         cpAssertHard([self isClosed], "Cannot create a poly shape for a non-closed polyline.");
107         return [ChipmunkPolyShape polyWithBody:body count:_line->count - 1 verts:_line->verts transform:transform radius:radius];
108 }
109
110 @end
111
112
113
114 @implementation ChipmunkPolylineSet
115
116 -(id)initWithPolylineSet:(cpPolylineSet *)set
117 {
118         if((self = [super init])){
119                 _lines = [[NSMutableArray alloc] initWithCapacity:set->count];
120                 for(int i=0; i<set->count; i++) [_lines addObject:[ChipmunkPolyline fromPolyline:set->lines[i]]];
121         }
122         
123         return self;
124 }
125
126 -(void)dealloc
127 {
128         [_lines release];
129         
130         [super dealloc];
131 }
132
133 +(ChipmunkPolylineSet *)fromPolylineSet:(cpPolylineSet *)set
134 {
135         return [[[self alloc] initWithPolylineSet:set] autorelease];
136 }
137
138 -(NSUInteger)count {return _lines.count;}
139
140 -(ChipmunkPolyline *)lineAtIndex:(NSUInteger)index
141 {
142         return [_lines objectAtIndex:index];
143 }
144
145 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
146 {
147         return [_lines countByEnumeratingWithState:state objects:stackbuf count:len];
148 }
149
150 @end
151
152
153
154 @implementation ChipmunkAbstractSampler
155
156 @synthesize marchThreshold = _marchThreshold;
157 @synthesize sampleFunc = _sampleFunc;
158
159 -(id)init {
160         @throw [NSException
161                 exceptionWithName:NSInternalInconsistencyException
162                 reason:[NSString stringWithFormat:@"Use designated initializer initWithSamplingFunction: to initialize a sampler."]
163                 userInfo:nil
164         ];
165 }
166
167 -(id)initWithSamplingFunction:(cpMarchSampleFunc)sampleFunc
168 {
169         if((self = [super init])){
170                 _sampleFunc = sampleFunc;
171                 _marchThreshold = 0.5;
172         }
173         
174         return self;
175 }
176
177 -(cpFloat)sample:(cpVect)pos
178 {
179         return _sampleFunc(pos, self);
180 }
181
182
183 -(ChipmunkPolylineSet *)march:(cpBB)bb xSamples:(NSUInteger)xSamples ySamples:(NSUInteger)ySamples hard:(bool)hard
184 {
185         cpPolylineSet set;
186         cpPolylineSetInit(&set);
187         
188         (hard ? cpMarchHard : cpMarchSoft)(
189                 bb, xSamples, ySamples, _marchThreshold,
190                 (cpMarchSegmentFunc)cpPolylineSetCollectSegment, &set,
191                 _sampleFunc, self
192         );
193         
194         ChipmunkPolylineSet *value = [ChipmunkPolylineSet fromPolylineSet:&set];
195         
196         cpPolylineSetDestroy(&set, FALSE);
197         return value;
198 }
199
200 @end
201
202
203
204 @implementation ChipmunkBlockSampler
205
206 static cpFloat
207 SampleFromBlock(cpVect point, ChipmunkBlockSampler *self)
208 {
209         return self->_block(point);
210 }
211
212 -(id)initWithBlock:(ChipmunkMarchSampleBlock)block
213 {
214         if((self = [super initWithSamplingFunction:(cpMarchSampleFunc)SampleFromBlock])){
215                 _block = [block copy];
216         }
217         
218         return self;
219 }
220
221 +(ChipmunkBlockSampler *)samplerWithBlock:(ChipmunkMarchSampleBlock)block
222 {
223         return [[[self alloc] initWithBlock:block] autorelease];
224 }
225
226 -(void)dealloc
227 {
228         [_block release];
229         [super dealloc];
230 }
231
232 @end