725 |
} |
} |
726 |
|
|
727 |
// Compute p for an l^p norm to be used as the blending function |
// Compute p for an l^p norm to be used as the blending function |
728 |
// p == 1: sum of distance, |
// p == 1: sum of distances, |
729 |
// p == \infty: maximum of distances |
// p == \infty: maximum of distances |
730 |
float p = 1.0 + sum; |
float p = 1.0 + sum; |
731 |
|
|
737 |
|
|
738 |
} |
} |
739 |
|
|
740 |
|
struct Vert : ZVec { |
741 |
|
bool bound; |
742 |
|
ZVec norm; |
743 |
|
Vert(const ZVec &v, bool b = false) : ZVec(v), bound(b) {} |
744 |
|
}; |
745 |
|
|
746 |
|
struct Verts : std::vector<Vert> { |
747 |
|
const Fillet3DBlend &f; |
748 |
|
Conn **conns; |
749 |
|
int N; |
750 |
|
float r; |
751 |
|
|
752 |
|
int operator() (int i, int j, float fract = .5) { |
753 |
|
int ind = size(); |
754 |
|
push_back(f.blend(conns, N, r, |
755 |
|
lerp(operator[](i), operator[](j), fract))); |
756 |
|
return ind; |
757 |
|
} |
758 |
|
|
759 |
|
Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) : |
760 |
|
f(f), conns(conns), N(N), r(r) {} |
761 |
|
}; |
762 |
|
|
763 |
|
struct DiceCrit { |
764 |
|
const Verts &v; |
765 |
|
float dicelen; |
766 |
|
|
767 |
|
DiceCrit(const Verts &v, float dicelen) : v(v), dicelen(dicelen) {} |
768 |
|
|
769 |
|
int operator()(int i, int j, int k) { |
770 |
|
float l0 = (v[i] - v[j]).length() * !(v[i].bound && v[j].bound); |
771 |
|
float l1 = (v[j] - v[k]).length() * !(v[j].bound && v[k].bound); |
772 |
|
float l2 = (v[k] - v[i]).length() * !(v[k].bound && v[i].bound); |
773 |
|
|
774 |
|
if (l0 < dicelen && l1 < dicelen && l2 < dicelen) |
775 |
|
return -1; |
776 |
|
|
777 |
|
if(l0 > l1 && l0 > l2) return 0; |
778 |
|
if(l1 > l2) return 1; |
779 |
|
return 2; |
780 |
|
} |
781 |
|
}; |
782 |
|
|
783 |
|
|
784 |
|
|
785 |
|
|
786 |
void render(const Transform **t, int n) const { |
void render(const Transform **t, int n) const { |
787 |
const Transform &thick_t = *t[0]; |
const Transform &thick_t = *t[0]; |
788 |
const Transform &angle_t = *t[1]; |
const Transform &angle_t = *t[1]; |
796 |
|
|
797 |
Conn* conns[N]; |
Conn* conns[N]; |
798 |
|
|
799 |
|
std::vector<ZVec> dirs; |
800 |
|
std::vector<int3> tri; |
801 |
|
|
802 |
int i, j; |
int i, j; |
803 |
for (i = 0; i < N; i++) { |
for (i = 0; i < N; i++) { |
804 |
const Transform &t1 = *t[3 + i]; |
const Transform &t1 = *t[3 + i]; |
809 |
|
|
810 |
conns[i] = new Conn(node, d, conn.th, conn.a, |
conns[i] = new Conn(node, d, conn.th, conn.a, |
811 |
(p1 - p0).normalized()); |
(p1 - p0).normalized()); |
812 |
|
|
813 |
|
dirs.push_back((p1 - p0).normalized()); |
814 |
|
} |
815 |
|
|
816 |
|
if (dirs.size() == 2) { |
817 |
|
ZVec sum = dirs[0] + dirs[1]; |
818 |
|
ZVec dif = dirs[1] - dirs[0]; |
819 |
|
|
820 |
|
ZVec v0 = -sum.normalized(); |
821 |
|
ZVec v1 = sum.crossp(dif).normalized(); |
822 |
|
dirs.push_back((v0 - v1).normalized()); |
823 |
|
dirs.push_back((v0 + v1).normalized()); |
824 |
|
} |
825 |
|
|
826 |
|
Triangulate(dirs, dirs.size(), tri); |
827 |
|
|
828 |
|
{ |
829 |
|
int edge[dirs.size() * dirs.size()]; |
830 |
|
int vert[dirs.size()]; |
831 |
|
FindEdges(edge, dirs.size(), tri); |
832 |
|
FindEdgeVertices(vert, edge, dirs.size()); |
833 |
|
ZVec sum(0,0,0); |
834 |
|
bool incomplete = false; |
835 |
|
for (i = 0; i < (int)dirs.size(); i++) { |
836 |
|
if (vert[i]) { |
837 |
|
sum += dirs[i]; |
838 |
|
incomplete = true; |
839 |
|
} |
840 |
|
} |
841 |
|
if (incomplete) { |
842 |
|
dirs.push_back(-sum.normalized()); |
843 |
|
tri.clear(); |
844 |
|
Triangulate(dirs, dirs.size(), tri); |
845 |
|
} |
846 |
|
} |
847 |
|
|
848 |
|
|
849 |
|
|
850 |
|
for (i = 0; i < (int)tri.size(); i++) { |
851 |
|
glBegin(GL_LINE_LOOP); |
852 |
|
glVertex(p0 + 3 * r * dirs[tri[i][0]]); |
853 |
|
glVertex(p0 + 3 * r * dirs[tri[i][1]]); |
854 |
|
glVertex(p0 + 3 * r * dirs[tri[i][2]]); |
855 |
|
glEnd(); |
856 |
} |
} |
857 |
|
|
858 |
|
|