forked from JTippetts/U3DTerrainEditor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpline.cpp
139 lines (111 loc) · 3.87 KB
/
Spline.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "Spline.h"
void BuildQuadStripA(Vector<Vector3> &points, Vector<Vector3> &out, float width, Vector3 up)
{
out.Clear();
if(points.Size()<2) return; // Need at least 2 points
// Push end quad and first quad
Vector3 p0=points[0];
Vector3 p1=points[1];
Vector3 forward=p1-p0;
Vector3 forwardnorm=forward;
forwardnorm.Normalize();
Vector3 right=forward.CrossProduct(up);
Vector3 rightnorm=right;
rightnorm.Normalize();
// First, push 2 verts behind start point
Vector3 pf=p0-forwardnorm*width*0.5f;
out.Push(pf+rightnorm*width*0.5f);
out.Push(pf-rightnorm*width*0.5f);
// Now, push first quad
out.Push(p0+rightnorm*width*0.5f);
out.Push(p0-rightnorm*width*0.5f);
out.Push(p1+rightnorm*width*0.5f);
out.Push(p1-rightnorm*width*0.5f);
for(int c=1; c<points.Size()-1; ++c)
{
// Generate first set of points in quad.
p0=points[c];
p1=points[c+1];
forward=p1-p0;
right=forward.CrossProduct(up);
rightnorm=right;
rightnorm.Normalize();
Vector3 rp0=p0+rightnorm*width*0.5f;
Vector3 lp0=p0-rightnorm*width*0.5f;
// Average the previous points and the new points.
Vector3 avgr=(rp0 + out[out.Size()-2]) * 0.5f;
Vector3 avgl=(lp0 + out[out.Size()-1]) * 0.5f;
// Push the averages out to length
Vector3 ra=avgr-p0;
Vector3 la=avgl-p0;
ra.Normalize();
la.Normalize();
out[out.Size()-2]=p0+ra*width*0.5f;
out[out.Size()-1]=p0+la*width*0.5f;
// Now push second set of points
out.Push(p1+rightnorm*width*0.5f);
out.Push(p1-rightnorm*width*0.5f);
}
// Push two verts beyond end point
forwardnorm=forward;
forwardnorm.Normalize();
pf=p1+forwardnorm*width*0.5f;
out.Push(pf+rightnorm*width*0.5f);
out.Push(pf-rightnorm*width*0.5f);
}
void BuildQuadStripVaryingA(Vector<Vector3> &points, Vector<Vector3> &out, float swidth, float ewidth, Vector3 up)
{
out.Clear();
if(points.Size()<2) return; // Need at least 2 points
// Push end quad and first quad
Vector3 p0=points[0];
Vector3 p1=points[1];
Vector3 forward=p1-p0;
Vector3 forwardnorm=forward;
forwardnorm.Normalize();
Vector3 right=forward.CrossProduct(up);
Vector3 rightnorm=right;
rightnorm.Normalize();
// First, push 2 verts behind start point
Vector3 pf=p0-forwardnorm*swidth*0.5f;
out.Push(pf+rightnorm*swidth*0.5f);
out.Push(pf-rightnorm*swidth*0.5f);
// Now, push first quad
out.Push(p0+rightnorm*swidth*0.5f);
out.Push(p0-rightnorm*swidth*0.5f);
out.Push(p1+rightnorm*swidth*0.5f);
out.Push(p1-rightnorm*swidth*0.5f);
for(int c=1; c<points.Size()-1; ++c)
{
// Generate first set of points in quad.
float wt=(float)c / (float)points.Size();
float width=swidth + wt*(ewidth-swidth);
p0=points[c];
p1=points[c+1];
forward=p1-p0;
right=forward.CrossProduct(up);
rightnorm=right;
rightnorm.Normalize();
Vector3 rp0=p0+rightnorm*width*0.5f;
Vector3 lp0=p0-rightnorm*width*0.5f;
// Average the previous points and the new points.
Vector3 avgr=(rp0 + out[out.Size()-2]) * 0.5f;
Vector3 avgl=(lp0 + out[out.Size()-1]) * 0.5f;
// Push the averages out to length
Vector3 ra=avgr-p0;
Vector3 la=avgl-p0;
ra.Normalize();
la.Normalize();
out[out.Size()-2]=p0+ra*width*0.5f;
out[out.Size()-1]=p0+la*width*0.5f;
// Now push second set of points
out.Push(p1+rightnorm*width*0.5f);
out.Push(p1-rightnorm*width*0.5f);
}
// Push two verts beyond end point
forwardnorm=forward;
forwardnorm.Normalize();
pf=p1+forwardnorm*ewidth*0.5f;
out.Push(pf+rightnorm*ewidth*0.5f);
out.Push(pf-rightnorm*ewidth*0.5f);
}