~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/blenlib/intern/math_geom.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: math_geom.c 30526 2010-07-20 10:41:08Z campbellbarton $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
19
17
 *
20
18
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21
19
 * All rights reserved.
22
 
 
 
20
 *
23
21
 * The Original Code is: some of this file.
24
22
 *
25
23
 * ***** END GPL LICENSE BLOCK *****
26
24
 * */
27
25
 
 
26
/** \file blender/blenlib/intern/math_geom.c
 
27
 *  \ingroup bli
 
28
 */
 
29
 
 
30
 
28
31
 
29
32
#include "MEM_guardedalloc.h"
30
33
 
31
34
#include "BLI_math.h"
32
35
#include "BLI_memarena.h"
33
 
 
34
 
#include "BKE_utildefines.h"
 
36
#include "BLI_utildefines.h"
35
37
 
36
38
/********************************** Polygons *********************************/
37
39
 
38
 
void cent_tri_v3(float *cent, float *v1, float *v2, float *v3)
 
40
void cent_tri_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3])
39
41
{
40
 
        cent[0]= 0.33333f*(v1[0]+v2[0]+v3[0]);
41
 
        cent[1]= 0.33333f*(v1[1]+v2[1]+v3[1]);
42
 
        cent[2]= 0.33333f*(v1[2]+v2[2]+v3[2]);
 
42
        cent[0] = 0.33333f * (v1[0] + v2[0] + v3[0]);
 
43
        cent[1] = 0.33333f * (v1[1] + v2[1] + v3[1]);
 
44
        cent[2] = 0.33333f * (v1[2] + v2[2] + v3[2]);
43
45
}
44
46
 
45
 
void cent_quad_v3(float *cent, float *v1, float *v2, float *v3, float *v4)
 
47
void cent_quad_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
46
48
{
47
 
        cent[0]= 0.25f*(v1[0]+v2[0]+v3[0]+v4[0]);
48
 
        cent[1]= 0.25f*(v1[1]+v2[1]+v3[1]+v4[1]);
49
 
        cent[2]= 0.25f*(v1[2]+v2[2]+v3[2]+v4[2]);
 
49
        cent[0] = 0.25f * (v1[0] + v2[0] + v3[0] + v4[0]);
 
50
        cent[1] = 0.25f * (v1[1] + v2[1] + v3[1] + v4[1]);
 
51
        cent[2] = 0.25f * (v1[2] + v2[2] + v3[2] + v4[2]);
50
52
}
51
53
 
52
54
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
53
55
{
54
 
        float n1[3],n2[3];
 
56
        float n1[3], n2[3];
55
57
 
56
 
        n1[0]= v1[0]-v2[0];
57
 
        n2[0]= v2[0]-v3[0];
58
 
        n1[1]= v1[1]-v2[1];
59
 
        n2[1]= v2[1]-v3[1];
60
 
        n1[2]= v1[2]-v2[2];
61
 
        n2[2]= v2[2]-v3[2];
62
 
        n[0]= n1[1]*n2[2]-n1[2]*n2[1];
63
 
        n[1]= n1[2]*n2[0]-n1[0]*n2[2];
64
 
        n[2]= n1[0]*n2[1]-n1[1]*n2[0];
 
58
        n1[0] = v1[0] - v2[0];
 
59
        n2[0] = v2[0] - v3[0];
 
60
        n1[1] = v1[1] - v2[1];
 
61
        n2[1] = v2[1] - v3[1];
 
62
        n1[2] = v1[2] - v2[2];
 
63
        n2[2] = v2[2] - v3[2];
 
64
        n[0] = n1[1] * n2[2] - n1[2] * n2[1];
 
65
        n[1] = n1[2] * n2[0] - n1[0] * n2[2];
 
66
        n[2] = n1[0] * n2[1] - n1[1] * n2[0];
65
67
 
66
68
        return normalize_v3(n);
67
69
}
69
71
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
70
72
{
71
73
        /* real cross! */
72
 
        float n1[3],n2[3];
73
 
 
74
 
        n1[0]= v1[0]-v3[0];
75
 
        n1[1]= v1[1]-v3[1];
76
 
        n1[2]= v1[2]-v3[2];
77
 
 
78
 
        n2[0]= v2[0]-v4[0];
79
 
        n2[1]= v2[1]-v4[1];
80
 
        n2[2]= v2[2]-v4[2];
81
 
 
82
 
        n[0]= n1[1]*n2[2]-n1[2]*n2[1];
83
 
        n[1]= n1[2]*n2[0]-n1[0]*n2[2];
84
 
        n[2]= n1[0]*n2[1]-n1[1]*n2[0];
 
74
        float n1[3], n2[3];
 
75
 
 
76
        n1[0] = v1[0] - v3[0];
 
77
        n1[1] = v1[1] - v3[1];
 
78
        n1[2] = v1[2] - v3[2];
 
79
 
 
80
        n2[0] = v2[0] - v4[0];
 
81
        n2[1] = v2[1] - v4[1];
 
82
        n2[2] = v2[2] - v4[2];
 
83
 
 
84
        n[0] = n1[1] * n2[2] - n1[2] * n2[1];
 
85
        n[1] = n1[2] * n2[0] - n1[0] * n2[2];
 
86
        n[2] = n1[0] * n2[1] - n1[1] * n2[0];
85
87
 
86
88
        return normalize_v3(n);
87
89
}
88
90
 
89
91
float area_tri_v2(const float v1[2], const float v2[2], const float v3[2])
90
92
{
91
 
        return (float)(0.5f*fabs((v1[0]-v2[0])*(v2[1]-v3[1]) + (v1[1]-v2[1])*(v3[0]-v2[0])));
 
93
        return 0.5f * fabsf((v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]));
92
94
}
93
95
 
94
96
float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2])
95
97
{
96
 
   return (float)(0.5f*((v1[0]-v2[0])*(v2[1]-v3[1]) + (v1[1]-v2[1])*(v3[0]-v2[0])));
 
98
        return 0.5f * ((v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]));
97
99
}
98
100
 
99
 
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])  /* only convex Quadrilaterals */
 
101
/* only convex Quadrilaterals */
 
102
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
100
103
{
101
104
        float len, vec1[3], vec2[3], n[3];
102
105
 
103
106
        sub_v3_v3v3(vec1, v2, v1);
104
107
        sub_v3_v3v3(vec2, v4, v1);
105
108
        cross_v3_v3v3(n, vec1, vec2);
106
 
        len= normalize_v3(n);
 
109
        len = normalize_v3(n);
107
110
 
108
111
        sub_v3_v3v3(vec1, v4, v3);
109
112
        sub_v3_v3v3(vec2, v2, v3);
110
113
        cross_v3_v3v3(n, vec1, vec2);
111
 
        len+= normalize_v3(n);
 
114
        len += normalize_v3(n);
112
115
 
113
 
        return (len/2.0f);
 
116
        return (len / 2.0f);
114
117
}
115
118
 
116
 
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])  /* Triangles */
 
119
/* Triangles */
 
120
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
117
121
{
118
122
        float len, vec1[3], vec2[3], n[3];
119
123
 
120
124
        sub_v3_v3v3(vec1, v3, v2);
121
125
        sub_v3_v3v3(vec2, v1, v2);
122
126
        cross_v3_v3v3(n, vec1, vec2);
123
 
        len= normalize_v3(n);
 
127
        len = normalize_v3(n);
124
128
 
125
 
        return (len/2.0f);
 
129
        return (len / 2.0f);
126
130
}
127
131
 
128
 
float area_poly_v3(int nr, float verts[][3], float *normal)
 
132
float area_poly_v3(int nr, float verts[][3], const float normal[3])
129
133
{
130
134
        float x, y, z, area, max;
131
135
        float *cur, *prev;
132
 
        int a, px=0, py=1;
 
136
        int a, px = 0, py = 1;
133
137
 
134
 
        /* first: find dominant axis: 0==X, 1==Y, 2==Z */
135
 
        x= (float)fabs(normal[0]);
136
 
        y= (float)fabs(normal[1]);
137
 
        z= (float)fabs(normal[2]);
 
138
        /* first: find dominant axis: 0==X, 1==Y, 2==Z
 
139
         * don't use 'axis_dominant_v3()' because we need max axis too */
 
140
        x = fabsf(normal[0]);
 
141
        y = fabsf(normal[1]);
 
142
        z = fabsf(normal[2]);
138
143
        max = MAX3(x, y, z);
139
 
        if(max==y) py=2;
140
 
        else if(max==x) {
141
 
                px=1; 
142
 
                py= 2;
 
144
        if (max == y) py = 2;
 
145
        else if (max == x) {
 
146
                px = 1;
 
147
                py = 2;
143
148
        }
144
149
 
145
150
        /* The Trapezium Area Rule */
146
 
        prev= verts[nr-1];
147
 
        cur= verts[0];
148
 
        area= 0;
149
 
        for(a=0; a<nr; a++) {
150
 
                area+= (cur[px]-prev[px])*(cur[py]+prev[py]);
151
 
                prev= verts[a];
152
 
                cur= verts[a+1];
 
151
        prev = verts[nr - 1];
 
152
        cur = verts[0];
 
153
        area = 0;
 
154
        for (a = 0; a < nr; a++) {
 
155
                area += (cur[px] - prev[px]) * (cur[py] + prev[py]);
 
156
                prev = verts[a];
 
157
                cur = verts[a + 1];
153
158
        }
154
159
 
155
 
        return (float)fabs(0.5*area/max);
 
160
        return fabsf(0.5f * area / max);
156
161
}
157
162
 
158
163
/********************************* Distance **********************************/
159
164
 
160
 
/* distance v1 to line v2-v3 */
161
 
/* using Hesse formula, NO LINE PIECE! */
162
 
float dist_to_line_v2(float *v1, float *v2, float *v3)
 
165
/* distance v1 to line v2-v3
 
166
 * using Hesse formula, NO LINE PIECE! */
 
167
float dist_to_line_v2(const float v1[2], const float v2[2], const float v3[2])
163
168
{
164
 
        float a[2],deler;
165
 
 
166
 
        a[0]= v2[1]-v3[1];
167
 
        a[1]= v3[0]-v2[0];
168
 
        deler= (float)sqrt(a[0]*a[0]+a[1]*a[1]);
169
 
        if(deler== 0.0f) return 0;
170
 
 
171
 
        return (float)(fabs((v1[0]-v2[0])*a[0]+(v1[1]-v2[1])*a[1])/deler);
 
169
        float a[2], deler;
 
170
 
 
171
        a[0] = v2[1] - v3[1];
 
172
        a[1] = v3[0] - v2[0];
 
173
        deler = (float)sqrt(a[0] * a[0] + a[1] * a[1]);
 
174
        if (deler == 0.0f) return 0;
 
175
 
 
176
        return fabsf((v1[0] - v2[0]) * a[0] + (v1[1] - v2[1]) * a[1]) / deler;
172
177
 
173
178
}
174
179
 
175
180
/* distance v1 to line-piece v2-v3 */
176
 
float dist_to_line_segment_v2(float *v1, float *v2, float *v3) 
 
181
float dist_to_line_segment_v2(const float v1[2], const float v2[2], const float v3[2])
177
182
{
178
183
        float labda, rc[2], pt[2], len;
179
 
        
180
 
        rc[0]= v3[0]-v2[0];
181
 
        rc[1]= v3[1]-v2[1];
182
 
        len= rc[0]*rc[0]+ rc[1]*rc[1];
183
 
        if(len==0.0) {
184
 
                rc[0]= v1[0]-v2[0];
185
 
                rc[1]= v1[1]-v2[1];
186
 
                return (float)(sqrt(rc[0]*rc[0]+ rc[1]*rc[1]));
187
 
        }
188
 
        
189
 
        labda= (rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]))/len;
190
 
        if(labda<=0.0) {
191
 
                pt[0]= v2[0];
192
 
                pt[1]= v2[1];
193
 
        }
194
 
        else if(labda>=1.0) {
195
 
                pt[0]= v3[0];
196
 
                pt[1]= v3[1];
 
184
 
 
185
        rc[0] = v3[0] - v2[0];
 
186
        rc[1] = v3[1] - v2[1];
 
187
        len = rc[0] * rc[0] + rc[1] * rc[1];
 
188
        if (len == 0.0f) {
 
189
                rc[0] = v1[0] - v2[0];
 
190
                rc[1] = v1[1] - v2[1];
 
191
                return (float)(sqrt(rc[0] * rc[0] + rc[1] * rc[1]));
 
192
        }
 
193
 
 
194
        labda = (rc[0] * (v1[0] - v2[0]) + rc[1] * (v1[1] - v2[1])) / len;
 
195
        if (labda <= 0.0f) {
 
196
                pt[0] = v2[0];
 
197
                pt[1] = v2[1];
 
198
        }
 
199
        else if (labda >= 1.0f) {
 
200
                pt[0] = v3[0];
 
201
                pt[1] = v3[1];
197
202
        }
198
203
        else {
199
 
                pt[0]= labda*rc[0]+v2[0];
200
 
                pt[1]= labda*rc[1]+v2[1];
 
204
                pt[0] = labda * rc[0] + v2[0];
 
205
                pt[1] = labda * rc[1] + v2[1];
201
206
        }
202
207
 
203
 
        rc[0]= pt[0]-v1[0];
204
 
        rc[1]= pt[1]-v1[1];
205
 
        return (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]);
 
208
        rc[0] = pt[0] - v1[0];
 
209
        rc[1] = pt[1] - v1[1];
 
210
        return sqrtf(rc[0] * rc[0] + rc[1] * rc[1]);
 
211
}
 
212
 
 
213
/* point closest to v1 on line v2-v3 in 2D */
 
214
void closest_to_line_segment_v2(float close_r[2], const float p[2], const float l1[2], const float l2[2])
 
215
{
 
216
        float lambda, cp[2];
 
217
 
 
218
        lambda = closest_to_line_v2(cp, p, l1, l2);
 
219
 
 
220
        if (lambda <= 0.0f)
 
221
                copy_v2_v2(close_r, l1);
 
222
        else if (lambda >= 1.0f)
 
223
                copy_v2_v2(close_r, l2);
 
224
        else
 
225
                copy_v2_v2(close_r, cp);
206
226
}
207
227
 
208
228
/* point closest to v1 on line v2-v3 in 3D */
209
 
void closest_to_line_segment_v3(float *closest, float v1[3], float v2[3], float v3[3])
 
229
void closest_to_line_segment_v3(float close_r[3], const float v1[3], const float v2[3], const float v3[3])
210
230
{
211
231
        float lambda, cp[3];
212
232
 
213
 
        lambda= closest_to_line_v3(cp,v1, v2, v3);
 
233
        lambda = closest_to_line_v3(cp, v1, v2, v3);
214
234
 
215
 
        if(lambda <= 0.0f)
216
 
                copy_v3_v3(closest, v2);
217
 
        else if(lambda >= 1.0f)
218
 
                copy_v3_v3(closest, v3);
 
235
        if (lambda <= 0.0f)
 
236
                copy_v3_v3(close_r, v2);
 
237
        else if (lambda >= 1.0f)
 
238
                copy_v3_v3(close_r, v3);
219
239
        else
220
 
                copy_v3_v3(closest, cp);
 
240
                copy_v3_v3(close_r, cp);
 
241
}
 
242
 
 
243
/* find the closest point on a plane to another point and store it in close_r
 
244
 * close_r:       return coordinate
 
245
 * plane_co:      a point on the plane
 
246
 * plane_no_unit: the plane's normal, and d is the last number in the plane equation 0 = ax + by + cz + d
 
247
 * pt:            the point that you want the nearest of
 
248
 */
 
249
 
 
250
void closest_to_plane_v3(float close_r[3], const float plane_co[3], const float plane_no_unit[3], const float pt[3])
 
251
{
 
252
        float temp[3];
 
253
        float dotprod;
 
254
 
 
255
        sub_v3_v3v3(temp, pt, plane_co);
 
256
        dotprod = dot_v3v3(temp, plane_no_unit);
 
257
 
 
258
        close_r[0] = pt[0] - (plane_no_unit[0] * dotprod);
 
259
        close_r[1] = pt[1] - (plane_no_unit[1] * dotprod);
 
260
        close_r[2] = pt[2] - (plane_no_unit[2] * dotprod);
 
261
}
 
262
 
 
263
/* signed distance from the point to the plane in 3D */
 
264
float dist_to_plane_normalized_v3(const float p[3], const float plane_co[3], const float plane_no_unit[3])
 
265
{
 
266
        float plane_co_other[3];
 
267
 
 
268
        add_v3_v3v3(plane_co_other, plane_co, plane_no_unit);
 
269
 
 
270
        return line_point_factor_v3(p, plane_co, plane_co_other);
 
271
}
 
272
 
 
273
float dist_to_plane_v3(const float p[3], const float plane_co[3], const float plane_no[3])
 
274
{
 
275
        float plane_no_unit[3];
 
276
        float plane_co_other[3];
 
277
 
 
278
        normalize_v3_v3(plane_no_unit, plane_no);
 
279
        add_v3_v3v3(plane_co_other, plane_co, plane_no_unit);
 
280
 
 
281
        return line_point_factor_v3(p, plane_co, plane_co_other);
221
282
}
222
283
 
223
284
/* distance v1 to line-piece v2-v3 in 3D */
224
 
float dist_to_line_segment_v3(float *v1, float *v2, float *v3) 
 
285
float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float v3[3])
225
286
{
226
287
        float closest[3];
227
288
 
233
294
/******************************* Intersection ********************************/
234
295
 
235
296
/* intersect Line-Line, shorts */
236
 
int isect_line_line_v2_short(short *v1, short *v2, short *v3, short *v4)
 
297
int isect_line_line_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
237
298
{
238
 
        /* return:
239
 
        -1: colliniar
240
 
         0: no intersection of segments
241
 
         1: exact intersection of segments
242
 
         2: cross-intersection of segments
243
 
        */
244
299
        float div, labda, mu;
245
 
        
246
 
        div= (float)((v2[0]-v1[0])*(v4[1]-v3[1])-(v2[1]-v1[1])*(v4[0]-v3[0]));
247
 
        if(div==0.0f) return -1;
248
 
        
249
 
        labda= ((float)(v1[1]-v3[1])*(v4[0]-v3[0])-(v1[0]-v3[0])*(v4[1]-v3[1]))/div;
250
 
        
251
 
        mu= ((float)(v1[1]-v3[1])*(v2[0]-v1[0])-(v1[0]-v3[0])*(v2[1]-v1[1]))/div;
252
 
        
253
 
        if(labda>=0.0f && labda<=1.0f && mu>=0.0f && mu<=1.0f) {
254
 
                if(labda==0.0f || labda==1.0f || mu==0.0f || mu==1.0f) return 1;
255
 
                return 2;
 
300
 
 
301
        div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]));
 
302
        if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR;
 
303
 
 
304
        labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 
305
 
 
306
        mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
 
307
 
 
308
        if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
 
309
                if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
 
310
                return ISECT_LINE_LINE_CROSS;
256
311
        }
257
 
        return 0;
 
312
        return ISECT_LINE_LINE_NONE;
258
313
}
259
314
 
260
315
/* intersect Line-Line, floats */
261
 
int isect_line_line_v2(float *v1, float *v2, float *v3, float *v4)
 
316
int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
262
317
{
263
 
        /* return:
264
 
        -1: colliniar
265
 
0: no intersection of segments
266
 
1: exact intersection of segments
267
 
2: cross-intersection of segments
268
 
        */
269
318
        float div, labda, mu;
270
 
        
271
 
        div= (v2[0]-v1[0])*(v4[1]-v3[1])-(v2[1]-v1[1])*(v4[0]-v3[0]);
272
 
        if(div==0.0) return -1;
273
 
        
274
 
        labda= ((float)(v1[1]-v3[1])*(v4[0]-v3[0])-(v1[0]-v3[0])*(v4[1]-v3[1]))/div;
275
 
        
276
 
        mu= ((float)(v1[1]-v3[1])*(v2[0]-v1[0])-(v1[0]-v3[0])*(v2[1]-v1[1]))/div;
277
 
        
278
 
        if(labda>=0.0 && labda<=1.0 && mu>=0.0 && mu<=1.0) {
279
 
                if(labda==0.0 || labda==1.0 || mu==0.0 || mu==1.0) return 1;
280
 
                return 2;
281
 
        }
282
 
        return 0;
 
319
 
 
320
        div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
 
321
        if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR;
 
322
 
 
323
        labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
 
324
 
 
325
        mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
 
326
 
 
327
        if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
 
328
                if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT;
 
329
                return ISECT_LINE_LINE_CROSS;
 
330
        }
 
331
        return ISECT_LINE_LINE_NONE;
 
332
}
 
333
 
 
334
/* get intersection point of two 2D segments and return intersection type:
 
335
 *  -1: colliniar
 
336
 *   1: intersection
 
337
 */
 
338
int isect_seg_seg_v2_point(const float v1[2], const float v2[2], const float v3[2], const float v4[2], float vi[2])
 
339
{
 
340
        float a1, a2, b1, b2, c1, c2, d;
 
341
        float u, v;
 
342
        const float eps = 0.000001f;
 
343
 
 
344
        a1 = v2[0] - v1[0];
 
345
        b1 = v4[0] - v3[0];
 
346
        c1 = v1[0] - v4[0];
 
347
 
 
348
        a2 = v2[1] - v1[1];
 
349
        b2 = v4[1] - v3[1];
 
350
        c2 = v1[1] - v4[1];
 
351
 
 
352
        d = a1 * b2 - a2 * b1;
 
353
 
 
354
        if (d == 0) {
 
355
                if (a1 * c2 - a2 * c1 == 0.0f && b1 * c2 - b2 * c1 == 0.0f) { /* equal lines */
 
356
                        float a[2], b[2], c[2];
 
357
                        float u2;
 
358
 
 
359
                        if (len_v2v2(v1, v2) == 0.0f) {
 
360
                                if (len_v2v2(v3, v4) > eps) {
 
361
                                        /* use non-point segment as basis */
 
362
                                        SWAP(const float *, v1, v3);
 
363
                                        SWAP(const float *, v2, v4);
 
364
                                }
 
365
                                else { /* both of segments are points */
 
366
                                        if (equals_v2v2(v1, v3)) { /* points are equal */
 
367
                                                copy_v2_v2(vi, v1);
 
368
                                                return 1;
 
369
                                        }
 
370
 
 
371
                                        /* two different points */
 
372
                                        return -1;
 
373
                                }
 
374
                        }
 
375
 
 
376
                        sub_v2_v2v2(a, v3, v1);
 
377
                        sub_v2_v2v2(b, v2, v1);
 
378
                        sub_v2_v2v2(c, v2, v1);
 
379
                        u = dot_v2v2(a, b) / dot_v2v2(c, c);
 
380
 
 
381
                        sub_v2_v2v2(a, v4, v1);
 
382
                        u2 = dot_v2v2(a, b) / dot_v2v2(c, c);
 
383
 
 
384
                        if (u > u2) SWAP(float, u, u2);
 
385
 
 
386
                        if (u > 1.0f + eps || u2 < -eps) return -1;  /* non-ovlerlapping segments */
 
387
                        else if (maxf(0.0f, u) == minf(1.0f, u2)) { /* one common point: can return result */
 
388
                                interp_v2_v2v2(vi, v1, v2, maxf(0, u));
 
389
                                return 1;
 
390
                        }
 
391
                }
 
392
 
 
393
                /* lines are colliniar */
 
394
                return -1;
 
395
        }
 
396
 
 
397
        u = (c2 * b1 - b2 * c1) / d;
 
398
        v = (c1 * a2 - a1 * c2) / d;
 
399
 
 
400
        if (u >= -eps && u <= 1.0f + eps && v >= -eps && v <= 1.0f + eps) { /* intersection */
 
401
                interp_v2_v2v2(vi, v1, v2, u);
 
402
                return 1;
 
403
        }
 
404
 
 
405
        /* out of segment intersection */
 
406
        return -1;
 
407
}
 
408
 
 
409
int isect_line_sphere_v3(const float l1[3], const float l2[3],
 
410
                         const float sp[3], const float r,
 
411
                         float r_p1[3], float r_p2[3])
 
412
{
 
413
        /* l1:         coordinates (point of line)
 
414
         * l2:         coordinates (point of line)
 
415
         * sp, r:      coordinates and radius (sphere)
 
416
         * r_p1, r_p2: return intersection coordinates
 
417
         */
 
418
 
 
419
 
 
420
        /* adapted for use in blender by Campbell Barton - 2011
 
421
         *
 
422
         * atelier iebele abel - 2001
 
423
         * atelier@iebele.nl
 
424
         * http://www.iebele.nl
 
425
         *
 
426
         * sphere_line_intersection function adapted from:
 
427
         * http://astronomy.swin.edu.au/pbourke/geometry/sphereline
 
428
         * Paul Bourke pbourke@swin.edu.au
 
429
         */
 
430
 
 
431
        const float ldir[3] = {
 
432
            l2[0] - l1[0],
 
433
            l2[1] - l1[1],
 
434
            l2[2] - l1[2]
 
435
        };
 
436
 
 
437
        const float a = dot_v3v3(ldir, ldir);
 
438
 
 
439
        const float b = 2.0f *
 
440
                (ldir[0] * (l1[0] - sp[0]) +
 
441
                 ldir[1] * (l1[1] - sp[1]) +
 
442
                 ldir[2] * (l1[2] - sp[2]));
 
443
 
 
444
        const float c =
 
445
                dot_v3v3(sp, sp) +
 
446
                dot_v3v3(l1, l1) -
 
447
                (2.0f * dot_v3v3(sp, l1)) -
 
448
                (r * r);
 
449
 
 
450
        const float i = b * b - 4.0f * a * c;
 
451
 
 
452
        float mu;
 
453
 
 
454
        if (i < 0.0f) {
 
455
                /* no intersections */
 
456
                return 0;
 
457
        }
 
458
        else if (i == 0.0f) {
 
459
                /* one intersection */
 
460
                mu = -b / (2.0f * a);
 
461
                madd_v3_v3v3fl(r_p1, l1, ldir, mu);
 
462
                return 1;
 
463
        }
 
464
        else if (i > 0.0f) {
 
465
                const float i_sqrt = sqrt(i); /* avoid calc twice */
 
466
 
 
467
                /* first intersection */
 
468
                mu = (-b + i_sqrt) / (2.0f * a);
 
469
                madd_v3_v3v3fl(r_p1, l1, ldir, mu);
 
470
 
 
471
                /* second intersection */
 
472
                mu = (-b - i_sqrt) / (2.0f * a);
 
473
                madd_v3_v3v3fl(r_p2, l1, ldir, mu);
 
474
                return 2;
 
475
        }
 
476
        else {
 
477
                /* math domain error - nan */
 
478
                return -1;
 
479
        }
 
480
}
 
481
 
 
482
/* keep in sync with isect_line_sphere_v3 */
 
483
int isect_line_sphere_v2(const float l1[2], const float l2[2],
 
484
                         const float sp[2], const float r,
 
485
                         float r_p1[2], float r_p2[2])
 
486
{
 
487
        const float ldir[2] = {l2[0] - l1[0],
 
488
                               l2[1] - l1[1]};
 
489
 
 
490
        const float a = dot_v2v2(ldir, ldir);
 
491
 
 
492
        const float b = 2.0f *
 
493
                (ldir[0] * (l1[0] - sp[0]) +
 
494
                 ldir[1] * (l1[1] - sp[1]));
 
495
 
 
496
        const float c =
 
497
                dot_v2v2(sp, sp) +
 
498
                dot_v2v2(l1, l1) -
 
499
                (2.0f * dot_v2v2(sp, l1)) -
 
500
                (r * r);
 
501
 
 
502
        const float i = b * b - 4.0f * a * c;
 
503
 
 
504
        float mu;
 
505
 
 
506
        if (i < 0.0f) {
 
507
                /* no intersections */
 
508
                return 0;
 
509
        }
 
510
        else if (i == 0.0f) {
 
511
                /* one intersection */
 
512
                mu = -b / (2.0f * a);
 
513
                madd_v2_v2v2fl(r_p1, l1, ldir, mu);
 
514
                return 1;
 
515
        }
 
516
        else if (i > 0.0f) {
 
517
                const float i_sqrt = sqrt(i); /* avoid calc twice */
 
518
 
 
519
                /* first intersection */
 
520
                mu = (-b + i_sqrt) / (2.0f * a);
 
521
                madd_v2_v2v2fl(r_p1, l1, ldir, mu);
 
522
 
 
523
                /* second intersection */
 
524
                mu = (-b - i_sqrt) / (2.0f * a);
 
525
                madd_v2_v2v2fl(r_p2, l1, ldir, mu);
 
526
                return 2;
 
527
        }
 
528
        else {
 
529
                /* math domain error - nan */
 
530
                return -1;
 
531
        }
283
532
}
284
533
 
285
534
/*
286
 
-1: colliniar
287
 
 1: intersection
288
 
 
289
 
*/
290
 
static short IsectLLPt2Df(float x0,float y0,float x1,float y1,
291
 
                                         float x2,float y2,float x3,float y3, float *xi,float *yi)
 
535
 * -1: colliniar
 
536
 *  1: intersection
 
537
 */
 
538
static short IsectLLPt2Df(const float x0, const float y0, const float x1, const float y1,
 
539
                          const float x2, const float y2, const float x3, const float y3, float *xi, float *yi)
292
540
 
293
541
{
294
542
        /*
295
 
        this function computes the intersection of the sent lines
296
 
        and returns the intersection point, note that the function assumes
297
 
        the lines intersect. the function can handle vertical as well
298
 
        as horizontal lines. note the function isn't very clever, it simply
299
 
        applies the math, but we don't need speed since this is a
300
 
        pre-processing step
301
 
        */
302
 
        float c1,c2, // constants of linear equations
303
 
        det_inv,  // the inverse of the determinant of the coefficient
304
 
        m1,m2;    // the slopes of each line
 
543
         * this function computes the intersection of the sent lines
 
544
         * and returns the intersection point, note that the function assumes
 
545
         * the lines intersect. the function can handle vertical as well
 
546
         * as horizontal lines. note the function isn't very clever, it simply
 
547
         * applies the math, but we don't need speed since this is a
 
548
         * pre-processing step
 
549
         */
 
550
        float c1, c2; /* constants of linear equations */
 
551
        float det_inv; /* the inverse of the determinant of the coefficient */
 
552
        float m1, m2; /* the slopes of each line */
305
553
        /*
306
 
        compute slopes, note the cludge for infinity, however, this will
307
 
        be close enough
308
 
        */
309
 
        if (fabs(x1-x0) > 0.000001)
310
 
                m1 = (y1-y0) / (x1-x0);
311
 
        else
312
 
                return -1; /*m1 = (float) 1e+10;*/   // close enough to infinity
313
 
 
314
 
        if (fabs(x3-x2) > 0.000001)
315
 
                m2 = (y3-y2) / (x3-x2);
316
 
        else
317
 
                return -1; /*m2 = (float) 1e+10;*/   // close enough to infinity
318
 
 
319
 
        if (fabs(m1-m2) < 0.000001)
320
 
                return -1; /* parallel lines */
321
 
        
322
 
// compute constants
323
 
 
324
 
        c1 = (y0-m1*x0);
325
 
        c2 = (y2-m2*x2);
326
 
 
327
 
// compute the inverse of the determinate
 
554
         * compute slopes, note the cludge for infinity, however, this will
 
555
         * be close enough
 
556
         */
 
557
        if (fabs(x1 - x0) > 0.000001)
 
558
                m1 = (y1 - y0) / (x1 - x0);
 
559
        else
 
560
                return -1; /*m1 = (float)1e+10;*/ // close enough to infinity
 
561
 
 
562
        if (fabs(x3 - x2) > 0.000001)
 
563
                m2 = (y3 - y2) / (x3 - x2);
 
564
        else
 
565
                return -1; /*m2 = (float)1e+10;*/ // close enough to infinity
 
566
 
 
567
        if (fabs(m1 - m2) < 0.000001)
 
568
                return -1;  /* parallel lines */
 
569
 
 
570
        // compute constants
 
571
 
 
572
        c1 = (y0 - m1 * x0);
 
573
        c2 = (y2 - m2 * x2);
 
574
 
 
575
        // compute the inverse of the determinate
328
576
 
329
577
        det_inv = 1.0f / (-m1 + m2);
330
578
 
331
 
// use Kramers rule to compute xi and yi
332
 
 
333
 
        *xi= ((-c2 + c1) *det_inv);
334
 
        *yi= ((m2*c1 - m1*c2) *det_inv);
335
 
        
336
 
        return 1; 
337
 
} // end Intersect_Lines
338
 
 
339
 
#define SIDE_OF_LINE(pa,pb,pp)  ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
 
579
        // use Kramers rule to compute xi and yi
 
580
 
 
581
        *xi = ((-c2 + c1) * det_inv);
 
582
        *yi = ((m2 * c1 - m1 * c2) * det_inv);
 
583
 
 
584
        return 1;
 
585
}
 
586
 
340
587
/* point in tri */
341
 
// XXX was called IsectPT2Df
342
 
int isect_point_tri_v2(float pt[2], float v1[2], float v2[2], float v3[2])
 
588
 
 
589
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
343
590
{
344
 
        if (SIDE_OF_LINE(v1,v2,pt)>=0.0) {
345
 
                if (SIDE_OF_LINE(v2,v3,pt)>=0.0) {
346
 
                        if (SIDE_OF_LINE(v3,v1,pt)>=0.0) {
 
591
        if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
 
592
                if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
 
593
                        if (line_point_side_v2(v3, v1, pt) >= 0.0f) {
347
594
                                return 1;
348
595
                        }
349
596
                }
350
 
        } else {
351
 
                if (! (SIDE_OF_LINE(v2,v3,pt)>=0.0)) {
352
 
                        if (! (SIDE_OF_LINE(v3,v1,pt)>=0.0)) {
 
597
        }
 
598
        else {
 
599
                if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
 
600
                        if (!(line_point_side_v2(v3, v1, pt) >= 0.0f)) {
353
601
                                return -1;
354
602
                        }
355
603
                }
356
604
        }
357
 
        
 
605
 
358
606
        return 0;
359
607
}
 
608
 
360
609
/* point in quad - only convex quads */
361
 
int isect_point_quad_v2(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2])
 
610
int isect_point_quad_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2])
362
611
{
363
 
        if (SIDE_OF_LINE(v1,v2,pt)>=0.0) {
364
 
                if (SIDE_OF_LINE(v2,v3,pt)>=0.0) {
365
 
                        if (SIDE_OF_LINE(v3,v4,pt)>=0.0) {
366
 
                                if (SIDE_OF_LINE(v4,v1,pt)>=0.0) {
 
612
        if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
 
613
                if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
 
614
                        if (line_point_side_v2(v3, v4, pt) >= 0.0f) {
 
615
                                if (line_point_side_v2(v4, v1, pt) >= 0.0f) {
367
616
                                        return 1;
368
617
                                }
369
618
                        }
370
619
                }
371
 
        } else {
372
 
                if (! (SIDE_OF_LINE(v2,v3,pt)>=0.0)) {
373
 
                        if (! (SIDE_OF_LINE(v3,v4,pt)>=0.0)) {
374
 
                                if (! (SIDE_OF_LINE(v4,v1,pt)>=0.0)) {
 
620
        }
 
621
        else {
 
622
                if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
 
623
                        if (!(line_point_side_v2(v3, v4, pt) >= 0.0f)) {
 
624
                                if (!(line_point_side_v2(v4, v1, pt) >= 0.0f)) {
375
625
                                        return -1;
376
626
                                }
377
627
                        }
378
628
                }
379
629
        }
380
 
        
 
630
 
381
631
        return 0;
382
632
}
383
633
 
384
634
/* moved from effect.c
385
 
   test if the line starting at p1 ending at p2 intersects the triangle v0..v2
386
 
   return non zero if it does 
387
 
*/
388
 
int isect_line_tri_v3(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv)
 
635
 * test if the line starting at p1 ending at p2 intersects the triangle v0..v2
 
636
 * return non zero if it does
 
637
 */
 
638
int isect_line_tri_v3(const float p1[3], const float p2[3],
 
639
                      const float v0[3], const float v1[3], const float v2[3],
 
640
                      float *r_lambda, float r_uv[2])
389
641
{
390
642
 
391
643
        float p[3], s[3], d[3], e1[3], e2[3], q[3];
392
644
        float a, f, u, v;
393
 
        
 
645
 
394
646
        sub_v3_v3v3(e1, v1, v0);
395
647
        sub_v3_v3v3(e2, v2, v0);
396
648
        sub_v3_v3v3(d, p2, p1);
397
 
        
 
649
 
398
650
        cross_v3_v3v3(p, d, e2);
399
651
        a = dot_v3v3(e1, p);
400
 
        if ((a > -0.000001) && (a < 0.000001)) return 0;
401
 
        f = 1.0f/a;
402
 
        
 
652
        if ((a > -0.000001f) && (a < 0.000001f)) return 0;
 
653
        f = 1.0f / a;
 
654
 
403
655
        sub_v3_v3v3(s, p1, v0);
404
 
        
 
656
 
405
657
        u = f * dot_v3v3(s, p);
406
 
        if ((u < 0.0)||(u > 1.0)) return 0;
407
 
        
 
658
        if ((u < 0.0f) || (u > 1.0f)) return 0;
 
659
 
408
660
        cross_v3_v3v3(q, s, e1);
409
 
        
410
 
        v = f * dot_v3v3(d, q);
411
 
        if ((v < 0.0)||((u + v) > 1.0)) return 0;
412
 
 
413
 
        *lambda = f * dot_v3v3(e2, q);
414
 
        if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
415
 
 
416
 
        if(uv) {
417
 
                uv[0]= u;
418
 
                uv[1]= v;
 
661
 
 
662
        v = f * dot_v3v3(d, q);
 
663
        if ((v < 0.0f) || ((u + v) > 1.0f)) return 0;
 
664
 
 
665
        *r_lambda = f * dot_v3v3(e2, q);
 
666
        if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0;
 
667
 
 
668
        if (r_uv) {
 
669
                r_uv[0] = u;
 
670
                r_uv[1] = v;
419
671
        }
420
 
        
 
672
 
421
673
        return 1;
422
674
}
423
675
 
424
676
/* moved from effect.c
425
 
   test if the ray starting at p1 going in d direction intersects the triangle v0..v2
426
 
   return non zero if it does 
427
 
*/
428
 
int isect_ray_tri_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv)
429
 
{
430
 
        float p[3], s[3], e1[3], e2[3], q[3];
431
 
        float a, f, u, v;
432
 
        
433
 
        sub_v3_v3v3(e1, v1, v0);
434
 
        sub_v3_v3v3(e2, v2, v0);
435
 
        
436
 
        cross_v3_v3v3(p, d, e2);
437
 
        a = dot_v3v3(e1, p);
438
 
        /* note: these values were 0.000001 in 2.4x but for projection snapping on
439
 
         * a human head (1BU==1m), subsurf level 2, this gave many errors - campbell */
440
 
        if ((a > -0.00000001) && (a < 0.00000001)) return 0;
441
 
        f = 1.0f/a;
442
 
        
443
 
        sub_v3_v3v3(s, p1, v0);
444
 
        
445
 
        u = f * dot_v3v3(s, p);
446
 
        if ((u < 0.0)||(u > 1.0)) return 0;
447
 
        
448
 
        cross_v3_v3v3(q, s, e1);
449
 
        
450
 
        v = f * dot_v3v3(d, q);
451
 
        if ((v < 0.0)||((u + v) > 1.0)) return 0;
452
 
 
453
 
        *lambda = f * dot_v3v3(e2, q);
454
 
        if ((*lambda < 0.0)) return 0;
455
 
 
456
 
        if(uv) {
457
 
                uv[0]= u;
458
 
                uv[1]= v;
459
 
        }
460
 
        
461
 
        return 1;
462
 
}
463
 
 
464
 
int isect_ray_tri_epsilon_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float epsilon)
465
 
{
466
 
    float p[3], s[3], e1[3], e2[3], q[3];
467
 
    float a, f, u, v;
468
 
 
469
 
    sub_v3_v3v3(e1, v1, v0);
470
 
    sub_v3_v3v3(e2, v2, v0);
471
 
 
472
 
    cross_v3_v3v3(p, d, e2);
473
 
    a = dot_v3v3(e1, p);
474
 
    if (a == 0.0f) return 0;
475
 
    f = 1.0f/a;
476
 
 
477
 
    sub_v3_v3v3(s, p1, v0);
478
 
 
479
 
    u = f * dot_v3v3(s, p);
480
 
    if ((u < -epsilon)||(u > 1.0f+epsilon)) return 0;
481
 
 
482
 
    cross_v3_v3v3(q, s, e1);
483
 
 
484
 
    v = f * dot_v3v3(d, q);
485
 
    if ((v < -epsilon)||((u + v) > 1.0f+epsilon)) return 0;
486
 
 
487
 
    *lambda = f * dot_v3v3(e2, q);
488
 
    if ((*lambda < 0.0f)) return 0;
489
 
 
490
 
    if(uv) {
491
 
        uv[0]= u;
492
 
        uv[1]= v;
493
 
    }
494
 
 
495
 
    return 1;
496
 
}
497
 
 
498
 
int isect_ray_tri_threshold_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold)
 
677
 * test if the ray starting at p1 going in d direction intersects the triangle v0..v2
 
678
 * return non zero if it does
 
679
 */
 
680
int isect_ray_tri_v3(const float p1[3], const float d[3],
 
681
                     const float v0[3], const float v1[3], const float v2[3],
 
682
                     float *r_lambda, float r_uv[2])
 
683
{
 
684
        float p[3], s[3], e1[3], e2[3], q[3];
 
685
        float a, f, u, v;
 
686
 
 
687
        sub_v3_v3v3(e1, v1, v0);
 
688
        sub_v3_v3v3(e2, v2, v0);
 
689
 
 
690
        cross_v3_v3v3(p, d, e2);
 
691
        a = dot_v3v3(e1, p);
 
692
        /* note: these values were 0.000001 in 2.4x but for projection snapping on
 
693
         * a human head (1BU==1m), subsurf level 2, this gave many errors - campbell */
 
694
        if ((a > -0.00000001f) && (a < 0.00000001f)) return 0;
 
695
        f = 1.0f / a;
 
696
 
 
697
        sub_v3_v3v3(s, p1, v0);
 
698
 
 
699
        u = f * dot_v3v3(s, p);
 
700
        if ((u < 0.0f) || (u > 1.0f)) return 0;
 
701
 
 
702
        cross_v3_v3v3(q, s, e1);
 
703
 
 
704
        v = f * dot_v3v3(d, q);
 
705
        if ((v < 0.0f) || ((u + v) > 1.0f)) return 0;
 
706
 
 
707
        *r_lambda = f * dot_v3v3(e2, q);
 
708
        if ((*r_lambda < 0.0f)) return 0;
 
709
 
 
710
        if (r_uv) {
 
711
                r_uv[0] = u;
 
712
                r_uv[1] = v;
 
713
        }
 
714
 
 
715
        return 1;
 
716
}
 
717
 
 
718
int isect_ray_plane_v3(const float p1[3], const float d[3],
 
719
                       const float v0[3], const float v1[3], const float v2[3],
 
720
                       float *r_lambda, const int clip)
 
721
{
 
722
        float p[3], s[3], e1[3], e2[3], q[3];
 
723
        float a, f;
 
724
        /* float  u, v; */ /*UNUSED*/
 
725
 
 
726
        sub_v3_v3v3(e1, v1, v0);
 
727
        sub_v3_v3v3(e2, v2, v0);
 
728
 
 
729
        cross_v3_v3v3(p, d, e2);
 
730
        a = dot_v3v3(e1, p);
 
731
        /* note: these values were 0.000001 in 2.4x but for projection snapping on
 
732
         * a human head (1BU==1m), subsurf level 2, this gave many errors - campbell */
 
733
        if ((a > -0.00000001f) && (a < 0.00000001f)) return 0;
 
734
        f = 1.0f / a;
 
735
 
 
736
        sub_v3_v3v3(s, p1, v0);
 
737
 
 
738
        /* u = f * dot_v3v3(s, p); */ /*UNUSED*/
 
739
 
 
740
        cross_v3_v3v3(q, s, e1);
 
741
 
 
742
        /* v = f * dot_v3v3(d, q); */ /*UNUSED*/
 
743
 
 
744
        *r_lambda = f * dot_v3v3(e2, q);
 
745
        if (clip && (*r_lambda < 0.0f)) return 0;
 
746
 
 
747
        return 1;
 
748
}
 
749
 
 
750
int isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
 
751
                             const float v0[3], const float v1[3], const float v2[3],
 
752
                             float *r_lambda, float uv[2], const float epsilon)
 
753
{
 
754
        float p[3], s[3], e1[3], e2[3], q[3];
 
755
        float a, f, u, v;
 
756
 
 
757
        sub_v3_v3v3(e1, v1, v0);
 
758
        sub_v3_v3v3(e2, v2, v0);
 
759
 
 
760
        cross_v3_v3v3(p, d, e2);
 
761
        a = dot_v3v3(e1, p);
 
762
        if (a == 0.0f) return 0;
 
763
        f = 1.0f / a;
 
764
 
 
765
        sub_v3_v3v3(s, p1, v0);
 
766
 
 
767
        u = f * dot_v3v3(s, p);
 
768
        if ((u < -epsilon) || (u > 1.0f + epsilon)) return 0;
 
769
 
 
770
        cross_v3_v3v3(q, s, e1);
 
771
 
 
772
        v = f * dot_v3v3(d, q);
 
773
        if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return 0;
 
774
 
 
775
        *r_lambda = f * dot_v3v3(e2, q);
 
776
        if ((*r_lambda < 0.0f)) return 0;
 
777
 
 
778
        if (uv) {
 
779
                uv[0] = u;
 
780
                uv[1] = v;
 
781
        }
 
782
 
 
783
        return 1;
 
784
}
 
785
 
 
786
int isect_ray_tri_threshold_v3(const float p1[3], const float d[3],
 
787
                               const float v0[3], const float v1[3], const float v2[3],
 
788
                               float *r_lambda, float r_uv[2], const float threshold)
499
789
{
500
790
        float p[3], s[3], e1[3], e2[3], q[3];
501
791
        float a, f, u, v;
502
792
        float du = 0, dv = 0;
503
 
        
 
793
 
504
794
        sub_v3_v3v3(e1, v1, v0);
505
795
        sub_v3_v3v3(e2, v2, v0);
506
 
        
 
796
 
507
797
        cross_v3_v3v3(p, d, e2);
508
798
        a = dot_v3v3(e1, p);
509
 
        if ((a > -0.000001) && (a < 0.000001)) return 0;
510
 
        f = 1.0f/a;
511
 
        
 
799
        if ((a > -0.000001f) && (a < 0.000001f)) return 0;
 
800
        f = 1.0f / a;
 
801
 
512
802
        sub_v3_v3v3(s, p1, v0);
513
 
        
 
803
 
514
804
        cross_v3_v3v3(q, s, e1);
515
 
        *lambda = f * dot_v3v3(e2, q);
516
 
        if ((*lambda < 0.0)) return 0;
517
 
        
 
805
        *r_lambda = f * dot_v3v3(e2, q);
 
806
        if ((*r_lambda < 0.0f)) return 0;
 
807
 
518
808
        u = f * dot_v3v3(s, p);
519
809
        v = f * dot_v3v3(d, q);
520
 
        
 
810
 
521
811
        if (u < 0) du = u;
522
812
        if (u > 1) du = u - 1;
523
813
        if (v < 0) dv = v;
524
814
        if (v > 1) dv = v - 1;
525
 
        if (u > 0 && v > 0 && u + v > 1)
526
 
        {
 
815
        if (u > 0 && v > 0 && u + v > 1) {
527
816
                float t = u + v - 1;
528
 
                du = u - t/2;
529
 
                dv = v - t/2;
 
817
                du = u - t / 2;
 
818
                dv = v - t / 2;
530
819
        }
531
820
 
532
821
        mul_v3_fl(e1, du);
533
822
        mul_v3_fl(e2, dv);
534
 
        
535
 
        if (dot_v3v3(e1, e1) + dot_v3v3(e2, e2) > threshold * threshold)
536
 
        {
 
823
 
 
824
        if (dot_v3v3(e1, e1) + dot_v3v3(e2, e2) > threshold * threshold) {
537
825
                return 0;
538
826
        }
539
827
 
540
 
        if(uv) {
541
 
                uv[0]= u;
542
 
                uv[1]= v;
 
828
        if (r_uv) {
 
829
                r_uv[0] = u;
 
830
                r_uv[1] = v;
543
831
        }
544
 
        
 
832
 
545
833
        return 1;
546
834
}
547
835
 
 
836
int isect_line_plane_v3(float out[3],
 
837
                        const float l1[3], const float l2[3],
 
838
                        const float plane_co[3], const float plane_no[3], const short no_flip)
 
839
{
 
840
        float l_vec[3]; /* l1 -> l2 normalized vector */
 
841
        float p_no[3]; /* 'plane_no' normalized */
 
842
        float dot;
 
843
 
 
844
        sub_v3_v3v3(l_vec, l2, l1);
 
845
 
 
846
        normalize_v3(l_vec);
 
847
        normalize_v3_v3(p_no, plane_no);
 
848
 
 
849
        dot = dot_v3v3(l_vec, p_no);
 
850
        if (dot == 0.0f) {
 
851
                return 0;
 
852
        }
 
853
        else {
 
854
                float l1_plane[3]; /* line point aligned with the plane */
 
855
                float dist; /* 'plane_no' aligned distance to the 'plane_co' */
 
856
 
 
857
                /* for predictable flipping since the plane is only used to
 
858
                 * define a direction, ignore its flipping and aligned with 'l_vec' */
 
859
                if (dot < 0.0f) {
 
860
                        dot = -dot;
 
861
                        negate_v3(p_no);
 
862
                }
 
863
 
 
864
                add_v3_v3v3(l1_plane, l1, p_no);
 
865
 
 
866
                dist = line_point_factor_v3(plane_co, l1, l1_plane);
 
867
 
 
868
                /* treat line like a ray, when 'no_flip' is set */
 
869
                if (no_flip && dist < 0.0f) {
 
870
                        dist = -dist;
 
871
                }
 
872
 
 
873
                mul_v3_fl(l_vec, dist / dot);
 
874
 
 
875
                add_v3_v3v3(out, l1, l_vec);
 
876
 
 
877
                return 1;
 
878
        }
 
879
}
 
880
 
 
881
/* note: return normal isn't unit length */
 
882
void isect_plane_plane_v3(float r_isect_co[3], float r_isect_no[3],
 
883
                          const float plane_a_co[3], const float plane_a_no[3],
 
884
                          const float plane_b_co[3], const float plane_b_no[3])
 
885
{
 
886
        float plane_a_co_other[3];
 
887
        cross_v3_v3v3(r_isect_no, plane_a_no, plane_b_no); /* direction is simply the cross product */
 
888
        cross_v3_v3v3(plane_a_co_other, plane_a_no, r_isect_no);
 
889
        add_v3_v3(plane_a_co_other, plane_a_co);
 
890
        isect_line_plane_v3(r_isect_co, plane_a_co, plane_a_co_other, plane_b_co, plane_b_no, FALSE);
 
891
}
 
892
 
548
893
 
549
894
/* Adapted from the paper by Kasper Fauerby */
 
895
 
550
896
/* "Improved Collision detection and Response" */
551
 
static int getLowestRoot(float a, float b, float c, float maxR, float* root)
 
897
static int getLowestRoot(const float a, const float b, const float c, const float maxR, float *root)
552
898
{
553
899
        // Check if a solution exists
554
 
        float determinant = b*b - 4.0f*a*c;
 
900
        float determinant = b * b - 4.0f * a * c;
555
901
 
556
902
        // If determinant is negative it means no solutions.
557
 
        if (determinant >= 0.0f)
558
 
        {
 
903
        if (determinant >= 0.0f) {
559
904
                // calculate the two roots: (if determinant == 0 then
560
 
                // x1==x2 but let’s disregard that slight optimization)
 
905
                // x1==x2 but lets disregard that slight optimization)
561
906
                float sqrtD = (float)sqrt(determinant);
562
 
                float r1 = (-b - sqrtD) / (2.0f*a);
563
 
                float r2 = (-b + sqrtD) / (2.0f*a);
564
 
                
 
907
                float r1 = (-b - sqrtD) / (2.0f * a);
 
908
                float r2 = (-b + sqrtD) / (2.0f * a);
 
909
 
565
910
                // Sort so x1 <= x2
566
911
                if (r1 > r2)
567
912
                        SWAP(float, r1, r2);
568
913
 
569
914
                // Get lowest root:
570
 
                if (r1 > 0.0f && r1 < maxR)
571
 
                {
 
915
                if (r1 > 0.0f && r1 < maxR) {
572
916
                        *root = r1;
573
917
                        return 1;
574
918
                }
575
919
 
576
920
                // It is possible that we want x2 - this can happen
577
921
                // if x1 < 0
578
 
                if (r2 > 0.0f && r2 < maxR)
579
 
                {
 
922
                if (r2 > 0.0f && r2 < maxR) {
580
923
                        *root = r2;
581
924
                        return 1;
582
925
                }
585
928
        return 0;
586
929
}
587
930
 
588
 
int isect_sweeping_sphere_tri_v3(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint)
 
931
int isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const float radius,
 
932
                                 const float v0[3], const float v1[3], const float v2[3],
 
933
                                 float *r_lambda, float ipoint[3])
589
934
{
590
935
        float e1[3], e2[3], e3[3], point[3], vel[3], /*dist[3],*/ nor[3], temp[3], bv[3];
591
 
        float a, b, c, d, e, x, y, z, radius2=radius*radius;
592
 
        float elen2,edotv,edotbv,nordotv,vel2;
 
936
        float a, b, c, d, e, x, y, z, radius2 = radius * radius;
 
937
        float elen2, edotv, edotbv, nordotv;
593
938
        float newLambda;
594
 
        int found_by_sweep=0;
595
 
 
596
 
        sub_v3_v3v3(e1,v1,v0);
597
 
        sub_v3_v3v3(e2,v2,v0);
598
 
        sub_v3_v3v3(vel,p2,p1);
599
 
 
600
 
/*---test plane of tri---*/
601
 
        cross_v3_v3v3(nor,e1,e2);
 
939
        int found_by_sweep = 0;
 
940
 
 
941
        sub_v3_v3v3(e1, v1, v0);
 
942
        sub_v3_v3v3(e2, v2, v0);
 
943
        sub_v3_v3v3(vel, p2, p1);
 
944
 
 
945
        /*---test plane of tri---*/
 
946
        cross_v3_v3v3(nor, e1, e2);
602
947
        normalize_v3(nor);
603
948
 
604
949
        /* flip normal */
605
 
        if(dot_v3v3(nor,vel)>0.0f) negate_v3(nor);
606
 
        
607
 
        a=dot_v3v3(p1,nor)-dot_v3v3(v0,nor);
608
 
        nordotv=dot_v3v3(nor,vel);
609
 
 
610
 
        if (fabs(nordotv) < 0.000001)
611
 
        {
612
 
                if(fabs(a)>=radius)
613
 
                {
 
950
        if (dot_v3v3(nor, vel) > 0.0f) negate_v3(nor);
 
951
 
 
952
        a = dot_v3v3(p1, nor) - dot_v3v3(v0, nor);
 
953
        nordotv = dot_v3v3(nor, vel);
 
954
 
 
955
        if (fabsf(nordotv) < 0.000001f) {
 
956
                if (fabsf(a) >= radius) {
614
957
                        return 0;
615
958
                }
616
959
        }
617
 
        else
618
 
        {
619
 
                float t0=(-a+radius)/nordotv;
620
 
                float t1=(-a-radius)/nordotv;
 
960
        else {
 
961
                float t0 = (-a + radius) / nordotv;
 
962
                float t1 = (-a - radius) / nordotv;
621
963
 
622
 
                if(t0>t1)
 
964
                if (t0 > t1)
623
965
                        SWAP(float, t0, t1);
624
966
 
625
 
                if(t0>1.0f || t1<0.0f) return 0;
 
967
                if (t0 > 1.0f || t1 < 0.0f) return 0;
626
968
 
627
969
                /* clamp to [0,1] */
628
970
                CLAMP(t0, 0.0f, 1.0f);
631
973
                /*---test inside of tri---*/
632
974
                /* plane intersection point */
633
975
 
634
 
                point[0] = p1[0] + vel[0]*t0 - nor[0]*radius;
635
 
                point[1] = p1[1] + vel[1]*t0 - nor[1]*radius;
636
 
                point[2] = p1[2] + vel[2]*t0 - nor[2]*radius;
 
976
                point[0] = p1[0] + vel[0] * t0 - nor[0] * radius;
 
977
                point[1] = p1[1] + vel[1] * t0 - nor[1] * radius;
 
978
                point[2] = p1[2] + vel[2] * t0 - nor[2] * radius;
637
979
 
638
980
 
639
981
                /* is the point in the tri? */
640
 
                a=dot_v3v3(e1,e1);
641
 
                b=dot_v3v3(e1,e2);
642
 
                c=dot_v3v3(e2,e2);
643
 
 
644
 
                sub_v3_v3v3(temp,point,v0);
645
 
                d=dot_v3v3(temp,e1);
646
 
                e=dot_v3v3(temp,e2);
647
 
                
648
 
                x=d*c-e*b;
649
 
                y=e*a-d*b;
650
 
                z=x+y-(a*c-b*b);
651
 
 
652
 
 
653
 
                if(z <= 0.0f && (x >= 0.0f && y >= 0.0f))
654
 
                {
655
 
                //(((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y))) & 0x80000000){
656
 
                        *lambda=t0;
657
 
                        copy_v3_v3(ipoint,point);
 
982
                a = dot_v3v3(e1, e1);
 
983
                b = dot_v3v3(e1, e2);
 
984
                c = dot_v3v3(e2, e2);
 
985
 
 
986
                sub_v3_v3v3(temp, point, v0);
 
987
                d = dot_v3v3(temp, e1);
 
988
                e = dot_v3v3(temp, e2);
 
989
 
 
990
                x = d * c - e * b;
 
991
                y = e * a - d * b;
 
992
                z = x + y - (a * c - b * b);
 
993
 
 
994
 
 
995
                if (z <= 0.0f && (x >= 0.0f && y >= 0.0f)) {
 
996
                        //(((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y))) & 0x80000000) {
 
997
                        *r_lambda = t0;
 
998
                        copy_v3_v3(ipoint, point);
658
999
                        return 1;
659
1000
                }
660
1001
        }
661
1002
 
662
1003
 
663
 
        *lambda=1.0f;
 
1004
        *r_lambda = 1.0f;
664
1005
 
665
 
/*---test points---*/
666
 
        a=vel2=dot_v3v3(vel,vel);
 
1006
        /*---test points---*/
 
1007
        a = dot_v3v3(vel, vel);
667
1008
 
668
1009
        /*v0*/
669
 
        sub_v3_v3v3(temp,p1,v0);
670
 
        b=2.0f*dot_v3v3(vel,temp);
671
 
        c=dot_v3v3(temp,temp)-radius2;
 
1010
        sub_v3_v3v3(temp, p1, v0);
 
1011
        b = 2.0f * dot_v3v3(vel, temp);
 
1012
        c = dot_v3v3(temp, temp) - radius2;
672
1013
 
673
 
        if(getLowestRoot(a, b, c, *lambda, lambda))
674
 
        {
675
 
                copy_v3_v3(ipoint,v0);
676
 
                found_by_sweep=1;
 
1014
        if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
 
1015
                copy_v3_v3(ipoint, v0);
 
1016
                found_by_sweep = 1;
677
1017
        }
678
1018
 
679
1019
        /*v1*/
680
 
        sub_v3_v3v3(temp,p1,v1);
681
 
        b=2.0f*dot_v3v3(vel,temp);
682
 
        c=dot_v3v3(temp,temp)-radius2;
 
1020
        sub_v3_v3v3(temp, p1, v1);
 
1021
        b = 2.0f * dot_v3v3(vel, temp);
 
1022
        c = dot_v3v3(temp, temp) - radius2;
683
1023
 
684
 
        if(getLowestRoot(a, b, c, *lambda, lambda))
685
 
        {
686
 
                copy_v3_v3(ipoint,v1);
687
 
                found_by_sweep=1;
 
1024
        if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
 
1025
                copy_v3_v3(ipoint, v1);
 
1026
                found_by_sweep = 1;
688
1027
        }
689
 
        
 
1028
 
690
1029
        /*v2*/
691
 
        sub_v3_v3v3(temp,p1,v2);
692
 
        b=2.0f*dot_v3v3(vel,temp);
693
 
        c=dot_v3v3(temp,temp)-radius2;
 
1030
        sub_v3_v3v3(temp, p1, v2);
 
1031
        b = 2.0f * dot_v3v3(vel, temp);
 
1032
        c = dot_v3v3(temp, temp) - radius2;
694
1033
 
695
 
        if(getLowestRoot(a, b, c, *lambda, lambda))
696
 
        {
697
 
                copy_v3_v3(ipoint,v2);
698
 
                found_by_sweep=1;
 
1034
        if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
 
1035
                copy_v3_v3(ipoint, v2);
 
1036
                found_by_sweep = 1;
699
1037
        }
700
1038
 
701
 
/*---test edges---*/
702
 
        sub_v3_v3v3(e3,v2,v1); //wasnt yet calculated
 
1039
        /*---test edges---*/
 
1040
        sub_v3_v3v3(e3, v2, v1); //wasnt yet calculated
703
1041
 
704
1042
 
705
1043
        /*e1*/
706
 
        sub_v3_v3v3(bv,v0,p1);
707
 
 
708
 
        elen2 = dot_v3v3(e1,e1);
709
 
        edotv = dot_v3v3(e1,vel);
710
 
        edotbv = dot_v3v3(e1,bv);
711
 
 
712
 
        a=elen2*(-dot_v3v3(vel,vel))+edotv*edotv;
713
 
        b=2.0f*(elen2*dot_v3v3(vel,bv)-edotv*edotbv);
714
 
        c=elen2*(radius2-dot_v3v3(bv,bv))+edotbv*edotbv;
715
 
 
716
 
        if(getLowestRoot(a, b, c, *lambda, &newLambda))
717
 
        {
718
 
                e=(edotv*newLambda-edotbv)/elen2;
719
 
 
720
 
                if(e >= 0.0f && e <= 1.0f)
721
 
                {
722
 
                        *lambda = newLambda;
723
 
                        copy_v3_v3(ipoint,e1);
724
 
                        mul_v3_fl(ipoint,e);
 
1044
        sub_v3_v3v3(bv, v0, p1);
 
1045
 
 
1046
        elen2 = dot_v3v3(e1, e1);
 
1047
        edotv = dot_v3v3(e1, vel);
 
1048
        edotbv = dot_v3v3(e1, bv);
 
1049
 
 
1050
        a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
 
1051
        b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
 
1052
        c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
 
1053
 
 
1054
        if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
 
1055
                e = (edotv * newLambda - edotbv) / elen2;
 
1056
 
 
1057
                if (e >= 0.0f && e <= 1.0f) {
 
1058
                        *r_lambda = newLambda;
 
1059
                        copy_v3_v3(ipoint, e1);
 
1060
                        mul_v3_fl(ipoint, e);
725
1061
                        add_v3_v3(ipoint, v0);
726
 
                        found_by_sweep=1;
 
1062
                        found_by_sweep = 1;
727
1063
                }
728
1064
        }
729
1065
 
730
1066
        /*e2*/
731
1067
        /*bv is same*/
732
 
        elen2 = dot_v3v3(e2,e2);
733
 
        edotv = dot_v3v3(e2,vel);
734
 
        edotbv = dot_v3v3(e2,bv);
735
 
 
736
 
        a=elen2*(-dot_v3v3(vel,vel))+edotv*edotv;
737
 
        b=2.0f*(elen2*dot_v3v3(vel,bv)-edotv*edotbv);
738
 
        c=elen2*(radius2-dot_v3v3(bv,bv))+edotbv*edotbv;
739
 
 
740
 
        if(getLowestRoot(a, b, c, *lambda, &newLambda))
741
 
        {
742
 
                e=(edotv*newLambda-edotbv)/elen2;
743
 
 
744
 
                if(e >= 0.0f && e <= 1.0f)
745
 
                {
746
 
                        *lambda = newLambda;
747
 
                        copy_v3_v3(ipoint,e2);
748
 
                        mul_v3_fl(ipoint,e);
 
1068
        elen2 = dot_v3v3(e2, e2);
 
1069
        edotv = dot_v3v3(e2, vel);
 
1070
        edotbv = dot_v3v3(e2, bv);
 
1071
 
 
1072
        a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
 
1073
        b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
 
1074
        c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
 
1075
 
 
1076
        if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
 
1077
                e = (edotv * newLambda - edotbv) / elen2;
 
1078
 
 
1079
                if (e >= 0.0f && e <= 1.0f) {
 
1080
                        *r_lambda = newLambda;
 
1081
                        copy_v3_v3(ipoint, e2);
 
1082
                        mul_v3_fl(ipoint, e);
749
1083
                        add_v3_v3(ipoint, v0);
750
 
                        found_by_sweep=1;
 
1084
                        found_by_sweep = 1;
751
1085
                }
752
1086
        }
753
1087
 
754
1088
        /*e3*/
755
 
        sub_v3_v3v3(bv,v0,p1);
756
 
        elen2 = dot_v3v3(e1,e1);
757
 
        edotv = dot_v3v3(e1,vel);
758
 
        edotbv = dot_v3v3(e1,bv);
759
 
 
760
 
        sub_v3_v3v3(bv,v1,p1);
761
 
        elen2 = dot_v3v3(e3,e3);
762
 
        edotv = dot_v3v3(e3,vel);
763
 
        edotbv = dot_v3v3(e3,bv);
764
 
 
765
 
        a=elen2*(-dot_v3v3(vel,vel))+edotv*edotv;
766
 
        b=2.0f*(elen2*dot_v3v3(vel,bv)-edotv*edotbv);
767
 
        c=elen2*(radius2-dot_v3v3(bv,bv))+edotbv*edotbv;
768
 
 
769
 
        if(getLowestRoot(a, b, c, *lambda, &newLambda))
770
 
        {
771
 
                e=(edotv*newLambda-edotbv)/elen2;
772
 
 
773
 
                if(e >= 0.0f && e <= 1.0f)
774
 
                {
775
 
                        *lambda = newLambda;
776
 
                        copy_v3_v3(ipoint,e3);
777
 
                        mul_v3_fl(ipoint,e);
 
1089
        /* sub_v3_v3v3(bv,v0,p1); */ /* UNUSED */
 
1090
        /* elen2 = dot_v3v3(e1,e1); */ /* UNUSED */
 
1091
        /* edotv = dot_v3v3(e1,vel); */ /* UNUSED */
 
1092
        /* edotbv = dot_v3v3(e1,bv); */ /* UNUSED */
 
1093
 
 
1094
        sub_v3_v3v3(bv, v1, p1);
 
1095
        elen2 = dot_v3v3(e3, e3);
 
1096
        edotv = dot_v3v3(e3, vel);
 
1097
        edotbv = dot_v3v3(e3, bv);
 
1098
 
 
1099
        a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
 
1100
        b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
 
1101
        c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
 
1102
 
 
1103
        if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
 
1104
                e = (edotv * newLambda - edotbv) / elen2;
 
1105
 
 
1106
                if (e >= 0.0f && e <= 1.0f) {
 
1107
                        *r_lambda = newLambda;
 
1108
                        copy_v3_v3(ipoint, e3);
 
1109
                        mul_v3_fl(ipoint, e);
778
1110
                        add_v3_v3(ipoint, v1);
779
 
                        found_by_sweep=1;
 
1111
                        found_by_sweep = 1;
780
1112
                }
781
1113
        }
782
1114
 
783
1115
 
784
1116
        return found_by_sweep;
785
1117
}
786
 
int isect_axial_line_tri_v3(int axis, float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
 
1118
 
 
1119
int isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3],
 
1120
                            const float v0[3], const float v1[3], const float v2[3], float *r_lambda)
787
1121
{
788
1122
        float p[3], e1[3], e2[3];
789
1123
        float u, v, f;
790
 
        int a0=axis, a1=(axis+1)%3, a2=(axis+2)%3;
 
1124
        int a0 = axis, a1 = (axis + 1) % 3, a2 = (axis + 2) % 3;
791
1125
 
792
1126
        //return isect_line_tri_v3(p1,p2,v0,v1,v2,lambda);
793
1127
 
794
1128
        ///* first a simple bounding box test */
795
 
        //if(MIN3(v0[a1],v1[a1],v2[a1]) > p1[a1]) return 0;
796
 
        //if(MIN3(v0[a2],v1[a2],v2[a2]) > p1[a2]) return 0;
797
 
        //if(MAX3(v0[a1],v1[a1],v2[a1]) < p1[a1]) return 0;
798
 
        //if(MAX3(v0[a2],v1[a2],v2[a2]) < p1[a2]) return 0;
 
1129
        //if (MIN3(v0[a1],v1[a1],v2[a1]) > p1[a1]) return 0;
 
1130
        //if (MIN3(v0[a2],v1[a2],v2[a2]) > p1[a2]) return 0;
 
1131
        //if (MAX3(v0[a1],v1[a1],v2[a1]) < p1[a1]) return 0;
 
1132
        //if (MAX3(v0[a2],v1[a2],v2[a2]) < p1[a2]) return 0;
799
1133
 
800
1134
        ///* then a full intersection test */
801
 
        
802
 
        sub_v3_v3v3(e1,v1,v0);
803
 
        sub_v3_v3v3(e2,v2,v0);
804
 
        sub_v3_v3v3(p,v0,p1);
805
 
 
806
 
        f= (e2[a1]*e1[a2]-e2[a2]*e1[a1]);
807
 
        if ((f > -0.000001) && (f < 0.000001)) return 0;
808
 
 
809
 
        v= (p[a2]*e1[a1]-p[a1]*e1[a2])/f;
810
 
        if ((v < 0.0)||(v > 1.0)) return 0;
811
 
        
812
 
        f= e1[a1];
813
 
        if((f > -0.000001) && (f < 0.000001)){
814
 
                f= e1[a2];
815
 
                if((f > -0.000001) && (f < 0.000001)) return 0;
816
 
                u= (-p[a2]-v*e2[a2])/f;
 
1135
 
 
1136
        sub_v3_v3v3(e1, v1, v0);
 
1137
        sub_v3_v3v3(e2, v2, v0);
 
1138
        sub_v3_v3v3(p, v0, p1);
 
1139
 
 
1140
        f = (e2[a1] * e1[a2] - e2[a2] * e1[a1]);
 
1141
        if ((f > -0.000001f) && (f < 0.000001f)) return 0;
 
1142
 
 
1143
        v = (p[a2] * e1[a1] - p[a1] * e1[a2]) / f;
 
1144
        if ((v < 0.0f) || (v > 1.0f)) return 0;
 
1145
 
 
1146
        f = e1[a1];
 
1147
        if ((f > -0.000001f) && (f < 0.000001f)) {
 
1148
                f = e1[a2];
 
1149
                if ((f > -0.000001f) && (f < 0.000001f)) return 0;
 
1150
                u = (-p[a2] - v * e2[a2]) / f;
817
1151
        }
818
1152
        else
819
 
                u= (-p[a1]-v*e2[a1])/f;
820
 
 
821
 
        if ((u < 0.0)||((u + v) > 1.0)) return 0;
822
 
 
823
 
        *lambda = (p[a0]+u*e1[a0]+v*e2[a0])/(p2[a0]-p1[a0]);
824
 
 
825
 
        if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
 
1153
                u = (-p[a1] - v * e2[a1]) / f;
 
1154
 
 
1155
        if ((u < 0.0f) || ((u + v) > 1.0f)) return 0;
 
1156
 
 
1157
        *r_lambda = (p[a0] + u * e1[a0] + v * e2[a0]) / (p2[a0] - p1[a0]);
 
1158
 
 
1159
        if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0;
826
1160
 
827
1161
        return 1;
828
1162
}
830
1164
/* Returns the number of point of interests
831
1165
 * 0 - lines are colinear
832
1166
 * 1 - lines are coplanar, i1 is set to intersection
833
 
 * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively 
 
1167
 * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively
834
1168
 * */
835
 
int isect_line_line_v3(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3])
 
1169
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float i1[3], float i2[3])
836
1170
{
837
1171
        float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
838
1172
        float d;
839
 
        
 
1173
 
840
1174
        sub_v3_v3v3(c, v3, v1);
841
1175
        sub_v3_v3v3(a, v2, v1);
842
1176
        sub_v3_v3v3(b, v4, v3);
843
1177
 
844
 
        copy_v3_v3(dir1, a);
845
 
        normalize_v3(dir1);
846
 
        copy_v3_v3(dir2, b);
847
 
        normalize_v3(dir2);
 
1178
        normalize_v3_v3(dir1, a);
 
1179
        normalize_v3_v3(dir2, b);
848
1180
        d = dot_v3v3(dir1, dir2);
849
1181
        if (d == 1.0f || d == -1.0f) {
850
1182
                /* colinear */
861
1193
                mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
862
1194
                add_v3_v3v3(i1, v1, a);
863
1195
                copy_v3_v3(i2, i1);
864
 
                
 
1196
 
865
1197
                return 1; /* one intersection only */
866
1198
        }
867
1199
        /* if not */
877
1209
                /* for the first line, offset the second line until it is coplanar */
878
1210
                add_v3_v3v3(v3t, v3, t);
879
1211
                add_v3_v3v3(v4t, v4, t);
880
 
                
 
1212
 
881
1213
                sub_v3_v3v3(c, v3t, v1);
882
1214
                sub_v3_v3v3(a, v2, v1);
883
1215
                sub_v3_v3v3(b, v4t, v3t);
890
1222
 
891
1223
                /* for the second line, just substract the offset from the first intersection point */
892
1224
                sub_v3_v3v3(i2, i1, t);
893
 
                
 
1225
 
894
1226
                return 2; /* two nearest points */
895
1227
        }
896
 
 
1228
}
897
1229
 
898
1230
/* Intersection point strictly between the two lines
899
 
 * 0 when no intersection is found 
 
1231
 * 0 when no intersection is found
900
1232
 * */
901
 
int isect_line_line_strict_v3(float v1[3], float v2[3], float v3[3], float v4[3], float vi[3], float *lambda)
 
1233
int isect_line_line_strict_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float vi[3], float *r_lambda)
902
1234
{
903
1235
        float a[3], b[3], c[3], ab[3], cb[3], ca[3], dir1[3], dir2[3];
904
1236
        float d;
905
 
        float d1;
906
 
        
 
1237
 
907
1238
        sub_v3_v3v3(c, v3, v1);
908
1239
        sub_v3_v3v3(a, v2, v1);
909
1240
        sub_v3_v3v3(b, v4, v3);
910
1241
 
911
 
        copy_v3_v3(dir1, a);
912
 
        normalize_v3(dir1);
913
 
        copy_v3_v3(dir2, b);
914
 
        normalize_v3(dir2);
 
1242
        normalize_v3_v3(dir1, a);
 
1243
        normalize_v3_v3(dir2, b);
915
1244
        d = dot_v3v3(dir1, dir2);
916
1245
        if (d == 1.0f || d == -1.0f || d == 0) {
917
1246
                /* colinear or one vector is zero-length*/
918
1247
                return 0;
919
1248
        }
920
 
        
921
 
        d1 = d;
922
1249
 
923
1250
        cross_v3_v3v3(ab, a, b);
924
1251
        d = dot_v3v3(c, ab);
931
1258
 
932
1259
                f1 = dot_v3v3(cb, ab) / dot_v3v3(ab, ab);
933
1260
                f2 = dot_v3v3(ca, ab) / dot_v3v3(ab, ab);
934
 
                
 
1261
 
935
1262
                if (f1 >= 0 && f1 <= 1 &&
936
 
                        f2 >= 0 && f2 <= 1)
 
1263
                    f2 >= 0 && f2 <= 1)
937
1264
                {
938
1265
                        mul_v3_fl(a, f1);
939
1266
                        add_v3_v3v3(vi, v1, a);
940
 
                        
941
 
                        if (lambda != NULL)
942
 
                        {
943
 
                                *lambda = f1;
944
 
                        }
945
 
                        
 
1267
 
 
1268
                        if (r_lambda) *r_lambda = f1;
 
1269
 
946
1270
                        return 1; /* intersection found */
947
1271
                }
948
 
                else
949
 
                {
 
1272
                else {
950
1273
                        return 0;
951
1274
                }
952
1275
        }
953
 
        else
954
 
        {
 
1276
        else {
955
1277
                return 0;
956
1278
        }
957
 
 
1279
}
958
1280
 
959
 
int isect_aabb_aabb_v3(float min1[3], float max1[3], float min2[3], float max2[3])
 
1281
int isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3])
960
1282
{
961
 
        return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&
962
 
                        min2[0]<max1[0] && min2[1]<max1[1] && min2[2]<max1[2]);
 
1283
        return (min1[0] < max2[0] && min1[1] < max2[1] && min1[2] < max2[2] &&
 
1284
                min2[0] < max1[0] && min2[1] < max1[1] && min2[2] < max1[2]);
963
1285
}
964
1286
 
965
1287
/* find closest point to p on line through l1,l2 and return lambda,
966
1288
 * where (0 <= lambda <= 1) when cp is in the line segement l1,l2
967
1289
 */
968
 
float closest_to_line_v3(float cp[3],float p[3], float l1[3], float l2[3])
 
1290
float closest_to_line_v3(float cp[3], const float p[3], const float l1[3], const float l2[3])
969
1291
{
970
 
        float h[3],u[3],lambda;
 
1292
        float h[3], u[3], lambda;
971
1293
        sub_v3_v3v3(u, l2, l1);
972
1294
        sub_v3_v3v3(h, p, l1);
973
 
        lambda =dot_v3v3(u,h)/dot_v3v3(u,u);
 
1295
        lambda = dot_v3v3(u, h) / dot_v3v3(u, u);
974
1296
        cp[0] = l1[0] + u[0] * lambda;
975
1297
        cp[1] = l1[1] + u[1] * lambda;
976
1298
        cp[2] = l1[2] + u[2] * lambda;
977
1299
        return lambda;
978
1300
}
979
1301
 
980
 
#if 0
 
1302
float closest_to_line_v2(float cp[2], const float p[2], const float l1[2], const float l2[2])
 
1303
{
 
1304
        float h[2], u[2], lambda;
 
1305
        sub_v2_v2v2(u, l2, l1);
 
1306
        sub_v2_v2v2(h, p, l1);
 
1307
        lambda = dot_v2v2(u, h) / dot_v2v2(u, u);
 
1308
        cp[0] = l1[0] + u[0] * lambda;
 
1309
        cp[1] = l1[1] + u[1] * lambda;
 
1310
        return lambda;
 
1311
}
 
1312
 
981
1313
/* little sister we only need to know lambda */
982
 
static float lambda_cp_line(float p[3], float l1[3], float l2[3])
 
1314
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
983
1315
{
984
 
        float h[3],u[3];
 
1316
        float h[3], u[3];
985
1317
        sub_v3_v3v3(u, l2, l1);
986
1318
        sub_v3_v3v3(h, p, l1);
987
 
        return(dot_v3v3(u,h)/dot_v3v3(u,u));
988
 
}
989
 
#endif
 
1319
        return (dot_v3v3(u, h) / dot_v3v3(u, u));
 
1320
}
 
1321
 
 
1322
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2])
 
1323
{
 
1324
        float h[2], u[2];
 
1325
        sub_v2_v2v2(u, l2, l1);
 
1326
        sub_v2_v2v2(h, p, l1);
 
1327
        return (dot_v2v2(u, h) / dot_v2v2(u, u));
 
1328
}
 
1329
 
 
1330
/* ensyre the distance between these points is no greater then 'dist'
 
1331
 * if it is, scale then both into the center */
 
1332
void limit_dist_v3(float v1[3], float v2[3], const float dist)
 
1333
{
 
1334
        const float dist_old = len_v3v3(v1, v2);
 
1335
 
 
1336
        if (dist_old > dist) {
 
1337
                float v1_old[3];
 
1338
                float v2_old[3];
 
1339
                float fac = (dist / dist_old) * 0.5f;
 
1340
 
 
1341
                copy_v3_v3(v1_old, v1);
 
1342
                copy_v3_v3(v2_old, v2);
 
1343
 
 
1344
                interp_v3_v3v3(v1, v1_old, v2_old, 0.5f - fac);
 
1345
                interp_v3_v3v3(v2, v1_old, v2_old, 0.5f + fac);
 
1346
        }
 
1347
}
990
1348
 
991
1349
/* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */
992
 
void isect_point_quad_uv_v2(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv)
 
1350
void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2],
 
1351
                            const float pt[2], float r_uv[2])
993
1352
{
994
 
        float x0,y0, x1,y1, wtot, v2d[2], w1, w2;
995
 
        
 
1353
        float x0, y0, x1, y1, wtot, v2d[2], w1, w2;
 
1354
 
996
1355
        /* used for parallel lines */
997
1356
        float pt3d[3], l1[3], l2[3], pt_on_line[3];
998
 
        
 
1357
 
999
1358
        /* compute 2 edges  of the quad  intersection point */
1000
 
        if (IsectLLPt2Df(v0[0],v0[1],v1[0],v1[1],  v2[0],v2[1],v3[0],v3[1], &x0,&y0) == 1) {
 
1359
        if (IsectLLPt2Df(v0[0], v0[1], v1[0], v1[1], v2[0], v2[1], v3[0], v3[1], &x0, &y0) == 1) {
1001
1360
                /* the intersection point between the quad-edge intersection and the point in the quad we want the uv's for */
1002
1361
                /* should never be paralle !! */
1003
1362
                /*printf("\tnot parallel 1\n");*/
1004
 
                IsectLLPt2Df(pt[0],pt[1],x0,y0,  v0[0],v0[1],v3[0],v3[1], &x1,&y1);
1005
 
                
 
1363
                IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v3[0], v3[1], &x1, &y1);
 
1364
 
1006
1365
                /* Get the weights from the new intersection point, to each edge */
1007
 
                v2d[0] = x1-v0[0];
1008
 
                v2d[1] = y1-v0[1];
 
1366
                v2d[0] = x1 - v0[0];
 
1367
                v2d[1] = y1 - v0[1];
1009
1368
                w1 = len_v2(v2d);
1010
 
                
1011
 
                v2d[0] = x1-v3[0]; /* some but for the other vert */
1012
 
                v2d[1] = y1-v3[1];
 
1369
 
 
1370
                v2d[0] = x1 - v3[0]; /* some but for the other vert */
 
1371
                v2d[1] = y1 - v3[1];
1013
1372
                w2 = len_v2(v2d);
1014
 
                wtot = w1+w2;
 
1373
                wtot = w1 + w2;
1015
1374
                /*w1 = w1/wtot;*/
1016
1375
                /*w2 = w2/wtot;*/
1017
 
                uv[0] = w1/wtot;
1018
 
        } else {
 
1376
                r_uv[0] = w1 / wtot;
 
1377
        }
 
1378
        else {
1019
1379
                /* lines are parallel, lambda_cp_line_ex is 3d grrr */
1020
1380
                /*printf("\tparallel1\n");*/
1021
1381
                pt3d[0] = pt[0];
1022
1382
                pt3d[1] = pt[1];
1023
1383
                pt3d[2] = l1[2] = l2[2] = 0.0f;
1024
 
                
1025
 
                l1[0] = v0[0]; l1[1] = v0[1];
1026
 
                l2[0] = v1[0]; l2[1] = v1[1];
1027
 
                closest_to_line_v3(pt_on_line,pt3d, l1, l2);
1028
 
                v2d[0] = pt[0]-pt_on_line[0]; /* same, for the other vert */
1029
 
                v2d[1] = pt[1]-pt_on_line[1];
 
1384
 
 
1385
                l1[0] = v0[0];
 
1386
                l1[1] = v0[1];
 
1387
                l2[0] = v1[0];
 
1388
                l2[1] = v1[1];
 
1389
                closest_to_line_v3(pt_on_line, pt3d, l1, l2);
 
1390
                v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */
 
1391
                v2d[1] = pt[1] - pt_on_line[1];
1030
1392
                w1 = len_v2(v2d);
1031
 
                
1032
 
                l1[0] = v2[0]; l1[1] = v2[1];
1033
 
                l2[0] = v3[0]; l2[1] = v3[1];
1034
 
                closest_to_line_v3(pt_on_line,pt3d, l1, l2);
1035
 
                v2d[0] = pt[0]-pt_on_line[0]; /* same, for the other vert */
1036
 
                v2d[1] = pt[1]-pt_on_line[1];
 
1393
 
 
1394
                l1[0] = v2[0];
 
1395
                l1[1] = v2[1];
 
1396
                l2[0] = v3[0];
 
1397
                l2[1] = v3[1];
 
1398
                closest_to_line_v3(pt_on_line, pt3d, l1, l2);
 
1399
                v2d[0] = pt[0] - pt_on_line[0]; /* same, for the other vert */
 
1400
                v2d[1] = pt[1] - pt_on_line[1];
1037
1401
                w2 = len_v2(v2d);
1038
 
                wtot = w1+w2;
1039
 
                uv[0] = w1/wtot;        
 
1402
                wtot = w1 + w2;
 
1403
                r_uv[0] = w1 / wtot;
1040
1404
        }
1041
 
        
 
1405
 
1042
1406
        /* Same as above to calc the uv[1] value, alternate calculation */
1043
 
        
1044
 
        if (IsectLLPt2Df(v0[0],v0[1],v3[0],v3[1],  v1[0],v1[1],v2[0],v2[1], &x0,&y0) == 1) { /* was v0,v1  v2,v3  now v0,v3  v1,v2*/
 
1407
 
 
1408
        if (IsectLLPt2Df(v0[0], v0[1], v3[0], v3[1], v1[0], v1[1], v2[0], v2[1], &x0, &y0) == 1) { /* was v0,v1  v2,v3  now v0,v3  v1,v2*/
1045
1409
                /* never paralle if above was not */
1046
1410
                /*printf("\tnot parallel2\n");*/
1047
 
                IsectLLPt2Df(pt[0],pt[1],x0,y0,  v0[0],v0[1],v1[0],v1[1], &x1,&y1);/* was v0,v3  now v0,v1*/
1048
 
                
1049
 
                v2d[0] = x1-v0[0];
1050
 
                v2d[1] = y1-v0[1];
 
1411
                IsectLLPt2Df(pt[0], pt[1], x0, y0, v0[0], v0[1], v1[0], v1[1], &x1, &y1); /* was v0,v3  now v0,v1*/
 
1412
 
 
1413
                v2d[0] = x1 - v0[0];
 
1414
                v2d[1] = y1 - v0[1];
1051
1415
                w1 = len_v2(v2d);
1052
 
                
1053
 
                v2d[0] = x1-v1[0];
1054
 
                v2d[1] = y1-v1[1];
 
1416
 
 
1417
                v2d[0] = x1 - v1[0];
 
1418
                v2d[1] = y1 - v1[1];
1055
1419
                w2 = len_v2(v2d);
1056
 
                wtot = w1+w2;
1057
 
                uv[1] = w1/wtot;
1058
 
        } else {
 
1420
                wtot = w1 + w2;
 
1421
                r_uv[1] = w1 / wtot;
 
1422
        }
 
1423
        else {
1059
1424
                /* lines are parallel, lambda_cp_line_ex is 3d grrr */
1060
1425
                /*printf("\tparallel2\n");*/
1061
1426
                pt3d[0] = pt[0];
1062
1427
                pt3d[1] = pt[1];
1063
1428
                pt3d[2] = l1[2] = l2[2] = 0.0f;
1064
 
                
1065
 
                
1066
 
                l1[0] = v0[0]; l1[1] = v0[1];
1067
 
                l2[0] = v3[0]; l2[1] = v3[1];
1068
 
                closest_to_line_v3(pt_on_line,pt3d, l1, l2);
1069
 
                v2d[0] = pt[0]-pt_on_line[0]; /* some but for the other vert */
1070
 
                v2d[1] = pt[1]-pt_on_line[1];
 
1429
 
 
1430
 
 
1431
                l1[0] = v0[0];
 
1432
                l1[1] = v0[1];
 
1433
                l2[0] = v3[0];
 
1434
                l2[1] = v3[1];
 
1435
                closest_to_line_v3(pt_on_line, pt3d, l1, l2);
 
1436
                v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */
 
1437
                v2d[1] = pt[1] - pt_on_line[1];
1071
1438
                w1 = len_v2(v2d);
1072
 
                
1073
 
                l1[0] = v1[0]; l1[1] = v1[1];
1074
 
                l2[0] = v2[0]; l2[1] = v2[1];
1075
 
                closest_to_line_v3(pt_on_line,pt3d, l1, l2);
1076
 
                v2d[0] = pt[0]-pt_on_line[0]; /* some but for the other vert */
1077
 
                v2d[1] = pt[1]-pt_on_line[1];
 
1439
 
 
1440
                l1[0] = v1[0];
 
1441
                l1[1] = v1[1];
 
1442
                l2[0] = v2[0];
 
1443
                l2[1] = v2[1];
 
1444
                closest_to_line_v3(pt_on_line, pt3d, l1, l2);
 
1445
                v2d[0] = pt[0] - pt_on_line[0]; /* some but for the other vert */
 
1446
                v2d[1] = pt[1] - pt_on_line[1];
1078
1447
                w2 = len_v2(v2d);
1079
 
                wtot = w1+w2;
1080
 
                uv[1] = w1/wtot;
 
1448
                wtot = w1 + w2;
 
1449
                r_uv[1] = w1 / wtot;
1081
1450
        }
1082
1451
        /* may need to flip UV's here */
1083
1452
}
1084
1453
 
1085
1454
/* same as above but does tri's and quads, tri's are a bit of a hack */
1086
 
void isect_point_face_uv_v2(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv)
 
1455
void isect_point_face_uv_v2(const int isquad,
 
1456
                            const float v0[2], const float v1[2], const float v2[2], const float v3[2],
 
1457
                            const float pt[2], float r_uv[2])
1087
1458
{
1088
1459
        if (isquad) {
1089
 
                isect_point_quad_uv_v2(v0, v1, v2, v3, pt, uv);
 
1460
                isect_point_quad_uv_v2(v0, v1, v2, v3, pt, r_uv);
1090
1461
        }
1091
1462
        else {
1092
1463
                /* not for quads, use for our abuse of LineIntersectsTriangleUV */
1093
1464
                float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3], lambda;
1094
 
                        
1095
 
                p1_3d[0] = p2_3d[0] = uv[0];
1096
 
                p1_3d[1] = p2_3d[1] = uv[1];
 
1465
 
 
1466
                p1_3d[0] = p2_3d[0] = r_uv[0];
 
1467
                p1_3d[1] = p2_3d[1] = r_uv[1];
1097
1468
                p1_3d[2] = 1.0f;
1098
1469
                p2_3d[2] = -1.0f;
1099
1470
                v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
1100
 
                
 
1471
 
1101
1472
                /* generate a new fuv, (this is possibly a non optimal solution,
1102
1473
                 * since we only need 2d calculation but use 3d func's)
1103
 
                 * 
 
1474
                 *
1104
1475
                 * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
1105
1476
                 * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
1106
 
                 * This means the new values will be correct in relation to the derived meshes face. 
 
1477
                 * This means the new values will be correct in relation to the derived meshes face.
1107
1478
                 */
1108
1479
                copy_v2_v2(v0_3d, v0);
1109
1480
                copy_v2_v2(v1_3d, v1);
1110
1481
                copy_v2_v2(v2_3d, v2);
1111
 
                
 
1482
 
1112
1483
                /* Doing this in 3D is not nice */
1113
 
                isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv);
 
1484
                isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, r_uv);
1114
1485
        }
1115
1486
}
1116
1487
 
1117
1488
#if 0 // XXX this version used to be used in isect_point_tri_v2_int() and was called IsPointInTri2D
 
1489
 
1118
1490
int isect_point_tri_v2(float pt[2], float v1[2], float v2[2], float v3[2])
1119
1491
{
1120
1492
        float inp1, inp2, inp3;
1121
 
        
1122
 
        inp1= (v2[0]-v1[0])*(v1[1]-pt[1]) + (v1[1]-v2[1])*(v1[0]-pt[0]);
1123
 
        inp2= (v3[0]-v2[0])*(v2[1]-pt[1]) + (v2[1]-v3[1])*(v2[0]-pt[0]);
1124
 
        inp3= (v1[0]-v3[0])*(v3[1]-pt[1]) + (v3[1]-v1[1])*(v3[0]-pt[0]);
1125
 
        
1126
 
        if(inp1<=0.0f && inp2<=0.0f && inp3<=0.0f) return 1;
1127
 
        if(inp1>=0.0f && inp2>=0.0f && inp3>=0.0f) return 1;
1128
 
        
 
1493
 
 
1494
        inp1 = (v2[0] - v1[0]) * (v1[1] - pt[1]) + (v1[1] - v2[1]) * (v1[0] - pt[0]);
 
1495
        inp2 = (v3[0] - v2[0]) * (v2[1] - pt[1]) + (v2[1] - v3[1]) * (v2[0] - pt[0]);
 
1496
        inp3 = (v1[0] - v3[0]) * (v3[1] - pt[1]) + (v3[1] - v1[1]) * (v3[0] - pt[0]);
 
1497
 
 
1498
        if (inp1 <= 0.0f && inp2 <= 0.0f && inp3 <= 0.0f) return 1;
 
1499
        if (inp1 >= 0.0f && inp2 >= 0.0f && inp3 >= 0.0f) return 1;
 
1500
 
1129
1501
        return 0;
1130
1502
}
1131
1503
#endif
1132
1504
 
1133
1505
#if 0
 
1506
 
1134
1507
int isect_point_tri_v2(float v0[2], float v1[2], float v2[2], float pt[2])
1135
1508
{
1136
 
                /* not for quads, use for our abuse of LineIntersectsTriangleUV */
1137
 
                float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3];
1138
 
                /* not used */
1139
 
                float lambda, uv[3];
1140
 
                        
1141
 
                p1_3d[0] = p2_3d[0] = uv[0]= pt[0];
1142
 
                p1_3d[1] = p2_3d[1] = uv[1]= uv[2]= pt[1];
1143
 
                p1_3d[2] = 1.0f;
1144
 
                p2_3d[2] = -1.0f;
1145
 
                v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
1146
 
                
1147
 
                /* generate a new fuv, (this is possibly a non optimal solution,
1148
 
                 * since we only need 2d calculation but use 3d func's)
1149
 
                 * 
1150
 
                 * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
1151
 
                 * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
1152
 
                 * This means the new values will be correct in relation to the derived meshes face. 
1153
 
                 */
1154
 
                copy_v2_v2(v0_3d, v0);
1155
 
                copy_v2_v2(v1_3d, v1);
1156
 
                copy_v2_v2(v2_3d, v2);
1157
 
                
1158
 
                /* Doing this in 3D is not nice */
1159
 
                return isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv);
 
1509
        /* not for quads, use for our abuse of LineIntersectsTriangleUV */
 
1510
        float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3];
 
1511
        /* not used */
 
1512
        float lambda, uv[3];
 
1513
 
 
1514
        p1_3d[0] = p2_3d[0] = uv[0] = pt[0];
 
1515
        p1_3d[1] = p2_3d[1] = uv[1] = uv[2] = pt[1];
 
1516
        p1_3d[2] = 1.0f;
 
1517
        p2_3d[2] = -1.0f;
 
1518
        v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
 
1519
 
 
1520
        /* generate a new fuv, (this is possibly a non optimal solution,
 
1521
         * since we only need 2d calculation but use 3d func's)
 
1522
         *
 
1523
         * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
 
1524
         * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
 
1525
         * This means the new values will be correct in relation to the derived meshes face.
 
1526
         */
 
1527
        copy_v2_v2(v0_3d, v0);
 
1528
        copy_v2_v2(v1_3d, v1);
 
1529
        copy_v2_v2(v2_3d, v2);
 
1530
 
 
1531
        /* Doing this in 3D is not nice */
 
1532
        return isect_line_tri_v3(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv);
1160
1533
}
1161
1534
#endif
1162
1535
 
1163
1536
/*
1164
 
 
1165
 
        x1,y2
1166
 
        |  \
1167
 
        |   \     .(a,b)
1168
 
        |    \
1169
 
        x1,y1-- x2,y1
1170
 
 
1171
 
*/
1172
 
int isect_point_tri_v2_int(int x1, int y1, int x2, int y2, int a, int b)
 
1537
 *     x1,y2
 
1538
 *     |  \
 
1539
 *     |   \     .(a,b)
 
1540
 *     |    \
 
1541
 *     x1,y1-- x2,y1
 
1542
 */
 
1543
int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b)
1173
1544
{
1174
1545
        float v1[2], v2[2], v3[2], p[2];
1175
 
        
1176
 
        v1[0]= (float)x1;
1177
 
        v1[1]= (float)y1;
1178
 
        
1179
 
        v2[0]= (float)x1;
1180
 
        v2[1]= (float)y2;
1181
 
        
1182
 
        v3[0]= (float)x2;
1183
 
        v3[1]= (float)y1;
1184
 
        
1185
 
        p[0]= (float)a;
1186
 
        p[1]= (float)b;
1187
 
        
 
1546
 
 
1547
        v1[0] = (float)x1;
 
1548
        v1[1] = (float)y1;
 
1549
 
 
1550
        v2[0] = (float)x1;
 
1551
        v2[1] = (float)y2;
 
1552
 
 
1553
        v3[0] = (float)x2;
 
1554
        v3[1] = (float)y1;
 
1555
 
 
1556
        p[0] = (float)a;
 
1557
        p[1] = (float)b;
 
1558
 
1188
1559
        return isect_point_tri_v2(p, v1, v2, v3);
1189
1560
}
1190
1561
 
1191
 
static int point_in_slice(float p[3], float v1[3], float l1[3], float l2[3])
 
1562
static int point_in_slice(const float p[3], const float v1[3], const float l1[3], const float l2[3])
1192
1563
{
1193
 
/* 
1194
 
what is a slice ?
1195
 
some maths:
1196
 
a line including l1,l2 and a point not on the line 
1197
 
define a subset of R3 delimeted by planes parallel to the line and orthogonal 
1198
 
to the (point --> line) distance vector,one plane on the line one on the point, 
1199
 
the room inside usually is rather small compared to R3 though still infinte
1200
 
useful for restricting (speeding up) searches 
1201
 
e.g. all points of triangular prism are within the intersection of 3 'slices'
1202
 
onother trivial case : cube 
1203
 
but see a 'spat' which is a deformed cube with paired parallel planes needs only 3 slices too
1204
 
*/
1205
 
        float h,rp[3],cp[3],q[3];
1206
 
 
1207
 
        closest_to_line_v3(cp,v1,l1,l2);
1208
 
        sub_v3_v3v3(q,cp,v1);
1209
 
 
1210
 
        sub_v3_v3v3(rp,p,v1);
1211
 
        h=dot_v3v3(q,rp)/dot_v3v3(q,q);
 
1564
        /*
 
1565
         * what is a slice ?
 
1566
         * some maths:
 
1567
         * a line including l1,l2 and a point not on the line
 
1568
         * define a subset of R3 delimited by planes parallel to the line and orthogonal
 
1569
         * to the (point --> line) distance vector,one plane on the line one on the point,
 
1570
         * the room inside usually is rather small compared to R3 though still infinte
 
1571
         * useful for restricting (speeding up) searches
 
1572
         * e.g. all points of triangular prism are within the intersection of 3 'slices'
 
1573
         * onother trivial case : cube
 
1574
         * but see a 'spat' which is a deformed cube with paired parallel planes needs only 3 slices too
 
1575
         */
 
1576
        float h, rp[3], cp[3], q[3];
 
1577
 
 
1578
        closest_to_line_v3(cp, v1, l1, l2);
 
1579
        sub_v3_v3v3(q, cp, v1);
 
1580
 
 
1581
        sub_v3_v3v3(rp, p, v1);
 
1582
        h = dot_v3v3(q, rp) / dot_v3v3(q, q);
1212
1583
        if (h < 0.0f || h > 1.0f) return 0;
1213
1584
        return 1;
1214
1585
}
1215
1586
 
1216
1587
#if 0
1217
 
/*adult sister defining the slice planes by the origin and the normal  
1218
 
NOTE |normal| may not be 1 but defining the thickness of the slice*/
1219
 
static int point_in_slice_as(float p[3],float origin[3],float normal[3])
 
1588
 
 
1589
/* adult sister defining the slice planes by the origin and the normal
 
1590
 * NOTE |normal| may not be 1 but defining the thickness of the slice */
 
1591
static int point_in_slice_as(float p[3], float origin[3], float normal[3])
1220
1592
{
1221
 
        float h,rp[3];
1222
 
        sub_v3_v3v3(rp,p,origin);
1223
 
        h=dot_v3v3(normal,rp)/dot_v3v3(normal,normal);
 
1593
        float h, rp[3];
 
1594
        sub_v3_v3v3(rp, p, origin);
 
1595
        h = dot_v3v3(normal, rp) / dot_v3v3(normal, normal);
1224
1596
        if (h < 0.0f || h > 1.0f) return 0;
1225
1597
        return 1;
1226
1598
}
1227
1599
 
1228
 
/*mama (knowing the squared lenght of the normal)*/
1229
 
static int point_in_slice_m(float p[3],float origin[3],float normal[3],float lns)
 
1600
/*mama (knowing the squared length of the normal)*/
 
1601
static int point_in_slice_m(float p[3], float origin[3], float normal[3], float lns)
1230
1602
{
1231
 
        float h,rp[3];
1232
 
        sub_v3_v3v3(rp,p,origin);
1233
 
        h=dot_v3v3(normal,rp)/lns;
 
1603
        float h, rp[3];
 
1604
        sub_v3_v3v3(rp, p, origin);
 
1605
        h = dot_v3v3(normal, rp) / lns;
1234
1606
        if (h < 0.0f || h > 1.0f) return 0;
1235
1607
        return 1;
1236
1608
}
1237
1609
#endif
1238
1610
 
1239
 
int isect_point_tri_prism_v3(float p[3], float v1[3], float v2[3], float v3[3])
 
1611
int isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3])
1240
1612
{
1241
 
        if(!point_in_slice(p,v1,v2,v3)) return 0;
1242
 
        if(!point_in_slice(p,v2,v3,v1)) return 0;
1243
 
        if(!point_in_slice(p,v3,v1,v2)) return 0;
 
1613
        if (!point_in_slice(p, v1, v2, v3)) return 0;
 
1614
        if (!point_in_slice(p, v2, v3, v1)) return 0;
 
1615
        if (!point_in_slice(p, v3, v1, v2)) return 0;
1244
1616
        return 1;
1245
1617
}
1246
1618
 
1247
 
int clip_line_plane(float p1[3], float p2[3], float plane[4])
 
1619
int clip_line_plane(float p1[3], float p2[3], const float plane[4])
1248
1620
{
1249
1621
        float dp[3], n[3], div, t, pc[3];
1250
1622
 
1251
1623
        copy_v3_v3(n, plane);
1252
1624
        sub_v3_v3v3(dp, p2, p1);
1253
 
        div= dot_v3v3(dp, n);
 
1625
        div = dot_v3v3(dp, n);
1254
1626
 
1255
 
        if(div == 0.0f) /* parallel */
 
1627
        if (div == 0.0f) /* parallel */
1256
1628
                return 1;
1257
1629
 
1258
 
        t= -(dot_v3v3(p1, n) + plane[3])/div;
 
1630
        t = -(dot_v3v3(p1, n) + plane[3]) / div;
1259
1631
 
1260
 
        if(div > 0.0f) {
 
1632
        if (div > 0.0f) {
1261
1633
                /* behind plane, completely clipped */
1262
 
                if(t >= 1.0f) {
 
1634
                if (t >= 1.0f) {
1263
1635
                        zero_v3(p1);
1264
1636
                        zero_v3(p2);
1265
1637
                        return 0;
1266
1638
                }
1267
1639
 
1268
1640
                /* intersect plane */
1269
 
                if(t > 0.0f) {
 
1641
                if (t > 0.0f) {
1270
1642
                        madd_v3_v3v3fl(pc, p1, dp, t);
1271
1643
                        copy_v3_v3(p1, pc);
1272
1644
                        return 1;
1276
1648
        }
1277
1649
        else {
1278
1650
                /* behind plane, completely clipped */
1279
 
                if(t <= 0.0f) {
 
1651
                if (t <= 0.0f) {
1280
1652
                        zero_v3(p1);
1281
1653
                        zero_v3(p2);
1282
1654
                        return 0;
1283
1655
                }
1284
1656
 
1285
1657
                /* intersect plane */
1286
 
                if(t < 1.0f) {
 
1658
                if (t < 1.0f) {
1287
1659
                        madd_v3_v3v3fl(pc, p1, dp, t);
1288
1660
                        copy_v3_v3(p2, pc);
1289
1661
                        return 1;
1293
1665
        }
1294
1666
}
1295
1667
 
 
1668
void plot_line_v2v2i(const int p1[2], const int p2[2], int (*callback)(int, int, void *), void *userData)
 
1669
{
 
1670
        int x1 = p1[0];
 
1671
        int y1 = p1[1];
 
1672
        int x2 = p2[0];
 
1673
        int y2 = p2[1];
 
1674
 
 
1675
        signed char ix;
 
1676
        signed char iy;
 
1677
 
 
1678
        // if x1 == x2 or y1 == y2, then it does not matter what we set here
 
1679
        int delta_x = (x2 > x1 ? (ix = 1, x2 - x1) : (ix = -1, x1 - x2)) << 1;
 
1680
        int delta_y = (y2 > y1 ? (iy = 1, y2 - y1) : (iy = -1, y1 - y2)) << 1;
 
1681
 
 
1682
        if (callback(x1, y1, userData) == 0) {
 
1683
                return;
 
1684
        }
 
1685
 
 
1686
        if (delta_x >= delta_y) {
 
1687
                // error may go below zero
 
1688
                int error = delta_y - (delta_x >> 1);
 
1689
 
 
1690
                while (x1 != x2) {
 
1691
                        if (error >= 0) {
 
1692
                                if (error || (ix > 0)) {
 
1693
                                        y1 += iy;
 
1694
                                        error -= delta_x;
 
1695
                                }
 
1696
                                // else do nothing
 
1697
                        }
 
1698
                        // else do nothing
 
1699
 
 
1700
                        x1 += ix;
 
1701
                        error += delta_y;
 
1702
 
 
1703
                        if (callback(x1, y1, userData) == 0) {
 
1704
                                return;
 
1705
                        }
 
1706
                }
 
1707
        }
 
1708
        else {
 
1709
                // error may go below zero
 
1710
                int error = delta_x - (delta_y >> 1);
 
1711
 
 
1712
                while (y1 != y2) {
 
1713
                        if (error >= 0) {
 
1714
                                if (error || (iy > 0)) {
 
1715
                                        x1 += ix;
 
1716
                                        error -= delta_y;
 
1717
                                }
 
1718
                                // else do nothing
 
1719
                        }
 
1720
                        // else do nothing
 
1721
 
 
1722
                        y1 += iy;
 
1723
                        error += delta_x;
 
1724
 
 
1725
                        if (callback(x1, y1, userData) == 0) {
 
1726
                                return;
 
1727
                        }
 
1728
                }
 
1729
        }
 
1730
}
 
1731
 
1296
1732
/****************************** Interpolation ********************************/
1297
1733
 
1298
 
static float tri_signed_area(float *v1, float *v2, float *v3, int i, int j)
1299
 
{
1300
 
        return 0.5f*((v1[i]-v2[i])*(v2[j]-v3[j]) + (v1[j]-v2[j])*(v3[i]-v2[i]));
1301
 
}
1302
 
 
1303
 
static int barycentric_weights(float *v1, float *v2, float *v3, float *co, float *n, float *w)
1304
 
{
1305
 
        float xn, yn, zn, a1, a2, a3, asum;
1306
 
        short i, j;
1307
 
 
1308
 
        /* find best projection of face XY, XZ or YZ: barycentric weights of
1309
 
           the 2d projected coords are the same and faster to compute */
1310
 
        xn= (float)fabs(n[0]);
1311
 
        yn= (float)fabs(n[1]);
1312
 
        zn= (float)fabs(n[2]);
1313
 
        if(zn>=xn && zn>=yn) {i= 0; j= 1;}
1314
 
        else if(yn>=xn && yn>=zn) {i= 0; j= 2;}
1315
 
        else {i= 1; j= 2;} 
1316
 
 
1317
 
        a1= tri_signed_area(v2, v3, co, i, j);
1318
 
        a2= tri_signed_area(v3, v1, co, i, j);
1319
 
        a3= tri_signed_area(v1, v2, co, i, j);
1320
 
 
1321
 
        asum= a1 + a2 + a3;
1322
 
 
1323
 
        if (fabs(asum) < FLT_EPSILON) {
 
1734
/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */
 
1735
void axis_dominant_v3(int *axis_a, int *axis_b, const float axis[3])
 
1736
{
 
1737
        const float xn = fabsf(axis[0]);
 
1738
        const float yn = fabsf(axis[1]);
 
1739
        const float zn = fabsf(axis[2]);
 
1740
 
 
1741
        if      (zn >= xn && zn >= yn) { *axis_a= 0; *axis_b = 1; }
 
1742
        else if (yn >= xn && yn >= zn) { *axis_a= 0; *axis_b = 2; }
 
1743
        else                           { *axis_a= 1; *axis_b = 2; }
 
1744
}
 
1745
 
 
1746
static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j)
 
1747
{
 
1748
        return 0.5f * ((v1[i] - v2[i]) * (v2[j] - v3[j]) + (v1[j] - v2[j]) * (v3[i] - v2[i]));
 
1749
}
 
1750
 
 
1751
/* return 1 when degenerate */
 
1752
static int barycentric_weights(const float v1[3], const float v2[3], const float v3[3], const float co[3], const float n[3], float w[3])
 
1753
{
 
1754
        float wtot;
 
1755
        int i, j;
 
1756
 
 
1757
        axis_dominant_v3(&i, &j, n);
 
1758
 
 
1759
        w[0] = tri_signed_area(v2, v3, co, i, j);
 
1760
        w[1] = tri_signed_area(v3, v1, co, i, j);
 
1761
        w[2] = tri_signed_area(v1, v2, co, i, j);
 
1762
 
 
1763
        wtot = w[0] + w[1] + w[2];
 
1764
 
 
1765
        if (fabsf(wtot) > FLT_EPSILON) {
 
1766
                mul_v3_fl(w, 1.0f / wtot);
 
1767
                return 0;
 
1768
        }
 
1769
        else {
1324
1770
                /* zero area triangle */
1325
 
                w[0]= w[1]= w[2]= 1.0f/3.0f;
 
1771
                copy_v3_fl(w, 1.0f / 3.0f);
1326
1772
                return 1;
1327
1773
        }
1328
 
 
1329
 
        asum= 1.0f/asum;
1330
 
        w[0]= a1*asum;
1331
 
        w[1]= a2*asum;
1332
 
        w[2]= a3*asum;
1333
 
 
1334
 
        return 0;
1335
1774
}
1336
1775
 
1337
 
void interp_weights_face_v3(float *w,float *v1, float *v2, float *v3, float *v4, float *co)
 
1776
void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float co[3])
1338
1777
{
1339
1778
        float w2[3];
1340
1779
 
1341
 
        w[0]= w[1]= w[2]= w[3]= 0.0f;
 
1780
        w[0] = w[1] = w[2] = w[3] = 0.0f;
1342
1781
 
1343
1782
        /* first check for exact match */
1344
 
        if(equals_v3v3(co, v1))
1345
 
                w[0]= 1.0f;
1346
 
        else if(equals_v3v3(co, v2))
1347
 
                w[1]= 1.0f;
1348
 
        else if(equals_v3v3(co, v3))
1349
 
                w[2]= 1.0f;
1350
 
        else if(v4 && equals_v3v3(co, v4))
1351
 
                w[3]= 1.0f;
 
1783
        if (equals_v3v3(co, v1))
 
1784
                w[0] = 1.0f;
 
1785
        else if (equals_v3v3(co, v2))
 
1786
                w[1] = 1.0f;
 
1787
        else if (equals_v3v3(co, v3))
 
1788
                w[2] = 1.0f;
 
1789
        else if (v4 && equals_v3v3(co, v4))
 
1790
                w[3] = 1.0f;
1352
1791
        else {
1353
1792
                /* otherwise compute barycentric interpolation weights */
1354
1793
                float n1[3], n2[3], n[3];
1365
1804
 
1366
1805
                /* OpenGL seems to split this way, so we do too */
1367
1806
                if (v4) {
1368
 
                        degenerate= barycentric_weights(v1, v2, v4, co, n, w);
 
1807
                        degenerate = barycentric_weights(v1, v2, v4, co, n, w);
1369
1808
                        SWAP(float, w[2], w[3]);
1370
1809
 
1371
 
                        if(degenerate || (w[0] < 0.0f)) {
 
1810
                        if (degenerate || (w[0] < 0.0f)) {
1372
1811
                                /* if w[1] is negative, co is on the other side of the v1-v3 edge,
1373
 
                                   so we interpolate using the other triangle */
1374
 
                                degenerate= barycentric_weights(v2, v3, v4, co, n, w2);
 
1812
                                 * so we interpolate using the other triangle */
 
1813
                                degenerate = barycentric_weights(v2, v3, v4, co, n, w2);
1375
1814
 
1376
 
                                if(!degenerate) {
1377
 
                                        w[0]= 0.0f;
1378
 
                                        w[1]= w2[0];
1379
 
                                        w[2]= w2[1];
1380
 
                                        w[3]= w2[2];
 
1815
                                if (!degenerate) {
 
1816
                                        w[0] = 0.0f;
 
1817
                                        w[1] = w2[0];
 
1818
                                        w[2] = w2[1];
 
1819
                                        w[3] = w2[2];
1381
1820
                                }
1382
1821
                        }
1383
1822
                }
1390
1829
 * note: using area_tri_signed_v2 means locations outside the triangle are correctly weighted */
1391
1830
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
1392
1831
{
1393
 
   float wtot_inv, wtot;
1394
 
 
1395
 
   w[0] = area_tri_signed_v2(v2, v3, co);
1396
 
   w[1] = area_tri_signed_v2(v3, v1, co);
1397
 
   w[2] = area_tri_signed_v2(v1, v2, co);
1398
 
   wtot = w[0]+w[1]+w[2];
1399
 
 
1400
 
   if (wtot != 0.0f) {
1401
 
           wtot_inv = 1.0f/wtot;
1402
 
 
1403
 
           w[0] = w[0]*wtot_inv;
1404
 
           w[1] = w[1]*wtot_inv;
1405
 
           w[2] = w[2]*wtot_inv;
1406
 
   }
1407
 
   else /* dummy values for zero area face */
1408
 
           w[0] = w[1] = w[2] = 1.0f/3.0f;
 
1832
        float wtot;
 
1833
 
 
1834
        w[0] = area_tri_signed_v2(v2, v3, co);
 
1835
        w[1] = area_tri_signed_v2(v3, v1, co);
 
1836
        w[2] = area_tri_signed_v2(v1, v2, co);
 
1837
        wtot = w[0] + w[1] + w[2];
 
1838
 
 
1839
        if (wtot != 0.0f) {
 
1840
                mul_v3_fl(w, 1.0f / wtot);
 
1841
        }
 
1842
        else { /* dummy values for zero area face */
 
1843
                copy_v3_fl(w, 1.0f / 3.0f);
 
1844
        }
1409
1845
}
1410
1846
 
1411
1847
/* given 2 triangles in 3D space, and a point in relation to the first triangle.
1412
1848
 * calculate the location of a point in relation to the second triangle.
1413
1849
 * Useful for finding relative positions with geometry */
1414
1850
void barycentric_transform(float pt_tar[3], float const pt_src[3],
1415
 
                const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3],
1416
 
                const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3])
 
1851
                           const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3],
 
1852
                           const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3])
1417
1853
{
1418
1854
        /* this works by moving the source triangle so its normal is pointing on the Z
1419
1855
         * axis where its barycentric wights can be calculated in 2D and its Z offset can
1424
1860
        float no_tar[3], no_src[3];
1425
1861
        float quat_src[4];
1426
1862
        float pt_src_xy[3];
1427
 
        float  tri_xy_src[3][3];
 
1863
        float tri_xy_src[3][3];
1428
1864
        float w_src[3];
1429
1865
        float area_tar, area_src;
1430
1866
        float z_ofs_src;
1449
1885
        barycentric_weights_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2], pt_src_xy, w_src);
1450
1886
        interp_v3_v3v3v3(pt_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3, w_src);
1451
1887
 
1452
 
        area_tar= sqrtf(area_tri_v3(tri_tar_p1, tri_tar_p2, tri_tar_p3));
1453
 
        area_src= sqrtf(area_tri_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2]));
 
1888
        area_tar = sqrtf(area_tri_v3(tri_tar_p1, tri_tar_p2, tri_tar_p3));
 
1889
        area_src = sqrtf(area_tri_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2]));
1454
1890
 
1455
 
        z_ofs_src= pt_src_xy[2] - tri_xy_src[0][2];
 
1891
        z_ofs_src = pt_src_xy[2] - tri_xy_src[0][2];
1456
1892
        madd_v3_v3v3fl(pt_tar, pt_tar, no_tar, (z_ofs_src / area_src) * area_tar);
1457
1893
}
1458
1894
 
1459
1895
/* given an array with some invalid values this function interpolates valid values
1460
1896
 * replacing the invalid ones */
1461
 
int interp_sparse_array(float *array, int list_size, float skipval)
 
1897
int interp_sparse_array(float *array, int const list_size, const float skipval)
1462
1898
{
1463
1899
        int found_invalid = 0;
1464
1900
        int found_valid = 0;
1465
1901
        int i;
1466
1902
 
1467
 
        for (i=0; i < list_size; i++) {
1468
 
                if(array[i] == skipval)
1469
 
                        found_invalid= 1;
 
1903
        for (i = 0; i < list_size; i++) {
 
1904
                if (array[i] == skipval)
 
1905
                        found_invalid = 1;
1470
1906
                else
1471
 
                        found_valid= 1;
 
1907
                        found_valid = 1;
1472
1908
        }
1473
1909
 
1474
 
        if(found_valid==0) {
 
1910
        if (found_valid == 0) {
1475
1911
                return -1;
1476
1912
        }
1477
 
        else if (found_invalid==0) {
 
1913
        else if (found_invalid == 0) {
1478
1914
                return 0;
1479
1915
        }
1480
1916
        else {
1481
1917
                /* found invalid depths, interpolate */
1482
 
                float valid_last= skipval;
1483
 
                int valid_ofs= 0;
1484
 
 
1485
 
                float *array_up= MEM_callocN(sizeof(float) * list_size, "interp_sparse_array up");
1486
 
                float *array_down= MEM_callocN(sizeof(float) * list_size, "interp_sparse_array up");
1487
 
 
1488
 
                int *ofs_tot_up= MEM_callocN(sizeof(int) * list_size, "interp_sparse_array tup");
1489
 
                int *ofs_tot_down= MEM_callocN(sizeof(int) * list_size, "interp_sparse_array tdown");
1490
 
 
1491
 
                for (i=0; i < list_size; i++) {
1492
 
                        if(array[i] == skipval) {
1493
 
                                array_up[i]= valid_last;
1494
 
                                ofs_tot_up[i]= ++valid_ofs;
 
1918
                float valid_last = skipval;
 
1919
                int valid_ofs = 0;
 
1920
 
 
1921
                float *array_up = MEM_callocN(sizeof(float) * list_size, "interp_sparse_array up");
 
1922
                float *array_down = MEM_callocN(sizeof(float) * list_size, "interp_sparse_array up");
 
1923
 
 
1924
                int *ofs_tot_up = MEM_callocN(sizeof(int) * list_size, "interp_sparse_array tup");
 
1925
                int *ofs_tot_down = MEM_callocN(sizeof(int) * list_size, "interp_sparse_array tdown");
 
1926
 
 
1927
                for (i = 0; i < list_size; i++) {
 
1928
                        if (array[i] == skipval) {
 
1929
                                array_up[i] = valid_last;
 
1930
                                ofs_tot_up[i] = ++valid_ofs;
1495
1931
                        }
1496
1932
                        else {
1497
 
                                valid_last= array[i];
1498
 
                                valid_ofs= 0;
 
1933
                                valid_last = array[i];
 
1934
                                valid_ofs = 0;
1499
1935
                        }
1500
1936
                }
1501
1937
 
1502
 
                valid_last= skipval;
1503
 
                valid_ofs= 0;
 
1938
                valid_last = skipval;
 
1939
                valid_ofs = 0;
1504
1940
 
1505
 
                for (i=list_size-1; i >= 0; i--) {
1506
 
                        if(array[i] == skipval) {
1507
 
                                array_down[i]= valid_last;
1508
 
                                ofs_tot_down[i]= ++valid_ofs;
 
1941
                for (i = list_size - 1; i >= 0; i--) {
 
1942
                        if (array[i] == skipval) {
 
1943
                                array_down[i] = valid_last;
 
1944
                                ofs_tot_down[i] = ++valid_ofs;
1509
1945
                        }
1510
1946
                        else {
1511
 
                                valid_last= array[i];
1512
 
                                valid_ofs= 0;
 
1947
                                valid_last = array[i];
 
1948
                                valid_ofs = 0;
1513
1949
                        }
1514
1950
                }
1515
1951
 
1516
1952
                /* now blend */
1517
 
                for (i=0; i < list_size; i++) {
1518
 
                        if(array[i] == skipval) {
1519
 
                                if(array_up[i] != skipval && array_down[i] != skipval) {
1520
 
                                        array[i]= ((array_up[i] * ofs_tot_down[i]) +  (array_down[i] * ofs_tot_up[i])) / (float)(ofs_tot_down[i] + ofs_tot_up[i]);
1521
 
                                } else if (array_up[i] != skipval) {
1522
 
                                        array[i]= array_up[i];
1523
 
                                } else if (array_down[i] != skipval) {
1524
 
                                        array[i]= array_down[i];
 
1953
                for (i = 0; i < list_size; i++) {
 
1954
                        if (array[i] == skipval) {
 
1955
                                if (array_up[i] != skipval && array_down[i] != skipval) {
 
1956
                                        array[i] = ((array_up[i] * ofs_tot_down[i]) + (array_down[i] * ofs_tot_up[i])) / (float)(ofs_tot_down[i] + ofs_tot_up[i]);
 
1957
                                }
 
1958
                                else if (array_up[i] != skipval) {
 
1959
                                        array[i] = array_up[i];
 
1960
                                }
 
1961
                                else if (array_down[i] != skipval) {
 
1962
                                        array[i] = array_down[i];
1525
1963
                                }
1526
1964
                        }
1527
1965
                }
1538
1976
 
1539
1977
/* Mean value weights - smooth interpolation weights for polygons with
1540
1978
 * more than 3 vertices */
1541
 
static float mean_value_half_tan(float *v1, float *v2, float *v3)
 
1979
static float mean_value_half_tan(const float v1[3], const float v2[3], const float v3[3])
1542
1980
{
1543
1981
        float d2[3], d3[3], cross[3], area, dot, len;
1544
1982
 
1546
1984
        sub_v3_v3v3(d3, v3, v1);
1547
1985
        cross_v3_v3v3(cross, d2, d3);
1548
1986
 
1549
 
        area= len_v3(cross);
1550
 
        dot= dot_v3v3(d2, d3);
1551
 
        len= len_v3(d2)*len_v3(d3);
 
1987
        area = len_v3(cross);
 
1988
        dot = dot_v3v3(d2, d3);
 
1989
        len = len_v3(d2) * len_v3(d3);
1552
1990
 
1553
 
        if(area == 0.0f)
 
1991
        if (area == 0.0f)
1554
1992
                return 0.0f;
1555
1993
        else
1556
 
                return (len - dot)/area;
 
1994
                return (len - dot) / area;
1557
1995
}
1558
1996
 
1559
 
void interp_weights_poly_v3(float *w,float v[][3], int n, float *co)
 
1997
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
1560
1998
{
1561
1999
        float totweight, t1, t2, len, *vmid, *vprev, *vnext;
1562
2000
        int i;
1563
2001
 
1564
 
        totweight= 0.0f;
1565
 
 
1566
 
        for(i=0; i<n; i++) {
1567
 
                vmid= v[i];
1568
 
                vprev= (i == 0)? v[n-1]: v[i-1];
1569
 
                vnext= (i == n-1)? v[0]: v[i+1];
1570
 
 
1571
 
                t1= mean_value_half_tan(co, vprev, vmid);
1572
 
                t2= mean_value_half_tan(co, vmid, vnext);
1573
 
 
1574
 
                len= len_v3v3(co, vmid);
1575
 
                w[i]= (t1+t2)/len;
 
2002
        totweight = 0.0f;
 
2003
 
 
2004
        for (i = 0; i < n; i++) {
 
2005
                vmid = v[i];
 
2006
                vprev = (i == 0) ? v[n - 1] : v[i - 1];
 
2007
                vnext = (i == n - 1) ? v[0] : v[i + 1];
 
2008
 
 
2009
                t1 = mean_value_half_tan(co, vprev, vmid);
 
2010
                t2 = mean_value_half_tan(co, vmid, vnext);
 
2011
 
 
2012
                len = len_v3v3(co, vmid);
 
2013
                w[i] = (t1 + t2) / len;
1576
2014
                totweight += w[i];
1577
2015
        }
1578
2016
 
1579
 
        if(totweight != 0.0f)
1580
 
                for(i=0; i<n; i++)
 
2017
        if (totweight != 0.0f)
 
2018
                for (i = 0; i < n; i++)
1581
2019
                        w[i] /= totweight;
1582
2020
}
1583
2021
 
1584
2022
/* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
1585
 
void interp_cubic_v3(float *x, float *v,float *x1, float *v1, float *x2, float *v2, float t)
 
2023
void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t)
1586
2024
{
1587
 
        float a[3],b[3];
1588
 
        float t2= t*t;
1589
 
        float t3= t2*t;
 
2025
        float a[3], b[3];
 
2026
        float t2 = t * t;
 
2027
        float t3 = t2 * t;
1590
2028
 
1591
2029
        /* cubic interpolation */
1592
 
        a[0]= v1[0] + v2[0] + 2*(x1[0] - x2[0]);
1593
 
        a[1]= v1[1] + v2[1] + 2*(x1[1] - x2[1]);
1594
 
        a[2]= v1[2] + v2[2] + 2*(x1[2] - x2[2]);
1595
 
 
1596
 
        b[0]= -2*v1[0] - v2[0] - 3*(x1[0] - x2[0]);
1597
 
        b[1]= -2*v1[1] - v2[1] - 3*(x1[1] - x2[1]);
1598
 
        b[2]= -2*v1[2] - v2[2] - 3*(x1[2] - x2[2]);
1599
 
 
1600
 
        x[0]= a[0]*t3 + b[0]*t2 + v1[0]*t + x1[0];
1601
 
        x[1]= a[1]*t3 + b[1]*t2 + v1[1]*t + x1[1];
1602
 
        x[2]= a[2]*t3 + b[2]*t2 + v1[2]*t + x1[2];
1603
 
 
1604
 
        v[0]= 3*a[0]*t2 + 2*b[0]*t + v1[0];
1605
 
        v[1]= 3*a[1]*t2 + 2*b[1]*t + v1[1];
1606
 
        v[2]= 3*a[2]*t2 + 2*b[2]*t + v1[2];
1607
 
}
 
2030
        a[0] = v1[0] + v2[0] + 2 * (x1[0] - x2[0]);
 
2031
        a[1] = v1[1] + v2[1] + 2 * (x1[1] - x2[1]);
 
2032
        a[2] = v1[2] + v2[2] + 2 * (x1[2] - x2[2]);
 
2033
 
 
2034
        b[0] = -2 * v1[0] - v2[0] - 3 * (x1[0] - x2[0]);
 
2035
        b[1] = -2 * v1[1] - v2[1] - 3 * (x1[1] - x2[1]);
 
2036
        b[2] = -2 * v1[2] - v2[2] - 3 * (x1[2] - x2[2]);
 
2037
 
 
2038
        x[0] = a[0] * t3 + b[0] * t2 + v1[0] * t + x1[0];
 
2039
        x[1] = a[1] * t3 + b[1] * t2 + v1[1] * t + x1[1];
 
2040
        x[2] = a[2] * t3 + b[2] * t2 + v1[2] * t + x1[2];
 
2041
 
 
2042
        v[0] = 3 * a[0] * t2 + 2 * b[0] * t + v1[0];
 
2043
        v[1] = 3 * a[1] * t2 + 2 * b[1] * t + v1[1];
 
2044
        v[2] = 3 * a[2] * t2 + 2 * b[2] * t + v1[2];
 
2045
}
 
2046
 
 
2047
/* unfortunately internal calculations have to be done at double precision to achieve correct/stable results. */
 
2048
 
 
2049
#define IS_ZERO(x) ((x > (-DBL_EPSILON) && x < DBL_EPSILON) ? 1 : 0)
 
2050
 
 
2051
/* Barycentric reverse  */
 
2052
void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2])
 
2053
{
 
2054
        /* find UV such that
 
2055
         * t = u * t0 + v * t1 + (1 - u - v) * t2
 
2056
         * u * (t0 - t2) + v * (t1 - t2) = t - t2 */
 
2057
        const double a = st0[0] - st2[0], b = st1[0] - st2[0];
 
2058
        const double c = st0[1] - st2[1], d = st1[1] - st2[1];
 
2059
        const double det = a * d - c * b;
 
2060
 
 
2061
        if (IS_ZERO(det) == 0) { /* det should never be zero since the determinant is the signed ST area of the triangle. */
 
2062
                const double x[] = {st[0] - st2[0], st[1] - st2[1]};
 
2063
 
 
2064
                r_uv[0] = (float)((d * x[0] - b * x[1]) / det);
 
2065
                r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det);
 
2066
        }
 
2067
        else zero_v2(r_uv);
 
2068
}
 
2069
 
 
2070
/* bilinear reverse */
 
2071
void resolve_quad_uv(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
 
2072
{
 
2073
        const double signed_area = (st0[0] * st1[1] - st0[1] * st1[0]) + (st1[0] * st2[1] - st1[1] * st2[0]) +
 
2074
                                   (st2[0] * st3[1] - st2[1] * st3[0]) + (st3[0] * st0[1] - st3[1] * st0[0]);
 
2075
 
 
2076
        /* X is 2D cross product (determinant)
 
2077
         * A= (p0-p) X (p0-p3)*/
 
2078
        const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]);
 
2079
 
 
2080
        /* B= ( (p0-p) X (p1-p2) + (p1-p) X (p0-p3) ) / 2 */
 
2081
        const double b = 0.5 * (((st0[0] - st[0]) * (st1[1] - st2[1]) - (st0[1] - st[1]) * (st1[0] - st2[0])) +
 
2082
                                ((st1[0] - st[0]) * (st0[1] - st3[1]) - (st1[1] - st[1]) * (st0[0] - st3[0])));
 
2083
 
 
2084
        /* C = (p1-p) X (p1-p2) */
 
2085
        const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]);
 
2086
        const double denom = a - 2 * b + fC;
 
2087
 
 
2088
        // clear outputs
 
2089
        zero_v2(r_uv);
 
2090
 
 
2091
        if (IS_ZERO(denom) != 0) {
 
2092
                const double fDen = a - fC;
 
2093
                if (IS_ZERO(fDen) == 0)
 
2094
                        r_uv[0] = (float)(a / fDen);
 
2095
        }
 
2096
        else {
 
2097
                const double desc_sq = b * b - a * fC;
 
2098
                const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
 
2099
                const double s = signed_area > 0 ? (-1.0) : 1.0;
 
2100
 
 
2101
                r_uv[0] = (float)(((a - b) + s * desc) / denom);
 
2102
        }
 
2103
 
 
2104
        /* find UV such that
 
2105
         * fST = (1-u)(1-v) * ST0 + u * (1-v) * ST1 + u * v * ST2 + (1-u) * v * ST3 */
 
2106
        {
 
2107
                const double denom_s = (1 - r_uv[0]) * (st0[0] - st3[0]) + r_uv[0] * (st1[0] - st2[0]);
 
2108
                const double denom_t = (1 - r_uv[0]) * (st0[1] - st3[1]) + r_uv[0] * (st1[1] - st2[1]);
 
2109
                int i = 0;
 
2110
                double denom = denom_s;
 
2111
 
 
2112
                if (fabs(denom_s) < fabs(denom_t)) {
 
2113
                        i = 1;
 
2114
                        denom = denom_t;
 
2115
                }
 
2116
 
 
2117
                if (IS_ZERO(denom) == 0)
 
2118
                        r_uv[1] = (float)(((1.0f - r_uv[0]) * (st0[i] - st[i]) + r_uv[0] * (st1[i] - st[i])) / denom);
 
2119
        }
 
2120
}
 
2121
 
 
2122
#undef IS_ZERO
1608
2123
 
1609
2124
/***************************** View & Projection *****************************/
1610
2125
 
1611
 
void orthographic_m4(float matrix[][4],float left, float right, float bottom, float top, float nearClip, float farClip)
 
2126
void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip)
1612
2127
{
1613
2128
        float Xdelta, Ydelta, Zdelta;
1614
 
 
 
2129
 
1615
2130
        Xdelta = right - left;
1616
2131
        Ydelta = top - bottom;
1617
2132
        Zdelta = farClip - nearClip;
1618
 
        if (Xdelta == 0.0 || Ydelta == 0.0 || Zdelta == 0.0) {
 
2133
        if (Xdelta == 0.0f || Ydelta == 0.0f || Zdelta == 0.0f) {
1619
2134
                return;
1620
2135
        }
1621
2136
        unit_m4(matrix);
1622
 
        matrix[0][0] = 2.0f/Xdelta;
1623
 
        matrix[3][0] = -(right + left)/Xdelta;
1624
 
        matrix[1][1] = 2.0f/Ydelta;
1625
 
        matrix[3][1] = -(top + bottom)/Ydelta;
1626
 
        matrix[2][2] = -2.0f/Zdelta;            /* note: negate Z       */
1627
 
        matrix[3][2] = -(farClip + nearClip)/Zdelta;
 
2137
        matrix[0][0] = 2.0f / Xdelta;
 
2138
        matrix[3][0] = -(right + left) / Xdelta;
 
2139
        matrix[1][1] = 2.0f / Ydelta;
 
2140
        matrix[3][1] = -(top + bottom) / Ydelta;
 
2141
        matrix[2][2] = -2.0f / Zdelta; /* note: negate Z        */
 
2142
        matrix[3][2] = -(farClip + nearClip) / Zdelta;
1628
2143
}
1629
2144
 
1630
 
void perspective_m4(float mat[][4],float left, float right, float bottom, float top, float nearClip, float farClip)
 
2145
void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip)
1631
2146
{
1632
2147
        float Xdelta, Ydelta, Zdelta;
1633
2148
 
1635
2150
        Ydelta = top - bottom;
1636
2151
        Zdelta = farClip - nearClip;
1637
2152
 
1638
 
        if (Xdelta == 0.0 || Ydelta == 0.0 || Zdelta == 0.0) {
 
2153
        if (Xdelta == 0.0f || Ydelta == 0.0f || Zdelta == 0.0f) {
1639
2154
                return;
1640
2155
        }
1641
 
        mat[0][0] = nearClip * 2.0f/Xdelta;
1642
 
        mat[1][1] = nearClip * 2.0f/Ydelta;
1643
 
        mat[2][0] = (right + left)/Xdelta;              /* note: negate Z       */
1644
 
        mat[2][1] = (top + bottom)/Ydelta;
1645
 
        mat[2][2] = -(farClip + nearClip)/Zdelta;
 
2156
        mat[0][0] = nearClip * 2.0f / Xdelta;
 
2157
        mat[1][1] = nearClip * 2.0f / Ydelta;
 
2158
        mat[2][0] = (right + left) / Xdelta; /* note: negate Z  */
 
2159
        mat[2][1] = (top + bottom) / Ydelta;
 
2160
        mat[2][2] = -(farClip + nearClip) / Zdelta;
1646
2161
        mat[2][3] = -1.0f;
1647
 
        mat[3][2] = (-2.0f * nearClip * farClip)/Zdelta;
 
2162
        mat[3][2] = (-2.0f * nearClip * farClip) / Zdelta;
1648
2163
        mat[0][1] = mat[0][2] = mat[0][3] =
1649
 
                mat[1][0] = mat[1][2] = mat[1][3] =
1650
 
                mat[3][0] = mat[3][1] = mat[3][3] = 0.0;
1651
 
 
 
2164
                mat[1][0] = mat[1][2] = mat[1][3] =
 
2165
                mat[3][0] = mat[3][1] = mat[3][3] = 0.0;
 
2166
 
 
2167
}
 
2168
 
 
2169
/* translate a matrix created by orthographic_m4 or perspective_m4 in XY coords (used to jitter the view) */
 
2170
void window_translate_m4(float winmat[][4], float perspmat[][4], const float x, const float y)
 
2171
{
 
2172
        if (winmat[2][3] == -1.0f) {
 
2173
                /* in the case of a win-matrix, this means perspective always */
 
2174
                float v1[3];
 
2175
                float v2[3];
 
2176
                float len1, len2;
 
2177
 
 
2178
                v1[0] = perspmat[0][0];
 
2179
                v1[1] = perspmat[1][0];
 
2180
                v1[2] = perspmat[2][0];
 
2181
 
 
2182
                v2[0] = perspmat[0][1];
 
2183
                v2[1] = perspmat[1][1];
 
2184
                v2[2] = perspmat[2][1];
 
2185
 
 
2186
                len1 = (1.0f / len_v3(v1));
 
2187
                len2 = (1.0f / len_v3(v2));
 
2188
 
 
2189
                winmat[2][0] += len1 * winmat[0][0] * x;
 
2190
                winmat[2][1] += len2 * winmat[1][1] * y;
 
2191
        }
 
2192
        else {
 
2193
                winmat[3][0] += x;
 
2194
                winmat[3][1] += y;
 
2195
        }
1652
2196
}
1653
2197
 
1654
2198
static void i_multmatrix(float icand[][4], float Vm[][4])
1656
2200
        int row, col;
1657
2201
        float temp[4][4];
1658
2202
 
1659
 
        for(row=0 ; row<4 ; row++) 
1660
 
                for(col=0 ; col<4 ; col++)
1661
 
                        temp[row][col] = icand[row][0] * Vm[0][col]
1662
 
                                                   + icand[row][1] * Vm[1][col]
1663
 
                                                   + icand[row][2] * Vm[2][col]
1664
 
                                                   + icand[row][3] * Vm[3][col];
 
2203
        for (row = 0; row < 4; row++)
 
2204
                for (col = 0; col < 4; col++)
 
2205
                        temp[row][col] = (icand[row][0] * Vm[0][col] +
 
2206
                                          icand[row][1] * Vm[1][col] +
 
2207
                                          icand[row][2] * Vm[2][col] +
 
2208
                                          icand[row][3] * Vm[3][col]);
1665
2209
        copy_m4_m4(Vm, temp);
1666
2210
}
1667
2211
 
1668
 
 
1669
 
void polarview_m4(float Vm[][4],float dist, float azimuth, float incidence, float twist)
 
2212
void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, float twist)
1670
2213
{
1671
2214
 
1672
2215
        unit_m4(Vm);
1673
2216
 
1674
 
        translate_m4(Vm,0.0, 0.0, -dist);
1675
 
        rotate_m4(Vm,'Z',-twist);
1676
 
        rotate_m4(Vm,'X',-incidence);
1677
 
        rotate_m4(Vm,'Z',-azimuth);
 
2217
        translate_m4(Vm, 0.0, 0.0, -dist);
 
2218
        rotate_m4(Vm, 'Z', -twist);
 
2219
        rotate_m4(Vm, 'X', -incidence);
 
2220
        rotate_m4(Vm, 'Z', -azimuth);
1678
2221
}
1679
2222
 
1680
 
void lookat_m4(float mat[][4],float vx, float vy, float vz, float px, float py, float pz, float twist)
 
2223
void lookat_m4(float mat[][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
1681
2224
{
1682
2225
        float sine, cosine, hyp, hyp1, dx, dy, dz;
1683
 
        float mat1[4][4];
1684
 
        
 
2226
        float mat1[4][4] = MAT4_UNITY;
 
2227
 
1685
2228
        unit_m4(mat);
1686
 
        unit_m4(mat1);
1687
2229
 
1688
2230
        rotate_m4(mat, 'Z', -twist);
1689
2231
 
1690
2232
        dx = px - vx;
1691
2233
        dy = py - vy;
1692
2234
        dz = pz - vz;
1693
 
        hyp = dx * dx + dz * dz;        /* hyp squared  */
1694
 
        hyp1 = (float)sqrt(dy*dy + hyp);
1695
 
        hyp = (float)sqrt(hyp);         /* the real hyp */
1696
 
        
1697
 
        if (hyp1 != 0.0) {              /* rotate X     */
 
2235
        hyp = dx * dx + dz * dz; /* hyp squared */
 
2236
        hyp1 = (float)sqrt(dy * dy + hyp);
 
2237
        hyp = (float)sqrt(hyp); /* the real hyp */
 
2238
 
 
2239
        if (hyp1 != 0.0f) { /* rotate X */
1698
2240
                sine = -dy / hyp1;
1699
 
                cosine = hyp /hyp1;
1700
 
        } else {
 
2241
                cosine = hyp / hyp1;
 
2242
        }
 
2243
        else {
1701
2244
                sine = 0;
1702
2245
                cosine = 1.0f;
1703
2246
        }
1705
2248
        mat1[1][2] = sine;
1706
2249
        mat1[2][1] = -sine;
1707
2250
        mat1[2][2] = cosine;
1708
 
        
 
2251
 
1709
2252
        i_multmatrix(mat1, mat);
1710
2253
 
1711
 
        mat1[1][1] = mat1[2][2] = 1.0f; /* be careful here to reinit    */
1712
 
        mat1[1][2] = mat1[2][1] = 0.0;  /* those modified by the last   */
1713
 
        
 
2254
        mat1[1][1] = mat1[2][2] = 1.0f; /* be careful here to reinit    */
 
2255
        mat1[1][2] = mat1[2][1] = 0.0; /* those modified by the last    */
 
2256
 
1714
2257
        /* paragraph    */
1715
 
        if (hyp != 0.0f) {                      /* rotate Y     */
 
2258
        if (hyp != 0.0f) { /* rotate Y  */
1716
2259
                sine = dx / hyp;
1717
2260
                cosine = -dz / hyp;
1718
 
        } else {
 
2261
        }
 
2262
        else {
1719
2263
                sine = 0;
1720
2264
                cosine = 1.0f;
1721
2265
        }
1723
2267
        mat1[0][2] = -sine;
1724
2268
        mat1[2][0] = sine;
1725
2269
        mat1[2][2] = cosine;
1726
 
        
 
2270
 
1727
2271
        i_multmatrix(mat1, mat);
1728
 
        translate_m4(mat,-vx,-vy,-vz);  /* translate viewpoint to origin */
 
2272
        translate_m4(mat, -vx, -vy, -vz); /* translate viewpoint to origin */
1729
2273
}
1730
2274
 
1731
 
int box_clip_bounds_m4(float boundbox[2][3], float bounds[4], float winmat[4][4])
 
2275
int box_clip_bounds_m4(float boundbox[2][3], const float bounds[4], float winmat[4][4])
1732
2276
{
1733
2277
        float mat[4][4], vec[4];
1734
 
        int a, fl, flag= -1;
 
2278
        int a, fl, flag = -1;
1735
2279
 
1736
2280
        copy_m4_m4(mat, winmat);
1737
2281
 
1738
 
        for(a=0; a<8; a++) {
1739
 
                vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0];
1740
 
                vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1];
1741
 
                vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2];
1742
 
                vec[3]= 1.0;
 
2282
        for (a = 0; a < 8; a++) {
 
2283
                vec[0] = (a & 1) ? boundbox[0][0] : boundbox[1][0];
 
2284
                vec[1] = (a & 2) ? boundbox[0][1] : boundbox[1][1];
 
2285
                vec[2] = (a & 4) ? boundbox[0][2] : boundbox[1][2];
 
2286
                vec[3] = 1.0;
1743
2287
                mul_m4_v4(mat, vec);
1744
2288
 
1745
 
                fl= 0;
1746
 
                if(bounds) {
1747
 
                        if(vec[0] > bounds[1]*vec[3]) fl |= 1;
1748
 
                        if(vec[0]< bounds[0]*vec[3]) fl |= 2;
1749
 
                        if(vec[1] > bounds[3]*vec[3]) fl |= 4;
1750
 
                        if(vec[1]< bounds[2]*vec[3]) fl |= 8;
 
2289
                fl = 0;
 
2290
                if (bounds) {
 
2291
                        if (vec[0] > bounds[1] * vec[3]) fl |= 1;
 
2292
                        if (vec[0] < bounds[0] * vec[3]) fl |= 2;
 
2293
                        if (vec[1] > bounds[3] * vec[3]) fl |= 4;
 
2294
                        if (vec[1] < bounds[2] * vec[3]) fl |= 8;
1751
2295
                }
1752
2296
                else {
1753
 
                        if(vec[0] < -vec[3]) fl |= 1;
1754
 
                        if(vec[0] > vec[3]) fl |= 2;
1755
 
                        if(vec[1] < -vec[3]) fl |= 4;
1756
 
                        if(vec[1] > vec[3]) fl |= 8;
 
2297
                        if (vec[0] < -vec[3]) fl |= 1;
 
2298
                        if (vec[0] > vec[3]) fl |= 2;
 
2299
                        if (vec[1] < -vec[3]) fl |= 4;
 
2300
                        if (vec[1] > vec[3]) fl |= 8;
1757
2301
                }
1758
 
                if(vec[2] < -vec[3]) fl |= 16;
1759
 
                if(vec[2] > vec[3]) fl |= 32;
 
2302
                if (vec[2] < -vec[3]) fl |= 16;
 
2303
                if (vec[2] > vec[3]) fl |= 32;
1760
2304
 
1761
2305
                flag &= fl;
1762
 
                if(flag==0) return 0;
 
2306
                if (flag == 0) return 0;
1763
2307
        }
1764
2308
 
1765
2309
        return flag;
1773
2317
        copy_v3_v3(mn, min);
1774
2318
        copy_v3_v3(mx, max);
1775
2319
 
1776
 
        for(a=0; a<8; a++) {
1777
 
                vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0];
1778
 
                vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1];
1779
 
                vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2];
 
2320
        for (a = 0; a < 8; a++) {
 
2321
                vec[0] = (a & 1) ? boundbox[0][0] : boundbox[1][0];
 
2322
                vec[1] = (a & 2) ? boundbox[0][1] : boundbox[1][1];
 
2323
                vec[2] = (a & 4) ? boundbox[0][2] : boundbox[1][2];
1780
2324
 
1781
2325
                mul_m4_v3(mat, vec);
1782
2326
                DO_MINMAX(vec, mn, mx);
1788
2332
 
1789
2333
/********************************** Mapping **********************************/
1790
2334
 
1791
 
void map_to_tube(float *u, float *v,float x, float y, float z)
1792
 
{
1793
 
        float len;
1794
 
        
1795
 
        *v = (z + 1.0f) / 2.0f;
1796
 
        
1797
 
        len= (float)sqrt(x*x+y*y);
1798
 
        if(len > 0.0f)
1799
 
                *u = (float)((1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0);
1800
 
        else
1801
 
                *v = *u = 0.0f; /* to avoid un-initialized variables */
1802
 
}
1803
 
 
1804
 
void map_to_sphere(float *u, float *v,float x, float y, float z)
1805
 
{
1806
 
        float len;
1807
 
        
1808
 
        len= (float)sqrt(x*x+y*y+z*z);
1809
 
        if(len > 0.0f) {
1810
 
                if(x==0.0f && y==0.0f) *u= 0.0f;        /* othwise domain error */
1811
 
                else *u = (float)((1.0 - (float)atan2(x,y) / M_PI) / 2.0);
1812
 
                
1813
 
                z/=len;
1814
 
                *v = 1.0f - (float)saacos(z)/(float)M_PI;
1815
 
        } else {
1816
 
                *v = *u = 0.0f; /* to avoid un-initialized variables */
 
2335
void map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z)
 
2336
{
 
2337
        float len;
 
2338
 
 
2339
        *r_v = (z + 1.0f) / 2.0f;
 
2340
 
 
2341
        len = sqrtf(x * x + y * y);
 
2342
        if (len > 0.0f) {
 
2343
                *r_u = (float)((1.0 - (atan2(x / len, y / len) / M_PI)) / 2.0);
 
2344
        }
 
2345
        else {
 
2346
                *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
 
2347
        }
 
2348
}
 
2349
 
 
2350
void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z)
 
2351
{
 
2352
        float len;
 
2353
 
 
2354
        len = sqrtf(x * x + y * y + z * z);
 
2355
        if (len > 0.0f) {
 
2356
                if (x == 0.0f && y == 0.0f) *r_u = 0.0f;  /* othwise domain error */
 
2357
                else *r_u = (1.0f - atan2f(x, y) / (float)M_PI) / 2.0f;
 
2358
 
 
2359
                *r_v = 1.0f - (float)saacos(z / len) / (float)M_PI;
 
2360
        }
 
2361
        else {
 
2362
                *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
 
2363
        }
 
2364
}
 
2365
 
 
2366
/********************************* Normals **********************************/
 
2367
 
 
2368
void accumulate_vertex_normals(float n1[3], float n2[3], float n3[3],
 
2369
                               float n4[3], const float f_no[3], const float co1[3], const float co2[3],
 
2370
                               const float co3[3], const float co4[3])
 
2371
{
 
2372
        float vdiffs[4][3];
 
2373
        const int nverts = (n4 != NULL && co4 != NULL) ? 4 : 3;
 
2374
 
 
2375
        /* compute normalized edge vectors */
 
2376
        sub_v3_v3v3(vdiffs[0], co2, co1);
 
2377
        sub_v3_v3v3(vdiffs[1], co3, co2);
 
2378
 
 
2379
        if (nverts == 3) {
 
2380
                sub_v3_v3v3(vdiffs[2], co1, co3);
 
2381
        }
 
2382
        else {
 
2383
                sub_v3_v3v3(vdiffs[2], co4, co3);
 
2384
                sub_v3_v3v3(vdiffs[3], co1, co4);
 
2385
                normalize_v3(vdiffs[3]);
 
2386
        }
 
2387
 
 
2388
        normalize_v3(vdiffs[0]);
 
2389
        normalize_v3(vdiffs[1]);
 
2390
        normalize_v3(vdiffs[2]);
 
2391
 
 
2392
        /* accumulate angle weighted face normal */
 
2393
        {
 
2394
                float *vn[] = {n1, n2, n3, n4};
 
2395
                const float *prev_edge = vdiffs[nverts - 1];
 
2396
                int i;
 
2397
 
 
2398
                for (i = 0; i < nverts; i++) {
 
2399
                        const float *cur_edge = vdiffs[i];
 
2400
                        const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
 
2401
 
 
2402
                        // accumulate
 
2403
                        madd_v3_v3fl(vn[i], f_no, fac);
 
2404
                        prev_edge = cur_edge;
 
2405
                }
 
2406
        }
 
2407
}
 
2408
 
 
2409
/* Add weighted face normal component into normals of the face vertices.
 
2410
 * Caller must pass pre-allocated vdiffs of nverts length. */
 
2411
void accumulate_vertex_normals_poly(float **vertnos, float polyno[3],
 
2412
                                    float **vertcos, float vdiffs[][3], int nverts)
 
2413
{
 
2414
        int i;
 
2415
 
 
2416
        /* calculate normalized edge directions for each edge in the poly */
 
2417
        for (i = 0; i < nverts; i++) {
 
2418
                sub_v3_v3v3(vdiffs[i], vertcos[(i + 1) % nverts], vertcos[i]);
 
2419
                normalize_v3(vdiffs[i]);
 
2420
        }
 
2421
 
 
2422
        /* accumulate angle weighted face normal */
 
2423
        {
 
2424
                const float *prev_edge = vdiffs[nverts - 1];
 
2425
                int i;
 
2426
 
 
2427
                for (i = 0; i < nverts; i++) {
 
2428
                        const float *cur_edge = vdiffs[i];
 
2429
 
 
2430
                        /* calculate angle between the two poly edges incident on
 
2431
                         * this vertex */
 
2432
                        const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
 
2433
 
 
2434
                        /* accumulate */
 
2435
                        madd_v3_v3fl(vertnos[i], polyno, fac);
 
2436
                        prev_edge = cur_edge;
 
2437
                }
1817
2438
        }
1818
2439
}
1819
2440
 
1820
2441
/********************************* Tangents **********************************/
1821
2442
 
1822
2443
/* For normal map tangents we need to detect uv boundaries, and only average
1823
 
 * tangents in case the uvs are connected. Alternative would be to store 1 
 
2444
 * tangents in case the uvs are connected. Alternative would be to store 1
1824
2445
 * tangent per face rather than 4 per face vertex, but that's not compatible
1825
2446
 * with games */
1826
2447
 
1827
2448
 
1828
2449
/* from BKE_mesh.h */
1829
 
#define STD_UV_CONNECT_LIMIT    0.0001f
 
2450
#define STD_UV_CONNECT_LIMIT  0.0001f
1830
2451
 
1831
 
void sum_or_add_vertex_tangent(void *arena, VertexTangent **vtang, float *tang, float *uv)
 
2452
void sum_or_add_vertex_tangent(void *arena, VertexTangent **vtang, const float tang[3], const float uv[2])
1832
2453
{
1833
2454
        VertexTangent *vt;
1834
2455
 
1835
2456
        /* find a tangent with connected uvs */
1836
 
        for(vt= *vtang; vt; vt=vt->next) {
1837
 
                if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT) {
 
2457
        for (vt = *vtang; vt; vt = vt->next) {
 
2458
                if (fabsf(uv[0] - vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabsf(uv[1] - vt->uv[1]) < STD_UV_CONNECT_LIMIT) {
1838
2459
                        add_v3_v3(vt->tang, tang);
1839
2460
                        return;
1840
2461
                }
1841
2462
        }
1842
2463
 
1843
2464
        /* if not found, append a new one */
1844
 
        vt= BLI_memarena_alloc((MemArena *)arena, sizeof(VertexTangent));
 
2465
        vt = BLI_memarena_alloc((MemArena *) arena, sizeof(VertexTangent));
1845
2466
        copy_v3_v3(vt->tang, tang);
1846
 
        vt->uv[0]= uv[0];
1847
 
        vt->uv[1]= uv[1];
 
2467
        vt->uv[0] = uv[0];
 
2468
        vt->uv[1] = uv[1];
1848
2469
 
1849
 
        if(*vtang)
1850
 
                vt->next= *vtang;
1851
 
        *vtang= vt;
 
2470
        if (*vtang)
 
2471
                vt->next = *vtang;
 
2472
        *vtang = vt;
1852
2473
}
1853
2474
 
1854
 
float *find_vertex_tangent(VertexTangent *vtang, float *uv)
 
2475
float *find_vertex_tangent(VertexTangent *vtang, const float uv[2])
1855
2476
{
1856
2477
        VertexTangent *vt;
1857
2478
        static float nulltang[3] = {0.0f, 0.0f, 0.0f};
1858
2479
 
1859
 
        for(vt= vtang; vt; vt=vt->next)
1860
 
                if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT)
 
2480
        for (vt = vtang; vt; vt = vt->next)
 
2481
                if (fabsf(uv[0] - vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabsf(uv[1] - vt->uv[1]) < STD_UV_CONNECT_LIMIT)
1861
2482
                        return vt->tang;
1862
2483
 
1863
 
        return nulltang;        /* shouldn't happen, except for nan or so */
 
2484
        return nulltang; /* shouldn't happen, except for nan or so */
1864
2485
}
1865
2486
 
1866
 
void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, float *co3, float *n, float *tang)
 
2487
void tangent_from_uv(float uv1[2], float uv2[2], float uv3[3], float co1[3], float co2[3], float co3[3], float n[3], float tang[3])
1867
2488
{
1868
 
        float s1= uv2[0] - uv1[0];
1869
 
        float s2= uv3[0] - uv1[0];
1870
 
        float t1= uv2[1] - uv1[1];
1871
 
        float t2= uv3[1] - uv1[1];
1872
 
        float det= (s1 * t2 - s2 * t1);
 
2489
        float s1 = uv2[0] - uv1[0];
 
2490
        float s2 = uv3[0] - uv1[0];
 
2491
        float t1 = uv2[1] - uv1[1];
 
2492
        float t2 = uv3[1] - uv1[1];
 
2493
        float det = (s1 * t2 - s2 * t1);
1873
2494
 
1874
 
        if(det != 0.0f) { /* otherwise 'tang' becomes nan */
 
2495
        if (det != 0.0f) { /* otherwise 'tang' becomes nan */
1875
2496
                float tangv[3], ct[3], e1[3], e2[3];
1876
2497
 
1877
 
                det= 1.0f/det;
 
2498
                det = 1.0f / det;
1878
2499
 
1879
2500
                /* normals in render are inversed... */
1880
2501
                sub_v3_v3v3(e1, co1, co2);
1881
2502
                sub_v3_v3v3(e2, co1, co3);
1882
 
                tang[0] = (t2*e1[0] - t1*e2[0])*det;
1883
 
                tang[1] = (t2*e1[1] - t1*e2[1])*det;
1884
 
                tang[2] = (t2*e1[2] - t1*e2[2])*det;
1885
 
                tangv[0] = (s1*e2[0] - s2*e1[0])*det;
1886
 
                tangv[1] = (s1*e2[1] - s2*e1[1])*det;
1887
 
                tangv[2] = (s1*e2[2] - s2*e1[2])*det;
 
2503
                tang[0] = (t2 * e1[0] - t1 * e2[0]) * det;
 
2504
                tang[1] = (t2 * e1[1] - t1 * e2[1]) * det;
 
2505
                tang[2] = (t2 * e1[2] - t1 * e2[2]) * det;
 
2506
                tangv[0] = (s1 * e2[0] - s2 * e1[0]) * det;
 
2507
                tangv[1] = (s1 * e2[1] - s2 * e1[1]) * det;
 
2508
                tangv[2] = (s1 * e2[2] - s2 * e1[2]) * det;
1888
2509
                cross_v3_v3v3(ct, tang, tangv);
1889
 
        
 
2510
 
1890
2511
                /* check flip */
1891
 
                if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f)
 
2512
                if (dot_v3v3(ct, n) < 0.0f) {
1892
2513
                        negate_v3(tang);
 
2514
                }
1893
2515
        }
1894
2516
        else {
1895
 
                tang[0]= tang[1]= tang[2]=  0.0;
 
2517
                tang[0] = tang[1] = tang[2] = 0.0;
1896
2518
        }
1897
2519
}
1898
2520
 
1900
2522
 
1901
2523
/* vector clouds */
1902
2524
/* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight,
1903
 
                                                                 float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3])
1904
 
 
1905
 
input
1906
 
(
1907
 
int list_size
1908
 
4 lists as pointer to array[list_size]
1909
 
1. current pos array of 'new' positions 
1910
 
2. current weight array of 'new'weights (may be NULL pointer if you have no weights )
1911
 
3. reference rpos array of 'old' positions
1912
 
4. reference rweight array of 'old'weights (may be NULL pointer if you have no weights )
1913
 
)
1914
 
output  
1915
 
(
1916
 
float lloc[3] center of mass pos
1917
 
float rloc[3] center of mass rpos
1918
 
float lrot[3][3] rotation matrix
1919
 
float lscale[3][3] scale matrix
1920
 
pointers may be NULL if not needed
1921
 
)
1922
 
 
1923
 
*/
 
2525
 *                                float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3])
 
2526
 *
 
2527
 * input
 
2528
 * (
 
2529
 * int list_size
 
2530
 * 4 lists as pointer to array[list_size]
 
2531
 * 1. current pos array of 'new' positions
 
2532
 * 2. current weight array of 'new'weights (may be NULL pointer if you have no weights )
 
2533
 * 3. reference rpos array of 'old' positions
 
2534
 * 4. reference rweight array of 'old'weights (may be NULL pointer if you have no weights )
 
2535
 * )
 
2536
 * output
 
2537
 * (
 
2538
 * float lloc[3] center of mass pos
 
2539
 * float rloc[3] center of mass rpos
 
2540
 * float lrot[3][3] rotation matrix
 
2541
 * float lscale[3][3] scale matrix
 
2542
 * pointers may be NULL if not needed
 
2543
 * )
 
2544
 */
 
2545
 
1924
2546
/* can't believe there is none in math utils */
1925
 
float _det_m3(float m2[3][3])
 
2547
static float _det_m3(float m2[3][3])
1926
2548
{
1927
2549
        float det = 0.f;
1928
 
        if (m2){
1929
 
        det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1])
1930
 
                -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1])
1931
 
                +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]);
 
2550
        if (m2) {
 
2551
                det = (m2[0][0] * (m2[1][1] * m2[2][2] - m2[1][2] * m2[2][1]) -
 
2552
                       m2[1][0] * (m2[0][1] * m2[2][2] - m2[0][2] * m2[2][1]) +
 
2553
                       m2[2][0] * (m2[0][1] * m2[1][2] - m2[0][2] * m2[1][1]));
1932
2554
        }
1933
2555
        return det;
1934
2556
}
1935
2557
 
1936
 
 
1937
 
void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight,
1938
 
                                                        float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3])
 
2558
void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, float (*rpos)[3], float *rweight,
 
2559
                               float lloc[3], float rloc[3], float lrot[3][3], float lscale[3][3])
1939
2560
{
1940
 
        float accu_com[3]= {0.0f,0.0f,0.0f}, accu_rcom[3]= {0.0f,0.0f,0.0f};
1941
 
        float accu_weight = 0.0f,accu_rweight = 0.0f,eps = 0.000001f;
 
2561
        float accu_com[3] = {0.0f, 0.0f, 0.0f}, accu_rcom[3] = {0.0f, 0.0f, 0.0f};
 
2562
        float accu_weight = 0.0f, accu_rweight = 0.0f, eps = 0.000001f;
1942
2563
 
1943
2564
        int a;
1944
2565
        /* first set up a nice default response */
1947
2568
        if (lrot) unit_m3(lrot);
1948
2569
        if (lscale) unit_m3(lscale);
1949
2570
        /* do com for both clouds */
1950
 
        if (pos && rpos && (list_size > 0)) /* paranoya check */
1951
 
        {
 
2571
        if (pos && rpos && (list_size > 0)) { /* paranoya check */
1952
2572
                /* do com for both clouds */
1953
 
                for(a=0; a<list_size; a++){
1954
 
                        if (weight){
 
2573
                for (a = 0; a < list_size; a++) {
 
2574
                        if (weight) {
1955
2575
                                float v[3];
1956
 
                                copy_v3_v3(v,pos[a]);
1957
 
                                mul_v3_fl(v,weight[a]);
 
2576
                                copy_v3_v3(v, pos[a]);
 
2577
                                mul_v3_fl(v, weight[a]);
1958
2578
                                add_v3_v3(accu_com, v);
1959
 
                                accu_weight +=weight[a]; 
 
2579
                                accu_weight += weight[a];
1960
2580
                        }
1961
2581
                        else add_v3_v3(accu_com, pos[a]);
1962
2582
 
1963
 
                        if (rweight){
 
2583
                        if (rweight) {
1964
2584
                                float v[3];
1965
 
                                copy_v3_v3(v,rpos[a]);
1966
 
                                mul_v3_fl(v,rweight[a]);
 
2585
                                copy_v3_v3(v, rpos[a]);
 
2586
                                mul_v3_fl(v, rweight[a]);
1967
2587
                                add_v3_v3(accu_rcom, v);
1968
 
                                accu_rweight +=rweight[a]; 
 
2588
                                accu_rweight += rweight[a];
1969
2589
                        }
1970
2590
                        else add_v3_v3(accu_rcom, rpos[a]);
1971
2591
 
1972
2592
                }
1973
 
                if (!weight || !rweight){
 
2593
                if (!weight || !rweight) {
1974
2594
                        accu_weight = accu_rweight = list_size;
1975
2595
                }
1976
2596
 
1977
 
                mul_v3_fl(accu_com,1.0f/accu_weight);
1978
 
                mul_v3_fl(accu_rcom,1.0f/accu_rweight);
1979
 
                if (lloc) copy_v3_v3(lloc,accu_com);
1980
 
                if (rloc) copy_v3_v3(rloc,accu_rcom);
1981
 
                if (lrot || lscale){ /* caller does not want rot nor scale, strange but legal */
 
2597
                mul_v3_fl(accu_com, 1.0f / accu_weight);
 
2598
                mul_v3_fl(accu_rcom, 1.0f / accu_rweight);
 
2599
                if (lloc) copy_v3_v3(lloc, accu_com);
 
2600
                if (rloc) copy_v3_v3(rloc, accu_rcom);
 
2601
                if (lrot || lscale) { /* caller does not want rot nor scale, strange but legal */
1982
2602
                        /*so now do some reverse engeneering and see if we can split rotation from scale ->Polardecompose*/
1983
2603
                        /* build 'projection' matrix */
1984
 
                        float m[3][3],mr[3][3],q[3][3],qi[3][3];
1985
 
                        float va[3],vb[3],stunt[3];
1986
 
                        float odet,ndet;
1987
 
                        int i=0,imax=15;
 
2604
                        float m[3][3], mr[3][3], q[3][3], qi[3][3];
 
2605
                        float va[3], vb[3], stunt[3];
 
2606
                        float odet, ndet;
 
2607
                        int i = 0, imax = 15;
1988
2608
                        zero_m3(m);
1989
2609
                        zero_m3(mr);
1990
2610
 
1991
2611
                        /* build 'projection' matrix */
1992
 
                        for(a=0; a<list_size; a++){
1993
 
                                sub_v3_v3v3(va,rpos[a],accu_rcom);
 
2612
                        for (a = 0; a < list_size; a++) {
 
2613
                                sub_v3_v3v3(va, rpos[a], accu_rcom);
1994
2614
                                /* mul_v3_fl(va,bp->mass);  mass needs renormalzation here ?? */
1995
 
                                sub_v3_v3v3(vb,pos[a],accu_com);
 
2615
                                sub_v3_v3v3(vb, pos[a], accu_com);
1996
2616
                                /* mul_v3_fl(va,rp->mass); */
1997
2617
                                m[0][0] += va[0] * vb[0];
1998
2618
                                m[0][1] += va[0] * vb[1];
2006
2626
                                m[2][1] += va[2] * vb[1];
2007
2627
                                m[2][2] += va[2] * vb[2];
2008
2628
 
2009
 
                                /* building the referenc matrix on the fly
2010
 
                                needed to scale properly later*/
 
2629
                                /* building the reference matrix on the fly
 
2630
                                 * needed to scale properly later */
2011
2631
 
2012
2632
                                mr[0][0] += va[0] * va[0];
2013
2633
                                mr[0][1] += va[0] * va[1];
2021
2641
                                mr[2][1] += va[2] * va[1];
2022
2642
                                mr[2][2] += va[2] * va[2];
2023
2643
                        }
2024
 
                        copy_m3_m3(q,m);
2025
 
                        stunt[0] = q[0][0]; stunt[1] = q[1][1]; stunt[2] = q[2][2];
 
2644
                        copy_m3_m3(q, m);
 
2645
                        stunt[0] = q[0][0];
 
2646
                        stunt[1] = q[1][1];
 
2647
                        stunt[2] = q[2][2];
2026
2648
                        /* renormalizing for numeric stability */
2027
 
                        mul_m3_fl(q,1.f/len_v3(stunt)); 
 
2649
                        mul_m3_fl(q, 1.f / len_v3(stunt));
2028
2650
 
2029
2651
                        /* this is pretty much Polardecompose 'inline' the algo based on Higham's thesis */
2030
2652
                        /* without the far case ... but seems to work here pretty neat                   */
2031
2653
                        odet = 0.f;
2032
2654
                        ndet = _det_m3(q);
2033
 
                        while((odet-ndet)*(odet-ndet) > eps && i<imax){
2034
 
                                invert_m3_m3(qi,q);
 
2655
                        while ((odet - ndet) * (odet - ndet) > eps && i < imax) {
 
2656
                                invert_m3_m3(qi, q);
2035
2657
                                transpose_m3(qi);
2036
 
                                add_m3_m3m3(q,q,qi);
2037
 
                                mul_m3_fl(q,0.5f);
2038
 
                                odet =ndet;
2039
 
                                ndet =_det_m3(q);
 
2658
                                add_m3_m3m3(q, q, qi);
 
2659
                                mul_m3_fl(q, 0.5f);
 
2660
                                odet = ndet;
 
2661
                                ndet = _det_m3(q);
2040
2662
                                i++;
2041
2663
                        }
2042
2664
 
2043
 
                        if (i){
 
2665
                        if (i) {
2044
2666
                                float scale[3][3];
2045
2667
                                float irot[3][3];
2046
 
                                if(lrot) copy_m3_m3(lrot,q);
2047
 
                                invert_m3_m3(irot,q);
2048
 
                                invert_m3_m3(qi,mr);
2049
 
                                mul_m3_m3m3(q,m,qi); 
2050
 
                                mul_m3_m3m3(scale,irot,q); 
2051
 
                                if(lscale) copy_m3_m3(lscale,scale);
 
2668
                                if (lrot) copy_m3_m3(lrot, q);
 
2669
                                invert_m3_m3(irot, q);
 
2670
                                invert_m3_m3(qi, mr);
 
2671
                                mul_m3_m3m3(q, m, qi);
 
2672
                                mul_m3_m3m3(scale, irot, q);
 
2673
                                if (lscale) copy_m3_m3(lscale, scale);
2052
2674
 
2053
2675
                        }
2054
2676
                }
2057
2679
 
2058
2680
/******************************* Form Factor *********************************/
2059
2681
 
2060
 
static void vec_add_dir(float r[3], float v1[3], float v2[3], float fac)
 
2682
static void vec_add_dir(float r[3], const float v1[3], const float v2[3], const float fac)
2061
2683
{
2062
 
        r[0]= v1[0] + fac*(v2[0] - v1[0]);
2063
 
        r[1]= v1[1] + fac*(v2[1] - v1[1]);
2064
 
        r[2]= v1[2] + fac*(v2[2] - v1[2]);
 
2684
        r[0] = v1[0] + fac * (v2[0] - v1[0]);
 
2685
        r[1] = v1[1] + fac * (v2[1] - v1[1]);
 
2686
        r[2] = v1[2] + fac * (v2[2] - v1[2]);
2065
2687
}
2066
2688
 
2067
 
static int ff_visible_quad(float p[3], float n[3], float v0[3], float v1[3], float v2[3], float q0[3], float q1[3], float q2[3], float q3[3])
 
2689
static int ff_visible_quad(const float p[3], const float n[3],
 
2690
                           const float v0[3], const float v1[3], const float v2[3],
 
2691
                           float q0[3], float q1[3], float q2[3], float q3[3])
2068
2692
{
2069
2693
        static const float epsilon = 1e-6f;
2070
2694
        float c, sd[3];
2071
 
        
2072
 
        c= dot_v3v3(n, p);
 
2695
 
 
2696
        c = dot_v3v3(n, p);
2073
2697
 
2074
2698
        /* signed distances from the vertices to the plane. */
2075
 
        sd[0]= dot_v3v3(n, v0) - c;
2076
 
        sd[1]= dot_v3v3(n, v1) - c;
2077
 
        sd[2]= dot_v3v3(n, v2) - c;
2078
 
 
2079
 
        if(fabsf(sd[0]) < epsilon) sd[0] = 0.0f;
2080
 
        if(fabsf(sd[1]) < epsilon) sd[1] = 0.0f;
2081
 
        if(fabsf(sd[2]) < epsilon) sd[2] = 0.0f;
2082
 
 
2083
 
        if(sd[0] > 0) {
2084
 
                if(sd[1] > 0) {
2085
 
                        if(sd[2] > 0) {
 
2699
        sd[0] = dot_v3v3(n, v0) - c;
 
2700
        sd[1] = dot_v3v3(n, v1) - c;
 
2701
        sd[2] = dot_v3v3(n, v2) - c;
 
2702
 
 
2703
        if (fabsf(sd[0]) < epsilon) sd[0] = 0.0f;
 
2704
        if (fabsf(sd[1]) < epsilon) sd[1] = 0.0f;
 
2705
        if (fabsf(sd[2]) < epsilon) sd[2] = 0.0f;
 
2706
 
 
2707
        if (sd[0] > 0) {
 
2708
                if (sd[1] > 0) {
 
2709
                        if (sd[2] > 0) {
2086
2710
                                // +++
2087
2711
                                copy_v3_v3(q0, v0);
2088
2712
                                copy_v3_v3(q1, v1);
2089
2713
                                copy_v3_v3(q2, v2);
2090
2714
                                copy_v3_v3(q3, q2);
2091
2715
                        }
2092
 
                        else if(sd[2] < 0) {
 
2716
                        else if (sd[2] < 0) {
2093
2717
                                // ++-
2094
2718
                                copy_v3_v3(q0, v0);
2095
2719
                                copy_v3_v3(q1, v1);
2096
 
                                vec_add_dir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
2097
 
                                vec_add_dir(q3, v0, v2, (sd[0]/(sd[0]-sd[2])));
 
2720
                                vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
 
2721
                                vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2])));
2098
2722
                        }
2099
2723
                        else {
2100
2724
                                // ++0
2104
2728
                                copy_v3_v3(q3, q2);
2105
2729
                        }
2106
2730
                }
2107
 
                else if(sd[1] < 0) {
2108
 
                        if(sd[2] > 0) {
 
2731
                else if (sd[1] < 0) {
 
2732
                        if (sd[2] > 0) {
2109
2733
                                // +-+
2110
2734
                                copy_v3_v3(q0, v0);
2111
 
                                vec_add_dir(q1, v0, v1, (sd[0]/(sd[0]-sd[1])));
2112
 
                                vec_add_dir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
 
2735
                                vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
 
2736
                                vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
2113
2737
                                copy_v3_v3(q3, v2);
2114
2738
                        }
2115
 
                        else if(sd[2] < 0) {
 
2739
                        else if (sd[2] < 0) {
2116
2740
                                // +--
2117
2741
                                copy_v3_v3(q0, v0);
2118
 
                                vec_add_dir(q1, v0, v1, (sd[0]/(sd[0]-sd[1])));
2119
 
                                vec_add_dir(q2, v0, v2, (sd[0]/(sd[0]-sd[2])));
 
2742
                                vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
 
2743
                                vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2])));
2120
2744
                                copy_v3_v3(q3, q2);
2121
2745
                        }
2122
2746
                        else {
2123
2747
                                // +-0
2124
2748
                                copy_v3_v3(q0, v0);
2125
 
                                vec_add_dir(q1, v0, v1, (sd[0]/(sd[0]-sd[1])));
 
2749
                                vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
2126
2750
                                copy_v3_v3(q2, v2);
2127
2751
                                copy_v3_v3(q3, q2);
2128
2752
                        }
2129
2753
                }
2130
2754
                else {
2131
 
                        if(sd[2] > 0) {
 
2755
                        if (sd[2] > 0) {
2132
2756
                                // +0+
2133
2757
                                copy_v3_v3(q0, v0);
2134
2758
                                copy_v3_v3(q1, v1);
2135
2759
                                copy_v3_v3(q2, v2);
2136
2760
                                copy_v3_v3(q3, q2);
2137
2761
                        }
2138
 
                        else if(sd[2] < 0) {
 
2762
                        else if (sd[2] < 0) {
2139
2763
                                // +0-
2140
2764
                                copy_v3_v3(q0, v0);
2141
2765
                                copy_v3_v3(q1, v1);
2142
 
                                vec_add_dir(q2, v0, v2, (sd[0]/(sd[0]-sd[2])));
 
2766
                                vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2])));
2143
2767
                                copy_v3_v3(q3, q2);
2144
2768
                        }
2145
2769
                        else {
2151
2775
                        }
2152
2776
                }
2153
2777
        }
2154
 
        else if(sd[0] < 0) {
2155
 
                if(sd[1] > 0) {
2156
 
                        if(sd[2] > 0) {
 
2778
        else if (sd[0] < 0) {
 
2779
                if (sd[1] > 0) {
 
2780
                        if (sd[2] > 0) {
2157
2781
                                // -++
2158
 
                                vec_add_dir(q0, v0, v1, (sd[0]/(sd[0]-sd[1])));
 
2782
                                vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
2159
2783
                                copy_v3_v3(q1, v1);
2160
2784
                                copy_v3_v3(q2, v2);
2161
 
                                vec_add_dir(q3, v0, v2, (sd[0]/(sd[0]-sd[2])));
 
2785
                                vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2])));
2162
2786
                        }
2163
 
                        else if(sd[2] < 0) {
 
2787
                        else if (sd[2] < 0) {
2164
2788
                                // -+-
2165
 
                                vec_add_dir(q0, v0, v1, (sd[0]/(sd[0]-sd[1])));
 
2789
                                vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
2166
2790
                                copy_v3_v3(q1, v1);
2167
 
                                vec_add_dir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
 
2791
                                vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
2168
2792
                                copy_v3_v3(q3, q2);
2169
2793
                        }
2170
2794
                        else {
2171
2795
                                // -+0
2172
 
                                vec_add_dir(q0, v0, v1, (sd[0]/(sd[0]-sd[1])));
 
2796
                                vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
2173
2797
                                copy_v3_v3(q1, v1);
2174
2798
                                copy_v3_v3(q2, v2);
2175
2799
                                copy_v3_v3(q3, q2);
2176
2800
                        }
2177
2801
                }
2178
 
                else if(sd[1] < 0) {
2179
 
                        if(sd[2] > 0) {
 
2802
                else if (sd[1] < 0) {
 
2803
                        if (sd[2] > 0) {
2180
2804
                                // --+
2181
 
                                vec_add_dir(q0, v0, v2, (sd[0]/(sd[0]-sd[2])));
2182
 
                                vec_add_dir(q1, v1, v2, (sd[1]/(sd[1]-sd[2])));
 
2805
                                vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2])));
 
2806
                                vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2])));
2183
2807
                                copy_v3_v3(q2, v2);
2184
2808
                                copy_v3_v3(q3, q2);
2185
2809
                        }
2186
 
                        else if(sd[2] < 0) {
 
2810
                        else if (sd[2] < 0) {
2187
2811
                                // ---
2188
2812
                                return 0;
2189
2813
                        }
2193
2817
                        }
2194
2818
                }
2195
2819
                else {
2196
 
                        if(sd[2] > 0) {
 
2820
                        if (sd[2] > 0) {
2197
2821
                                // -0+
2198
 
                                vec_add_dir(q0, v0, v2, (sd[0]/(sd[0]-sd[2])));
 
2822
                                vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2])));
2199
2823
                                copy_v3_v3(q1, v1);
2200
2824
                                copy_v3_v3(q2, v2);
2201
2825
                                copy_v3_v3(q3, q2);
2202
2826
                        }
2203
 
                        else if(sd[2] < 0) {
 
2827
                        else if (sd[2] < 0) {
2204
2828
                                // -0-
2205
2829
                                return 0;
2206
2830
                        }
2211
2835
                }
2212
2836
        }
2213
2837
        else {
2214
 
                if(sd[1] > 0) {
2215
 
                        if(sd[2] > 0) {
 
2838
                if (sd[1] > 0) {
 
2839
                        if (sd[2] > 0) {
2216
2840
                                // 0++
2217
2841
                                copy_v3_v3(q0, v0);
2218
2842
                                copy_v3_v3(q1, v1);
2219
2843
                                copy_v3_v3(q2, v2);
2220
2844
                                copy_v3_v3(q3, q2);
2221
2845
                        }
2222
 
                        else if(sd[2] < 0) {
 
2846
                        else if (sd[2] < 0) {
2223
2847
                                // 0+-
2224
2848
                                copy_v3_v3(q0, v0);
2225
2849
                                copy_v3_v3(q1, v1);
2226
 
                                vec_add_dir(q2, v1, v2, (sd[1]/(sd[1]-sd[2])));
 
2850
                                vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
2227
2851
                                copy_v3_v3(q3, q2);
2228
2852
                        }
2229
2853
                        else {
2234
2858
                                copy_v3_v3(q3, q2);
2235
2859
                        }
2236
2860
                }
2237
 
                else if(sd[1] < 0) {
2238
 
                        if(sd[2] > 0) {
 
2861
                else if (sd[1] < 0) {
 
2862
                        if (sd[2] > 0) {
2239
2863
                                // 0-+
2240
2864
                                copy_v3_v3(q0, v0);
2241
 
                                vec_add_dir(q1, v1, v2, (sd[1]/(sd[1]-sd[2])));
 
2865
                                vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2])));
2242
2866
                                copy_v3_v3(q2, v2);
2243
2867
                                copy_v3_v3(q3, q2);
2244
2868
                        }
2245
 
                        else if(sd[2] < 0) {
 
2869
                        else if (sd[2] < 0) {
2246
2870
                                // 0--
2247
2871
                                return 0;
2248
2872
                        }
2252
2876
                        }
2253
2877
                }
2254
2878
                else {
2255
 
                        if(sd[2] > 0) {
 
2879
                        if (sd[2] > 0) {
2256
2880
                                // 00+
2257
2881
                                copy_v3_v3(q0, v0);
2258
2882
                                copy_v3_v3(q1, v1);
2259
2883
                                copy_v3_v3(q2, v2);
2260
2884
                                copy_v3_v3(q3, q2);
2261
2885
                        }
2262
 
                        else if(sd[2] < 0) {
 
2886
                        else if (sd[2] < 0) {
2263
2887
                                // 00-
2264
2888
                                return 0;
2265
2889
                        }
2285
2909
 
2286
2910
static vFloat vec_splat_float(float val)
2287
2911
{
2288
 
        return (vFloat){val, val, val, val};
 
2912
        return (vFloat) {val, val, val, val};
2289
2913
}
2290
2914
 
2291
2915
static float ff_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3)
2292
2916
{
2293
2917
        vFloat vcos, rlen, vrx, vry, vrz, vsrx, vsry, vsrz, gx, gy, gz, vangle;
2294
 
        vUInt8 rotate = (vUInt8){4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3};
 
2918
        vUInt8 rotate = (vUInt8) {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3};
2295
2919
        vFloatResult vresult;
2296
2920
        float result;
2297
2921
 
2298
2922
        /* compute r* */
2299
 
        vrx = (vFloat){q0[0], q1[0], q2[0], q3[0]} - vec_splat_float(p[0]);
2300
 
        vry = (vFloat){q0[1], q1[1], q2[1], q3[1]} - vec_splat_float(p[1]);
2301
 
        vrz = (vFloat){q0[2], q1[2], q2[2], q3[2]} - vec_splat_float(p[2]);
 
2923
        vrx = (vFloat) {q0[0], q1[0], q2[0], q3[0]} -vec_splat_float(p[0]);
 
2924
        vry = (vFloat) {q0[1], q1[1], q2[1], q3[1]} -vec_splat_float(p[1]);
 
2925
        vrz = (vFloat) {q0[2], q1[2], q2[2], q3[2]} -vec_splat_float(p[2]);
2302
2926
 
2303
2927
        /* normalize r* */
2304
 
        rlen = vec_rsqrte(vrx*vrx + vry*vry + vrz*vrz + vec_splat_float(1e-16f));
2305
 
        vrx = vrx*rlen;
2306
 
        vry = vry*rlen;
2307
 
        vrz = vrz*rlen;
 
2928
        rlen = vec_rsqrte(vrx * vrx + vry * vry + vrz * vrz + vec_splat_float(1e-16f));
 
2929
        vrx = vrx * rlen;
 
2930
        vry = vry * rlen;
 
2931
        vrz = vrz * rlen;
2308
2932
 
2309
2933
        /* rotate r* for cross and dot */
2310
 
        vsrx= vec_perm(vrx, vrx, rotate);
2311
 
        vsry= vec_perm(vry, vry, rotate);
2312
 
        vsrz= vec_perm(vrz, vrz, rotate);
 
2934
        vsrx = vec_perm(vrx, vrx, rotate);
 
2935
        vsry = vec_perm(vry, vry, rotate);
 
2936
        vsrz = vec_perm(vrz, vrz, rotate);
2313
2937
 
2314
2938
        /* cross product */
2315
 
        gx = vsry*vrz - vsrz*vry;
2316
 
        gy = vsrz*vrx - vsrx*vrz;
2317
 
        gz = vsrx*vry - vsry*vrx;
 
2939
        gx = vsry * vrz - vsrz * vry;
 
2940
        gy = vsrz * vrx - vsrx * vrz;
 
2941
        gz = vsrx * vry - vsry * vrx;
2318
2942
 
2319
2943
        /* normalize */
2320
 
        rlen = vec_rsqrte(gx*gx + gy*gy + gz*gz + vec_splat_float(1e-16f));
2321
 
        gx = gx*rlen;
2322
 
        gy = gy*rlen;
2323
 
        gz = gz*rlen;
 
2944
        rlen = vec_rsqrte(gx * gx + gy * gy + gz * gz + vec_splat_float(1e-16f));
 
2945
        gx = gx * rlen;
 
2946
        gy = gy * rlen;
 
2947
        gz = gz * rlen;
2324
2948
 
2325
2949
        /* angle */
2326
 
        vcos = vrx*vsrx + vry*vsry + vrz*vsrz;
2327
 
        vcos= vec_max(vec_min(vcos, vec_splat_float(1.0f)), vec_splat_float(-1.0f));
2328
 
        vangle= vacosf(vcos);
 
2950
        vcos = vrx * vsrx + vry * vsry + vrz * vsrz;
 
2951
        vcos = vec_max(vec_min(vcos, vec_splat_float(1.0f)), vec_splat_float(-1.0f));
 
2952
        vangle = vacosf(vcos);
2329
2953
 
2330
2954
        /* dot */
2331
 
        vresult.v = (vec_splat_float(n[0])*gx +
2332
 
                     vec_splat_float(n[1])*gy +
2333
 
                     vec_splat_float(n[2])*gz)*vangle;
 
2955
        vresult.v = (vec_splat_float(n[0]) * gx +
 
2956
                     vec_splat_float(n[1]) * gy +
 
2957
                     vec_splat_float(n[2]) * gz) * vangle;
2334
2958
 
2335
 
        result= (vresult.f[0] + vresult.f[1] + vresult.f[2] + vresult.f[3])*(0.5f/(float)M_PI);
2336
 
        result= MAX2(result, 0.0f);
 
2959
        result = (vresult.f[0] + vresult.f[1] + vresult.f[2] + vresult.f[3]) * (0.5f / (float)M_PI);
 
2960
        result = MAX2(result, 0.0f);
2337
2961
 
2338
2962
        return result;
2339
2963
}
2349
2973
static __m128 sse_approx_acos(__m128 x)
2350
2974
{
2351
2975
        /* needs a better approximation than taylor expansion of acos, since that
2352
 
         * gives big erros for near 1.0 values, sqrt(2*x)*acos(1-x) should work
 
2976
         * gives big erros for near 1.0 values, sqrt(2 * x) * acos(1 - x) should work
2353
2977
         * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */
2354
2978
 
2355
2979
        return _mm_set_ps1(1.0f);
2372
2996
        rz = qz - _mm_set_ps1(p[2]);
2373
2997
 
2374
2998
        /* normalize r */
2375
 
        rlen = _mm_rsqrt_ps(rx*rx + ry*ry + rz*rz + _mm_set_ps1(1e-16f));
2376
 
        rx = rx*rlen;
2377
 
        ry = ry*rlen;
2378
 
        rz = rz*rlen;
 
2999
        rlen = _mm_rsqrt_ps(rx * rx + ry * ry + rz * rz + _mm_set_ps1(1e-16f));
 
3000
        rx = rx * rlen;
 
3001
        ry = ry * rlen;
 
3002
        rz = rz * rlen;
2379
3003
 
2380
3004
        /* cross product */
2381
 
        srx = _mm_shuffle_ps(rx, rx, _MM_SHUFFLE(0,3,2,1));
2382
 
        sry = _mm_shuffle_ps(ry, ry, _MM_SHUFFLE(0,3,2,1));
2383
 
        srz = _mm_shuffle_ps(rz, rz, _MM_SHUFFLE(0,3,2,1));
 
3005
        srx = _mm_shuffle_ps(rx, rx, _MM_SHUFFLE(0, 3, 2, 1));
 
3006
        sry = _mm_shuffle_ps(ry, ry, _MM_SHUFFLE(0, 3, 2, 1));
 
3007
        srz = _mm_shuffle_ps(rz, rz, _MM_SHUFFLE(0, 3, 2, 1));
2384
3008
 
2385
 
        gx = sry*rz - srz*ry;
2386
 
        gy = srz*rx - srx*rz;
2387
 
        gz = srx*ry - sry*rx;
 
3009
        gx = sry * rz - srz * ry;
 
3010
        gy = srz * rx - srx * rz;
 
3011
        gz = srx * ry - sry * rx;
2388
3012
 
2389
3013
        /* normalize g */
2390
 
        glen = _mm_rsqrt_ps(gx*gx + gy*gy + gz*gz + _mm_set_ps1(1e-16f));
2391
 
        gx = gx*glen;
2392
 
        gy = gy*glen;
2393
 
        gz = gz*glen;
 
3014
        glen = _mm_rsqrt_ps(gx * gx + gy * gy + gz * gz + _mm_set_ps1(1e-16f));
 
3015
        gx = gx * glen;
 
3016
        gy = gy * glen;
 
3017
        gz = gz * glen;
2394
3018
 
2395
3019
        /* compute angle */
2396
 
        rcos = rx*srx + ry*sry + rz*srz;
2397
 
        rcos= _mm_max_ps(_mm_min_ps(rcos, _mm_set_ps1(1.0f)), _mm_set_ps1(-1.0f));
 
3020
        rcos = rx * srx + ry * sry + rz * srz;
 
3021
        rcos = _mm_max_ps(_mm_min_ps(rcos, _mm_set_ps1(1.0f)), _mm_set_ps1(-1.0f));
2398
3022
 
2399
3023
        angle = sse_approx_cos(rcos);
2400
 
        aresult = (_mm_set_ps1(n[0])*gx + _mm_set_ps1(n[1])*gy + _mm_set_ps1(n[2])*gz)*angle;
 
3024
        aresult = (_mm_set_ps1(n[0]) * gx + _mm_set_ps1(n[1]) * gy + _mm_set_ps1(n[2]) * gz) * angle;
2401
3025
 
2402
3026
        /* sum together */
2403
 
    result= (fresult[0] + fresult[1] + fresult[2] + fresult[3])*(0.5f/(float)M_PI);
2404
 
        result= MAX2(result, 0.0f);
 
3027
        result = (fresult[0] + fresult[1] + fresult[2] + fresult[3]) * (0.5f / (float)M_PI);
 
3028
        result = MAX2(result, 0.0f);
2405
3029
 
2406
3030
        return result;
2407
3031
}
2411
3035
static void ff_normalize(float n[3])
2412
3036
{
2413
3037
        float d;
2414
 
        
2415
 
        d= dot_v3v3(n, n);
2416
 
 
2417
 
        if(d > 1.0e-35F) {
2418
 
                d= 1.0f/sqrtf(d);
2419
 
 
2420
 
                n[0] *= d; 
2421
 
                n[1] *= d; 
 
3038
 
 
3039
        d = dot_v3v3(n, n);
 
3040
 
 
3041
        if (d > 1.0e-35F) {
 
3042
                d = 1.0f / sqrtf(d);
 
3043
 
 
3044
                n[0] *= d;
 
3045
                n[1] *= d;
2422
3046
                n[2] *= d;
2423
 
        } 
 
3047
        }
2424
3048
}
2425
3049
 
2426
 
static float ff_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3)
 
3050
static float ff_quad_form_factor(const float p[3], const float n[3],
 
3051
                                 const float q0[3], const float q1[3], const float q2[3], const float q3[3])
2427
3052
{
2428
3053
        float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3];
2429
3054
        float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result;
2438
3063
        ff_normalize(r2);
2439
3064
        ff_normalize(r3);
2440
3065
 
2441
 
        cross_v3_v3v3(g0, r1, r0); ff_normalize(g0);
2442
 
        cross_v3_v3v3(g1, r2, r1); ff_normalize(g1);
2443
 
        cross_v3_v3v3(g2, r3, r2); ff_normalize(g2);
2444
 
        cross_v3_v3v3(g3, r0, r3); ff_normalize(g3);
2445
 
 
2446
 
        a1= saacosf(dot_v3v3(r0, r1));
2447
 
        a2= saacosf(dot_v3v3(r1, r2));
2448
 
        a3= saacosf(dot_v3v3(r2, r3));
2449
 
        a4= saacosf(dot_v3v3(r3, r0));
2450
 
 
2451
 
        dot1= dot_v3v3(n, g0);
2452
 
        dot2= dot_v3v3(n, g1);
2453
 
        dot3= dot_v3v3(n, g2);
2454
 
        dot4= dot_v3v3(n, g3);
2455
 
 
2456
 
        result= (a1*dot1 + a2*dot2 + a3*dot3 + a4*dot4)*0.5f/(float)M_PI;
2457
 
        result= MAX2(result, 0.0f);
 
3066
        cross_v3_v3v3(g0, r1, r0);
 
3067
        ff_normalize(g0);
 
3068
        cross_v3_v3v3(g1, r2, r1);
 
3069
        ff_normalize(g1);
 
3070
        cross_v3_v3v3(g2, r3, r2);
 
3071
        ff_normalize(g2);
 
3072
        cross_v3_v3v3(g3, r0, r3);
 
3073
        ff_normalize(g3);
 
3074
 
 
3075
        a1 = saacosf(dot_v3v3(r0, r1));
 
3076
        a2 = saacosf(dot_v3v3(r1, r2));
 
3077
        a3 = saacosf(dot_v3v3(r2, r3));
 
3078
        a4 = saacosf(dot_v3v3(r3, r0));
 
3079
 
 
3080
        dot1 = dot_v3v3(n, g0);
 
3081
        dot2 = dot_v3v3(n, g1);
 
3082
        dot3 = dot_v3v3(n, g2);
 
3083
        dot4 = dot_v3v3(n, g3);
 
3084
 
 
3085
        result = (a1 * dot1 + a2 * dot2 + a3 * dot3 + a4 * dot4) * 0.5f / (float)M_PI;
 
3086
        result = MAX2(result, 0.0f);
2458
3087
 
2459
3088
        return result;
2460
3089
}
2462
3091
float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3])
2463
3092
{
2464
3093
        /* computes how much hemisphere defined by point and normal is
2465
 
           covered by a quad or triangle, cosine weighted */
2466
 
        float q0[3], q1[3], q2[3], q3[3], contrib= 0.0f;
 
3094
         * covered by a quad or triangle, cosine weighted */
 
3095
        float q0[3], q1[3], q2[3], q3[3], contrib = 0.0f;
2467
3096
 
2468
 
        if(ff_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3))
 
3097
        if (ff_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3))
2469
3098
                contrib += ff_quad_form_factor(p, n, q0, q1, q2, q3);
2470
 
        
2471
 
        if(v4 && ff_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3))
 
3099
 
 
3100
        if (v4 && ff_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3))
2472
3101
                contrib += ff_quad_form_factor(p, n, q0, q1, q2, q3);
2473
3102
 
2474
3103
        return contrib;
2475
3104
}
2476
3105
 
 
3106
/* evaluate if entire quad is a proper convex quad */
 
3107
int is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
 
3108
{
 
3109
        float nor[3], nor1[3], nor2[3], vec[4][2];
 
3110
        int axis_a, axis_b;
 
3111
 
 
3112
        /* define projection, do both trias apart, quad is undefined! */
 
3113
 
 
3114
        normal_tri_v3(nor1, v1, v2, v3);
 
3115
        normal_tri_v3(nor2, v1, v3, v4);
 
3116
 
 
3117
        /* when the face is folded over as 2 tris we probably don't want to create
 
3118
         * a quad from it, but go ahead with the intersection test since this
 
3119
         * isn't a function for degenerate faces */
 
3120
        if (UNLIKELY(dot_v3v3(nor1, nor2) < 0.0f)) {
 
3121
                /* flip so adding normals in the opposite direction
 
3122
                 * doesnt give a zero length vector */
 
3123
                negate_v3(nor2);
 
3124
        }
 
3125
 
 
3126
        add_v3_v3v3(nor, nor1, nor2);
 
3127
 
 
3128
        axis_dominant_v3(&axis_a, &axis_b, nor);
 
3129
 
 
3130
        vec[0][0] = v1[axis_a];
 
3131
        vec[0][1] = v1[axis_b];
 
3132
        vec[1][0] = v2[axis_a];
 
3133
        vec[1][1] = v2[axis_b];
 
3134
 
 
3135
        vec[2][0] = v3[axis_a];
 
3136
        vec[2][1] = v3[axis_b];
 
3137
        vec[3][0] = v4[axis_a];
 
3138
        vec[3][1] = v4[axis_b];
 
3139
 
 
3140
        /* linetests, the 2 diagonals have to instersect to be convex */
 
3141
        return (isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0) ? TRUE : FALSE;
 
3142
}