697 |
for (i = 0; i < N; i++) { |
for (i = 0; i < N; i++) { |
698 |
bool success; |
bool success; |
699 |
float t = conns[i]->rad(pt, success); |
float t = conns[i]->rad(pt, success); |
700 |
|
if (t < r) t = r; |
701 |
if (success) { |
if (success) { |
702 |
//cout << t << " "; |
//cout << t << " "; |
703 |
sum += x[num++] = (t - r) / r; |
sum += x[num++] = (t - r) / r; |
726 |
|
|
727 |
} |
} |
728 |
|
|
729 |
struct Vert : ZVec { |
struct Vert { |
|
int id; |
|
730 |
ZVec norm; |
ZVec norm; |
731 |
Vert(const ZVec &v, int id = 0) : ZVec(v), id(id) {} |
ZVec vert; |
732 |
|
int id; |
733 |
|
Vert(const ZVec &v, int id = 0) : vert(v), id(id) {} |
734 |
}; |
}; |
735 |
|
|
736 |
struct Verts : std::vector<Vert> { |
struct Verts : std::vector<Vert> { |
740 |
float r; |
float r; |
741 |
bool noblend; |
bool noblend; |
742 |
|
|
743 |
int append(ZVec v, int id = 0) { |
int append(const ZVec &v, int id = 0) { |
744 |
int ind = size(); |
int ind = size(); |
745 |
if (id || noblend) |
if (id || noblend) |
746 |
push_back(Vert(v, id)); |
push_back(Vert(v, id)); |
751 |
} |
} |
752 |
|
|
753 |
int operator() (int i, int j, float fract = .5) { |
int operator() (int i, int j, float fract = .5) { |
754 |
return append(lerp(operator[](i), operator[](j), fract)); |
return append(lerp((*this)[i].vert, (*this)[j].vert, fract)); |
755 |
} |
} |
756 |
|
|
757 |
Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) : |
Verts(const Fillet3DBlend &f, Conn **conns, int N, float r) : |
758 |
f(f), conns(conns), N(N), r(r), noblend(false) {} |
f(f), conns(conns), N(N), r(r), noblend(false) {} |
759 |
|
|
760 |
|
void startN3V3Operation() { |
761 |
|
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); |
762 |
|
glInterleavedArrays(GL_N3F_V3F, sizeof(Vert), &(operator[](0))); |
763 |
|
glLockArraysEXT(0, size()); |
764 |
|
} |
765 |
|
void endN3V3Operation() { |
766 |
|
glUnlockArraysEXT(); |
767 |
|
glPopClientAttrib(); |
768 |
|
} |
769 |
|
|
770 |
}; |
}; |
771 |
|
|
772 |
struct DiceCrit { |
struct DiceCrit { |
782 |
if (v[j].id && v[k].id && v[j].id != v[k].id) return 1; |
if (v[j].id && v[k].id && v[j].id != v[k].id) return 1; |
783 |
if (v[k].id && v[i].id && v[k].id != v[i].id) return 2; |
if (v[k].id && v[i].id && v[k].id != v[i].id) return 2; |
784 |
|
|
785 |
float l0 = (v[i] - v[j]).length() * !(v[i].id && v[i].id == v[j].id); |
float l0 = (v[i].vert - v[j].vert).length() * !(v[i].id && v[i].id == v[j].id); |
786 |
float l1 = (v[j] - v[k]).length() * !(v[j].id && v[j].id == v[k].id); |
float l1 = (v[j].vert - v[k].vert).length() * !(v[j].id && v[j].id == v[k].id); |
787 |
float l2 = (v[k] - v[i]).length() * !(v[k].id && v[k].id == v[i].id); |
float l2 = (v[k].vert - v[i].vert).length() * !(v[k].id && v[k].id == v[i].id); |
788 |
|
|
789 |
if (!(l0 < 1000 && l1 < 1000 && l2 < 1000)) |
if (!(l0 < 1000 && l1 < 1000 && l2 < 1000)) |
790 |
return -1; |
return -1; |
804 |
float d0min = 1E20; |
float d0min = 1E20; |
805 |
float d1min = 1E20; |
float d1min = 1E20; |
806 |
for (i = i0; i < i1; i++) { |
for (i = i0; i < i1; i++) { |
807 |
float dist0 = (verts[i] - d0).length(); |
float dist0 = (verts[i].vert - d0).length(); |
808 |
float dist1 = (verts[i] - d1).length(); |
float dist1 = (verts[i].vert - d1).length(); |
809 |
if (dist0 < d0min) d0min = dist0, k0 = i; |
if (dist0 < d0min) d0min = dist0, k0 = i; |
810 |
if (dist1 < d1min) d1min = dist1, k1 = i; |
if (dist1 < d1min) d1min = dist1, k1 = i; |
811 |
} |
} |
941 |
} |
} |
942 |
|
|
943 |
std::vector<bool> clip(pt.size()); |
std::vector<bool> clip(pt.size()); |
944 |
for (i = 0; i <= ndice; i++) { |
// note: not blending the connection mid-point |
945 |
|
for (j = 0; j < ndice; j++) { |
946 |
|
pt[j] += p0; |
947 |
|
clip[j] = false; |
948 |
|
} |
949 |
|
for (i = 1; i <= ndice; i++) { |
950 |
for (j = 0; j < ndice; j++) { |
for (j = 0; j < ndice; j++) { |
951 |
int ind = i * ndice + j; |
int ind = i * ndice + j; |
952 |
int maxi; |
int maxi; |
1100 |
// Triangulate as a star polygon |
// Triangulate as a star polygon |
1101 |
ZVec sum(0,0,0); |
ZVec sum(0,0,0); |
1102 |
for (j = 0; j < (int)poly.size(); j++) |
for (j = 0; j < (int)poly.size(); j++) |
1103 |
sum += verts[poly[j]].normalized(); |
sum += verts[poly[j]].vert.normalized(); |
1104 |
|
|
1105 |
int nvert = verts.append(dirs[tri[i][0]] + |
int nvert = verts.append(dirs[tri[i][0]] + |
1106 |
dirs[tri[i][1]] + |
dirs[tri[i][1]] + |
1110 |
triangler.add(nvert, poly[j], poly[(j+1) % poly.size()]); |
triangler.add(nvert, poly[j], poly[(j+1) % poly.size()]); |
1111 |
} |
} |
1112 |
|
|
1113 |
} else if (mode == 4) { |
} else if (mode == 4 || mode == 5) { |
1114 |
|
|
1115 |
// icosahedron code adapted from sphere.c found in |
// icosahedron code adapted from sphere.c found in |
1116 |
// http://www.sgi.com/Technology/openGL/advanced/programs.html |
// http://www.sgi.com/Technology/openGL/advanced/programs.html |
1127 |
#define X2_ (C2_*CZ_) |
#define X2_ (C2_*CZ_) |
1128 |
#define Y2_ (S2_*CZ_) |
#define Y2_ (S2_*CZ_) |
1129 |
|
|
1130 |
verts.noblend = true; |
if (mode == 5) verts.noblend = true; |
1131 |
int Ip0 = verts.append(ZVec( 0., 0., 1.)); |
int Ip0 = verts.append(ZVec( 0., 0., 1.)); |
1132 |
int Ip1 = verts.append(ZVec(-X2_, -Y2_, SZ_)); |
int Ip1 = verts.append(ZVec(-X2_, -Y2_, SZ_)); |
1133 |
int Ip2 = verts.append(ZVec( X2_, -Y2_, SZ_)); |
int Ip2 = verts.append(ZVec( X2_, -Y2_, SZ_)); |
1179 |
ZVec e2 = (t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0))); |
ZVec e2 = (t0.transform(ZVec(0,0,1)) - t0.transform(ZVec(0,0,0))); |
1180 |
for (i = 0; i < (int)verts.size(); i++) |
for (i = 0; i < (int)verts.size(); i++) |
1181 |
verts[i] = blend(conns, N, r, |
verts[i] = blend(conns, N, r, |
1182 |
e0 * verts[i].x + e1 * verts[i].y + e2 * verts[i].z); |
e0 * verts[i].vert.x + |
1183 |
|
e1 * verts[i].vert.y + |
1184 |
|
e2 * verts[i].vert.z); |
1185 |
} |
} |
1186 |
|
|
1187 |
// Compute normals |
// Compute normals |
1188 |
for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin(); |
for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin(); |
1189 |
x != triangler.tris.end(); x++) { |
x != triangler.tris.end(); x++) { |
1190 |
ZVec v0 = verts[x->v[1]] - verts[x->v[0]]; |
ZVec v0 = verts[x->v[1]].vert - verts[x->v[0]].vert; |
1191 |
ZVec v1 = verts[x->v[2]] - verts[x->v[1]]; |
ZVec v1 = verts[x->v[2]].vert - verts[x->v[1]].vert; |
1192 |
ZVec norm = v0.crossp(v1).normalized(); |
ZVec norm = v0.crossp(v1).normalized(); |
1193 |
verts[x->v[0]].norm += norm; |
verts[x->v[0]].norm += norm; |
1194 |
verts[x->v[1]].norm += norm; |
verts[x->v[1]].norm += norm; |
1196 |
} |
} |
1197 |
|
|
1198 |
for (i = 0; i < (int)verts.size(); i++) |
for (i = 0; i < (int)verts.size(); i++) |
1199 |
verts[i] += p0; |
verts[i].vert += p0; |
1200 |
|
|
1201 |
glBegin(GL_TRIANGLES); |
verts.startN3V3Operation(); |
1202 |
for(::Vob::Dicer::Triangles<Verts>::Titer x = triangler.tris.begin(); |
triangler.draw(); |
1203 |
x != triangler.tris.end(); x++) { |
verts.endN3V3Operation(); |
|
glNormal(verts[x->v[0]].norm); |
|
|
glVertex(verts[x->v[0]]); |
|
|
glNormal(verts[x->v[1]].norm); |
|
|
glVertex(verts[x->v[1]]); |
|
|
glNormal(verts[x->v[2]].norm); |
|
|
glVertex(verts[x->v[2]]); |
|
|
} |
|
|
glEnd(); |
|
1204 |
|
|
1205 |
} |
} |
1206 |
|
|