COLLADA.cpp (pymol-v1.8.6.0.tar.bz2) | : | COLLADA.cpp (pymol-v2.1.0.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
#include <time.h> | #include <time.h> | |||
#include "Setting.h" | #include "Setting.h" | |||
#include "Ortho.h" | #include "Ortho.h" | |||
#include "Color.h" | #include "Color.h" | |||
#include "Util.h" | #include "Util.h" | |||
#include "Version.h" | #include "Version.h" | |||
#include "MemoryDebug.h" | #include "MemoryDebug.h" | |||
#include "Sphere.h" | #include "Sphere.h" | |||
#include "Scene.h" | #include "Scene.h" | |||
#include "CGO.h" | ||||
#define XML_VERSION "1.0" | #define XML_VERSION "1.0" | |||
#define XML_ENCODING "UTF-8" | #define XML_ENCODING "UTF-8" | |||
#define PRECISION 0.001f | #define PRECISION 0.001f | |||
#define TRANS_PRECISION 0.01f | #define TRANS_PRECISION 0.01f | |||
/* | /* | |||
* Size of individual text nodes must be less than the maximum size for | * Size of individual text nodes must be less than the maximum size for | |||
* the LIBXML Parser node: 10MB. Text nodes longer than this will be split. | * the LIBXML Parser node: 10MB. Text nodes longer than this will be split. | |||
skipping to change at line 56 | skipping to change at line 57 | |||
#define COLLADA_GEOM_MODE_COUNT 2 | #define COLLADA_GEOM_MODE_COUNT 2 | |||
/* Returns a standard XML-formatted timestamp */ | /* Returns a standard XML-formatted timestamp */ | |||
static char *GetTimestamp(){ | static char *GetTimestamp(){ | |||
time_t now; | time_t now; | |||
struct tm *local; | struct tm *local; | |||
char buffer[20]; | char buffer[20]; | |||
time(&now); | time(&now); | |||
local = localtime(&now); | local = localtime(&now); | |||
strftime(buffer, 20, "%Y-%m-%dT%X", local); | strftime(buffer, 20, "%Y-%m-%dT%T", local); | |||
return strdup(buffer); | return strdup(buffer); | |||
} | } | |||
/* | /* | |||
* Returns index of the first float in an array matching the given value to | * Returns index of the first float in an array matching the given value to | |||
* the given precision. | * the given precision. | |||
*/ | */ | |||
static int GetFloatPositionInArray(float val, float *arr, int len, | static int GetFloatPositionInArray(float val, float *arr, int len, | |||
float precision) | float precision) | |||
{ | { | |||
skipping to change at line 523 | skipping to change at line 524 | |||
/* Writes a <p> element with the given string as its value. */ | /* Writes a <p> element with the given string as its value. */ | |||
static void ColladaWritePrimitiveElement(xmlTextWriterPtr w, char *p_str) | static void ColladaWritePrimitiveElement(xmlTextWriterPtr w, char *p_str) | |||
{ | { | |||
xmlTextWriterStartElement(w, BAD_CAST "p"); | xmlTextWriterStartElement(w, BAD_CAST "p"); | |||
xmlTextWriterWriteFormatString(w, "%s", p_str); | xmlTextWriterWriteFormatString(w, "%s", p_str); | |||
xmlTextWriterEndElement(w); // p | xmlTextWriterEndElement(w); // p | |||
} | } | |||
/* Writes a <triangles> element with the current primitive (<p>) string. */ | /* Writes a <triangles> element with the current primitive (<p>) string. */ | |||
static void ColladaWriteTrianglesElement(xmlTextWriterPtr w, int geom, int tri, | static void ColladaWriteTrianglesElement(xmlTextWriterPtr w, int geom, int tri, | |||
char *p_str) | char *p_str, int mode=0) | |||
{ | { | |||
xmlTextWriterStartElement(w, BAD_CAST "triangles"); | xmlTextWriterStartElement(w, BAD_CAST (mode == 1 ? "polylist" : "triangles")); | |||
xmlTextWriterWriteFormatAttribute(w, BAD_CAST "count", "%i", tri); | xmlTextWriterWriteFormatAttribute(w, BAD_CAST "count", "%i", tri); | |||
xmlTextWriterWriteFormatAttribute(w, BAD_CAST "material", | xmlTextWriterWriteFormatAttribute(w, BAD_CAST "material", | |||
"geom%i-material", geom); | "geom%i-material", geom); | |||
ColladaWriteVNCInputs(w, geom); | ColladaWriteVNCInputs(w, geom); | |||
if (mode == 1) { | ||||
ColladaWriteTrianglesVCountElement(w, tri); | ||||
} | ||||
ColladaWritePrimitiveElement(w, p_str); | ColladaWritePrimitiveElement(w, p_str); | |||
xmlTextWriterEndElement(w); // triangles | xmlTextWriterEndElement(w); // triangles | |||
} | } | |||
/* Writes a <polylist> element consisting entirely of triangles. */ | /* Writes a <polylist> element consisting entirely of triangles. */ | |||
static void ColladaWriteTrianglesPolylistElement(xmlTextWriterPtr w, int geom, i nt tri, | static void ColladaWriteTrianglesPolylistElement(xmlTextWriterPtr w, int geom, i nt tri, | |||
char *p_str) | char *p_str) | |||
{ | { | |||
xmlTextWriterStartElement(w, BAD_CAST "polylist"); | ColladaWriteTrianglesElement(w, geom, tri, p_str, 1); | |||
xmlTextWriterWriteFormatAttribute(w, BAD_CAST "count", "%i", tri); | ||||
xmlTextWriterWriteFormatAttribute(w, BAD_CAST "material", | ||||
"geom%i-material", geom); | ||||
ColladaWriteVNCInputs(w, geom); | ||||
ColladaWriteTrianglesVCountElement(w, tri); | ||||
ColladaWritePrimitiveElement(w, p_str); | ||||
xmlTextWriterEndElement(w); // triangles | ||||
} | } | |||
/* | /* | |||
* Opens a <polylist> element, including <input>s. Must be followed by at | * Opens a <polylist> element, including <input>s. Must be followed by at | |||
* least one <p> element and then closed. | * least one <p> element and then closed. | |||
*/ | */ | |||
static void ColladaBeginPolylistElement(xmlTextWriterPtr w, int geom, int count) | static void ColladaBeginPolylistElement(xmlTextWriterPtr w, int geom, int count) | |||
{ | { | |||
xmlTextWriterStartElement(w, BAD_CAST "polylist"); | xmlTextWriterStartElement(w, BAD_CAST "polylist"); | |||
xmlTextWriterWriteFormatAttribute(w, BAD_CAST "count", "%i", count); | xmlTextWriterWriteFormatAttribute(w, BAD_CAST "count", "%i", count); | |||
skipping to change at line 633 | skipping to change at line 630 | |||
{ | { | |||
ColladaBeginGeometryMesh(w, geom); | ColladaBeginGeometryMesh(w, geom); | |||
ColladaWrite3DSource(w, geom, (char *)"positions", pos, positions_str, | ColladaWrite3DSource(w, geom, (char *)"positions", pos, positions_str, | |||
(char *)"XYZ"); | (char *)"XYZ"); | |||
ColladaWrite3DSource(w, geom, (char *)"normals", norm, normals_str, | ColladaWrite3DSource(w, geom, (char *)"normals", norm, normals_str, | |||
(char *)"XYZ"); | (char *)"XYZ"); | |||
ColladaWrite3DSource(w, geom, (char *)"colors", col, colors_str, | ColladaWrite3DSource(w, geom, (char *)"colors", col, colors_str, | |||
(char *)"RGB"); | (char *)"RGB"); | |||
ColladaWriteVertices(w, geom); | ColladaWriteVertices(w, geom); | |||
if (mode == 1) { | ColladaWriteTrianglesElement(w, geom, tri, p_str, mode); | |||
ColladaWriteTrianglesPolylistElement(w, geom, tri, p_str); | ||||
} else { | ||||
ColladaWriteTrianglesElement(w, geom, tri, p_str); | ||||
} | ||||
ColladaEndGeometryMesh(w); | ColladaEndGeometryMesh(w); | |||
} | } | |||
#endif // _HAVE_LIBXML | #endif // _HAVE_LIBXML | |||
/* Generates COLLADA output and appends it to `vla_ptr`. */ | /* Generates COLLADA output and appends it to `vla_ptr`. */ | |||
void RayRenderCOLLADA(CRay * I, int width, int height, | void RayRenderCOLLADA(CRay * I, int width, int height, | |||
char **vla_ptr, float front, float back, | char **vla_ptr, float front, float back, | |||
float fov) | float fov) | |||
skipping to change at line 800 | skipping to change at line 793 | |||
/* | /* | |||
* Loop through primitives, plus one extra time to finish writing a | * Loop through primitives, plus one extra time to finish writing a | |||
* triangle mesh if necessary. | * triangle mesh if necessary. | |||
*/ | */ | |||
for (a = 0; a <= I->NPrimitive; a++) { | for (a = 0; a <= I->NPrimitive; a++) { | |||
prim = I->Primitive + a; | prim = I->Primitive + a; | |||
/* Handle transitions between/after triangle meshes. */ | /* Handle transitions between/after triangle meshes. */ | |||
if (mesh_obj) { | if (mesh_obj) { | |||
if (prim->type != cPrimTriangle || | if (a == I->NPrimitive || | |||
TRANS_PRECISION <= fabsf(prim->trans - cur_trans) || | prim->type != cPrimTriangle || | |||
a == I->NPrimitive) | TRANS_PRECISION <= fabsf(prim->trans - cur_trans)) | |||
{ | { | |||
/* | /* | |||
* Not a triangle primitive, but the previous mesh is still | * Not a triangle primitive, but the previous mesh is still | |||
* active; OR, transparency level is different; OR the final | * active; OR, transparency level is different; OR the final | |||
* primitive was part of a triangle mesh that needs to be | * primitive was part of a triangle mesh that needs to be | |||
* closed. | * closed. | |||
* | * | |||
* Write the previous triangle mesh from its data strings | * Write the previous triangle mesh from its data strings | |||
* and counters, reset mesh tracking variables. | * and counters, reset mesh tracking variables. | |||
*/ | */ | |||
ColladaWriteMeshGeometry(w, geom, pos, positions_str, | ColladaWriteMeshGeometry(w, geom, pos, positions_str, | |||
norm, normals_str, col, colors_str, tri, p_str, geom_mode); | norm, normals_str, col, colors_str, tri, p_str, geom_mode); | |||
geom += 1; | geom += 1; | |||
mesh_obj = false; | mesh_obj = false; | |||
VLAFree(positions_str); | ||||
VLAFree(normals_str); | ||||
VLAFree(colors_str); | ||||
VLAFree(p_str); | ||||
} | } | |||
} | } | |||
if(!mesh_obj) { | if(!mesh_obj) { | |||
/* First triangle primitive or any other primititve. */ | /* First triangle primitive or any other primititve. */ | |||
/* Allocate data strings */ | /* Allocate data strings */ | |||
positions_str = VLACalloc(char, 1000); | ||||
pos_str_cc = 0; | pos_str_cc = 0; | |||
normals_str = VLACalloc(char, 1000); | ||||
norm_str_cc = 0; | norm_str_cc = 0; | |||
colors_str = VLACalloc(char, 1000); | ||||
col_str_cc = 0; | col_str_cc = 0; | |||
p_str = VLACalloc(char, 1000); | ||||
p_str_cc = 0; | p_str_cc = 0; | |||
if(a < I->NPrimitive){ | if(a < I->NPrimitive){ | |||
/* Reset counters */ | /* Reset counters */ | |||
tri = 0; | tri = 0; | |||
pos = 0; | pos = 0; | |||
norm = 0; | norm = 0; | |||
col = 0; | col = 0; | |||
cur_trans = prim->trans; | cur_trans = prim->trans; | |||
skipping to change at line 910 | skipping to change at line 893 | |||
for (i = 0; i < 3; i++) { | for (i = 0; i < 3; i++) { | |||
if (fabsf(I->Pos[i]) > largest_dim) { | if (fabsf(I->Pos[i]) > largest_dim) { | |||
largest_dim = fabsf(I->Pos[i]); | largest_dim = fabsf(I->Pos[i]); | |||
} | } | |||
} | } | |||
/* Leave plenty of room */ | /* Leave plenty of room */ | |||
largest_dim *= 100; | largest_dim *= 100; | |||
/* Allocate data strings */ | /* Allocate data strings */ | |||
positions_str = VLACalloc(char, 1000); | ||||
pos_str_cc = 0; | pos_str_cc = 0; | |||
normals_str = VLACalloc(char, 1000); | ||||
norm_str_cc = 0; | norm_str_cc = 0; | |||
colors_str = VLACalloc(char, 1000); | ||||
col_str_cc = 0; | col_str_cc = 0; | |||
p_str = VLACalloc(char, 1000); | ||||
p_str_cc = 0; | p_str_cc = 0; | |||
int cube_coords[24] = { | int cube_coords[24] = { | |||
1, 1, 1, | 1, 1, 1, | |||
1, -1, 1, | 1, -1, 1, | |||
-1, -1, 1, | -1, -1, 1, | |||
-1, 1, 1, | -1, 1, 1, | |||
-1, 1, -1, | -1, 1, -1, | |||
-1, -1, -1, | -1, -1, -1, | |||
1, -1, -1, | 1, -1, -1, | |||
skipping to change at line 1182 | skipping to change at line 1161 | |||
/* Get a fresh p_str for the next strip. */ | /* Get a fresh p_str for the next strip. */ | |||
VLAFree(p_str); | VLAFree(p_str); | |||
p_str = VLACalloc(char, 1000); | p_str = VLACalloc(char, 1000); | |||
p_str_cc = 0; | p_str_cc = 0; | |||
} | } | |||
ColladaEndTristripsElement(w); | ColladaEndTristripsElement(w); | |||
} | } | |||
free(next); | ||||
ColladaEndGeometryMesh(w); | ColladaEndGeometryMesh(w); | |||
geom += 1; | geom += 1; | |||
break; | break; | |||
} // cPrimSphere | } // cPrimSphere | |||
case cPrimCylinder: // 2 | case cPrimCylinder: // 2 | |||
case cPrimSausage: // 4 | case cPrimSausage: // 4 | |||
case cPrimCone: // 7 | case cPrimCone: // 7 | |||
{ | { | |||
skipping to change at line 1214 | skipping to change at line 1195 | |||
/* Local vars */ | /* Local vars */ | |||
float d[3], t[3], p0[3], p1[3], p2[3]; | float d[3], t[3], p0[3], p1[3], p2[3]; | |||
float v_buf[9], *v, vv1[3], vv2[3], vvv1[3], vvv2[3]; | float v_buf[9], *v, vv1[3], vv2[3], vvv1[3], vvv2[3]; | |||
float x[DAE_MAX_EDGE + 1], y[DAE_MAX_EDGE + 1]; | float x[DAE_MAX_EDGE + 1], y[DAE_MAX_EDGE + 1]; | |||
float overlap, overlap2, nub, nub2, r2 = 0.F; | float overlap, overlap2, nub, nub2, r2 = 0.F; | |||
int nEdge, c; //colorFlag; | int nEdge, c; //colorFlag; | |||
int i; | int i; | |||
char *next = (char *) malloc(200 * sizeof(char)); | char *next = (char *) malloc(200 * sizeof(char)); | |||
char *cap1_p_str = VLACalloc(char, 1000); | char *cap1_p_str = VLACalloc(char, 1000); | |||
char *cap2_p_str = VLACalloc(char, 1000); | ||||
ov_size cap1_cc = 0; | ov_size cap1_cc = 0; | |||
ov_size cap2_cc = 0; | ||||
bool stick_round_nub = SettingGetGlobal_i(I->G, cSetting_stick_round | ||||
_nub); | ||||
const int j_arr[] = {2, 3, 2}; | ||||
int nCapTri = 0; | ||||
int captype[2] = {prim->cap1, prim->cap2}; | ||||
CGO *cgocap[2] = {NULL, NULL}; | ||||
if(prim->type == cPrimSausage) { | ||||
captype[0] = captype[1] = cCylCapRound; | ||||
} | ||||
v = v_buf; | v = v_buf; | |||
nEdge = SettingGetGlobal_i(I->G, cSetting_stick_quality); | nEdge = SettingGetGlobal_i(I->G, cSetting_stick_quality); | |||
overlap = prim->r1 * SettingGetGlobal_f(I->G, cSetting_stick_overlap ); | overlap = prim->r1 * SettingGetGlobal_f(I->G, cSetting_stick_overlap ); | |||
nub = prim->r1 * SettingGetGlobal_f(I->G, cSetting_stick_nub); | nub = prim->r1 * SettingGetGlobal_f(I->G, cSetting_stick_nub); | |||
if(prim->type == cPrimCone) { | if(prim->type == cPrimCone) { | |||
r2 = prim->r2; | ||||
overlap2 = prim->r2 * SettingGetGlobal_f(I->G, cSetting_stick_over lap); | overlap2 = prim->r2 * SettingGetGlobal_f(I->G, cSetting_stick_over lap); | |||
nub2 = prim->r2 * SettingGetGlobal_f(I->G, cSetting_stick_nub); | nub2 = prim->r2 * SettingGetGlobal_f(I->G, cSetting_stick_nub); | |||
} | } | |||
else { | else { | |||
r2 = prim->r1; | ||||
overlap2 = overlap; | overlap2 = overlap; | |||
nub2 = nub; | nub2 = nub; | |||
} | } | |||
if(nEdge > DAE_MAX_EDGE) | if(nEdge > DAE_MAX_EDGE) | |||
nEdge = DAE_MAX_EDGE; | nEdge = DAE_MAX_EDGE; | |||
subdivide(nEdge, x, y); | subdivide(nEdge, x, y); | |||
//colorFlag = (prim->c1 != prim->c2) && prim->c2; | //colorFlag = (prim->c1 != prim->c2) && prim->c2; | |||
/* primary axis vector p0 */ | /* primary axis vector p0 */ | |||
p0[0] = (prim->v2[0] - prim->v1[0]); | p0[0] = (prim->v2[0] - prim->v1[0]); | |||
p0[1] = (prim->v2[1] - prim->v1[1]); | p0[1] = (prim->v2[1] - prim->v1[1]); | |||
p0[2] = (prim->v2[2] - prim->v1[2]); | p0[2] = (prim->v2[2] - prim->v1[2]); | |||
normalize3f(p0); | normalize3f(p0); | |||
/* cap1 */ | /* cap1 */ | |||
copy3f(prim->v1, vv1); | copy3f(prim->v1, vv1); | |||
if(prim->type == cPrimSausage || | copy3f(vv1, vvv1); | |||
(prim->type == cPrimCylinder && prim->cap1 == cCylCapRound)) { | ||||
for(i = 0; i < 3; i++) { | ||||
vv1[i] -= p0[i] * overlap; | ||||
vvv1[i] = vv1[i] - p0[i] * nub; | ||||
} | ||||
} else { | ||||
copy3f(vv1, vvv1); | ||||
} | ||||
/* cap2 */ | /* cap2 */ | |||
copy3f(prim->v2, vv2); | copy3f(prim->v2, vv2); | |||
if(prim->type == cPrimSausage || | copy3f(vv2, vvv2); | |||
(prim->type == cPrimCylinder && prim->cap2 == cCylCapRound)) { | ||||
for(i = 0; i < 3; i++) { | ||||
vv2[i] += p0[i] * overlap2; | ||||
vvv2[i] = vv2[i] + p0[i] * nub2; | ||||
} | ||||
} else { | ||||
copy3f(vv2, vvv2); | ||||
} | ||||
d[0] = (vv2[0] - vv1[0]); | d[0] = (vv2[0] - vv1[0]); | |||
d[1] = (vv2[1] - vv1[1]); | d[1] = (vv2[1] - vv1[1]); | |||
d[2] = (vv2[2] - vv1[2]); | d[2] = (vv2[2] - vv1[2]); | |||
get_divergent3f(d, t); | get_divergent3f(d, t); | |||
/* orthogonal vectors p1, p2 */ | /* orthogonal vectors p1, p2 */ | |||
cross_product3f(d, t, p1); | cross_product3f(d, t, p1); | |||
normalize3f(p1); | normalize3f(p1); | |||
cross_product3f(d, p1, p2); | cross_product3f(d, p1, p2); | |||
normalize3f(p2); | normalize3f(p2); | |||
/* now we have a coordinate system */ | /* now we have a coordinate system */ | |||
/* cap1 */ | ||||
if(captype[0] == cCylCapRound) { | ||||
if (stick_round_nub) { | ||||
cgocap[0] = CGONew(I->G); | ||||
CGORoundNub(cgocap[0], prim->v1, p0, p1, p2, -1, nEdge, prim->r1 | ||||
); | ||||
} else { | ||||
for(i = 0; i < 3; i++) { | ||||
vv1[i] -= p0[i] * overlap; | ||||
vvv1[i] = vv1[i] - p0[i] * nub; | ||||
} | ||||
} | ||||
} | ||||
/* cap2 */ | ||||
if(captype[1] == cCylCapRound) { | ||||
if (stick_round_nub) { | ||||
cgocap[1] = CGONew(I->G); | ||||
CGORoundNub(cgocap[1], prim->v2, p0, p1, p2, 1, nEdge, prim->r1) | ||||
; | ||||
} else { | ||||
for(i = 0; i < 3; i++) { | ||||
vv2[i] += p0[i] * overlap2; | ||||
vvv2[i] = vv2[i] + p0[i] * nub2; | ||||
} | ||||
} | ||||
} | ||||
/* colors */ | ||||
sprintf(next, "%6.4f %6.4f %6.4f %6.4f %6.4f %6.4f ", | ||||
prim->c1[0], prim->c1[1], prim->c1[2], | ||||
prim->c2[0], prim->c2[1], prim->c2[2]); | ||||
UtilConcatVLA(&colors_str, &col_str_cc, next); | ||||
/* Generate the data strings */ | /* Generate the data strings */ | |||
char *vcount_str = VLACalloc(char, 100); | char *vcount_str = VLACalloc(char, 100); | |||
ov_size vc_cc = 0; | ov_size vc_cc = 0; | |||
{ | { | |||
/* Write values for each edge. The first edge is also the last | /* Write values for each edge. The first edge is also the last | |||
* edge. */ | * edge. */ | |||
for(c = nEdge; c >= 0; c--) { | for(c = nEdge; c >= 0; c--) { | |||
/* vector only, not positioned yet */ | /* vector only, not positioned yet */ | |||
v[0] = p1[0] * x[c] + p2[0] * y[c]; | v[0] = p1[0] * x[c] + p2[0] * y[c]; | |||
v[1] = p1[1] * x[c] + p2[1] * y[c]; | v[1] = p1[1] * x[c] + p2[1] * y[c]; | |||
v[2] = p1[2] * x[c] + p2[2] * y[c]; | v[2] = p1[2] * x[c] + p2[2] * y[c]; | |||
if(prim->type == cPrimCone){ | ||||
r2 = prim->r2; | ||||
} else { | ||||
r2 = prim->r1; | ||||
} | ||||
/* vertices */ | /* vertices */ | |||
v[3] = vv1[0] + v[0] * prim->r1; | v[3] = vv1[0] + v[0] * prim->r1; | |||
v[4] = vv1[1] + v[1] * prim->r1; | v[4] = vv1[1] + v[1] * prim->r1; | |||
v[5] = vv1[2] + v[2] * prim->r1; | v[5] = vv1[2] + v[2] * prim->r1; | |||
v[6] = vv2[0] + v[0] * r2; | v[6] = vv2[0] + v[0] * r2; | |||
v[7] = vv2[1] + v[1] * r2; | v[7] = vv2[1] + v[1] * r2; | |||
v[8] = vv2[2] + v[2] * r2; | v[8] = vv2[2] + v[2] * r2; | |||
/* positions */ | /* positions */ | |||
sprintf(next, "%6.4f %6.4f %6.4f %6.4f %6.4f %6.4f ", | sprintf(next, "%6.4f %6.4f %6.4f %6.4f %6.4f %6.4f ", | |||
v[3], v[4], v[5], v[6], v[7], v[8]); | v[3], v[4], v[5], v[6], v[7], v[8]); | |||
UtilConcatVLA(&positions_str, &pos_str_cc, next); | UtilConcatVLA(&positions_str, &pos_str_cc, next); | |||
/* normals: Both vertices have the same normal. */ | /* normals: Both vertices have the same normal. */ | |||
sprintf(next, "%6.4f %6.4f %6.4f ", | sprintf(next, "%6.4f %6.4f %6.4f ", | |||
v[0], v[1], v[2]); | v[0], v[1], v[2]); | |||
UtilConcatVLA(&normals_str, &norm_str_cc, next); | UtilConcatVLA(&normals_str, &norm_str_cc, next); | |||
/* colors */ | ||||
sprintf(next, "%6.4f %6.4f %6.4f %6.4f %6.4f %6.4f ", | ||||
prim->c1[0], prim->c1[1], prim->c1[2], | ||||
prim->c2[0], prim->c2[1], prim->c2[2]); | ||||
UtilConcatVLA(&colors_str, &col_str_cc, next); | ||||
if (c > 0) { | if (c > 0) { | |||
/* vcount */ | /* vcount */ | |||
sprintf(next, "4 "); | sprintf(next, "4 "); | |||
UtilConcatVLA(&vcount_str, &vc_cc, next); | UtilConcatVLA(&vcount_str, &vc_cc, next); | |||
/* p for polylist */ | /* p for polylist */ | |||
sprintf(next, "%i %i %i %i %i %i %i %i %i %i %i %i ", | sprintf(next, "%i %i %i %i %i %i %i %i %i %i %i %i ", | |||
pos, norm, col, | pos, norm, col, | |||
pos + 1, norm, col + 1, | pos + 1, norm, col + 1, | |||
pos + 3, norm + 1, col + 3, | pos + 3, norm + 1, col, | |||
pos + 2, norm + 1, col + 2); | pos + 2, norm + 1, col + 1); | |||
UtilConcatVLA(&p_str, &p_str_cc, next); | UtilConcatVLA(&p_str, &p_str_cc, next); | |||
} | } | |||
pos += 2; | pos += 2; | |||
norm += 1; | norm += 1; | |||
col += 2; | ||||
} | } | |||
/* Caps */ | /* Caps */ | |||
{ | { | |||
/* add another vertex-normal-color set for the center of each | /* add another vertex-normal-color set for the center of each | |||
* cap if r > 0 */ | * cap if r > 0 */ | |||
#define CONE_MIN_RADIUS 10e-6f | #define CONE_MIN_RADIUS 10e-6f | |||
/* positions */ | if(prim->r1 > CONE_MIN_RADIUS && !cgocap[0] && captype[0] != cCy | |||
if(prim->r1 > CONE_MIN_RADIUS){ | lCapNone){ | |||
/* positions */ | ||||
sprintf(next, "%6.4f %6.4f %6.4f ", | sprintf(next, "%6.4f %6.4f %6.4f ", | |||
vvv1[0], vvv1[1], vvv1[2]); | vvv1[0], vvv1[1], vvv1[2]); | |||
UtilConcatVLA(&positions_str, &pos_str_cc, next); | UtilConcatVLA(&positions_str, &pos_str_cc, next); | |||
} | ||||
if(r2 > CONE_MIN_RADIUS){ | ||||
sprintf(next, "%6.4f %6.4f %6.4f ", | ||||
vvv2[0], vvv2[1], vvv2[2]); | ||||
UtilConcatVLA(&positions_str, &pos_str_cc, next); | ||||
} | ||||
/* normals */ | /* normals */ | |||
if(prim->r1 > CONE_MIN_RADIUS){ | ||||
sprintf(next, "%6.4f %6.4f %6.4f ", | sprintf(next, "%6.4f %6.4f %6.4f ", | |||
-p0[0], -p0[1], -p0[2]); | -p0[0], -p0[1], -p0[2]); | |||
UtilConcatVLA(&normals_str, &norm_str_cc, next); | UtilConcatVLA(&normals_str, &norm_str_cc, next); | |||
} | ||||
if(r2 > CONE_MIN_RADIUS){ | /* p */ | |||
sprintf(next, "%6.4f %6.4f %6.4f ", | for(i = 0; i < nEdge; i++) { | |||
p0[0], p0[1], p0[2]); | sprintf(next, "%i %i %i %i %i %i %i %i %i ", | |||
UtilConcatVLA(&normals_str, &norm_str_cc, next); | pos, norm, col, | |||
2*i, i, col, | ||||
2*i+2, i+1, col); | ||||
UtilConcatVLA(&cap1_p_str, &cap1_cc, next); | ||||
++nCapTri; | ||||
} | ||||
++pos; | ||||
++norm; | ||||
} | } | |||
/* colors */ | if(r2 > CONE_MIN_RADIUS && !cgocap[1] && captype[1] != cCylCapNo | |||
if(prim->r1 > CONE_MIN_RADIUS){ | ne){ | |||
/* positions */ | ||||
sprintf(next, "%6.4f %6.4f %6.4f ", | sprintf(next, "%6.4f %6.4f %6.4f ", | |||
prim->c1[0], prim->c1[1], prim->c1[2]); | vvv2[0], vvv2[1], vvv2[2]); | |||
UtilConcatVLA(&colors_str, &col_str_cc, next); | UtilConcatVLA(&positions_str, &pos_str_cc, next); | |||
} | ||||
if(r2 > CONE_MIN_RADIUS){ | /* normals */ | |||
sprintf(next, "%6.4f %6.4f %6.4f ", | sprintf(next, "%6.4f %6.4f %6.4f ", | |||
prim->c2[0], prim->c2[1], prim->c2[2]); | p0[0], p0[1], p0[2]); | |||
UtilConcatVLA(&colors_str, &col_str_cc, next); | UtilConcatVLA(&normals_str, &norm_str_cc, next); | |||
} | ||||
/* p */ | /* p */ | |||
for(i = 0; i < nEdge; i++) { | for(i = 0; i < nEdge; i++) { | |||
if(prim->r1 > CONE_MIN_RADIUS){ | /* reverse order for other end */ | |||
sprintf(next, "%i %i %i %i %i %i %i %i %i ", | sprintf(next, "%i %i %i %i %i %i %i %i %i ", | |||
pos, norm, col, | pos, norm, col + 1, | |||
2*i, i, 2*i, | 2*i+3, i+1, col + 1, | |||
2*i+2, i+1, 2*i+2); | 2*i+1, i, col + 1); | |||
UtilConcatVLA(&cap1_p_str, &cap1_cc, next); | UtilConcatVLA(&cap1_p_str, &cap1_cc, next); | |||
++nCapTri; | ||||
} | } | |||
/* reverse order for other end */ | ||||
if(r2 > CONE_MIN_RADIUS){ | ||||
sprintf(next, "%i %i %i %i %i %i %i %i %i ", | ||||
pos+1, norm+1, col+1, | ||||
2*i+3, i+1, 2*i+3, | ||||
2*i+1, i, 2*i+1); | ||||
UtilConcatVLA(&cap2_p_str, &cap2_cc, next); | ||||
} | ||||
} | ||||
pos += 2; | ++pos; | |||
norm += 2; | ++norm; | |||
col += 2; | } | |||
} | } | |||
free(next); | ||||
#if COLLADA_DEBUG > 1 | #if COLLADA_DEBUG > 1 | |||
printf("positions: %s\n", positions_str); | printf("positions: %s\n", positions_str); | |||
printf("normals: %s\n", normals_str); | printf("normals: %s\n", normals_str); | |||
printf("colors: %s\n", colors_str); | printf("colors: %s\n", colors_str); | |||
printf("p: %s\n", p_str); | printf("p: %s\n", p_str); | |||
#endif | #endif | |||
for (i = 0; i < 2; ++i) { | ||||
if (!cgocap[i]) | ||||
continue; | ||||
int pos0 = -1; | ||||
for (auto it = cgocap[i]->begin(); !it.is_stop(); ++it) { | ||||
auto pc = it.data(); | ||||
int op = it.op_code(); | ||||
switch (op){ | ||||
case CGO_BEGIN: | ||||
pos0 = pos; | ||||
break; | ||||
case CGO_NORMAL: | ||||
/* normals */ | ||||
sprintf(next, "%6.4f %6.4f %6.4f ", pc[0], pc[1], pc[2]); | ||||
UtilConcatVLA(&normals_str, &norm_str_cc, next); | ||||
++norm; | ||||
break; | ||||
case CGO_VERTEX: | ||||
/* positions */ | ||||
sprintf(next, "%6.4f %6.4f %6.4f ", pc[0], pc[1], pc[2]); | ||||
UtilConcatVLA(&positions_str, &pos_str_cc, next); | ||||
++pos; | ||||
/* unroll the triangle strip */ | ||||
if (pos > pos0 + 2) { | ||||
const int * j = j_arr + ((pos - pos0) % 2); | ||||
sprintf(next, "%i %i %i %i %i %i %i %i %i ", | ||||
pos - j[0], norm - j[0], col + i, | ||||
pos - j[1], norm - j[1], col + i, | ||||
pos - 1, norm - 1, col + i); | ||||
UtilConcatVLA(&cap1_p_str, &cap1_cc, next); | ||||
++nCapTri; | ||||
} | ||||
break; | ||||
} | ||||
} | ||||
CGOFree(cgocap[i]); | ||||
} | ||||
} | } | |||
col += 2; | ||||
ColladaBeginGeometryMesh(w, geom); | ColladaBeginGeometryMesh(w, geom); | |||
ColladaWrite3DSource(w, geom, (char *)"positions", pos, | ColladaWrite3DSource(w, geom, (char *)"positions", pos, | |||
positions_str, (char *)"XYZ"); | positions_str, (char *)"XYZ"); | |||
ColladaWrite3DSource(w, geom, (char *)"normals", norm, | ColladaWrite3DSource(w, geom, (char *)"normals", norm, | |||
normals_str, (char *)"XYZ"); | normals_str, (char *)"XYZ"); | |||
ColladaWrite3DSource(w, geom, (char *)"colors", col, | ColladaWrite3DSource(w, geom, (char *)"colors", col, | |||
colors_str, (char *)"RGB"); | colors_str, (char *)"RGB"); | |||
ColladaWriteVertices(w, geom); | ColladaWriteVertices(w, geom); | |||
/* polylist for cylinder shaft */ | /* polylist for cylinder shaft */ | |||
ColladaBeginPolylistElement(w, geom, nEdge); | ColladaBeginPolylistElement(w, geom, nEdge); | |||
ColladaWriteVCountElement(w, vcount_str); | ColladaWriteVCountElement(w, vcount_str); | |||
ColladaWritePrimitiveElement(w, p_str); | ColladaWritePrimitiveElement(w, p_str); | |||
ColladaEndPolylistElement(w); | ColladaEndPolylistElement(w); | |||
switch (geom_mode) { | if (nCapTri) { | |||
case 1: | ColladaWriteTrianglesElement(w, geom, nCapTri, cap1_p_str, geom_mo | |||
/* triangles for caps (trifans would be better) */ | de); | |||
if(prim->r1 > CONE_MIN_RADIUS){ | ||||
ColladaWriteTrianglesPolylistElement(w, geom, nEdge, cap1_p_st | ||||
r); | ||||
} | ||||
if(r2 > CONE_MIN_RADIUS){ | ||||
ColladaWriteTrianglesPolylistElement(w, geom, nEdge, cap2_p_st | ||||
r); | ||||
} | ||||
break; | ||||
case 0: | ||||
default: | ||||
/* triangles for caps (trifans would be better) */ | ||||
if(prim->r1 > CONE_MIN_RADIUS){ | ||||
ColladaWriteTrianglesElement(w, geom, nEdge, cap1_p_str); | ||||
} | ||||
if(r2 > CONE_MIN_RADIUS){ | ||||
ColladaWriteTrianglesElement(w, geom, nEdge, cap2_p_str); | ||||
} | ||||
break; | ||||
} | } | |||
ColladaEndGeometryMesh(w); | ColladaEndGeometryMesh(w); | |||
geom += 1; | geom += 1; | |||
VLAFree(vcount_str); | VLAFree(vcount_str); | |||
VLAFree(cap1_p_str); | VLAFree(cap1_p_str); | |||
VLAFree(cap2_p_str); | ||||
free(next); | ||||
break; | break; | |||
} // cPrimCylinder | } // cPrimCylinder | |||
case cPrimTriangle: // 3 | case cPrimTriangle: // 3 | |||
{ | { | |||
#if COLLADA_DEBUG > 1 | #if COLLADA_DEBUG > 1 | |||
printf("Primitive %i: cPrimTriangle\n", a); | printf("Primitive %i: cPrimTriangle\n", a); | |||
#endif | #endif | |||
skipping to change at line 1541 | skipping to change at line 1550 | |||
printf("Reached XML_NODE_SIZE_LIMIT (%i) at a=%i, geom=%i\n", | printf("Reached XML_NODE_SIZE_LIMIT (%i) at a=%i, geom=%i\n", | |||
XML_NODE_SIZE_LIMIT, a, geom); | XML_NODE_SIZE_LIMIT, a, geom); | |||
#endif | #endif | |||
/* Write the current mesh object and clean up */ | /* Write the current mesh object and clean up */ | |||
ColladaWriteMeshGeometry(w, geom, pos, positions_str, | ColladaWriteMeshGeometry(w, geom, pos, positions_str, | |||
norm, normals_str, col, colors_str, tri, p_str, geom_mode); | norm, normals_str, col, colors_str, tri, p_str, geom_mode); | |||
geom += 1; | geom += 1; | |||
mesh_obj = false; | mesh_obj = false; | |||
VLAFree(positions_str); | ||||
VLAFree(normals_str); | ||||
VLAFree(colors_str); | ||||
VLAFree(p_str); | ||||
} | } | |||
break; | break; | |||
} // cPrimTriangle | } // cPrimTriangle | |||
/* Character and Ellipsoid not implemented */ | /* Character and Ellipsoid not implemented */ | |||
case cPrimCharacter: // 5 | case cPrimCharacter: // 5 | |||
{ | { | |||
#if COLLADA_DEBUG > 1 | #if COLLADA_DEBUG > 1 | |||
printf("Primitive %i: cPrimCharacter\n", a); | printf("Primitive %i: cPrimCharacter\n", a); | |||
skipping to change at line 1574 | skipping to change at line 1577 | |||
printf("Primitive %i: cPrimEllipsoid\n", a); | printf("Primitive %i: cPrimEllipsoid\n", a); | |||
#endif | #endif | |||
break; | break; | |||
} // cPrimEllipsoid | } // cPrimEllipsoid | |||
} // switch | } // switch | |||
} // for | } // for | |||
xmlTextWriterEndElement(w); // library_geometries | xmlTextWriterEndElement(w); // library_geometries | |||
VLAFree(positions_str); | ||||
VLAFree(normals_str); | ||||
VLAFree(colors_str); | ||||
VLAFree(p_str); | ||||
} | } | |||
/* Effects */ | /* Effects */ | |||
ColladaWriteLibraryEffects(w, G, trans_len, trans); | ColladaWriteLibraryEffects(w, G, trans_len, trans); | |||
/* Materials */ | /* Materials */ | |||
ColladaWriteLibraryMaterials(w, trans_len, trans); | ColladaWriteLibraryMaterials(w, trans_len, trans); | |||
/* Visual Scenes */ | /* Visual Scenes */ | |||
{ | { | |||
End of changes. 49 change blocks. | ||||
146 lines changed or deleted | 157 lines changed or added |