4
// Created by döme on 26.07.2009.
8
* Copyright (c) 2009 Doemoetoer Gulyas.
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
* 3. The name of the author may not be used to endorse or promote products
20
* derived from this software without specific prior written permission.
22
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
m16 computeAlignedBasesFromDownVector(v3 acc)
38
v3 up = vnormalize(vnegate(acc));
40
v3 X = {{1.0,0.0,0.0}};
41
v3 Y = {{0.0,1.0,0.0}};
42
// v3 Z = {{0.0,0.0,1.0}};
44
float udx = vdot(up, X);
45
float udy = vdot(up, Y);
47
// float upalignx = fabs(udx);
48
// float upaligny = fabs(udy);
52
v3 forwardax = vmul(vcross(up,X), 1.0);
54
v3 rightay = vmul(vcross(Y,up), 1.0);
55
v3 forwarday = vcross(up, rightay);
57
float weightx = 1.0 - udx;
58
float weighty = 1.0 - udy;
60
v3 forward = vnormalize(vadd(vmul(forwardax, weightx), vmul(forwarday, weighty)));
61
v3 right = vnormalize(vcross(forward, up));
64
m16 m = {{right.v.x, right.v.y, right.v.z, 0.0f,
65
forward.v.x, forward.v.y, forward.v.z, 0.0f,
66
up.v.x, up.v.y, up.v.z, 0.0f,
67
0.0f, 0.0f, 0.0f, 1.0f}};
72
m16 computeAlignedBasesFromDownVector2(v3 acc, v3 pf)
74
if (vdot(acc,acc) < FLT_EPSILON)
75
acc = vcreate(0.0,0.0,-1.0);
76
if (vdot(pf,pf) < FLT_EPSILON)
77
pf = vcreate(0.0,1.0,0.0);
78
v3 up = vnormalize(vnegate(acc));
80
v3 right = vnormalize(vcross(pf, up));
81
v3 forward = vnormalize(vcross(up,right));
84
m16 m = {{right.v.x, right.v.y, right.v.z, 0.0f,
85
forward.v.x, forward.v.y, forward.v.z, 0.0f,
86
up.v.x, up.v.y, up.v.z, 0.0f,
87
0.0f, 0.0f, 0.0f, 1.0f}};
93
CGPoint CGPointTransform(CGPoint a, CGAffineTransform m)
96
b.x = a.x*m.a + a.y*m.c + m.tx;
97
b.y = a.x*m.b + a.y*m.d + m.ty;
102
struct _bezierTransformerRec
104
CGMutablePathRef path;
105
const CGAffineTransform m;
108
static void _pathTransformer(void *_info,
109
const CGPathElement *element)
111
struct _bezierTransformerRec* info = _info;
112
CGMutablePathRef path = info->path;
114
switch(element->type)
116
case kCGPathElementMoveToPoint:
117
CGPathMoveToPoint(path, &info->m, element->points[0].x, element->points[0].y);
119
case kCGPathElementAddLineToPoint:
121
CGPathAddLineToPoint(path, &info->m, element->points[0].x, element->points[0].y);
124
case kCGPathElementAddQuadCurveToPoint:
126
CGPathAddQuadCurveToPoint(path, &info->m, element->points[0].x, element->points[0].y, element->points[1].x, element->points[1].y);
129
case kCGPathElementAddCurveToPoint:
131
CGPathAddCurveToPoint(path, &info->m, element->points[0].x, element->points[0].y, element->points[1].x, element->points[1].y, element->points[2].x, element->points[2].y);
134
case kCGPathElementCloseSubpath:
136
CGPathCloseSubpath(path);
142
static void _pathTransformerM(void *_info,
143
const CGPathElement *element)
145
struct _bezierTransformerRec* info = _info;
146
CGMutablePathRef path = info->path;
148
switch(element->type)
150
case kCGPathElementMoveToPoint:
152
CGPoint c0 = CGPointTransform(element->points[0], info->m);
153
CGPathMoveToPoint(path, NULL, c0.x, c0.y);
156
case kCGPathElementAddLineToPoint:
158
CGPoint c0 = CGPointTransform(element->points[0], info->m);
159
CGPathAddLineToPoint(path, NULL, c0.x, c0.y);
162
case kCGPathElementAddQuadCurveToPoint:
164
CGPoint c0 = CGPointTransform(element->points[0], info->m);
165
CGPoint c1 = CGPointTransform(element->points[1], info->m);
166
CGPathAddQuadCurveToPoint(path, NULL, c0.x, c0.y, c1.x, c1.y);
169
case kCGPathElementAddCurveToPoint:
171
CGPoint c0 = CGPointTransform(element->points[0], info->m);
172
CGPoint c1 = CGPointTransform(element->points[1], info->m);
173
CGPoint c2 = CGPointTransform(element->points[2], info->m);
174
CGPathAddCurveToPoint(path, NULL, c0.x, c0.y, c1.x, c1.y, c2.x, c2.y);
177
case kCGPathElementCloseSubpath:
179
CGPathCloseSubpath(path);
186
CGPathRef CreateTransformedPathFromCGPath(CGPathRef cpath, CGAffineTransform m)
188
struct _bezierTransformerRec rec = {CGPathCreateMutable(), m};
189
CGPathApply(cpath, &rec, _pathTransformerM);