00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "softToEggConverter.h"
00017 #include "config_softegg.h"
00018 #include "softEggGroupUserData.h"
00019
00020 #include "eggData.h"
00021 #include "eggGroup.h"
00022 #include "eggTable.h"
00023 #include "eggVertex.h"
00024 #include "eggComment.h"
00025 #include "eggVertexPool.h"
00026 #include "eggNurbsSurface.h"
00027 #include "eggNurbsCurve.h"
00028 #include "eggPolygon.h"
00029 #include "eggPrimitive.h"
00030 #include "eggTexture.h"
00031 #include "eggTextureCollection.h"
00032 #include "eggXfmSAnim.h"
00033 #include "eggSAnimData.h"
00034 #include "string_utils.h"
00035 #include "dcast.h"
00036
00037 SoftToEggConverter stec;
00038
00039 const int TEX_PER_MAT = 1;
00040
00041
00042
00043
00044
00045
00046 SoftToEggConverter::
00047 SoftToEggConverter(const string &program_name) :
00048 _program_name(program_name)
00049 {
00050 _from_selection = false;
00051 _polygon_output = false;
00052 _polygon_tolerance = 0.01;
00053
00054
00055
00056
00057 _transform_type = TT_model;
00058
00059 database_name = NULL;
00060 scene_name = NULL;
00061 model_name = NULL;
00062 animFileName = NULL;
00063 eggFileName = NULL;
00064 tex_path = NULL;
00065 eggGroupName = NULL;
00066 tex_filename = NULL;
00067 search_prefix = NULL;
00068 result = SI_SUCCESS;
00069
00070
00071 foundRoot = FALSE;
00072
00073
00074 geom_as_joint = 0;
00075 make_anim = 0;
00076 make_nurbs = 0;
00077 make_poly = 0;
00078 make_soft = 0;
00079 make_morph = 1;
00080 make_duv = 1;
00081 make_dart = TRUE;
00082 has_morph = 0;
00083 make_pose = 0;
00084
00085 nurbs_step = 1;
00086 anim_start = -1000;
00087 anim_end = -1000;
00088 anim_rate = 24;
00089 pose_frame = -1;
00090 verbose = 0;
00091 flatten = 0;
00092 shift_textures = 0;
00093 ignore_tex_offsets = 0;
00094 use_prefix = 0;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103 SoftToEggConverter::
00104 SoftToEggConverter(const SoftToEggConverter ©) :
00105 _from_selection(copy._from_selection),
00106
00107
00108
00109 _polygon_output(copy._polygon_output),
00110 _polygon_tolerance(copy._polygon_tolerance),
00111
00112
00113
00114
00115 _transform_type(copy._transform_type)
00116 {
00117 }
00118
00119
00120
00121
00122
00123
00124 SoftToEggConverter::
00125 ~SoftToEggConverter() {
00126
00127
00128
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 void SoftToEggConverter::
00138 Help()
00139 {
00140 softegg_cat.info() <<
00141 "soft2egg takes a SoftImage scene or model\n"
00142 "and outputs its contents as an egg file\n";
00143
00144 Usage();
00145 }
00146
00147
00148
00149
00150
00151
00152 void SoftToEggConverter::
00153 Usage() {
00154 softegg_cat.info()
00155 << "\nUsage:\n"
00156
00157 << "soft" << " [opts] (must specify -m or -s)\n\n"
00158 << "Options:\n";
00159
00160 ShowOpts();
00161 softegg_cat.info() << "\n";
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171 void SoftToEggConverter::
00172 ShowOpts()
00173 {
00174 softegg_cat.info() <<
00175 " -r <path> - Used to provide soft with the resource\n"
00176 " Defaults to '/ful/ufs/soft371_mips2/3D/rsrc'.\n"
00177 " -d <path> - Database path.\n"
00178 " -s <scene> - Indicates that a scene will be converted.\n"
00179 " -m <model> - Indicates that a model will be converted.\n"
00180 " -t <path> - Specify path to place converted textures.\n"
00181 " -T <name> - Specify filename for texture map listing.\n"
00182 " -S <step> - Specify step for nurbs surface triangulation.\n"
00183 " -M <name> - Specify model output filename. Defaults to scene name.\n"
00184 " -A <name> - Specify anim output filename. Defaults to scene name.\n"
00185 " -N <name> - Specify egg group name.\n"
00186 " -k - Enable soft assignment for geometry.\n"
00187 " -n - Specify egg NURBS representation instead of poly's.\n"
00188 " -p - Specify egg polygon output for geometry.\n"
00189 " -P <frame> - Specify frame number for static pose.\n"
00190 " -b <frame> - Specify starting frame for animation (default = first).\n"
00191 " -e <frame> - Specify ending frame for animation (default = last).\n"
00192 " -f <fps> - Specify frame rate for animation playback.\n"
00193 " -a - Compile animation tables if animation present.\n"
00194 " -F - Ignore hierarchy and build a completely flat skeleton.\n"
00195 " -v <level> - Set debug level.\n"
00196 " -x - Shift NURBS parameters to preserve Alias textures.\n"
00197 " -i - Ignore Soft texture uv offsets.\n"
00198 " -u - Use Soft prefix in model names.\n"
00199 " -c - Cancel morph conversion.\n"
00200 " -C - Cancel duv conversion.\n"
00201 " -D - Don't make the output model a character.\n"
00202 " -o <prefix>- Convert only models with given prefix.\n";
00203
00204
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 bool SoftToEggConverter::
00217 DoGetopts(int &argc, char **&argv) {
00218 bool okflag = true;
00219 int i = 0;
00220 softegg_cat.info() << "argc " << argc << "\n";
00221 if (argc <2) {
00222 Usage();
00223 okflag = false;
00224 }
00225 while( i < argc ) {
00226 strcat(_commandLine, argv[i]);
00227 strcat(_commandLine, " ");
00228 ++i;
00229 }
00230 softegg_cat.info() << endl << _commandLine << endl;
00231
00232 i = 1;
00233 while ((i < argc) && (argv[i][0] == '-') && okflag) {
00234 softegg_cat.info() << "arg " << i << " is " << argv[i] << "\n";
00235 okflag = HandleGetopts(i, argc, argv);
00236 }
00237 return okflag;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 bool SoftToEggConverter::
00248 HandleGetopts(int &idx, int argc, char **argv)
00249 {
00250 bool okflag = true;
00251
00252 char flag = argv[idx][1];
00253
00254 switch (flag)
00255 {
00256 case 'r':
00257 if ( strcmp( argv[idx+1], "" ) ) {
00258
00259 rsrc_path = argv[idx+1];
00260 softegg_cat.info() << "using rsrc path " << rsrc_path << "\n";
00261 }
00262 ++idx;
00263 break;
00264
00265 case 'd':
00266 if ( strcmp( argv[idx+1], "" ) ) {
00267
00268 database_name = argv[idx+1];
00269 softegg_cat.info() << "using database " << database_name << "\n";
00270 }
00271 ++idx;
00272 break;
00273
00274 case 's':
00275 if ( strcmp( argv[idx+1], "" ) ) {
00276
00277 scene_name = argv[idx+1];
00278 softegg_cat.info() << "loading scene " << scene_name << "\n";
00279 }
00280 ++idx;
00281 break;
00282
00283 case 'm':
00284 if ( strcmp( argv[idx+1], "" ) ) {
00285
00286 model_name = argv[idx+1];
00287 softegg_cat.info() << "loading model " << model_name << endl;
00288 }
00289 ++idx;
00290 break;
00291
00292 case 't':
00293 if ( strcmp( argv[idx+1], "" ) ) {
00294
00295 tex_path = argv[idx+1];
00296 softegg_cat.info() << "texture path: " << tex_path << endl;
00297 }
00298 ++idx;
00299 break;
00300
00301 case 'T':
00302 if ( strcmp( argv[idx+1], "") ) {
00303
00304 tex_filename = argv[idx+1];
00305 softegg_cat.info() << "creating texture list file: " << tex_filename << endl;
00306 }
00307 ++idx;
00308 break;
00309
00310 case 'S':
00311 if ( strcmp( argv[idx+1], "" ) ) {
00312 nurbs_step = atoi(argv[idx+1]);
00313 softegg_cat.info() << "NURBS step: " << nurbs_step << endl;
00314 }
00315 ++idx;
00316 break;
00317
00318 case 'M':
00319 if ( strcmp( argv[idx+1], "" ) ) {
00320 eggFileName = argv[idx+1];
00321 softegg_cat.info() << "Model output filename: " << eggFileName << endl;
00322 }
00323 ++idx;
00324 break;
00325
00326 case 'A':
00327 if ( strcmp( argv[idx+1], "" ) ) {
00328 animFileName = argv[idx+1];
00329 softegg_cat.info() << "Anim output filename: " << animFileName << endl;
00330 }
00331 ++idx;
00332 break;
00333
00334 case 'N':
00335 if ( strcmp( argv[idx+1], "" ) ) {
00336 eggGroupName = argv[idx+1];
00337 softegg_cat.info() << "Egg group name: " << eggGroupName << endl;
00338 }
00339 ++idx;
00340 break;
00341
00342 case 'o':
00343 if ( strcmp( argv[idx+1], "" ) ) {
00344 search_prefix = argv[idx+1];
00345 softegg_cat.info() << "Only converting models with prefix: " << search_prefix << endl;
00346 }
00347 ++idx;
00348 break;
00349
00350 case 'h':
00351 Help();
00352 exit(1);
00353 break;
00354
00355 case 'c':
00356 make_morph = FALSE;
00357 softegg_cat.info() << "canceling morph conversion\n";
00358 break;
00359
00360 case 'C':
00361 make_duv = FALSE;
00362 softegg_cat.info() << "canceling uv animation conversion\n";
00363 break;
00364
00365 case 'D':
00366 make_dart = FALSE;
00367 softegg_cat.info() << "making a non-character model\n";
00368 break;
00369
00370 case 'k':
00371
00372
00373 softegg_cat.info() << "-k flag no longer necessary\n";
00374 break;
00375
00376 case 'n':
00377 make_nurbs = TRUE;
00378 softegg_cat.info() << "outputting egg NURBS info\n";
00379 break;
00380
00381 case 'p':
00382 make_poly = TRUE;
00383 softegg_cat.info() << "outputting egg polygon info\n";
00384 break;
00385
00386 case 'P':
00387 if ( strcmp( argv[idx+1], "" ) ) {
00388 make_pose = TRUE;
00389 pose_frame = atoi(argv[idx+1]);
00390 softegg_cat.info() << "generating static pose from frame " << pose_frame << endl;
00391 }
00392 ++idx;
00393 break;
00394
00395 case 'a':
00396 make_anim = TRUE;
00397 softegg_cat.info() << "attempting to compile anim tables\n";
00398 break;
00399
00400 case 'F':
00401 flatten = TRUE;
00402 softegg_cat.info() << "building a flat skeleton!!!\n";
00403 break;
00404
00405 case 'x':
00406 shift_textures = TRUE;
00407 softegg_cat.info() << "shifting NURBS parameters...\n";
00408 break;
00409
00410 case 'i':
00411 ignore_tex_offsets = TRUE;
00412 softegg_cat.info() << "ignoring texture offsets...\n";
00413 break;
00414
00415 case 'u':
00416 use_prefix = TRUE;
00417 softegg_cat.info() << "using prefix in model names...\n";
00418 break;
00419
00420
00421 case 'v':
00422 if ( strcmp( argv[idx+1], "" ) ) {
00423 verbose = atoi(argv[idx+1]);
00424 softegg_cat.info() << "using debug level " << verbose << endl;
00425 }
00426 ++idx;
00427 break;
00428
00429 case 'b':
00430 anim_start = atoi(argv[idx]+2);
00431 softegg_cat.info() << "animation starting at frame: " << anim_start << endl;
00432 break;
00433
00434 case 'e':
00435 anim_end = atoi(argv[idx]+2);
00436 softegg_cat.info() << "animation ending at frame: " << anim_end << endl;
00437 break;
00438
00439 case 'f':
00440 if ( strcmp( argv[idx+1], "" ) ) {
00441 anim_rate = atoi(argv[idx+1]);
00442 softegg_cat.info() << "animation frame rate: " << anim_rate << endl;
00443 }
00444 ++idx;
00445 break;
00446
00447 default:
00448 softegg_cat.info() << flag << " flag not supported\n";
00449 okflag = false;
00450 }
00451 idx++;
00452 return (okflag);
00453 }
00454
00455
00456
00457
00458
00459
00460 SomethingToEggConverter *SoftToEggConverter::
00461 make_copy() {
00462 return new SoftToEggConverter(*this);
00463 }
00464
00465
00466
00467
00468
00469
00470
00471 string SoftToEggConverter::
00472 get_name() const {
00473 return "Soft";
00474 }
00475
00476
00477
00478
00479
00480
00481
00482 string SoftToEggConverter::
00483 get_extension() const {
00484 return "mb";
00485 }
00486
00487
00488
00489
00490
00491
00492
00493 SoftNodeDesc *SoftToEggConverter::
00494 find_node(string name) {
00495 return _tree.get_node(name);
00496 }
00497
00498
00499
00500
00501
00502
00503
00504 char *SoftToEggConverter::
00505 GetTextureName( SAA_Scene *scene, SAA_Elem *texture ) {
00506 char *fileName = new char[_MAX_PATH];
00507 char tempName[_MAX_PATH];
00508 SAA_texture2DGetPicName( scene, texture, _MAX_PATH, tempName );
00509
00510 if (tex_path) {
00511
00512 strcpy(fileName, tex_path);
00513
00514
00515 char *tmpName = NULL;
00516 tmpName = strrchr(tempName, '/');
00517 if (tmpName)
00518 tmpName++;
00519 else
00520 tmpName = tempName;
00521
00522
00523 strcat(fileName, "/");
00524 strcat(fileName, tmpName);
00525 }
00526 else {
00527 strcpy(fileName, tempName);
00528 }
00529
00530 strcat(fileName, ".pic");
00531
00532
00533 return fileName;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 bool SoftToEggConverter::
00548 convert_file(const Filename &filename) {
00549 if (!open_api()) {
00550 softegg_cat.error()
00551 << "Soft is not available.\n";
00552 return false;
00553 }
00554 if (_character_name.empty()) {
00555 _character_name = filename.get_basename_wo_extension();
00556 }
00557 return convert_soft(false);
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 bool SoftToEggConverter::
00570 convert_soft(bool from_selection) {
00571 bool all_ok = true;
00572
00573 _from_selection = from_selection;
00574 _textures.clear();
00575
00576 PT(EggData) egg_data = new EggData;
00577 set_egg_data(egg_data);
00578 softegg_cat.spam() << "eggData " << get_egg_data() << "\n";
00579
00580
00581 softegg_cat.info() << _commandLine << endl;
00582 get_egg_data()->insert(get_egg_data()->begin(), new EggComment("", _commandLine));
00583
00584 if (_egg_data->get_coordinate_system() != CS_default) {
00585 softegg_cat.spam() << "coordinate system is not default\n";
00586 exit(1);
00587 }
00588
00589 _tree._use_prefix = use_prefix;
00590 _tree._search_prefix = search_prefix;
00591 all_ok = _tree.build_complete_hierarchy(scene, database);
00592
00593
00594
00595
00596
00597 char *root_name = _tree.GetRootName( eggFileName );
00598
00599 softegg_cat.debug() << "main group name: " << root_name << endl;
00600 if (root_name)
00601 _character_name = root_name;
00602
00603 if (make_poly || make_nurbs) {
00604
00605
00606 Filename output_filename(eggFileName);
00607 _path_replace->_path_store = PS_relative;
00608 _path_replace->_path_directory = output_filename.get_dirname();
00609
00610 if (!convert_char_model()) {
00611 all_ok = false;
00612 }
00613
00614
00615 if (!make_soft_skin()) {
00616 all_ok = false;
00617 }
00618
00619
00620 if (!cleanup_soft_skin()) {
00621 all_ok = false;
00622 }
00623
00624
00625 softegg_cat.info() << "Converted Softimage file\n";
00626
00627
00628 _egg_data->write_egg(output_filename);
00629 softegg_cat.info() << "Wrote Egg file " << output_filename << endl;
00630 }
00631 if (make_anim) {
00632 if (!convert_char_chan()) {
00633 all_ok = false;
00634 }
00635
00636
00637 softegg_cat.info() << "Converted Softimage file\n";
00638
00639
00640 _egg_data->write_egg(Filename(animFileName));
00641 softegg_cat.info() << "Wrote Anim file " << animFileName << endl;
00642 }
00643 return all_ok;
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653 bool SoftToEggConverter::
00654 open_api() {
00655 if ((scene_name == NULL && model_name == NULL) || database_name == NULL) {
00656 Usage();
00657 exit( 1 );
00658 }
00659 if ((result = SAA_Init(rsrc_path, FALSE)) != SI_SUCCESS) {
00660 softegg_cat.info() << "Error: Couldn't get resource path!\n";
00661 exit( 1 );
00662 }
00663
00664 if ((result = SAA_databaseLoad(database_name, &database)) != SI_SUCCESS) {
00665 softegg_cat.info() << "Error: Couldn't load database!\n";
00666 exit( 1 );
00667 }
00668
00669 if ((result = SAA_sceneGetCurrent(&scene)) != SI_SUCCESS) {
00670 softegg_cat.info() << "Error: Couldn't get current scene!\n";
00671 exit( 1 );
00672 }
00673
00674 if ((result = SAA_sceneLoad( &database, scene_name, &scene )) != SI_SUCCESS) {
00675 softegg_cat.info() << "Error: Couldn't load scene " << scene_name << "!\n";
00676 exit( 1 );
00677 }
00678
00679 if ( SAA_updatelistGet( &scene ) == SI_SUCCESS ) {
00680 PN_stdfloat time;
00681
00682 softegg_cat.info() << "setting Scene to frame " << pose_frame << "...\n";
00683
00684 SAA_frame2Seconds( &scene, pose_frame, &time );
00685 SAA_updatelistEvalScene( &scene, time );
00686 if ( make_pose )
00687 SAA_sceneFreeze(&scene);
00688 }
00689
00690
00691 if ( eggFileName == NULL ) {
00692 string madeName;
00693 string tempName(scene_name);
00694 string::size_type end = tempName.find(".dsc");
00695 if (end != string::npos) {
00696 madeName.assign(tempName.substr(0,end));
00697 if ( make_nurbs )
00698 madeName.insert(madeName.size(), "-nurb");
00699 madeName.insert(madeName.size(), ".egg" );
00700 }
00701 eggFileName = new char[madeName.size()+1];
00702 strcpy(eggFileName, madeName.c_str());
00703
00704
00705 if ( animFileName == NULL ) {
00706 madeName.assign(tempName.substr(0,end));
00707 madeName.insert(madeName.size(), "-chan.egg");
00708 animFileName = new char[strlen(scene_name)+ 10];
00709 strcpy(animFileName, madeName.c_str());
00710 }
00711 }
00712
00713 return true;
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723 void SoftToEggConverter::
00724 close_api() {
00725
00726 }
00727
00728
00729
00730
00731
00732
00733
00734 bool SoftToEggConverter::
00735 convert_char_model() {
00736 softegg_cat.spam() << "character name " << _character_name << "\n";
00737 EggGroup *char_node = new EggGroup(eggGroupName);
00738 get_egg_data()->add_child(char_node);
00739 char_node->set_dart_type(EggGroup::DT_default);
00740
00741 return convert_hierarchy(char_node);
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751 EggSAnimData *SoftToEggConverter::
00752 find_morph_table(char *name) {
00753 EggSAnimData *anim = NULL;
00754 MorphTable::iterator mt;
00755 for (mt = _morph_table.begin(); mt != _morph_table.end(); ++mt) {
00756 anim = (*mt);
00757 if (!strcmp(anim->get_name().c_str(), name))
00758 return anim;
00759 }
00760
00761
00762 anim = new EggSAnimData(name);
00763 anim->set_fps(_tree._fps);
00764 _morph_table.push_back(anim);
00765 morph_node->add_child(anim);
00766 return anim;
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776 bool SoftToEggConverter::
00777 convert_char_chan() {
00778 int start_frame = -1;
00779 int end_frame = -1;
00780 int frame_inc, frame;
00781 double output_frame_rate = anim_rate;
00782
00783 PN_stdfloat time;
00784
00785 EggTable *root_table_node = new EggTable();
00786 get_egg_data()->add_child(root_table_node);
00787 EggTable *bundle_node = new EggTable(eggGroupName);
00788 bundle_node->set_table_type(EggTable::TT_bundle);
00789 root_table_node->add_child(bundle_node);
00790 EggTable *skeleton_node = new EggTable("<skeleton>");
00791 bundle_node->add_child(skeleton_node);
00792
00793 morph_node = new EggTable("morph");
00794
00795
00796
00797 SAA_sceneGetPlayCtrlStartFrame(&scene, &start_frame);
00798 SAA_sceneGetPlayCtrlEndFrame(&scene, &end_frame);
00799 SAA_sceneGetPlayCtrlFrameStep( &scene, &frame_inc );
00800 if (frame_inc != 1)
00801 frame_inc = 1;
00802
00803 softegg_cat.info() << "animation start frame: " << start_frame << " end frame: " << end_frame << endl;
00804 softegg_cat.info() << "animation frame inc: " << frame_inc << endl;
00805
00806 _tree._fps = output_frame_rate / frame_inc;
00807
00808 _tree.clear_egg(get_egg_data(), NULL, skeleton_node);
00809
00810
00811
00812
00813
00814
00815
00816 PT(EggGroup) tgroup = new EggGroup;
00817
00818 int num_nodes = _tree.get_num_nodes();
00819 int i;
00820
00821
00822
00823
00824 if (make_pose) {
00825 start_frame = pose_frame;
00826 end_frame = pose_frame;
00827 }
00828 if (anim_start > 0)
00829 start_frame = anim_start;
00830 if (anim_end > 0)
00831 end_frame = anim_end;
00832 for ( frame = start_frame; frame <= end_frame; frame += frame_inc) {
00833 SAA_frame2Seconds( &scene, frame, &time );
00834
00835 if (!make_pose) {
00836 SAA_updatelistEvalScene( &scene, time );
00837 }
00838 softegg_cat.spam() << "\n> animating frame " << frame << endl;
00839
00840
00841
00842 softegg_cat.info() << "frame " << time << "\n";
00843
00844
00845
00846
00847
00848
00849
00850 for (i = 0; i < num_nodes; i++) {
00851 SoftNodeDesc *node_desc = _tree.get_node(i);
00852
00853 if (node_desc->is_partial(search_prefix)) {
00854 softegg_cat.debug() << endl;
00855 continue;
00856 }
00857 if (make_morph) {
00858 node_desc->make_morph_table(time);
00859 }
00860 if (node_desc->is_joint()) {
00861 softegg_cat.spam() << "-----joint " << node_desc->get_name() << "\n";
00862 EggXfmSAnim *anim = _tree.get_egg_anim(node_desc);
00863
00864 node_desc->get_joint_transform(&scene, tgroup, anim, TRUE);
00865 }
00866 }
00867
00868
00869 }
00870
00871 if (has_morph)
00872 bundle_node->add_child(morph_node);
00873
00874
00875
00876
00877 for (i = 0; i < num_nodes; i++) {
00878 SoftNodeDesc *node_desc = _tree.get_node(i);
00879 if (node_desc->is_partial(search_prefix))
00880 continue;
00881
00882 if (node_desc->is_joint()) {
00883 _tree.get_egg_anim(node_desc)->optimize();
00884 }
00885 }
00886
00887 softegg_cat.info(false)
00888 << "\n";
00889
00890 return true;
00891 }
00892
00893
00894
00895
00896
00897
00898
00899 bool SoftToEggConverter::
00900 convert_hierarchy(EggGroupNode *egg_root) {
00901 int num_nodes = _tree.get_num_nodes();
00902
00903 _tree.clear_egg(get_egg_data(), egg_root, NULL);
00904 softegg_cat.spam() << "num_nodes = " << num_nodes << endl;
00905 for (int i = 0; i < num_nodes; i++) {
00906 if (!process_model_node(_tree.get_node(i))) {
00907 return false;
00908 }
00909 softegg_cat.debug() << i << endl;
00910 }
00911 return true;
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 bool SoftToEggConverter::
00923 process_model_node(SoftNodeDesc *node_desc) {
00924 EggGroup *egg_group = NULL;
00925 const char *name = NULL;
00926 char *fullname = NULL;
00927 SAA_ModelType type;
00928
00929 name = node_desc->get_name().c_str();
00930 softegg_cat.debug() << "element name <" << name << ">\n";
00931
00932 if (node_desc->is_junk()) {
00933 softegg_cat.spam() << "no processing, it is junk\n";
00934 return true;
00935 }
00936
00937
00938 if (node_desc->is_partial(search_prefix)) {
00939 softegg_cat.debug() << endl;
00940 return true;
00941 }
00942 else
00943 softegg_cat.debug() << endl << name << ":being processed" << endl;
00944
00945 egg_group = _tree.get_egg_group(node_desc);
00946
00947
00948 SAA_modelGetType( &scene, node_desc->get_model(), &type );
00949
00950 softegg_cat.debug() << "encountered ";
00951 switch(type){
00952 case SAA_MNILL:
00953 softegg_cat.debug() << "null\n";
00954 break;
00955 case SAA_MPTCH:
00956 softegg_cat.debug() << "patch\n";
00957 break;
00958 case SAA_MFACE:
00959 softegg_cat.debug() << "face\n";
00960
00961 case SAA_MSMSH:
00962 softegg_cat.debug() << "mesh\n";
00963 node_desc->get_transform(&scene, egg_group, TRUE);
00964 make_polyset(node_desc, egg_group, type);
00965 break;
00966 case SAA_MJNT:
00967 softegg_cat.debug() << "joint";
00968 softegg_cat.debug() << " joint type " << node_desc->is_joint() << endl;
00969 break;
00970 case SAA_MSPLN:
00971 softegg_cat.debug() << "spline\n";
00972 break;
00973 case SAA_MMETA:
00974 softegg_cat.debug() << "meta element\n";
00975 break;
00976 case SAA_MBALL:
00977 softegg_cat.debug() << "meta ball\n";
00978 break;
00979 case SAA_MNCRV:
00980 softegg_cat.debug() << "nurbs curve\n";
00981 break;
00982 case SAA_MNSRF:
00983 softegg_cat.debug() << "nurbs surf\n";
00984 node_desc->get_transform(&scene, egg_group, TRUE);
00985 make_nurb_surface(node_desc, egg_group, type);
00986 break;
00987 default:
00988 softegg_cat.debug() << "unknown type: " << type << "\n";
00989 }
00990
00991 if (node_desc->is_joint())
00992 node_desc->get_transform(&scene, egg_group, FALSE);
00993
00994 return true;
00995 }
00996
00997
00998
00999
01000
01001
01002
01003
01004 void SoftToEggConverter::
01005 make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
01006 int id = 0;
01007 int i, idx;
01008 int numShapes;
01009 SAA_Boolean valid;
01010 SAA_Boolean visible;
01011 PN_stdfloat *uCoords = NULL;
01012 PN_stdfloat *vCoords = NULL;
01013 string name = node_desc->get_name();
01014
01015 SAA_modelGetNodeVisibility( &scene, node_desc->get_model(), &visible );
01016 softegg_cat.spam() << "model visibility: " << visible << endl;
01017
01018
01019
01020
01021
01022
01023 if ( visible &&
01024 (type != SAA_MNILL) &&
01025 (type != SAA_MJNT) &&
01026 ((make_poly ||
01027 (make_nurbs && ((type == SAA_MSMSH) || (type == SAA_MFACE )) )) ||
01028 (!make_poly && !make_nurbs && make_duv &&
01029 ((type == SAA_MSMSH) || (type == SAA_MFACE )) ))
01030 )
01031 {
01032
01033 SAA_modelGetNbShapes( &scene, node_desc->get_model(), &numShapes );
01034 softegg_cat.spam() << "process_model_node: num shapes: " << numShapes << endl;
01035
01036
01037 node_desc->load_poly_model(&scene, type);
01038
01039 string vpool_name = name + ".verts";
01040 EggVertexPool *vpool = new EggVertexPool(vpool_name);
01041 vpool->set_highest_index(0);
01042
01043
01044
01045
01046
01047
01048 _tree.get_egg_root()->insert(_tree.get_egg_root()->begin(), vpool);
01049
01050
01051
01052
01053
01054
01055
01056 LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv();
01057
01058
01059 for (idx=0; idx<node_desc->numTri; ++idx) {
01060 EggPolygon *egg_poly = new EggPolygon;
01061 egg_group->add_child(egg_poly);
01062
01063 softegg_cat.spam() << "processing polygon " << idx << endl;
01064
01065
01066 char *modelNoteStr = _tree.GetModelNoteInfo( &scene, node_desc->get_model() );
01067 if ( modelNoteStr != NULL ) {
01068 if ( strstr( modelNoteStr, "bface" ) != NULL )
01069 egg_poly->set_bface_flag(TRUE);
01070 }
01071
01072
01073 SAA_SubElem cvertices[3];
01074 SAA_triangleGetCtrlVertices( &scene, node_desc->get_model(), node_desc->gtype, id, 1, node_desc->triangles+idx, cvertices );
01075
01076
01077 SAA_DVector cvertPos[3];
01078 SAA_ctrlVertexGetPositions( &scene, node_desc->get_model(), 3, cvertices, cvertPos);
01079
01080
01081 int indices[3];
01082 indices[0] = indices[1] = indices[2] = 0;
01083 SAA_ctrlVertexGetIndices( &scene, node_desc->get_model(), 3, cvertices, indices );
01084
01085
01086 SAA_DVector normals[3];
01087 SAA_ctrlVertexGetNormals( &scene, node_desc->get_model(), 3, cvertices, normals );
01088 for (i=0; i<3; ++i)
01089 softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " << normals[i].y
01090 << " " << normals[i].z << " " << normals[i].w << "\n";
01091
01092
01093 if (node_desc->textures) {
01094 if (node_desc->numTexLoc && node_desc->numTexTri[idx]) {
01095
01096
01097 uCoords = new PN_stdfloat[3];
01098 vCoords = new PN_stdfloat[3];
01099
01100
01101 if ( uCoords != NULL && vCoords != NULL) {
01102 for ( i = 0; i < 3; i++ )
01103 uCoords[i] = vCoords[i] = 0.0f;
01104
01105
01106 SAA_ctrlVertexGetUVTxtCoords( &scene, node_desc->get_model(), 3, cvertices,
01107 3, uCoords, vCoords );
01108 }
01109 else
01110 softegg_cat.info() << "Not enough Memory for texture coords...\n";
01111
01112 #if 1
01113 for ( i=0; i<3; i++ )
01114 softegg_cat.spam() << "texcoords[" << i << "] = ( " << uCoords[i] << " , " << vCoords[i] <<" )\n";
01115 #endif
01116 }
01117 else if (node_desc->numTexGlb) {
01118
01119 uCoords = new PN_stdfloat[node_desc->numTexGlb*3];
01120 vCoords = new PN_stdfloat[node_desc->numTexGlb*3];
01121
01122 for ( i = 0; i < node_desc->numTexGlb*3; i++ ) {
01123 uCoords[i] = vCoords[i] = 0.0f;
01124 }
01125
01126
01127 if ( uCoords != NULL && vCoords != NULL) {
01128 SAA_triCtrlVertexGetGlobalUVTxtCoords( &scene, node_desc->get_model(), 3, cvertices,
01129 node_desc->numTexGlb, node_desc->textures, uCoords, vCoords );
01130 }
01131 else
01132 softegg_cat.info() << "Not enough Memory for texture coords...\n";
01133 }
01134 }
01135
01136 for ( i=0; i < 3; i++ ) {
01137 EggVertex vert;
01138
01139
01140 SAA_DVector local = cvertPos[i];
01141 SAA_DVector global = {0};
01142
01143 _VCT_X_MAT( global, local, node_desc->matrix );
01144
01145 softegg_cat.spam() << "indices[" << i << "] = " << indices[i] << "\n";
01146 softegg_cat.spam() << "cvert[" << i << "] = " << cvertPos[i].x << " " << cvertPos[i].y
01147 << " " << cvertPos[i].z << " " << cvertPos[i].w << "\n";
01148 softegg_cat.spam() << " global cvert[" << i << "] = " << global.x << " " << global.y
01149 << " " << global.z << " " << global.w << "\n";
01150
01151
01152 LPoint3d p3d(global.x, global.y, global.z);
01153 p3d = p3d * vertex_frame_inv;
01154 vert.set_pos(p3d);
01155
01156 local = normals[i];
01157 _VCT_X_MAT( global, local, node_desc->matrix );
01158
01159 softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " << normals[i].y
01160 << " " << normals[i].z << " " << normals[i].w << "\n";
01161 softegg_cat.spam() << " global normals[" << i <<"] = " << global.x << " " << global.y
01162 << " " << global.z << " " << global.w << "\n";
01163
01164 LVector3d n3d(global.x, global.y, global.z);
01165 n3d = n3d * vertex_frame_inv;
01166 vert.set_normal(n3d);
01167
01168
01169 if (node_desc->textures) {
01170 PN_stdfloat u, v;
01171
01172 if (uCoords && vCoords) {
01173 u = uCoords[i];
01174 v = 1.0f - vCoords[i];
01175 softegg_cat.spam() << "texcoords[" << i << "] = " << u << " "
01176 << v << endl;
01177
01178 vert.set_uv(LTexCoordd(u, v));
01179
01180 }
01181 }
01182 vert.set_external_index(indices[i]);
01183 egg_poly->add_vertex(vpool->create_unique_vertex(vert));
01184
01185
01186 PN_stdfloat r,g,b,a;
01187 SAA_elementIsValid( &scene, &node_desc->materials[idx], &valid );
01188
01189 if ( valid ) {
01190 SAA_materialGetDiffuse( &scene, &node_desc->materials[idx], &r, &g, &b );
01191 SAA_materialGetTransparency( &scene, &node_desc->materials[idx], &a );
01192 egg_poly->set_color(LColor(r, g, b, 1.0f - a));
01193 softegg_cat.spam() << "color r = " << r << " g = " << g << " b = " << b << " a = " << 1.0f - a << "\n";
01194 }
01195 else {
01196 egg_poly->set_color(LColor(1.0, 1.0, 1.0, 1.0));
01197 softegg_cat.spam() << "default color\n";
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210 softegg_cat.spam() << "\n";
01211 }
01212
01213
01214 if (node_desc->textures != NULL) {
01215 if (node_desc->numTexLoc && node_desc->numTexTri[idx]) {
01216 if (!strstr(node_desc->texNameArray[idx], "noIcon"))
01217 set_shader_attributes(node_desc, *egg_poly, idx);
01218 else
01219 softegg_cat.spam() << "texname :" << node_desc->texNameArray[idx] << endl;
01220 }
01221 else {
01222 if (!strstr(node_desc->texNameArray[0], "noIcon"))
01223 set_shader_attributes(node_desc, *egg_poly, 0);
01224 else
01225 softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl;
01226 }
01227 }
01228 }
01229
01230 if ( numShapes > 0 && make_morph )
01231 node_desc->make_vertex_offsets( numShapes);
01232 }
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242 void SoftToEggConverter::
01243 make_nurb_surface(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
01244 int id = 0;
01245 int i, j, k;
01246 int numShapes;
01247 SAA_Boolean valid;
01248 SAA_Boolean visible;
01249 PN_stdfloat *uCoords = NULL;
01250 PN_stdfloat *vCoords = NULL;
01251 string name = node_desc->get_name();
01252
01253 SAA_modelGetNodeVisibility( &scene, node_desc->get_model(), &visible );
01254 softegg_cat.spam() << "model visibility: " << visible << endl;
01255 softegg_cat.spam() << "nurbs!!!surface!!!" << endl;
01256
01257
01258
01259
01260 if ( (type == SAA_MNSRF) && ( visible ) && (( make_nurbs )
01261 || ( !make_nurbs && !make_poly && make_duv )) )
01262 {
01263
01264 SAA_modelGetNbShapes( &scene, node_desc->get_model(), &numShapes );
01265 softegg_cat.spam() << "process_model_node: num shapes: " << numShapes << endl;
01266
01267
01268 node_desc->load_nurbs_model(&scene, type);
01269
01270 string vpool_name = name + ".verts";
01271 EggVertexPool *vpool = new EggVertexPool(vpool_name);
01272 vpool->set_highest_index(0);
01273
01274
01275
01276
01277
01278
01279
01280 _tree.get_egg_root()->insert(_tree.get_egg_root()->begin(), vpool);
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 int uRows, vRows;
01291 int uKnots, vKnots;
01292 int uExtra, vExtra;
01293 int uDegree, vDegree;
01294 int uCurves, vCurves;
01295
01296 vector <double> Knots;
01297
01298 EggNurbsSurface *eggNurbs = new EggNurbsSurface( name );
01299
01300
01301 SAA_nurbsSurfaceGetDegree( &scene, node_desc->get_model(), &uDegree, &vDegree );
01302 softegg_cat.spam() << "nurbs degree: " << uDegree << " u, " << vDegree << " v\n";
01303
01304 SAA_nurbsSurfaceGetNbKnots( &scene, node_desc->get_model(), &uKnots, &vKnots );
01305 softegg_cat.spam() << "nurbs knots: " << uKnots << " u, " << vKnots << " v\n";
01306
01307 SAA_Boolean uClosed = FALSE;
01308 SAA_Boolean vClosed = FALSE;
01309
01310 SAA_nurbsSurfaceGetClosed( &scene, node_desc->get_model(), &uClosed, &vClosed);
01311
01312 uExtra = vExtra = 2;
01313 if ( uClosed ) {
01314 softegg_cat.spam() << "nurbs is closed in u...\n";
01315 uExtra += 4;
01316 }
01317 if ( vClosed ) {
01318 softegg_cat.spam() << "nurbs is closed in v...\n";
01319 vExtra += 4;
01320 }
01321 eggNurbs->setup(uDegree+1, vDegree+1,
01322 uKnots + uExtra, vKnots + vExtra);
01323
01324 softegg_cat.spam() << "from eggNurbs: num u knots " << eggNurbs->get_num_u_knots() << endl;
01325 softegg_cat.spam() << "from eggNurbs: num v knots " << eggNurbs->get_num_v_knots() << endl;
01326 softegg_cat.spam() << "from eggNurbs: num u cvs " << eggNurbs->get_num_u_cvs() << endl;
01327 softegg_cat.spam() << "from eggNurbs: num v cvs " << eggNurbs->get_num_v_cvs() << endl;
01328
01329 SAA_nurbsSurfaceGetNbVertices( &scene, node_desc->get_model(), &uRows, &vRows );
01330 softegg_cat.spam() << "nurbs vertices: " << uRows << " u, " << vRows << " v\n";
01331
01332 SAA_nurbsSurfaceGetNbCurves( &scene, node_desc->get_model(), &uCurves, &vCurves );
01333 softegg_cat.spam() << "nurbs curves: " << uCurves << " u, " << vCurves << " v\n";
01334
01335 if ( shift_textures ) {
01336 if ( uClosed )
01337
01338 SAA_nurbsSurfaceShiftParameterization( &scene, node_desc->get_model(), -2, 0 );
01339
01340 if ( vClosed )
01341
01342 SAA_nurbsSurfaceShiftParameterization( &scene, node_desc->get_model(), 0, -2 );
01343 }
01344
01345 SAA_nurbsSurfaceSetStep( &scene, node_desc->get_model(), nurbs_step, nurbs_step );
01346
01347
01348 char *modelNoteStr = _tree.GetModelNoteInfo( &scene, node_desc->get_model() );
01349 if ( modelNoteStr != NULL ) {
01350 if ( strstr( modelNoteStr, "bface" ) != NULL ) {
01351 eggNurbs->set_bface_flag(TRUE);
01352 softegg_cat.spam() << "Set backface flag\n";
01353 }
01354 }
01355
01356 double *uKnotArray = new double[uKnots];
01357 double *vKnotArray = new double[vKnots];
01358 result = SAA_nurbsSurfaceGetKnots( &scene, node_desc->get_model(), node_desc->gtype, 0,
01359 uKnots, vKnots, uKnotArray, vKnotArray );
01360
01361 if (result != SI_SUCCESS) {
01362 softegg_cat.spam() << "Couldn't get knots\n";
01363 exit(1);
01364 }
01365
01366
01367 add_knots( Knots, uKnotArray, uKnots, uClosed, uDegree );
01368 softegg_cat.spam() << "u knots: ";
01369 for (i = 0; i < (int)Knots.size(); i++) {
01370 softegg_cat.spam() << Knots[i] << " ";
01371 eggNurbs->set_u_knot(i, Knots[i]);
01372 }
01373 softegg_cat.spam() << endl;
01374
01375 Knots.resize(0);
01376 add_knots( Knots, vKnotArray, vKnots, vClosed, vDegree );
01377 softegg_cat.spam() << "v knots: ";
01378 for (i = 0; i < (int)Knots.size(); i++) {
01379 softegg_cat.spam() << Knots[i] << " ";
01380 eggNurbs->set_v_knot(i, Knots[i]);
01381 }
01382 softegg_cat.spam() << endl;
01383
01384
01385 int numVert;
01386 SAA_modelGetNbVertices( &scene, node_desc->get_model(), &numVert );
01387
01388 softegg_cat.spam() << numVert << " CV's\n";
01389
01390
01391 SAA_DVector *vertices = NULL;
01392 vertices = new SAA_DVector[numVert];
01393
01394 SAA_modelGetVertices( &scene, node_desc->get_model(), node_desc->gtype, 0, numVert, vertices );
01395
01396 LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv();
01397
01398
01399 EggVertex *verts = new EggVertex[numVert];
01400
01401 softegg_cat.spam() << endl << eggNurbs->get_num_cvs() << endl << endl;
01402
01403
01404 for ( k = 0; k<numVert; k++ ) {
01405 SAA_DVector global;
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421 _VCT_X_MAT( global, vertices[k], node_desc->matrix );
01422
01423
01424 global.w = vertices[k].w;
01425
01426
01427 global.x *= global.w;
01428 global.y *= global.w;
01429 global.z *= global.w;
01430
01431
01432
01433
01434
01435
01436
01437 LPoint4d p4d(global.x, global.y, global.z, global.w);
01438 p4d = p4d * vertex_frame_inv;
01439 verts[k].set_pos(p4d);
01440
01441
01442 if (node_desc->numNurbMats) {
01443 PN_stdfloat r,g,b,a;
01444 SAA_elementIsValid( &scene, &node_desc->materials[0], &valid );
01445
01446 if ( valid ) {
01447 SAA_materialGetDiffuse( &scene, &node_desc->materials[0], &r, &g, &b );
01448 SAA_materialGetTransparency( &scene, &node_desc->materials[0], &a );
01449 verts[k].set_color(LColor(r, g, b, 1.0f - a));
01450
01451 }
01452 else {
01453 verts[k].set_color(LColor(1.0, 1.0, 1.0, 1.0));
01454 softegg_cat.spam() << "default color\n";
01455 }
01456 }
01457 vpool->add_vertex(verts+k, k);
01458 eggNurbs->add_vertex(vpool->get_vertex(k));
01459
01460 if ( uClosed ) {
01461
01462 if ( (k % uRows) == ( uRows - 1) ) {
01463 for ( i = 0; i < uDegree; i++ ) {
01464
01465 eggNurbs->add_vertex( vpool->get_vertex(i+((k/uRows)*uRows)) );
01466 }
01467 }
01468 }
01469 }
01470
01471
01472 if ( vClosed && !uClosed ) {
01473
01474 for ( int i = 0; i < vDegree*uRows; i++ )
01475 eggNurbs->add_vertex( vpool->get_vertex(i) );
01476 }
01477
01478 else if ( vClosed && uClosed ) {
01479
01480
01481 for ( i = 0; i < vDegree; i++ ) {
01482
01483 for ( j = 0; j < uRows; j++ )
01484 eggNurbs->add_vertex( vpool->get_vertex(j+(i*uRows)) );
01485
01486
01487
01488 for ( k = 0; k < uDegree; k++ )
01489 eggNurbs->add_vertex( vpool->get_vertex(k+(i*uRows)+((k/uRows)*uRows)) );
01490 }
01491 }
01492
01493
01494
01495 egg_group->add_child(eggNurbs);
01496
01497
01498 if (node_desc->textures != NULL) {
01499 if (!strstr(node_desc->texNameArray[0], "noIcon"))
01500 set_shader_attributes(node_desc, *eggNurbs, 0);
01501 else
01502 softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl;
01503 }
01504
01505
01506 if ( numShapes > 0 && make_morph )
01507 node_desc->make_vertex_offsets( numShapes);
01508 }
01509 }
01510
01511
01512
01513
01514
01515
01516
01517
01518 void SoftToEggConverter::
01519 add_knots( vector <double> &eggKnots, double *knots, int numKnots, SAA_Boolean closed, int degree ) {
01520
01521 int k = 0;
01522 double lastKnot = knots[0];
01523 double *newKnots;
01524
01525
01526 if ( closed ) {
01527 int i = 0;
01528 newKnots = new double[degree];
01529
01530
01531 for ( k = numKnots - 1; k >= numKnots - degree; k-- ) {
01532
01533
01534 newKnots[i] = lastKnot - (knots[k] - knots[k-1]);
01535 lastKnot = newKnots[i];
01536 i++;
01537 }
01538 for ( k = degree - 1; k >= 0; k-- ) {
01539 eggKnots.push_back( newKnots[k] );
01540 softegg_cat.spam() << "knots[" << k << "] = " << newKnots[k] << endl;
01541 }
01542 }
01543 else {
01544 eggKnots.push_back( knots[k] );
01545 softegg_cat.spam() << "knots[" << k << "] = " << knots[k] << endl;
01546 }
01547
01548
01549 for (k = 0; k < numKnots; k++) {
01550 eggKnots.push_back( knots[k] );
01551 softegg_cat.spam() << "knots[" << k+1 << "] = " << knots[k] << endl;
01552 }
01553
01554 lastKnot = knots[numKnots-1];
01555
01556
01557 if ( closed ) {
01558
01559 for ( k = 1; k <= degree; k++ ) {
01560 eggKnots.push_back( lastKnot + (knots[k] - knots[k-1]) );
01561 softegg_cat.spam() << "knots[" << k << "] = " << lastKnot + (knots[k] - knots[k-1]) << endl;
01562 lastKnot = lastKnot + (knots[k] - knots[k-1]);
01563 }
01564 }
01565 else {
01566 eggKnots.push_back( knots[k-1] );
01567 softegg_cat.spam() << "knots[" << k+1 << "] = " << knots[k-1] << endl;
01568 }
01569 }
01570
01571
01572
01573
01574
01575
01576
01577
01578 int *SoftToEggConverter::
01579 FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert ) {
01580 int i,j;
01581 int *vertMap = NULL;
01582 int vpoolSize = (int)vpool->size();
01583 PN_stdfloat closestDist;
01584 PN_stdfloat thisDist;
01585 int closest;
01586
01587 vertMap = new int[vpoolSize];
01588 i = 0;
01589 EggVertexPool::iterator vi;
01590 for (vi = vpool->begin(); vi != vpool->end(); ++vi, ++i) {
01591 EggVertex *vert = (*vi);
01592 softegg_cat.spam() << "vert external index = " << vert->get_external_index() << endl;
01593
01594
01595 LPoint3d p3d = vert->get_pos3();
01596
01597
01598 for ( j = 0; j < numVert; j++ ) {
01599
01600 thisDist = sqrtf(
01601 powf( p3d[0] - vertices[j].x , 2 ) +
01602 powf( p3d[1] - vertices[j].y , 2 ) +
01603 powf( p3d[2] - vertices[j].z , 2 ) );
01604
01605
01606 if ( !j || ( thisDist < closestDist ) ) {
01607 closest = j;
01608 closestDist = thisDist;
01609 }
01610 }
01611
01612 vertMap[i] = closest;
01613 softegg_cat.spam() << "mapping v " << i << " of " << vpoolSize-1 << ":( "
01614 << p3d[0] << " "
01615 << p3d[1] << " "
01616 << p3d[2] << ")\n";
01617
01618 softegg_cat.spam() << " to cv " << closest << " of " << numVert-1 << ":( "
01619 << vertices[closest].x << " "
01620 << vertices[closest].y << " "
01621 << vertices[closest].z << " )\tdelta = " << closestDist << endl;
01622 }
01623 return vertMap;
01624 }
01625
01626
01627
01628
01629
01630
01631
01632 bool SoftToEggConverter::
01633 make_soft_skin() {
01634 int num_nodes = _tree.get_num_nodes();
01635 SoftNodeDesc *node_desc;
01636 SAA_Boolean isSkeleton;
01637
01638 softegg_cat.spam() << endl << "----------------------------------------------------------------" << endl;
01639
01640 for (int i = 0; i < num_nodes; i++) {
01641 node_desc = _tree.get_node(i);
01642 SAA_modelIsSkeleton( &scene, node_desc->get_model(), &isSkeleton );
01643
01644 softegg_cat.spam() << "??checking node " << node_desc->get_name() << " isSkel " << isSkeleton << " isJoint " << node_desc->is_joint() << endl;
01645 if (isSkeleton && node_desc->is_joint()) {
01646
01647 if (node_desc->is_partial(search_prefix))
01648 continue;
01649
01650
01651
01652
01653
01654
01655 int numEnv;
01656 SAA_ModelType type;
01657 SAA_Elem *envelopes;
01658 SAA_Elem *model = node_desc->get_model();
01659 EggGroup *joint = NULL;
01660 EggVertexPool *vpool;
01661
01662 SAA_skeletonGetNbEnvelopes( &scene, model, &numEnv );
01663 if ( numEnv == 0 ) {
01664 softegg_cat.spam() << "no soft skinning for joint " << node_desc->get_name() << endl;
01665 continue;
01666 }
01667
01668
01669 softegg_cat.spam() << endl << "found skeleton part( " << node_desc->get_name() << ")!\n";
01670 softegg_cat.spam() << "numEnv = " << numEnv << endl;
01671
01672 envelopes = new SAA_Elem[numEnv];
01673 if ( envelopes == NULL ) {
01674 softegg_cat.info() << "Out Of Memory" << endl;
01675 exit(1);
01676 }
01677 int thisEnv;
01678 SAA_EnvType envType;
01679 bool hasEnvVertices = 0;
01680
01681 SAA_skeletonGetEnvelopes( &scene, model, numEnv, envelopes );
01682 for ( thisEnv = 0; thisEnv < numEnv; thisEnv++ ) {
01683 softegg_cat.spam() << "env[" << thisEnv << "]: ";
01684 SAA_envelopeGetType( &scene, &envelopes[thisEnv], &envType );
01685
01686 if ( envType == SAA_ENVTYPE_NONE ) {
01687 softegg_cat.spam() << "envType = none\n";
01688 }
01689 else if ( envType == SAA_ENVTYPE_FLXLCL ) {
01690 softegg_cat.spam() << "envType = flexible, local\n";
01691 hasEnvVertices = 1;
01692 }
01693 else if ( envType == SAA_ENVTYPE_FLXGLB ) {
01694 softegg_cat.spam() << "envType = flexible, global\n";
01695 hasEnvVertices = 1;
01696 }
01697 else if ( envType == SAA_ENVTYPE_RGDGLB ) {
01698 softegg_cat.spam() << "envType = rigid, global\n";
01699 hasEnvVertices = 1;
01700 }
01701 else {
01702 softegg_cat.spam() << "envType = unknown\n";
01703 }
01704
01705 }
01706 if ( !hasEnvVertices )
01707 continue;
01708
01709 SAA_SubElem *envVertices = NULL;
01710 int *numEnvVertices;
01711 int i,j,k;
01712
01713 numEnvVertices = new int[numEnv];
01714
01715 if ( numEnvVertices != NULL ) {
01716 SAA_envelopeGetNbCtrlVertices( &scene, model, numEnv, envelopes, numEnvVertices );
01717 int totalEnvVertices = 0;
01718 for( i = 0; i < numEnv; i++ ) {
01719 totalEnvVertices += numEnvVertices[i];
01720 softegg_cat.spam() << "numEnvVertices[" << i << "] = " << numEnvVertices[i] << endl;
01721 }
01722 softegg_cat.spam() << "total env verts = " << totalEnvVertices << endl;
01723 if ( totalEnvVertices == 0 )
01724 continue;
01725
01726 envVertices = new SAA_SubElem[totalEnvVertices];
01727 if ( envVertices != NULL ) {
01728 result = SAA_envelopeGetCtrlVertices( &scene, model,
01729 numEnv, envelopes, numEnvVertices, envVertices);
01730 if (result != SI_SUCCESS) {
01731 softegg_cat.spam() << "error: GetCtrlVertices\n";
01732 exit(1);
01733 }
01734
01735 for ( i = 0; i < numEnv; i++ ) {
01736 PN_stdfloat *weights = NULL;
01737 int vertArrayOffset = 0;
01738 softegg_cat.spam() << "envelope[" << i << "]: ";
01739 weights = new PN_stdfloat[numEnvVertices[i]];
01740 if ( weights ) {
01741 char *envName;
01742 int *vpoolMap = NULL;
01743 for ( j = 0; j < i; j++ )
01744 vertArrayOffset += numEnvVertices[j];
01745 softegg_cat.spam() << "envVertArray offset = " << vertArrayOffset;
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756 result = SAA_ctrlVertexGetEnvelopeWeights( &scene, model, &envelopes[i],
01757 numEnvVertices[i],
01758 &envVertices[vertArrayOffset], weights );
01759
01760
01761 if ( use_prefix ) {
01762
01763 envName = _tree.GetFullName( &scene, &envelopes[i] );
01764 }
01765 else {
01766
01767 envName = _tree.GetName( &scene, &envelopes[i] );
01768 }
01769
01770 softegg_cat.spam() << " envelop name is [" << envName << "]" << endl;
01771
01772 if (result != SI_SUCCESS) {
01773 softegg_cat.spam() << "warning: this envelop doesn't have any weights\n";
01774 continue;
01775 }
01776
01777 result = SAA_modelGetType( &scene, &envelopes[i], &type );
01778 if (result != SI_SUCCESS) {
01779 softegg_cat.debug() << "choked on get type\n";
01780 exit(1);
01781 }
01782
01783 softegg_cat.spam() << "envelope model type ";
01784 if ( type == SAA_MSMSH )
01785 softegg_cat.spam() << "MESH\n";
01786 else if ( type == SAA_MNSRF )
01787 softegg_cat.spam() << "NURBS\n";
01788 else
01789 softegg_cat.spam() << "OTHER\n";
01790
01791 int *envVtxIndices = NULL;
01792 envVtxIndices = new int[numEnvVertices[i]];
01793
01794
01795 result = SAA_ctrlVertexGetIndices( &scene, &envelopes[i], numEnvVertices[i],
01796 &envVertices[vertArrayOffset], envVtxIndices );
01797
01798 if (result != SI_SUCCESS) {
01799 softegg_cat.debug() << "error: choked on get indices\n";
01800 exit(1);
01801 }
01802
01803
01804 int modelNumVert;
01805
01806 SAA_modelGetNbVertices( &scene, &envelopes[i], &modelNumVert );
01807
01808 SAA_DVector *modelVertices = NULL;
01809 modelVertices = new SAA_DVector[modelNumVert];
01810
01811
01812 SAA_modelGetVertices( &scene, &envelopes[i],
01813 SAA_GEOM_ORIGINAL, 0, modelNumVert,
01814 modelVertices );
01815
01816
01817 SAA_DVector *globalModelVertices = NULL;
01818 globalModelVertices = new SAA_DVector[modelNumVert];
01819 PN_stdfloat matrix[4][4];
01820
01821
01822
01823
01824 SAA_modelGetMatrix( &scene, &envelopes[i], SAA_COORDSYS_GLOBAL, matrix );
01825
01826
01827 for ( j = 0; j < modelNumVert; j++ ) {
01828 _VCT_X_MAT( globalModelVertices[j],
01829 modelVertices[j], matrix );
01830 }
01831
01832
01833 string s_name = envName;
01834 SoftNodeDesc *mesh_node = find_node(s_name);
01835 if (!mesh_node) {
01836 softegg_cat.debug() << "error: node " << s_name << " not found in tree\n";
01837 exit(1);
01838 }
01839 string vpool_name = s_name + ".verts";
01840 EggNode *t = _tree.get_egg_root()->find_child(vpool_name);
01841 if (t)
01842 DCAST_INTO_R(vpool, t, NULL);
01843
01844
01845 if (vpool) {
01846 softegg_cat.spam() << "found vpool of size " << vpool->size() << endl;
01847 if ( !make_nurbs || (type == SAA_MSMSH) ) {
01848 vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
01849 }
01850 }
01851 else {
01852 softegg_cat.debug() << "warning: vpool " << vpool_name << " not found\n";
01853 continue;
01854 }
01855
01856 joint = node_desc->get_egg_group();
01857
01858 for (j = 0; j < numEnvVertices[i]; j++) {
01859 double scaledWeight = weights[j]/ 100.0f;
01860
01861
01862 if (( envVtxIndices[j] < modelNumVert )
01863 && ( envVtxIndices[j] >= 0 )) {
01864 if ( (type == SAA_MNSRF) && make_nurbs ) {
01865
01866 EggVertex *vert = vpool->get_vertex(envVtxIndices[j]);
01867 if (!vert) {
01868 softegg_cat.debug() << "possible error: index " << envVtxIndices[j] << ": vert is " << vert << endl;
01869 continue;
01870 }
01871 joint->ref_vertex( vert, scaledWeight );
01872 softegg_cat.spam() << j << ": adding vref to cv " << envVtxIndices[j]
01873 << " with weight " << scaledWeight << endl;
01874
01875
01876
01877
01878
01879
01880
01881 }
01882 else {
01883
01884
01885 softegg_cat.spam() << j << "--trying to find " << envVtxIndices[j] << endl;
01886 for ( k = 0; k < (int)vpool->size(); k++ ) {
01887 if ( vpoolMap[k] == envVtxIndices[j] ) {
01888 EggVertex *vert = vpool->get_vertex(k+1);
01889
01890 if (!vert) {
01891 softegg_cat.debug() << "possible error: index " << k+1 << ": vert is " << vert << endl;
01892 break;
01893 }
01894
01895 joint->ref_vertex(vert, scaledWeight);
01896 softegg_cat.spam() << j << ": adding vref from cv " << envVtxIndices[j]
01897 << " to vert " << k+1 << " with weight " << scaledWeight
01898 << "(vpool)\n";
01899
01900
01901
01902
01903
01904
01905 }
01906 }
01907 }
01908 }
01909 }
01910 }
01911 }
01912 }
01913 }
01914 }
01915 }
01916 return true;
01917 }
01918
01919
01920
01921
01922
01923
01924
01925 bool SoftToEggConverter::
01926 cleanup_soft_skin()
01927 {
01928 int num_nodes = _tree.get_num_nodes();
01929 SoftNodeDesc *node_desc;
01930
01931 softegg_cat.spam() << endl << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
01932
01933 for (int i = 0; i < num_nodes; i++) {
01934 node_desc = _tree.get_node(i);
01935 if (node_desc->is_partial(search_prefix))
01936 continue;
01937
01938 SAA_Elem *model = node_desc->get_model();
01939 EggGroup *joint = NULL;
01940 EggVertexPool *vpool = NULL;
01941 SAA_ModelType type;
01942
01943
01944
01945 SAA_modelGetType( &scene, model, &type );
01946
01947 softegg_cat.debug() << "Cleaning up model------- " << node_desc->get_name() << endl;
01948
01949
01950
01951
01952
01953
01954
01955 string vpool_name = node_desc->get_name() + ".verts";
01956 EggNode *t = _tree.get_egg_root()->find_child(vpool_name);
01957 if (t)
01958 DCAST_INTO_R(vpool, t, NULL);
01959
01960 if (!vpool) {
01961
01962 continue;
01963 }
01964
01965 int numVerts = (int)vpool->size();
01966 softegg_cat.spam() << "found vpool " << vpool_name << " w/ " << numVerts << " verts\n";
01967
01968
01969
01970 if (node_desc->is_joint())
01971 joint = node_desc->get_egg_group();
01972 else {
01973
01974 SoftNodeDesc *parentJ = node_desc;
01975 while( parentJ && !parentJ->_parentJoint) {
01976 if ( parentJ->_parent) {
01977 SAA_Boolean isSkeleton;
01978
01979 if (parentJ->_parent->has_model())
01980 SAA_modelIsSkeleton( &scene, parentJ->_parent->get_model(), &isSkeleton );
01981
01982 if (isSkeleton) {
01983 joint = parentJ->_parent->get_egg_group();
01984 softegg_cat.spam() << "parent to " << parentJ->_parent->get_name() << endl;
01985 break;
01986 }
01987
01988 parentJ = parentJ->_parent;
01989 }
01990 else
01991 break;
01992 }
01993 if (!joint && (!parentJ || !parentJ->_parentJoint)) {
01994 softegg_cat.spam() << node_desc->get_name() << " has no _parentJoint?!" << endl;
01995 continue;
01996 }
01997
01998 if (!joint) {
01999 softegg_cat.spam() << "parent joint to " << parentJ->_parentJoint->get_name() << endl;
02000 joint = parentJ->_parentJoint->get_egg_group();
02001 }
02002 }
02003 EggVertexPool::iterator vi;
02004 double membership = 1.0f;
02005 for ( vi = vpool->begin(); vi != vpool->end(); ++vi) {
02006 EggVertex *vert = (*vi);
02007
02008
02009 if ( vert->gref_size() == 0 ) {
02010
02011 softegg_cat.spam() << "vert " << vert->get_external_index() << " not assigned!\n";
02012
02013
02014 joint->ref_vertex( vert, 1.0f );
02015 }
02016 }
02017 }
02018 return true;
02019 }
02020
02021
02022
02023
02024
02025
02026
02027 void SoftToEggConverter::
02028 set_shader_attributes(SoftNodeDesc *node_desc, EggPrimitive &primitive, int idx) {
02029 char *texName = node_desc->texNameArray[idx];
02030 EggTexture tex(texName, "");
02031
02032 Filename filename = Filename::from_os_specific(texName);
02033 Filename fullpath = _path_replace->match_path(filename, get_model_path());
02034 tex.set_filename(_path_replace->store_path(fullpath));
02035 tex.set_fullpath(fullpath);
02036
02037 apply_texture_properties(tex, node_desc->uRepeat[idx], node_desc->vRepeat[idx]);
02038
02039 EggTexture *new_tex = _textures.create_unique_texture(tex, ~EggTexture::E_tref_name);
02040 primitive.set_texture(new_tex);
02041 }
02042
02043
02044
02045
02046
02047
02048
02049
02050 void SoftToEggConverter::
02051 apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat) {
02052
02053 tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
02054 tex.set_magfilter(EggTexture::FT_linear);
02055
02056 EggTexture::WrapMode wrap_u = uRepeat > 0 ? EggTexture::WM_repeat : EggTexture::WM_clamp;
02057 EggTexture::WrapMode wrap_v = vRepeat > 0 ? EggTexture::WM_repeat : EggTexture::WM_clamp;
02058
02059 tex.set_wrap_u(wrap_u);
02060 tex.set_wrap_v(wrap_v);
02061
02062
02063
02064
02065
02066
02067 }
02068 #if 0
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078 bool SoftToEggConverter::
02079 compare_texture_properties(EggTexture &tex,
02080 const SoftShaderColorDef &color_def) {
02081 bool okflag = true;
02082
02083 EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
02084 EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
02085
02086 if (wrap_u != tex.determine_wrap_u()) {
02087
02088 if (wrap_u == EggTexture::WM_repeat) {
02089 tex.set_wrap_u(wrap_u);
02090 }
02091 okflag = false;
02092 }
02093 if (wrap_v != tex.determine_wrap_v()) {
02094 if (wrap_v == EggTexture::WM_repeat) {
02095 tex.set_wrap_v(wrap_v);
02096 }
02097 okflag = false;
02098 }
02099
02100 LMatrix3d mat = color_def.compute_texture_matrix();
02101 if (!mat.almost_equal(tex.get_transform())) {
02102 okflag = false;
02103 }
02104
02105 return okflag;
02106 }
02107 #endif
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118 bool SoftToEggConverter::
02119 reparent_decals(EggGroupNode *egg_parent) {
02120 bool okflag = true;
02121
02122
02123
02124 EggGroup *decal_base = (EggGroup *)NULL;
02125 pvector<EggGroup *> decal_children;
02126
02127 EggGroupNode::iterator ci;
02128 for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
02129 EggNode *child = (*ci);
02130 if (child->is_of_type(EggGroup::get_class_type())) {
02131 EggGroup *child_group = DCAST(EggGroup, child);
02132 if (child_group->has_object_type("decalbase")) {
02133 if (decal_base != (EggNode *)NULL) {
02134 softegg_cat.error()
02135 << "Two children of " << egg_parent->get_name()
02136 << " both have decalbase set: " << decal_base->get_name()
02137 << " and " << child_group->get_name() << "\n";
02138 okflag = false;
02139 }
02140 child_group->remove_object_type("decalbase");
02141 decal_base = child_group;
02142
02143 } else if (child_group->has_object_type("decal")) {
02144 child_group->remove_object_type("decal");
02145 decal_children.push_back(child_group);
02146 }
02147 }
02148 }
02149
02150 if (decal_base == (EggGroup *)NULL) {
02151 if (!decal_children.empty()) {
02152 softegg_cat.warning()
02153 << decal_children.front()->get_name()
02154 << " has decal, but no sibling node has decalbase.\n";
02155 }
02156
02157 } else {
02158 if (decal_children.empty()) {
02159 softegg_cat.warning()
02160 << decal_base->get_name()
02161 << " has decalbase, but no sibling nodes have decal.\n";
02162
02163 } else {
02164
02165
02166
02167
02168 pvector<EggGroup *>::iterator di;
02169 for (di = decal_children.begin(); di != decal_children.end(); ++di) {
02170 EggGroup *child_group = (*di);
02171 decal_base->add_child(child_group);
02172 }
02173
02174
02175 decal_base->set_decal_flag(true);
02176 }
02177 }
02178
02179
02180 for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
02181 EggNode *child = (*ci);
02182 if (child->is_of_type(EggGroupNode::get_class_type())) {
02183 EggGroupNode *child_group = DCAST(EggGroupNode, child);
02184 if (!reparent_decals(child_group)) {
02185 okflag = false;
02186 }
02187 }
02188 }
02189
02190 return okflag;
02191 }
02192
02193
02194
02195
02196
02197
02198
02199 SoftToEggConverter::TransformType SoftToEggConverter::
02200 string_transform_type(const string &arg) {
02201 if (cmp_nocase(arg, "all") == 0) {
02202 return TT_all;
02203 } else if (cmp_nocase(arg, "model") == 0) {
02204 return TT_model;
02205 } else if (cmp_nocase(arg, "dcs") == 0) {
02206 return TT_dcs;
02207 } else if (cmp_nocase(arg, "none") == 0) {
02208 return TT_none;
02209 } else {
02210 return TT_invalid;
02211 }
02212 }
02213
02214
02215
02216
02217
02218
02219 extern "C" int init_soft2egg (int argc, char **argv)
02220 {
02221 stec._commandName = argv[0];
02222 stec.rsrc_path = "c:\\Softimage\\SOFT3D_3.9.2\\3D\\rsrc";
02223 if (stec.DoGetopts(argc, argv)) {
02224
02225
02226 Filename softFile(argv[1]);
02227 stec.convert_file(softFile);
02228 }
02229
02230 return 0;
02231 }
02232
02233
02234