668 |
enum { NTrans = -1 }; |
enum { NTrans = -1 }; |
669 |
|
|
670 |
int ndice; |
int ndice; |
671 |
|
float dicelen; |
672 |
|
|
673 |
template<class F> void params(F &f) { |
template<class F> void params(F &f) { |
674 |
f(ndice); |
f(ndice, dicelen); |
675 |
} |
} |
676 |
|
|
677 |
template<class T> float crad(const T &t) const { |
template<class T> float crad(const T &t) const { |
684 |
StretchedCircleFillet f; |
StretchedCircleFillet f; |
685 |
ZVec dir; |
ZVec dir; |
686 |
|
|
687 |
|
float da; |
688 |
|
vector<float> rtbl; |
689 |
|
|
690 |
Conn(const CircularNode &node, |
Conn(const CircularNode &node, |
691 |
float d, |
float d, |
692 |
float th, |
float th, |
695 |
node(&node), |
node(&node), |
696 |
c(node, 0, d, th, -1, 0), |
c(node, 0, d, th, -1, 0), |
697 |
f(node, c, a), dir(dir) { |
f(node, c, a), dir(dir) { |
698 |
|
compute_rtbl(100); |
699 |
} |
} |
700 |
|
|
701 |
Vec trans(ZVec v) const { |
Vec trans(ZVec v) const { |
705 |
} |
} |
706 |
|
|
707 |
float rad(ZVec v, bool &success) const { |
float rad(ZVec v, bool &success) const { |
708 |
Vec t = trans(v).normalized(); |
Vec t = trans(v); |
709 |
|
if (rtbl.size()) { |
710 |
|
success = true; |
711 |
|
return rad_rtbl(t); |
712 |
|
} |
713 |
ZVec pt = f.point(t, success); |
ZVec pt = f.point(t, success); |
714 |
if (success) return pt.length(); |
if (success) return pt.length(); |
715 |
if (f.infillet(t)) { |
if (f.infillet(t)) { |
719 |
} |
} |
720 |
return node->r; |
return node->r; |
721 |
} |
} |
722 |
|
|
723 |
|
void compute_rtbl(int n) { |
724 |
|
rtbl.resize(n + 1); |
725 |
|
for (int i = 0; i < n; i++) { |
726 |
|
float t = i * (1.0 / n); |
727 |
|
float a = (t * t) * f.tangentAngle; |
728 |
|
bool success; |
729 |
|
float fract; |
730 |
|
ZVec pt = f.point(dirVec(a), success, &fract, .001); |
731 |
|
if (success) |
732 |
|
rtbl[i] = pt.length(); |
733 |
|
else |
734 |
|
rtbl[i] = c.d / cos(a); |
735 |
|
//cout << i << ": " << rtbl[i] << pt << fract << std::endl; |
736 |
|
} |
737 |
|
rtbl[n] = node->r; |
738 |
|
} |
739 |
|
|
740 |
|
float rad_rtbl(Vec v) const { |
741 |
|
int n = rtbl.size() - 1; |
742 |
|
float a = v.atan(); |
743 |
|
float t = sqrt(a / f.tangentAngle); |
744 |
|
unsigned i = (unsigned)(t * n); |
745 |
|
float fract = t * n - i; |
746 |
|
if (i >= n) return rtbl[n]; |
747 |
|
return (1 - fract) * rtbl[i] + fract * rtbl[i + 1]; |
748 |
|
} |
749 |
}; |
}; |
750 |
|
|
751 |
ZVec blend(Conn *conns[], int N, float r, ZVec pt) const { |
ZVec blend(Conn *conns[], int N, float r, ZVec pt) const { |
753 |
float sum = 0; |
float sum = 0; |
754 |
float x[N]; |
float x[N]; |
755 |
|
|
756 |
|
pt = pt.normalized(); |
757 |
|
|
758 |
// Compute distances from the node for each fillet surface |
// Compute distances from the node for each fillet surface |
759 |
for (i = 0; i < N; i++) { |
for (i = 0; i < N; i++) { |
760 |
bool success; |
bool success; |
761 |
float t = conns[i]->rad(pt, success); |
float t = conns[i]->rad(pt, success); |
762 |
if (success) |
if (success) |
763 |
sum += x[num++] = (t - r) / r; |
sum += x[num++] = t - r; |
764 |
} |
} |
765 |
|
|
766 |
// 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 |
767 |
// p == 1: sum of distances, |
// p == 1: sum of distances, |
768 |
// p == \infty: maximum of distances |
// p == \infty: maximum of distances |
769 |
float p = 1.0 + sum; |
float p = 1.0 + sum / r; |
770 |
|
|
771 |
sum = 0; |
sum = 0; |
772 |
for (i = 0; i < num; i++) |
for (i = 0; i < num; i++) |
773 |
sum += pow(x[i], p); |
sum += pow(x[i], p); |
774 |
|
|
775 |
return pt * (1 + pow(sum, 1 / p)); |
return pt * (r + pow(sum, 1 / p)); |
776 |
|
|
777 |
} |
} |
778 |
|
|
779 |
struct Vert : ZVec { |
struct Vert : ZVec { |
780 |
bool bound; |
int id; |
781 |
ZVec norm; |
ZVec norm; |
782 |
Vert(const ZVec &v, bool b = false) : ZVec(v), bound(b) {} |
Vert(const ZVec &v, int id = 0) : ZVec(v), id(id) {} |
783 |
}; |
}; |
784 |
|
|
785 |
struct Verts : std::vector<Vert> { |
struct Verts : std::vector<Vert> { |
787 |
Conn **conns; |
Conn **conns; |
788 |
int N; |
int N; |
789 |
float r; |
float r; |
790 |
|
bool noblend; |
791 |
|
|
792 |
int append(ZVec v, bool b = false) { |
int append(ZVec v, int id = 0) { |
793 |
int ind = size(); |
int ind = size(); |
794 |
if (b) |
if (id || noblend) |
795 |
push_back(Vert(v, b)); |
push_back(Vert(v, id)); |
796 |
else |
else |
797 |
push_back(f.blend(conns, N, r, v)); |
push_back(f.blend(conns, N, r, v)); |
798 |
|
|
800 |
} |
} |
801 |
|
|
802 |
int operator() (int i, int j, float fract = .5) { |
int operator() (int i, int j, float fract = .5) { |
803 |
int ind = size(); |
return append(lerp(operator[](i), operator[](j), fract)); |
|
push_back(f.blend(conns, N, r, |
|
|
lerp(operator[](i), operator[](j), fract))); |
|
|
return ind; |
|
804 |
} |
} |
805 |
|
|
806 |
Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) : |
Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) : |
807 |
f(f), conns(conns), N(N), r(r) {} |
f(f), conns(conns), N(N), r(r), noblend(false) {} |
808 |
}; |
}; |
809 |
|
|
810 |
struct DiceCrit { |
struct DiceCrit { |
814 |
DiceCrit(const Verts &v, float dicelen) : v(v), dicelen(dicelen) {} |
DiceCrit(const Verts &v, float dicelen) : v(v), dicelen(dicelen) {} |
815 |
|
|
816 |
int operator()(int i, int j, int k) { |
int operator()(int i, int j, int k) { |
817 |
float l0 = (v[i] - v[j]).length() * !(v[i].bound && v[j].bound); |
if (dicelen >= 1000) return -1; |
818 |
float l1 = (v[j] - v[k]).length() * !(v[j].bound && v[k].bound); |
|
819 |
float l2 = (v[k] - v[i]).length() * !(v[k].bound && v[i].bound); |
if (v[i].id && v[j].id && v[i].id != v[j].id) return 0; |
820 |
|
if (v[j].id && v[k].id && v[j].id != v[k].id) return 1; |
821 |
|
if (v[k].id && v[i].id && v[k].id != v[i].id) return 2; |
822 |
|
|
823 |
|
float l0 = (v[i] - v[j]).length() * !(v[i].id && v[i].id == v[j].id); |
824 |
|
float l1 = (v[j] - v[k]).length() * !(v[j].id && v[j].id == v[k].id); |
825 |
|
float l2 = (v[k] - v[i]).length() * !(v[k].id && v[k].id == v[i].id); |
826 |
|
|
827 |
if (l0 < dicelen && l1 < dicelen && l2 < dicelen) |
if (l0 < dicelen && l1 < dicelen && l2 < dicelen) |
828 |
return -1; |
return -1; |
846 |
} |
} |
847 |
|
|
848 |
i = k0; |
i = k0; |
849 |
do { |
while (1) { |
850 |
poly.push_back(i); |
poly.push_back(i); |
851 |
|
if (i == k1) break; |
852 |
if (++i == i1) i = i0; |
if (++i == i1) i = i0; |
853 |
} while (i != k1); |
} |
854 |
|
|
855 |
} |
} |
856 |
|
|
868 |
Conn* conns[N]; |
Conn* conns[N]; |
869 |
|
|
870 |
std::vector<ZVec> dirs; |
std::vector<ZVec> dirs; |
|
std::vector<int3> tri; |
|
|
|
|
871 |
int i, j; |
int i, j; |
872 |
|
|
873 |
for (i = 0; i < N; i++) { |
for (i = 0; i < N; i++) { |
874 |
const Transform &t1 = *t[3 + i]; |
const Transform &t1 = *t[3 + i]; |
875 |
ZVec p1 = t1.transform(0.5 * t1.getSqSize()); |
ZVec p1 = t1.transform(0.5 * t1.getSqSize()); |
883 |
dirs.push_back((p1 - p0).normalized()); |
dirs.push_back((p1 - p0).normalized()); |
884 |
} |
} |
885 |
|
|
886 |
|
#if 1 // Old version without Dicer |
887 |
|
|
888 |
|
ZVec pt[ndice + 1][ndice*2]; |
889 |
|
ZVec norm[ndice + 1][ndice*2]; |
890 |
|
|
891 |
|
for (i = 0; i <= ndice; i++) { |
892 |
|
float a = i * M_PI / ndice; |
893 |
|
float x = cos(a); |
894 |
|
float R = sin(a); |
895 |
|
|
896 |
|
for (j = 0; j < ndice*2; j++) { |
897 |
|
float b = j * M_PI * 2 / (ndice*2); |
898 |
|
|
899 |
|
float y = cos(b) * R; |
900 |
|
float z = sin(b) * R; |
901 |
|
|
902 |
|
pt[i][j] = r * ZVec(x, y, z); |
903 |
|
} |
904 |
|
} |
905 |
|
|
906 |
|
|
907 |
|
for (i = 0; i <= ndice; i++) |
908 |
|
for (j = 0; j < ndice*2; j++) |
909 |
|
pt[i][j] = blend(conns, N, r, pt[i][j]) + p0; |
910 |
|
|
911 |
|
|
912 |
|
for (i = 0; i <= ndice; i++) { |
913 |
|
for (j = 0; j < ndice*2; j++) { |
914 |
|
ZVec px0 = pt[i==0 ? 0 : i-1][j]; |
915 |
|
ZVec px1 = pt[i==ndice ? ndice : i+1][j]; |
916 |
|
ZVec py0 = pt[i][j==0 ? 0 : j-1]; |
917 |
|
ZVec py1 = pt[i][j==ndice*2-1 ? ndice*2-1 : j+1]; |
918 |
|
|
919 |
|
norm[i][j] = (px1 - px0).crossp(py1 - py0).normalized(); |
920 |
|
} |
921 |
|
} |
922 |
|
|
923 |
|
for (i = 0; i < ndice; i++) { |
924 |
|
glBegin(GL_QUAD_STRIP); |
925 |
|
for (j = 0; j < ndice*2-1; j++) { |
926 |
|
glNormal(norm[i][j]); |
927 |
|
glVertex(pt[i][j]); |
928 |
|
|
929 |
|
glNormal(norm[i+1][j]); |
930 |
|
glVertex(pt[i+1][j]); |
931 |
|
} |
932 |
|
glNormal(norm[i][0]); |
933 |
|
glVertex(pt[i][0]); |
934 |
|
|
935 |
|
glNormal(norm[i+1][0]); |
936 |
|
glVertex(pt[i+1][0]); |
937 |
|
glEnd(); |
938 |
|
} |
939 |
|
|
940 |
|
#else // use Dicer |
941 |
|
|
942 |
|
Verts verts(*this, conns, N, r); |
943 |
|
::Vob::Dicer::Triangles<Verts> triangler(verts); |
944 |
|
|
945 |
|
#if 0 // use Delaunay triangulation based topology |
946 |
|
|
947 |
if (dirs.size() == 2) { |
if (dirs.size() == 2) { |
948 |
ZVec sum = dirs[0] + dirs[1]; |
ZVec sum = dirs[0] + dirs[1]; |
949 |
ZVec dif = dirs[1] - dirs[0]; |
ZVec dif = dirs[1] - dirs[0]; |
954 |
dirs.push_back((v0 + v1).normalized()); |
dirs.push_back((v0 + v1).normalized()); |
955 |
} |
} |
956 |
|
|
957 |
|
std::vector<int3> tri; |
958 |
Triangulate(dirs, dirs.size(), tri); |
Triangulate(dirs, dirs.size(), tri); |
959 |
|
|
960 |
{ |
{ |
977 |
} |
} |
978 |
} |
} |
979 |
|
|
980 |
|
/* |
|
|
|
981 |
for (i = 0; i < (int)tri.size(); i++) { |
for (i = 0; i < (int)tri.size(); i++) { |
982 |
glBegin(GL_LINE_LOOP); |
glBegin(GL_LINE_LOOP); |
983 |
glVertex(p0 + 3 * r * dirs[tri[i][0]]); |
glVertex(p0 + 3 * r * dirs[tri[i][0]]); |
985 |
glVertex(p0 + 3 * r * dirs[tri[i][2]]); |
glVertex(p0 + 3 * r * dirs[tri[i][2]]); |
986 |
glEnd(); |
glEnd(); |
987 |
} |
} |
988 |
|
*/ |
989 |
|
|
990 |
// Add the vertices of the diced midsections of the connectors |
// Add the vertices of the diced midsections of the connectors |
|
Verts verts(*this, conns, N, r); |
|
991 |
for (i = 0; i < N; i++) { |
for (i = 0; i < N; i++) { |
992 |
float t = 0.5 * conns[i]->c.t; |
float t = 0.5 * conns[i]->c.t; |
993 |
float d = conns[i]->c.d; |
float d = conns[i]->c.d; |
994 |
|
|
995 |
|
ZVec ref = t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0)); |
996 |
ZVec e0 = conns[i]->dir; |
ZVec e0 = conns[i]->dir; |
997 |
ZVec e1 = e0.crossp(ZVec(0,0,1)); |
ZVec e1 = e0.crossp(ref).normalized(); |
998 |
ZVec e2 = e0.crossp(e1); |
ZVec e2 = e0.crossp(e1); |
999 |
|
|
1000 |
ZVec p0 = d * e0; |
ZVec p0 = d * e0; |
1001 |
|
|
1002 |
for (j = 0; j < ndice; j++) { |
for (j = 0; j < ndice; j++) { |
1003 |
float a = j * M_PI * 2 / ndice; |
float a = -j * M_PI * 2 / ndice; |
1004 |
verts.append(p0 + t * (e1 * cos(a) + e2 * sin(a)), true); |
verts.append(p0 + t * (e1 * cos(a) + e2 * sin(a)), i + 1); |
1005 |
} |
} |
1006 |
} |
} |
1007 |
|
|
1012 |
} |
} |
1013 |
|
|
1014 |
// Triangulate the surface |
// Triangulate the surface |
|
::Vob::Dicer::Triangles<Verts> triangler(verts); |
|
1015 |
for (i = 0; i < (int)tri.size(); i++) { |
for (i = 0; i < (int)tri.size(); i++) { |
1016 |
std::vector<int> poly; |
std::vector<int> poly; |
1017 |
for (j = 0; j < 3; j++) { |
for (j = 0; j < 3; j++) { |
1021 |
} else { |
} else { |
1022 |
int k0 = tri[i][(j+1)%3]; |
int k0 = tri[i][(j+1)%3]; |
1023 |
int k1 = tri[i][(j+2)%3]; |
int k1 = tri[i][(j+2)%3]; |
|
if ((dirs[k0] - dirs[k]).crossp(dirs[k1] - dirs[k]).dot(dirs[k]) < 0) |
|
|
k0 ^= k1 ^= k0 ^= k1; // Swap |
|
1024 |
|
|
1025 |
addSpan(poly, verts, ndice * k, ndice * (k + 1), dirs[k0], dirs[k1]); |
addSpan(poly, verts, ndice * k, ndice * (k + 1), dirs[k1], dirs[k0]); |
1026 |
} |
} |
1027 |
} |
} |
1028 |
|
|
1029 |
// Triangulate as a star polygon |
// Triangulate as a star polygon |
1030 |
ZVec sum(0,0,0); |
ZVec sum(0,0,0); |
1031 |
for (j = 0; j < (int)poly.size(); j++) |
for (j = 0; j < (int)poly.size(); j++) |
1032 |
sum += verts[poly[j]]; |
sum += verts[poly[j]].normalized(); |
1033 |
|
|
1034 |
|
int nvert = verts.append(dirs[tri[i][0]] + |
1035 |
|
dirs[tri[i][1]] + |
1036 |
|
dirs[tri[i][2]]); |
1037 |
|
|
|
int nvert = verts.append(sum); |
|
1038 |
for (j = 0; j < (int)poly.size(); j++) |
for (j = 0; j < (int)poly.size(); j++) |
1039 |
triangler.add(nvert, poly[j], poly[(j+1) % poly.size()]); |
triangler.add(nvert, poly[j], poly[(j+1) % poly.size()]); |
1040 |
} |
} |
|
|
|
|
|
|
|
|
|
|
ZVec pt[ndice + 1][ndice*2]; |
|
|
ZVec norm[ndice + 1][ndice*2]; |
|
|
|
|
|
for (i = 0; i <= ndice; i++) { |
|
|
float a = i * M_PI / ndice; |
|
|
float x = cos(a); |
|
|
float R = sin(a); |
|
|
|
|
|
for (j = 0; j < ndice*2; j++) { |
|
|
float b = j * M_PI * 2 / (ndice*2); |
|
1041 |
|
|
1042 |
float y = cos(b) * R; |
#else // Icosahedron topology |
|
float z = sin(b) * R; |
|
1043 |
|
|
1044 |
pt[i][j] = r * ZVec(x, y, z); |
// icosahedron code adapted from sphere.c found in |
1045 |
} |
// http://www.sgi.com/Technology/openGL/advanced/programs.html |
|
} |
|
1046 |
|
|
1047 |
|
/* for icosahedron */ |
1048 |
|
#define CZ_ (0.89442719099991) /* 2/sqrt(5) */ |
1049 |
|
#define SZ_ (0.44721359549995) /* 1/sqrt(5) */ |
1050 |
|
#define C1_ (0.951056516) /* cos(18), */ |
1051 |
|
#define S1_ (0.309016994) /* sin(18) */ |
1052 |
|
#define C2_ (0.587785252) /* cos(54), */ |
1053 |
|
#define S2_ (0.809016994) /* sin(54) */ |
1054 |
|
#define X1_ (C1_*CZ_) |
1055 |
|
#define Y1_ (S1_*CZ_) |
1056 |
|
#define X2_ (C2_*CZ_) |
1057 |
|
#define Y2_ (S2_*CZ_) |
1058 |
|
|
1059 |
|
verts.noblend = true; |
1060 |
|
int Ip0 = verts.append(ZVec( 0., 0., 1.)); |
1061 |
|
int Ip1 = verts.append(ZVec(-X2_, -Y2_, SZ_)); |
1062 |
|
int Ip2 = verts.append(ZVec( X2_, -Y2_, SZ_)); |
1063 |
|
int Ip3 = verts.append(ZVec( X1_, Y1_, SZ_)); |
1064 |
|
int Ip4 = verts.append(ZVec( 0, CZ_, SZ_)); |
1065 |
|
int Ip5 = verts.append(ZVec(-X1_, Y1_, SZ_)); |
1066 |
|
|
1067 |
|
int Im0 = verts.append(ZVec(-X1_, -Y1_, -SZ_)); |
1068 |
|
int Im1 = verts.append(ZVec( 0, -CZ_, -SZ_)); |
1069 |
|
int Im2 = verts.append(ZVec( X1_, -Y1_, -SZ_)); |
1070 |
|
int Im3 = verts.append(ZVec( X2_, Y2_, -SZ_)); |
1071 |
|
int Im4 = verts.append(ZVec(-X2_, Y2_, -SZ_)); |
1072 |
|
int Im5 = verts.append(ZVec( 0., 0., -1.)); |
1073 |
|
|
1074 |
|
/* front pole */ |
1075 |
|
triangler.add(Ip0, Ip1, Ip2); |
1076 |
|
triangler.add(Ip0, Ip5, Ip1); |
1077 |
|
triangler.add(Ip0, Ip4, Ip5); |
1078 |
|
triangler.add(Ip0, Ip3, Ip4); |
1079 |
|
triangler.add(Ip0, Ip2, Ip3); |
1080 |
|
|
1081 |
|
/* mid */ |
1082 |
|
triangler.add(Ip1, Im0, Im1); |
1083 |
|
triangler.add(Im0, Ip1, Ip5); |
1084 |
|
triangler.add(Ip5, Im4, Im0); |
1085 |
|
triangler.add(Im4, Ip5, Ip4); |
1086 |
|
triangler.add(Ip4, Im3, Im4); |
1087 |
|
triangler.add(Im3, Ip4, Ip3); |
1088 |
|
triangler.add(Ip3, Im2, Im3); |
1089 |
|
triangler.add(Im2, Ip3, Ip2); |
1090 |
|
triangler.add(Ip2, Im1, Im2); |
1091 |
|
triangler.add(Im1, Ip2, Ip1); |
1092 |
|
|
1093 |
|
/* back pole */ |
1094 |
|
triangler.add(Im3, Im2, Im5); |
1095 |
|
triangler.add(Im4, Im3, Im5); |
1096 |
|
triangler.add(Im0, Im4, Im5); |
1097 |
|
triangler.add(Im1, Im0, Im5); |
1098 |
|
triangler.add(Im2, Im1, Im5); |
1099 |
|
|
1100 |
for (i = 0; i <= ndice; i++) |
#endif |
1101 |
for (j = 0; j < ndice*2; j++) |
|
|
pt[i][j] = blend(conns, N, r, pt[i][j]) + p0; |
|
1102 |
|
|
1103 |
|
triangler.dice(DiceCrit(verts, verts.noblend ? .01 * dicelen : dicelen)); |
|
for (i = 0; i <= ndice; i++) { |
|
|
for (j = 0; j < ndice*2; j++) { |
|
|
ZVec px0 = pt[i==0 ? 0 : i-1][j]; |
|
|
ZVec px1 = pt[i==ndice ? ndice : i+1][j]; |
|
|
ZVec py0 = pt[i][j==0 ? 0 : j-1]; |
|
|
ZVec py1 = pt[i][j==ndice*2-1 ? ndice*2-1 : j+1]; |
|
1104 |
|
|
1105 |
norm[i][j] = (px1 - px0).crossp(py1 - py0).normalized(); |
if (verts.noblend) { |
1106 |
} |
ZVec e0 = (t0.transform(ZVec(1,0,0)) - t0.transform(ZVec(0,0,0))); |
1107 |
|
ZVec e1 = (t0.transform(ZVec(0,1,0)) - t0.transform(ZVec(0,0,0))); |
1108 |
|
ZVec e2 = (t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0))); |
1109 |
|
for (i = 0; i < (int)verts.size(); i++) |
1110 |
|
verts[i] = blend(conns, N, r, |
1111 |
|
e0 * verts[i].x + e1 * verts[i].y + e2 * verts[i].z); |
1112 |
|
} |
1113 |
|
|
1114 |
|
// Compute normals |
1115 |
|
for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin(); |
1116 |
|
x != triangler.tris.end(); x++) { |
1117 |
|
ZVec v0 = verts[x->v[1]] - verts[x->v[0]]; |
1118 |
|
ZVec v1 = verts[x->v[2]] - verts[x->v[1]]; |
1119 |
|
ZVec norm = v0.crossp(v1).normalized(); |
1120 |
|
verts[x->v[0]].norm += norm; |
1121 |
|
verts[x->v[1]].norm += norm; |
1122 |
|
verts[x->v[2]].norm += norm; |
1123 |
} |
} |
1124 |
|
|
1125 |
for (i = 0; i < ndice; i++) { |
for (i = 0; i < (int)verts.size(); i++) |
1126 |
glBegin(GL_QUAD_STRIP); |
verts[i] += p0; |
1127 |
for (j = 0; j < ndice*2-1; j++) { |
|
1128 |
glNormal(norm[i][j]); |
glBegin(GL_TRIANGLES); |
1129 |
glVertex(pt[i][j]); |
for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin(); |
1130 |
|
x != triangler.tris.end(); x++) { |
1131 |
glNormal(norm[i+1][j]); |
glNormal(verts[x->v[0]].norm); |
1132 |
glVertex(pt[i+1][j]); |
glVertex(verts[x->v[0]]); |
1133 |
} |
glNormal(verts[x->v[1]].norm); |
1134 |
glNormal(norm[i][0]); |
glVertex(verts[x->v[1]]); |
1135 |
glVertex(pt[i][0]); |
glNormal(verts[x->v[2]].norm); |
1136 |
|
glVertex(verts[x->v[2]]); |
|
glNormal(norm[i+1][0]); |
|
|
glVertex(pt[i+1][0]); |
|
|
glEnd(); |
|
1137 |
} |
} |
1138 |
|
glEnd(); |
1139 |
|
|
1140 |
|
#endif // use Dicer |
1141 |
|
|
1142 |
for (i = 0; i < N; i++) { |
for (i = 0; i < N; i++) { |
1143 |
delete conns[i]; |
delete conns[i]; |