|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "maths.h" |
|
|
|
|
|
#include <vector> |
|
|
|
|
|
void Extrude(const Vec3* points, int numPoints, std::vector<Vec3>& vertices, std::vector<Vec3>& normals, std::vector<int>& triangles, float radius, int resolution, int smoothing) |
|
|
{ |
|
|
if (numPoints < 2) |
|
|
return; |
|
|
|
|
|
Vec3 u, v; |
|
|
Vec3 w = SafeNormalize(Vec3(points[1]) - Vec3(points[0]), Vec3(0.0f, 1.0f, 0.0f)); |
|
|
|
|
|
BasisFromVector(w, &u, &v); |
|
|
|
|
|
Matrix44 frame; |
|
|
frame.SetCol(0, Vec4(u.x, u.y, u.z, 0.0f)); |
|
|
frame.SetCol(1, Vec4(v.x, v.y, v.z, 0.0f)); |
|
|
frame.SetCol(2, Vec4(w.x, w.y, w.z, 0.0f)); |
|
|
frame.SetCol(3, Vec4(0.0f, 0.0f, 0.0f, 1.0f)); |
|
|
|
|
|
for (int i = 0; i < numPoints - 1; ++i) |
|
|
{ |
|
|
Vec3 next; |
|
|
|
|
|
if (i < numPoints - 1) |
|
|
next = Normalize(Vec3(points[i + 1]) - Vec3(points[i - 1])); |
|
|
else |
|
|
next = Normalize(Vec3(points[i]) - Vec3(points[i - 1])); |
|
|
|
|
|
int a = Max(i - 1, 0); |
|
|
int b = i; |
|
|
int c = Min(i + 1, numPoints - 1); |
|
|
int d = Min(i + 2, numPoints - 1); |
|
|
|
|
|
Vec3 p1 = Vec3(points[b]); |
|
|
Vec3 p2 = Vec3(points[c]); |
|
|
Vec3 m1 = 0.5f*(Vec3(points[c]) - Vec3(points[a])); |
|
|
Vec3 m2 = 0.5f*(Vec3(points[d]) - Vec3(points[b])); |
|
|
|
|
|
|
|
|
int segments = (i < numPoints - 2) ? smoothing : smoothing + 1; |
|
|
|
|
|
for (int s = 0; s < segments; ++s) |
|
|
{ |
|
|
Vec3 pos = HermiteInterpolate(p1, p2, m1, m2, s / float(smoothing)); |
|
|
Vec3 dir = Normalize(HermiteTangent(p1, p2, m1, m2, s / float(smoothing))); |
|
|
|
|
|
Vec3 cur = frame.GetAxis(2); |
|
|
const float angle = acosf(Dot(cur, dir)); |
|
|
|
|
|
|
|
|
if (fabsf(angle) > 0.001f) |
|
|
frame = RotationMatrix(angle, SafeNormalize(Cross(cur, dir)))*frame; |
|
|
|
|
|
size_t startIndex = vertices.size(); |
|
|
|
|
|
for (int c = 0; c < resolution; ++c) |
|
|
{ |
|
|
float angle = k2Pi / resolution; |
|
|
|
|
|
|
|
|
Vec4 v = frame*Vec4(cosf(angle*c), sinf(angle*c), 0.0f, 0.0f); |
|
|
|
|
|
vertices.push_back(Vec3(v)*radius + pos); |
|
|
normals.push_back(Vec3(v)); |
|
|
} |
|
|
|
|
|
|
|
|
if (startIndex != 0) |
|
|
{ |
|
|
for (int i = 0; i < resolution; ++i) |
|
|
{ |
|
|
int curIndex = static_cast<int>(startIndex + i); |
|
|
int nextIndex = static_cast<int>(startIndex + (i + 1) % resolution); |
|
|
|
|
|
triangles.push_back(curIndex); |
|
|
triangles.push_back(curIndex - resolution); |
|
|
triangles.push_back(nextIndex - resolution); |
|
|
|
|
|
triangles.push_back(nextIndex - resolution); |
|
|
triangles.push_back(nextIndex); |
|
|
triangles.push_back(curIndex); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|