*/
}
boolean isEccentric = (aspectRatio != 1 && wingVectors != null);
int nHermites = (hermiteLevel + 1) * 2 + 1; // 4 for hermiteLevel = 1
int nPer = (nHermites - 1) * 2 - 2; // 6 for hermiteLevel 1
Mesh mesh = meshes[i] = new Mesh("mesh_" + shapeID + "_" + i, g3d, (short) 0, i);
boolean variableRadius = (madBeg != madMid || madMid != madEnd);
if (controlHermites == null || controlHermites.length < nHermites + 1) {
controlHermites = new Point3f[nHermites + 1];
}
Graphics3D.getHermiteList(isNucleic ? 4 : 7, controlPoints[iPrev],
controlPoints[i], controlPoints[iNext], controlPoints[iNext2],
controlPoints[iNext3], controlHermites, 0, nHermites);
//System.out.println("create mesh " + thisChain + " mesh_" + shapeID + "_"+i+controlPoints[i] + controlPoints[iNext]);
if (isEccentric) {
if (wingHermites == null || wingHermites.length < nHermites + 1) {
wingHermites = new Vector3f[nHermites + 1];
}
wing.set(wingVectors[iPrev]);
if (madEnd == 0)
wing.scale(2.0f); //adds a flair to an arrow
Graphics3D.getHermiteList(isNucleic ? 4 : 7, wing, wingVectors[i],
wingVectors[iNext], wingVectors[iNext2], wingVectors[iNext3],
wingHermites, 0, nHermites);
}
float radius1 = madBeg / 2000f;
float radius2 = madMid / 2000f;
float radius3 = madEnd / 2000f;
if (variableRadius) {
if (radiusHermites == null
|| radiusHermites.length < ((nHermites + 1) >> 1) + 1) {
radiusHermites = new Point3f[((nHermites + 1) >> 1) + 1];
}
ptPrev.set(radius1, radius1, 0);
pt.set(radius1, radius2, 0);
pt1.set(radius2, radius3, 0);
ptNext.set(radius3, radius3, 0);
// two for the price of one!
Graphics3D.getHermiteList(4, ptPrev, pt, pt1, ptNext, ptNext,
radiusHermites, 0, (nHermites + 1) >> 1);
}
if (!isEccentric) {
norm.sub(controlHermites[1], controlHermites[0]);
wing0.cross(norm, Z);
wing0.cross(norm, wing0);
}
int nPoints = 0;
int iMid = nHermites >> 1;
for (int p = 0; p < nHermites; p++) {
norm.sub(controlHermites[p + 1], controlHermites[p]);
if (isEccentric) {
wing.set(wingHermites[p]);
wing1.set(wing);
wing.scale(2f / aspectRatio);
//dumpVector(controlHermites[p],wing)
} else {
wing.cross(norm, wing0);
wing.normalize();
}
float scale = (!variableRadius ? radius1 : p < iMid ? radiusHermites[p].x
: radiusHermites[p - iMid].y);
wing.scale(scale);
wing1.scale(scale);
aa.set(norm, (float) (2 * Math.PI / nPer));
mat.set(aa);
pt1.set(controlHermites[p]);
for (int k = 0; k < nPer; k++) {
mat.transform(wing);
wingT.set(wing);
if (isEccentric) {
if (k == (nPer + 2) / 4 || k == (3 * nPer + 2) / 4)
wing1.scale(-1);
wingT.add(wing1);
}
pt.add(pt1, wingT);
if (isEccentric) {
//dumpVector(wingHermites[p], pt);
}
mesh.addVertexCopy(pt);
}
if (p > 0) {
for (int k = 0; k < nPer; k++) {
mesh.addQuad(nPoints - nPer + k, nPoints - nPer + ((k + 1) % nPer),
nPoints + ((k + 1) % nPer), nPoints + k);
}
}
nPoints += nPer;
}
if (doCap0)
for (int k = hermiteLevel * 2; --k >= 0;)
mesh.addQuad(k + 2, k + 1, (nPer - k) % nPer, nPer - k - 1);
if (doCap1)
for (int k = hermiteLevel * 2; --k >= 0;)
mesh.addQuad(nPoints - k - 1, nPoints - nPer + (nPer - k) % nPer,
nPoints - nPer + k + 1, nPoints - nPer + k + 2);
mesh.initialize(JmolConstants.FRONTLIT, null, null);
//System.out.sprintln("mesh "+ mesh.thisID + " " + mesh.vertexCount+" "+mesh.vertices.length + " " + mesh.polygonCount + " " + mesh.polygonIndexes.length);
mesh.setVisibilityFlags(1);
return (meshReady[i] = true);
}