00001
00008 #include "ColladaTool.h"
00009
00010
00011 using namespace jbxl;
00012
00013
00014
00016
00017
00018
00019 ColladaXML::~ColladaXML(void)
00020 {
00021
00022 }
00023
00024
00025
00026 void ColladaXML::init(double meter, int axis, const char* ver)
00027 {
00028 initCollada(meter, axis, ver);
00029 blank_texture = init_Buffer();
00030
00031 forUnity3D = false;
00032 }
00033
00034
00035
00036
00037 void ColladaXML::free(void)
00038 {
00039 free_Buffer(&blank_texture);
00040 del_xml(&xml);
00041 }
00042
00043
00044
00045 void ColladaXML::clear(double meter, int axis, const char* ver)
00046 {
00047 del_xml(&xml);
00048 init(meter, axis, ver);
00049 }
00050
00051
00052
00053 bool ColladaXML::isBlankTexture(const char* name)
00054 {
00055 if (blank_texture.buf==NULL) return false;
00056 if (strncasecmp(_tochar(blank_texture.buf), name, strlen(_tochar(blank_texture.buf)))) return false;
00057
00058 return true;
00059 }
00060
00061
00062
00063
00065
00066
00067 void ColladaXML::initCollada(double meter, int axis, const char* ver)
00068 {
00069 Buffer buf;
00070 if (ver!=NULL) buf = make_Buffer_str(ver);
00071 else buf = make_Buffer_str("1.4.1");
00072
00073
00074 xml = init_xml_doc();
00075 collada = add_xml_node(xml, "COLLADA");
00076
00077 add_xml_attr_str(collada, "xmlns", COLLADA_STR_XMLNS);
00078 add_xml_attr_str(collada, "version", _tochar(buf.buf));
00079
00080
00081 asset = add_xml_node(collada, "asset");
00082 contributor = add_xml_node(asset, "contributor");
00083 author = add_xml_node(contributor, "author");
00084 authoring_tool = add_xml_node(contributor, "authoring_tool");
00085 created = add_xml_node(asset, "created");
00086 modified = add_xml_node(asset, "modified");
00087 unit = add_xml_node(asset, "unit");
00088 up_axis = add_xml_node(asset, "up_axis");
00089
00090
00091 char* ltime = get_local_timestamp(time(0), "%Y-%m-%dT%H:%M:%SZ");
00092
00093 add_xml_content(author, COLLADA_STR_AUTHOR);
00094 add_xml_content(authoring_tool, COLLADA_STR_TOOL);
00095 add_xml_content(created, ltime);
00096 add_xml_content(modified, ltime);
00097 add_xml_attr_str(unit, "name", "meter");
00098 add_xml_attr_float(unit, "meter", (float)meter);
00099 ::free(ltime);
00100
00101 if (axis==COLLADA_X_UP) add_xml_content(up_axis, "X_UP");
00102 else if (axis==COLLADA_Y_UP) add_xml_content(up_axis, "Y_UP");
00103 else add_xml_content(up_axis, "Z_UP");
00104
00105
00106 library_images = add_xml_node(collada, "library_images");
00107
00108
00109 library_materials = add_xml_node(collada, "library_materials");
00110
00111
00112 library_geometries = add_xml_node(collada, "library_geometries");
00113
00114
00115 library_effects = add_xml_node(collada, "library_effects");
00116
00117
00118
00119
00120
00121 library_physics_models = add_xml_node(collada, "library_physics_models");
00122 physics_model = add_xml_node(library_physics_models, "physics_model");
00123 add_xml_attr_str(physics_model, "id", "Physics_Model");
00124 add_xml_attr_str(physics_model, "name", "Physics_Model");
00125
00126
00127 library_physics_scenes = add_xml_node(collada, "library_physics_scenes");
00128 physics_scene = add_xml_node(library_physics_scenes, "physics_scene");
00129 add_xml_attr_str(physics_scene, "id", "Physics_Scene");
00130 add_xml_attr_str(physics_scene, "name", "Physics_Scene");
00131 instance_physics_model = add_xml_node(physics_scene, "instance_physics_model");
00132 add_xml_attr_str(instance_physics_model, "url", "#Physics_Model");
00133
00134
00135
00136
00137
00138 library_visual_scenes = add_xml_node(collada, "library_visual_scenes");
00139 visual_scene = add_xml_node(library_visual_scenes, "visual_scene");
00140 add_xml_attr_str(visual_scene, "id", "Scene");
00141 add_xml_attr_str(visual_scene, "name", "Scene");
00142
00143
00144 scene = add_xml_node(collada, "scene");
00145 instance_physics_scene = add_xml_node(scene, "instance_physics_scene");
00146 add_xml_attr_str(instance_physics_scene, "url", "#Physics_Scene");
00147 instance_visual_scene = add_xml_node(scene, "instance_visual_scene");
00148 add_xml_attr_str(instance_visual_scene, "url", "#Scene");
00149
00150
00151 free_Buffer(&buf);
00152 }
00153
00154
00155
00156 void ColladaXML::addObject(MeshObjectData* meshdata, bool collider)
00157 {
00158 if (meshdata==NULL) return;
00159
00160 char* geom_id = addGeometry(meshdata);
00161 if (geom_id==NULL) return;
00162
00163 addScene(geom_id, meshdata, collider);
00164
00165 ::free(geom_id);
00166 return;
00167 }
00168
00169
00170
00171 char* ColladaXML::addGeometry(MeshObjectData* meshdata)
00172 {
00173 if (meshdata==NULL) return NULL;
00174
00175
00176 Buffer randomstr = make_Buffer_randomstr(8);
00177 Buffer geometry_id = make_Buffer_str("#GEOMETRY_");
00178 cat_Buffer(&randomstr, &geometry_id);
00179
00180 Buffer geometry_name = dup_Buffer(meshdata->data_name);
00181 if (geometry_name.buf==NULL) geometry_name = make_Buffer_str(geometry_id.buf+1);
00182
00183
00184 tXML* geomrtry = add_xml_node(library_geometries, "geometry");
00185 add_xml_attr_str(geomrtry, "id", _tochar(geometry_id.buf+1));
00186 add_xml_attr_str(geomrtry, "name", _tochar(geometry_name.buf));
00187 tXML* mesh = add_xml_node(geomrtry, "mesh");
00188
00189
00190 char* psitin_id = addVertexSource(mesh, meshdata);
00191 char* normal_id = addNormalSource(mesh, meshdata);
00192 char* texcrd_id = addTexcrdSource(mesh, meshdata);
00193 char* vertex_id = addVerticesPos (mesh, psitin_id);
00194
00195
00196 addPolylists(mesh, meshdata, vertex_id, normal_id, texcrd_id);
00197
00198 freeNull(psitin_id);
00199 freeNull(normal_id);
00200 freeNull(vertex_id);
00201 freeNull(texcrd_id);
00202
00203 free_Buffer(&randomstr);
00204 free_Buffer(&geometry_name);
00205
00206 return _tochar(geometry_id.buf);
00207 }
00208
00209
00210
00211 char* ColladaXML::addVertexSource(tXML* mesh, MeshObjectData* meshdata)
00212 {
00213 if (mesh==NULL || meshdata==NULL) return NULL;
00214
00215 int vnum = meshdata->ttl_vertex;
00216 MeshObjectNode* node = meshdata->nodelist;
00217
00218 Buffer randomstr = make_Buffer_randomstr(8);
00219 Buffer source_id = make_Buffer_str("#SOURCE_POS_");
00220 Buffer source_array_id = make_Buffer_str("#SOURCE_POS_ARRAY_");
00221 cat_Buffer(&randomstr, &source_id);
00222 cat_Buffer(&randomstr, &source_array_id);
00223
00224 tXML* source = add_xml_node(mesh, "source");
00225 add_xml_attr_str(source, "id", _tochar(source_id.buf+1));
00226 tXML* source_array = add_xml_node(source, "float_array");
00227 add_xml_attr_str(source_array, "id", _tochar(source_array_id.buf+1));
00228 add_xml_attr_int(source_array, "count", vnum*3);
00229
00230 if (add_xml_content_area(source_array, meshdata->ttl_vertex*10)) {
00231 while (node!=NULL) {
00232 Vector<double>* vect = node->vertex_value;
00233 for (int i=0; i<node->num_vertex; i++) {
00234 append_xml_content(source_array, dtostr(vect[i].x));
00235 append_xml_content(source_array, dtostr(vect[i].y));
00236 append_xml_content(source_array, dtostr(vect[i].z));
00237 }
00238 node = node->next;
00239 }
00240 }
00241 addPosTechniqueAccessor(source, _tochar(source_array_id.buf), vnum);
00242
00243 free_Buffer(&randomstr);
00244 free_Buffer(&source_array_id);
00245
00246 return _tochar(source_id.buf);
00247 }
00248
00249
00250
00251 char* ColladaXML::addNormalSource(tXML* mesh, MeshObjectData* meshdata)
00252 {
00253 if (mesh==NULL || meshdata==NULL) return NULL;
00254
00255 int vnum = meshdata->ttl_vertex;
00256 MeshObjectNode* node = meshdata->nodelist;
00257
00258 Buffer randomstr = make_Buffer_randomstr(8);
00259 Buffer source_id = make_Buffer_str("#SOURCE_NORMAL_");
00260 Buffer source_array_id = make_Buffer_str("#SOURCE_NORMAL_ARRAY_");
00261 cat_Buffer(&randomstr, &source_id);
00262 cat_Buffer(&randomstr, &source_array_id);
00263
00264 tXML* source = add_xml_node(mesh, "source");
00265 add_xml_attr_str(source, "id", _tochar(source_id.buf+1));
00266 tXML* source_array = add_xml_node(source, "float_array");
00267 add_xml_attr_str(source_array, "id", _tochar(source_array_id.buf+1));
00268 add_xml_attr_int(source_array, "count", vnum*3);
00269
00270 if (add_xml_content_area(source_array, meshdata->ttl_vertex*10)) {
00271 while (node!=NULL) {
00272 Vector<double>* vect = node->normal_value;
00273 for (int i=0; i<node->num_vertex; i++) {
00274 append_xml_content(source_array, dtostr(vect[i].x));
00275 append_xml_content(source_array, dtostr(vect[i].y));
00276 append_xml_content(source_array, dtostr(vect[i].z));
00277 }
00278 node = node->next;
00279 }
00280 }
00281 addPosTechniqueAccessor(source, _tochar(source_array_id.buf), vnum);
00282
00283 free_Buffer(&randomstr);
00284 free_Buffer(&source_array_id);
00285
00286 return _tochar(source_id.buf);
00287 }
00288
00289
00290
00291
00292
00293 char* ColladaXML::addTexcrdSource(tXML* mesh, MeshObjectData* meshdata)
00294 {
00295 if (mesh==NULL || meshdata==NULL) return NULL;
00296
00297 int vnum = meshdata->ttl_vertex;
00298 MeshObjectNode* node = meshdata->nodelist;
00299
00300 Buffer randomstr = make_Buffer_randomstr(8);
00301 Buffer source_id = make_Buffer_str("#SOURCE_MAP_");
00302 Buffer source_array_id = make_Buffer_str("#SOURCE_MAP_ARRAY_");
00303 cat_Buffer(&randomstr, &source_id);
00304 cat_Buffer(&randomstr, &source_array_id);
00305
00306 tXML* source = add_xml_node(mesh, "source");
00307 add_xml_attr_str(source, "id", _tochar(source_id.buf+1));
00308 tXML* source_array = add_xml_node(source, "float_array");
00309 add_xml_attr_str(source_array, "id", _tochar(source_array_id.buf+1));
00310 add_xml_attr_int(source_array, "count", vnum*2);
00311
00312 if (add_xml_content_area(source_array, meshdata->ttl_texcrd*10)) {
00313 while (node!=NULL) {
00314 size_t len = node->num_texcrd*sizeof(UVMap<double>);
00315 UVMap<double>* uvmap = (UVMap<double>*)malloc(len);
00316 if (uvmap!=NULL) {
00317 memcpy(uvmap, node->texcrd_value, len);
00318
00319 if (node->material_param.mapping==MATERIAL_MAPPING_PLANAR) {
00320 Vector<double> scale(1.0, 1.0, 1.0);
00321 if (meshdata->affine_trans!=NULL) scale = meshdata->affine_trans->scale;
00322 node->generatePlanarUVMap(scale, uvmap);
00323 }
00324 node->execAffineTrans(uvmap, node->num_texcrd);
00325
00326 for (int i=0; i<node->num_texcrd; i++) {
00327 append_xml_content(source_array, dtostr(uvmap[i].u));
00328 append_xml_content(source_array, dtostr(uvmap[i].v));
00329 }
00330 ::free(uvmap);
00331 }
00332 node = node->next;
00333 }
00334 }
00335 addMapTechniqueAccessor(source, _tochar(source_array_id.buf), vnum);
00336
00337 free_Buffer(&randomstr);
00338 free_Buffer(&source_array_id);
00339
00340 return _tochar(source_id.buf);
00341 }
00342
00343
00344
00345 char* ColladaXML::addVerticesPos(tXML* mesh, const char* position_id)
00346 {
00347 if (mesh==NULL || position_id==NULL) return NULL;
00348
00349 Buffer randomstr = make_Buffer_randomstr(8);
00350 Buffer vertex_id = make_Buffer_str("#VERTEX_");
00351 cat_Buffer(&randomstr, &vertex_id);
00352
00353
00354 tXML* vertices = add_xml_node(mesh, "vertices");
00355 add_xml_attr_str(vertices, "id", _tochar(vertex_id.buf+1));
00356 tXML* position_input = add_xml_node(vertices, "input");
00357 add_xml_attr_str(position_input, "semantic", "POSITION");
00358 add_xml_attr_str(position_input, "source", position_id);
00359
00360 free_Buffer(&randomstr);
00361
00362 return _tochar(vertex_id.buf);
00363 }
00364
00365
00366
00367 void ColladaXML::addPosTechniqueAccessor(tXML* source, const char* source_array_id, int count)
00368 {
00369 if (source==NULL || source_array_id==NULL) return;
00370
00371 tXML* technique_common = add_xml_node(source, "technique_common");
00372 tXML* accessor = add_xml_node(technique_common, "accessor");
00373 add_xml_attr_str(accessor, "source", source_array_id);
00374 add_xml_attr_int(accessor, "count", count);
00375 add_xml_attr_int(accessor, "stride", 3);
00376
00377 tXML* param_x = add_xml_node(accessor, "param");
00378 tXML* param_y = add_xml_node(accessor, "param");
00379 tXML* param_z = add_xml_node(accessor, "param");
00380 add_xml_attr_str(param_x, "name", "X");
00381 add_xml_attr_str(param_y, "name", "Y");
00382 add_xml_attr_str(param_z, "name", "Z");
00383 add_xml_attr_str(param_x, "type", "float");
00384 add_xml_attr_str(param_y, "type", "float");
00385 add_xml_attr_str(param_z, "type", "float");
00386
00387 return;
00388 }
00389
00390
00391
00392 void ColladaXML::addMapTechniqueAccessor(tXML* source, const char* source_array_id, int count)
00393 {
00394 if (source==NULL || source_array_id==NULL) return;
00395
00396 tXML* technique_common = add_xml_node(source, "technique_common");
00397 tXML* accessor = add_xml_node(technique_common, "accessor");
00398 add_xml_attr_str(accessor, "source", source_array_id);
00399 add_xml_attr_int(accessor, "count", count);
00400 add_xml_attr_int(accessor, "stride", 2);
00401
00402 tXML* param_s = add_xml_node(accessor, "param");
00403 tXML* param_t = add_xml_node(accessor, "param");
00404 add_xml_attr_str(param_s, "name", "S");
00405 add_xml_attr_str(param_t, "name", "T");
00406 add_xml_attr_str(param_s, "type", "float");
00407 add_xml_attr_str(param_t, "type", "float");
00408
00409 return;
00410 }
00411
00412
00413
00414
00415 void ColladaXML::addPolylists(tXML* mesh, MeshObjectData* meshdata, const char* vertex_id, const char* normal_id, const char* texcrd_id)
00416 {
00417 if (vertex_id==NULL || meshdata==NULL) return;
00418
00419 int pnum = 0;
00420 MeshObjectNode* node = meshdata->nodelist;
00421
00422 while (node!=NULL) {
00423
00424 tXML* polylist = add_xml_node(mesh, "polylist");
00425 add_xml_attr_int(polylist, "count", node->num_polygon);
00426
00427
00428 if (node->material_param.enable && node->material_id.buf!=NULL) {
00429
00430 add_xml_attr_str(polylist, "material", _tochar(node->material_id.buf+1));
00431 if (!node->same_material) {
00432 char* material = _tochar(node->material_id.buf+1);
00433 bool exist_same_material = existSameID(library_materials, "<library_materials><material>", material);
00434 if (!exist_same_material) {
00435 char* material_url = addMaterial(_tochar(node->material_id.buf+1));
00436 char* file_id = addImage(node->material_param.getTextureName());
00437 tXML* profile = addEffect(material_url, file_id, node->material_param);
00438 ::free(material_url);
00439 ::free(file_id);
00440
00441 char* bump_id = addImage(node->material_param.getBumpMapName());
00442 if (bump_id!=NULL) {
00443 addExtraBumpmap(profile, bump_id);
00444 ::free(bump_id);
00445 }
00446 }
00447 }
00448 }
00449
00450
00451 tXML* vertex_input = add_xml_node(polylist, "input");
00452 add_xml_attr_str(vertex_input, "semantic", "VERTEX");
00453 add_xml_attr_str(vertex_input, "source", vertex_id);
00454 add_xml_attr_int(vertex_input, "offset", 0);
00455
00456 if (normal_id!=NULL) {
00457 tXML* normal_input = add_xml_node(polylist, "input");
00458 add_xml_attr_str(normal_input, "semantic", "NORMAL");
00459 add_xml_attr_str(normal_input, "source", normal_id);
00460 add_xml_attr_int(normal_input, "offset", 0);
00461 }
00462
00463 if (texcrd_id!=NULL) {
00464 tXML* normal_input = add_xml_node(polylist, "input");
00465 add_xml_attr_str(normal_input, "semantic", "TEXCOORD");
00466 add_xml_attr_str(normal_input, "source", texcrd_id);
00467 add_xml_attr_int(normal_input, "offset", 0);
00468 }
00469
00470 tXML* vcount = add_xml_node(polylist, "vcount");
00471 if (add_xml_content_area(vcount, node->num_polygon*10)) {
00472 for (int i=0; i<node->num_polygon; i++) {
00473 append_xml_content(vcount, itostr(meshdata->num_vcount));
00474 }
00475 }
00476
00477 tXML* p_data = add_xml_node(polylist, "p");
00478 if (add_xml_content_area(p_data, meshdata->num_vcount*10)) {
00479 for (int i=0; i<node->num_polygon; i++) {
00480 int n = i*meshdata->num_vcount;
00481 for (int j=0; j<meshdata->num_vcount; j++) {
00482 append_xml_content(p_data, itostr(node->data_index[n+j] + pnum));
00483 }
00484 append_xml_content(p_data, "");
00485 }
00486 }
00487
00488 pnum += node->num_vertex;
00489 node = node->next;
00490 }
00491
00492 return;
00493 }
00494
00495
00496
00497 char* ColladaXML::addImage(const char* fn)
00498 {
00499 if (fn==NULL) return NULL;
00500
00501 Buffer filename = make_Buffer_str(fn);
00502 Buffer temp_id = replace_sBuffer_str(filename, ".", "_");
00503 Buffer file_id = replace_sBuffer_str(temp_id , " ", "_");
00504 free_Buffer(&temp_id);
00505
00506 bool exist_same_image = existSameID(library_images, "<library_images><image>", _tochar(file_id.buf));
00507 if (!exist_same_image) {
00508 tXML* image = add_xml_node(library_images, "image");
00509 add_xml_attr_str(image, "id", _tochar(file_id.buf));
00510 add_xml_attr_str(image, "name", _tochar(file_id.buf));
00511 add_xml_attr_int(image, "height", 0);
00512 add_xml_attr_int(image, "width", 0);
00513
00514 tXML* init_from = add_xml_node(image, "init_from");
00515 append_xml_content(init_from, _tochar(filename.buf));
00516 }
00517
00518 free_Buffer(&filename);
00519
00520 return _tochar(file_id.buf);
00521 }
00522
00523
00524
00525 char* ColladaXML::addMaterial(const char* material_id)
00526 {
00527 if (material_id==NULL) return NULL;
00528
00529 Buffer material_url = make_Buffer_str("#");
00530 cat_s2Buffer(material_id, &material_url);
00531 cat_s2Buffer("_URL", &material_url);
00532
00533 tXML* material = add_xml_node(library_materials, "material");
00534 add_xml_attr_str(material, "id", material_id);
00535 tXML* instance_effect = add_xml_node(material, "instance_effect");
00536 add_xml_attr_str(instance_effect, "url", _tochar(material_url.buf));
00537
00538 return _tochar(material_url.buf);
00539 }
00540
00541
00542
00543 tXML* ColladaXML::addEffect(const char* material_url, const char* file_id, MaterialParam mparam)
00544 {
00545 if (material_url==NULL || file_id==NULL) return NULL;
00546
00547 Buffer fid = make_Buffer_str(file_id);
00548 Buffer srf = make_Buffer_str(file_id);
00549 Buffer smp = make_Buffer_str(file_id);
00550
00551 Buffer randomstr = make_Buffer_randomstr(5);
00552 cat_s2Buffer("-", &srf);
00553 cat_s2Buffer("-", &smp);
00554 cat_s2Buffer(randomstr.buf, &srf);
00555 cat_s2Buffer(randomstr.buf, &smp);
00556 cat_s2Buffer("-surface", &srf);
00557 cat_s2Buffer("-sampler", &smp);
00558 free_Buffer(&randomstr);
00559
00560 tXML* effect = add_xml_node(library_effects, "effect");
00561 add_xml_attr_str(effect, "id", material_url+1);
00562 tXML* profile = add_xml_node(effect, "profile_COMMON");
00563
00564 if (!isBlankTexture(mparam.getTextureName())) {
00565 tXML* newparam;
00566 newparam = add_xml_node(profile, "newparam");
00567 add_xml_attr_str(newparam, "sid", _tochar(srf.buf));
00568 tXML* surface = add_xml_node(newparam, "surface");
00569 add_xml_attr_str(surface, "type", "2D");
00570 tXML* init_from = add_xml_node(surface, "init_from");
00571 append_xml_content(init_from, _tochar(fid.buf));
00572
00573 newparam = add_xml_node(profile, "newparam");
00574 add_xml_attr_str(newparam, "sid", _tochar(smp.buf));
00575 tXML* sample = add_xml_node(newparam, "sampler2D");
00576 tXML* source = add_xml_node(sample, "source");
00577 append_xml_content(source, _tochar(srf.buf));
00578 }
00579
00580 tXML* technique = add_xml_node(profile, "technique");
00581 add_xml_attr_str(technique, "sid", "common");
00582 tXML* phong = add_xml_node(technique, "phong");
00583
00584
00585 if (mparam.isSetGlow()) {
00586 tXML* emission = add_xml_node(phong, "emission");
00587 tXML* color = add_xml_node(emission, "color");
00588 for (int i=0; i<3; i++) append_xml_content(color, dtostr(mparam.getGlow()));
00589 append_xml_content(color, "1.0");
00590 }
00591
00592
00593 if (mparam.isSetBright()) {
00594 tXML* ambient = add_xml_node(phong, "ambient");
00595 tXML* color = add_xml_node(ambient, "color");
00596 for (int i=0; i<3; i++) append_xml_content(color, dtostr(mparam.getBright()));
00597 append_xml_content(color, "1.0");
00598 }
00599
00600
00601 tXML* diffuse = NULL;
00602 if (!isBlankTexture(mparam.getTextureName())) {
00603 diffuse = add_xml_node(phong, "diffuse");
00604 tXML* texture = add_xml_node(diffuse, "texture");
00605 add_xml_attr_str(texture, "texture", _tochar(smp.buf));
00606 add_xml_attr_str(texture, "texcoord", _tochar(fid.buf));
00607 }
00608
00609
00610 if (mparam.isSetColor()) {
00611 if (diffuse==NULL || forUnity3D) {
00612
00613
00614 diffuse = add_xml_node(phong, "diffuse");
00615 }
00616
00617 tXML* color = add_xml_node(diffuse, "color");
00618 add_xml_attr_str(color, "sid", "diffuse");
00619 for (int i=0; i<4; i++) {
00620 double col = mparam.getColor(i);
00621
00622 append_xml_content(color, dtostr(col));
00623 }
00624 }
00625
00626
00627 if (mparam.isTransparency()) {
00628 double alpha = Min(mparam.getTransparent(), mparam.getColor(3));
00629 if (forUnity3D && alpha<0.01) alpha = 0.01;
00630 tXML* transparency = add_xml_node(phong, "transparency");
00631 tXML* transfloat = add_xml_node(transparency, "float");
00632 append_xml_content(transfloat, dtostr(alpha));
00633 }
00634
00635
00636 if (mparam.isSetShininess()) {
00637 tXML* specular = add_xml_node(phong, "specular");
00638 tXML* color = add_xml_node(specular, "color");
00639 for (int i=0; i<4; i++) append_xml_content(color, dtostr(mparam.specmap.getColor(i)));
00640
00641 tXML* shininess = add_xml_node(phong, "shininess");
00642 tXML* shinfloat = add_xml_node(shininess, "float");
00643 append_xml_content(shinfloat, dtostr(mparam.getShininess()));
00644 }
00645
00646 free_Buffer(&fid);
00647 free_Buffer(&srf);
00648 free_Buffer(&smp);
00649
00650 return profile;
00651 }
00652
00653
00654
00655 void ColladaXML::addExtraBumpmap(tXML* profile, const char* bump_id)
00656 {
00657 if (profile==NULL || bump_id==NULL) return;
00658
00659 Buffer fid = make_Buffer_str(bump_id);
00660 Buffer srf = make_Buffer_str(bump_id);
00661 Buffer smp = make_Buffer_str(bump_id);
00662
00663 Buffer randomstr = make_Buffer_randomstr(5);
00664 cat_s2Buffer("-", &srf);
00665 cat_s2Buffer("-", &smp);
00666 cat_s2Buffer(randomstr.buf, &srf);
00667 cat_s2Buffer(randomstr.buf, &smp);
00668 cat_s2Buffer("-surface", &srf);
00669 cat_s2Buffer("-sampler", &smp);
00670 free_Buffer(&randomstr);
00671
00672 tXML* newparam;
00673 newparam = insert_xml_node(profile, "newparam");
00674 add_xml_attr_str(newparam, "sid", _tochar(smp.buf));
00675 tXML* sample = add_xml_node(newparam, "sampler2D");
00676 tXML* source = add_xml_node(sample, "source");
00677 append_xml_content(source, _tochar(srf.buf));
00678
00679 newparam = insert_xml_node(profile, "newparam");
00680 add_xml_attr_str(newparam, "sid", _tochar(srf.buf));
00681 tXML* surface = add_xml_node(newparam, "surface");
00682 add_xml_attr_str(surface, "type", "2D");
00683 tXML* init_from = add_xml_node(surface, "init_from");
00684 append_xml_content(init_from, _tochar(fid.buf));
00685
00686 tXML* technique = get_xml_node_bystr(profile, "<technique>");
00687 tXML* extra = add_xml_node(technique, "extra");
00688 tXML* techbump = add_xml_node(extra, "technique");
00689 add_xml_attr_str(techbump, "profile", "BumpMap");
00690 tXML* bump = add_xml_node(techbump, "bump");
00691
00692 tXML* texture = add_xml_node(bump, "texture");
00693 add_xml_attr_str(texture, "texture", _tochar(smp.buf));
00694 add_xml_attr_str(texture, "texcoord", _tochar(fid.buf));
00695
00696 free_Buffer(&fid);
00697 free_Buffer(&srf);
00698 free_Buffer(&smp);
00699
00700 return;
00701 }
00702
00703
00704
00705
00706 void ColladaXML::addScene(const char* geometry_id, MeshObjectData* meshdata, bool collider)
00707 {
00708 if (geometry_id==NULL || meshdata==NULL) return;
00709
00710 bool local_affine = true;
00711 AffineTrans<double> affine;
00712 if (meshdata->affine_trans!=NULL) {
00713 local_affine = false;
00714 affine.free();
00715 affine = *(meshdata->affine_trans);
00716 }
00717
00718 Buffer geometry_name = dup_Buffer(meshdata->data_name);
00719 if (geometry_name.buf==NULL) geometry_name = make_Buffer_str(geometry_id+1);
00720
00721
00722 Buffer randomstr = make_Buffer_randomstr(8);
00723 Buffer node_id = make_Buffer_str("#NODE_");
00724 cat_Buffer(&randomstr, &node_id);
00725
00726 tXML* nodetag = add_xml_node(visual_scene, "node");
00727
00728 add_xml_attr_str(nodetag, "id", _tochar(node_id.buf+1));
00729 add_xml_attr_str(nodetag, "name", _tochar(geometry_name.buf));
00730 add_xml_attr_str(nodetag, "type", "NODE");
00731
00732
00733 tXML* rigid_body = NULL;
00734 tXML* instance_rigid_body = NULL;
00735 if (collider) {
00736 rigid_body = add_xml_node(physics_model, "rigid_body");
00737 add_xml_attr_str(rigid_body, "sid", _tochar(node_id.buf+1));
00738 add_xml_attr_str(rigid_body, "name", _tochar(geometry_name.buf));
00739
00740 instance_rigid_body = add_xml_node(instance_physics_model, "instance_rigid_body");
00741 add_xml_attr_str(instance_rigid_body, "body", _tochar(node_id.buf+1));
00742 add_xml_attr_str(instance_rigid_body, "target", _tochar(node_id.buf));
00743 }
00744
00745 free_Buffer(&randomstr);
00746 free_Buffer(&node_id);
00747
00748
00749 affine.computeMatrix(false);
00750 tXML* matrix = add_xml_node(nodetag, "matrix");
00751 for (int i=1; i<=4; i++) {
00752 for (int j=1; j<=4; j++) {
00753 append_xml_content(matrix, dtostr(affine.matrix.element(i,j)));
00754 }
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 tXML* scale = add_xml_node(nodetag, "scale");
00783 add_xml_attr_str(scale, "sid", "scale");
00784 append_xml_content(scale, dtostr(affine.scale.x));
00785 append_xml_content(scale, dtostr(affine.scale.y));
00786 append_xml_content(scale, dtostr(affine.scale.z));
00787
00788 tXML* instance = add_xml_node(nodetag, "instance_geometry");
00789 add_xml_attr_str(instance, "url", geometry_id);
00790
00791 tXML* bind_material = add_xml_node(instance, "bind_material");
00792 tXML* technique_common = add_xml_node(bind_material, "technique_common");
00793
00794 tXML* instance_material;
00795 MeshObjectNode* node = meshdata->nodelist;
00796 while(node!=NULL) {
00797 if (!node->same_material) {
00798 instance_material = add_xml_node(technique_common, "instance_material");
00799 add_xml_attr_str(instance_material, "symbol", _tochar(node->material_id.buf+1));
00800 add_xml_attr_str(instance_material, "target", _tochar(node->material_id.buf));
00801 }
00802 node = node->next;
00803 }
00804
00805
00806 if (collider) {
00807 technique_common = add_xml_node(rigid_body, "technique_common");
00808 tXML* dynamic = add_xml_node(technique_common, "dynamic");
00809 tXML* mass = add_xml_node(technique_common, "mass");
00810 add_xml_content(dynamic, "false");
00811 add_xml_content(mass, "0");
00812 tXML* shape = add_xml_node(technique_common, "shape");
00813 instance = add_xml_node(shape, "instance_geometry");
00814 add_xml_attr_str(instance, "url", geometry_id);
00815 }
00816
00817
00818 free_Buffer(&geometry_name);
00819 if (local_affine) affine.free();
00820
00821 return;
00822 }
00823
00824
00825
00826 bool ColladaXML::existSameID(tXML* top, const char* tag, const char* id)
00827 {
00828 bool ret = false;
00829
00830 tXML* xml = xml_parse((char*)tag);
00831 tXML* lst = get_xml_node_list(top, xml);
00832
00833 Buffer cmpid = make_Buffer_str("\"");
00834 cat_s2Buffer(id, &cmpid);
00835 cat_s2Buffer("\"", &cmpid);
00836
00837 while (lst!=NULL) {
00838 char* attr_id = xml_get_node_attr(lst->altp, "id");
00839 if (!strcmp(attr_id, _tochar(cmpid.buf))) {
00840 ret = true;
00841 break;
00842 }
00843 lst = lst->next;
00844 }
00845
00846 del_xml(&xml);
00847 del_xml(&lst);
00848 free_Buffer(&cmpid);
00849
00850 return ret;
00851 }
00852
00853
00854
00855 void ColladaXML::outputFile(const char* fname, const char* path, int mode)
00856 {
00857 char* packname = pack_head_tail_char(get_file_name(fname), ' ');
00858 Buffer file_name = make_Buffer_bystr(packname);
00859 ::free(packname);
00860
00861 rewrite_sBuffer_bystr(&file_name, ":", "_");
00862 rewrite_sBuffer_bystr(&file_name, "*", "_");
00863 rewrite_sBuffer_bystr(&file_name, "?", "_");
00864 rewrite_sBuffer_bystr(&file_name, "\"", "_");
00865 rewrite_sBuffer_bystr(&file_name, "<", "_");
00866 rewrite_sBuffer_bystr(&file_name, ">", "_");
00867 if (file_name.buf[0]=='.') file_name.buf[0] = '_';
00868
00869 Buffer out_path;
00870 if (path==NULL) out_path = make_Buffer_bystr("./");
00871 else out_path = make_Buffer_bystr(path);
00872 cat_Buffer(&file_name, &out_path);
00873 change_file_extension_Buffer(&out_path, ".dae");
00874
00875 FILE* fp = fopen((char*)out_path.buf, "wb");
00876 if (fp!=NULL) {
00877 print(fp, mode);
00878 fclose(fp);
00879 }
00880 free_Buffer(&file_name);
00881 free_Buffer(&out_path);
00882
00883 return;
00884 }
00885
00886
00887
00888
00890
00891
00892 void ColladaXML::addCenterObject(void)
00893 {
00894 addCenterScene();
00895 return;
00896 }
00897
00898
00899
00900
00901 void ColladaXML::addCenterScene(void)
00902 {
00903 tXML* nodetag = add_xml_node(visual_scene, "node");
00904 add_xml_attr_str(nodetag, "id", "#NODE_DUMMY");
00905 add_xml_attr_str(nodetag, "name", "center_origin");
00906 add_xml_attr_str(nodetag, "type", "NODE");
00907
00908
00909 AffineTrans<double> affine;
00910 affine.computeMatrix(false);
00911 tXML* matrix = add_xml_node(nodetag, "matrix");
00912 for (int i=1; i<=4; i++) {
00913 for (int j=1; j<=4; j++) {
00914 append_xml_content(matrix, dtostr(affine.matrix.element(i,j)));
00915 }
00916 }
00917 affine.free();
00918
00919 return;
00920 }
00921
00922