1-- NW4C Menu Utilities (2011/02/15) 2-- Version 1.0.0 3-- (c)2010-2011 Nintendo 4 5struct nw4c_userData 6( 7 dataname = "", 8 type = String, 9 val = #(), 10 fn copyTo dst = 11 ( 12 if (classof dst) != nw4c_userData do return false 13 dst.dataname = dataname 14 dst.type = type 15 dst.val = deepCopy val 16 return true 17 ), 18 fn valueToString oneline:false = 19 ( 20 local str = "" 21 for j = 1 to val.count do 22 ( 23 if j != 1 do 24 ( 25 str += if (not oneline) and (type == String) then "\n" else " " 26 ) 27 str += (val[j] as string) 28 ) 29 return str 30 ), 31 fn valueCount = 32 ( 33 local ret = 0 34 if type == String then 35 ( 36 for v in val do 37 ( 38 ret += v.count 39 ) 40 ) 41 else 42 ( 43 ret = val.count 44 ) 45 return ret 46 ), 47 fn toString = 48 ( 49 local str = dataname 50 str += "\"" 51 str += case type of 52 ( 53 Integer: "i" 54 Float: "f" 55 default: "s" -- string 56 ) 57 str += " " 58 str += valueToString() 59 str += "\"" 60 return str 61 ), 62 fn fromString s = 63 ( 64 local tokens = filterString s "\"" 65 if tokens.count != 2 do return false 66 dataname = tokens[1] 67 68 local valStr = tokens[2] 69 case valStr[1] of 70 ( 71 "i": type = Integer 72 "f": type = Float 73 default: type = String 74 ) 75 val = #( ) 76 77 local valTokens = #() 78 79 if type == String then 80 ( 81 valTokens = filterString (substring valStr 3 -1) "\n" 82 ) 83 else 84 ( 85 valTokens = filterString (substring valStr 3 -1) " " 86 ) 87 88 for i = 1 to valTokens.count do 89 ( 90 local v = case type of 91 ( 92 Integer: (valTokens[i] as Integer) 93 Float: (valTokens[i] as Float) 94 default: (valTokens[i]) 95 ) 96 if v != undefined do 97 ( 98 append val v 99 ) 100 ) 101 return true 102 ) 103) 104 105struct nw4c_userDataSet 106( 107 list = #(), 108 fn appendData data = 109 ( 110 if (classof data) != nw4c_userData do return false 111 append list data 112 ), 113 fn toString = 114 ( 115 local ret = "" 116 if (classof list) != Array do return "" 117 for i = 1 to list.count do 118 ( 119 local data = list[i] 120 if (classof data) != nw4c_userData do continue 121 if i != 1 do ret += " " 122 ret += data.toString() 123 ) 124 return ret 125 ), 126 fn fromString s = 127 ( 128 if (classof s) != String do return false 129 list = #() 130 local p = 1 131 while p <= s.count do 132 ( 133 while s[p] == " " and p < s.count do p += 1 -- �X�y�[�X���X�L�b�v 134 local ep = p 135 while s[ep] != "\"" and ep < s.count do ep += 1 -- �ŏ���"��T�� 136 ep += 1 137 while s[ep] != "\"" and ep <= s.count do ep += 1 -- �Ō��"��T�� 138 if ep <= s.count do 139 ( 140 local len = ep - p + 1 141 local d = nw4c_userData() 142 if (d.fromString (substring s p len) ) do 143 ( 144 append list d 145 ) 146 ) 147 p = ep + 1 148 ) 149 return true 150 ), 151 fn getFromAttribute attr = 152 ( 153 list = #() 154 ), 155 fn setToAttribute attr = 156 ( 157 ) 158) 159 160struct nw4c_utils 161( 162 enableSaveToScene = true, 163 164 fn outComment fs str = 165 ( 166 format "# %\n" str to:fs 167 ), 168 169 fn outReturn fs= 170 ( 171 format "\n" to:fs 172 ), 173 174 fn outValue fs key v = 175 ( 176 format "%=\"%\"\n" key (v as string) to:fs 177 ), 178 179 fn outVersion fs key v = 180 ( 181 local str = "" 182 for i = 1 to 3 do 183 ( 184 local d = (mod v 10) as integer 185 v = (v - d) / 10 186 str = (d as string) + str 187 if i != 3 do str = "." + str 188 ) 189 outValue fs key str 190 ), 191 192 fn outQuantValue fs key v = 193 ( 194 local str = case v of 195 ( 196 3: "Byte" 197 2: "Short" 198 default: "Float" 199 ) 200 201 outValue fs key str 202 ), 203 204 fn QuantStrToInt str = 205 ( 206 local val = toLower str 207 case val of 208 ( 209 "byte": 3 210 "short": 2 211 default: 1 212 ) 213 ), 214 215 fn useNonUniformScale = 216 ( 217 ((systemTools.getEnvVariable "NW4C_USE_NON_UNIFORM_SCALE") == "1") 218 ), 219 220 fn loadSettingFromFile filename isDefault:false = 221 ( 222 local nw4c = nw4cmax 223 if nw4c == undefined do return false 224 if filename == undefined do return false 225 local fs = openFile filename mode:"rt" 226 if fs == undefined do 227 ( 228 format "File Open Error(%)\n" filename 229 return false 230 ) 231 -- read header 232 if (findString (readLine fs) "NW4C_Export settings") == undefined do return false 233 local str, key, val, ver = 0 234 local isEOF = false 235 while isEOF == false do 236 ( 237 str = readLine fs 238 -- skip comment and null line 239 if (str.count < 1) or (str[1] == "#") do continue 240 local elem = filterString str "=" 241 if (classof elem != Array) or elem.count != 2 do continue 242 key = elem[1] 243 val = substituteString elem[2] "\"" "" 244 --format "\"%\"=\"%\"\n" key val 245 case key of 246 ( 247 "ExportTarget": ( 248 nw4c.doesExportSelected = ((stricmp val "Selection") == 0) 249 ) 250 "OutputFileName": nw4c.filename = val 251 "OutputFolder": nw4c.outFolder = val 252 "OutputMode": ( 253 if (stricmp val "CreativeStudio") == 0 then 254 ( 255 nw4c.UseCreativeStudio = true 256 nw4c.Use3DEditor = false 257 ) 258 else if (stricmp val "3DEditor") == 0 then 259 ( 260 nw4c.UseCreativeStudio = false 261 nw4c.Use3DEditor = true 262 ) 263 else 264 ( 265 nw4c.UseCreativeStudio = false 266 nw4c.Use3DEditor = false 267 ) 268 nw4c.UseCreativeStudio = ((stricmp val "CreativeStudio") == 0) 269 ) 270 "MergeCmdl": nw4c.UseMerge = val as booleanclass 271 "MergeCmdlPath": nw4c.MergeFilename = val 272 "CopyRelatedFiles": nw4c.CopyMergeRelatedFiles = val as booleanclass 273 "Magnify": nw4c.Magnify = val as float 274 "FrameRange": nw4c.doesExportAllFrames = ((stricmp val "Range") != 0) 275 "StartFrame": nw4c.StartFrame = val as integer 276 "EndFrame": nw4c.EndFrame = val as integer 277 "UseFigureMode": nw4c.useFiguremode = val as booleanclass 278 "OutputCmdl": nw4c.doesExportModel = val as booleanclass 279 "OutputCtex": nw4c.doesExportTexture = val as booleanclass 280 "OutputCskla": nw4c.doesExportAnimation = val as booleanclass 281 "OutputCmata": nw4c.doesExportMtlAnim = val as booleanclass 282 "OutputCcam": nw4c.doesExportCamera = val as booleanclass 283 "OutputClgt": nw4c.doesExportLight = val as booleanclass 284 "OutputCenv": nw4c.doesExportEnv = val as booleanclass 285 "OutputCmdla": nw4c.doesExportModelAnim = val as booleanclass 286 "OutputCmcla": nw4c.doesExportMtlColorAnim = val as booleanclass 287 "OutputCmtpa": nw4c.doesExportMtlTexPatternAnim = val as booleanclass 288 "OutputCmtsa": nw4c.doesExportMtlTexSRTAnim = val as booleanclass 289 290 "CompressNode": ( 291 nw4c.CompressNode = case val of 292 ( 293 "Cull": 2 294 "CullUninfluential": 3 295 "UniteCompressible": 4 296 "UniteAll": 5 297 default: 1 298 ) 299 ) 300 "CompressMaterial": ()--nw4c. 301 "OptimizePrimitive": nw4c.OptimizePrimitive = val as booleanclass 302 "ConvertToModel": ( -- 0.5.0���狓�����ς�����̂ŁA����ȑO�̃t���O�͖��� 303 --format "version %\n" ver 304 if ver < 130 then 305 ( 306 --print "old file is load.\n convert to model flag is ignored." 307 nw4c.DisableModelSimplification = true 308 ) 309 else 310 ( 311 nw4c.DisableModelSimplification = not (val as booleanclass) 312 ) 313 ) 314 "QuantizePos": nw4c.QuantPos = QuantStrToInt val 315 "QuantizeNrm": nw4c.QuantNormal = QuantStrToInt val 316 "QuantizeTex": nw4c.QuantTex = QuantStrToInt val 317 "NonUniformScale": ( -- 318 if useNonUniformScale() do 319 ( 320 nw4c.NonUniformScale = val as booleanclass 321 ) 322 ) 323 "MaxReservedUniformRegisters": nw4c.ReservedUniformRegister = val as integer 324 "MeshVisibilityMode": nw4c.VisibilityBindByName = ((stricmp val "BindByName") == 0) 325 "AdjustSkinning": nw4c.SkinningMode = if (val as booleanclass) then 2 else 1 326 327 "BakeAllAnim": () 328 "FramePrecision": ( 329 local fval = val as float 330 if fval > 0.0 do 331 ( 332 local ival = (1.0 / fval) as integer 333 nw4c.AnimPrecision = case of 334 ( 335 (ival <= 1): 1 336 (ival <= 2): 2 337 (ival <= 5): 5 338 default: 10 339 ) 340 ) 341 ) 342 "LoopAnim": nw4c.IsLoop = val as booleanclass 343 "FrameFormat": nw4c.IsFrameFormat = val as booleanclass 344 "BinPrecisionScale": ()--nw4c.PrecisionScale = val as float 345 "BinPrecisionRotate": ()--nw4c.PrecisionRotate = val as float 346 "BinPrecisionTranslate": ()--nw4c.PrecisionTrans = val as float 347 "ScaleQuantizeQuality": nw4c.ScaleQuality = val as integer 348 "RotateQuantizeQuality": nw4c.RotateQuality = val as integer 349 "TranslateQuantizeQuality": nw4c.TransQuality = val as integer 350 351 "ToleranceScale": nw4c.ToleranceScale = val as float 352 "ToleranceRotate": nw4c.ToleranceRotate = val as float 353 "ToleranceTranslate": nw4c.ToleranceTrans = val as float 354 "ToleranceUVScale": nw4c.ToleranceUVScale = val as float 355 "ToleranceUVRotate": nw4c.ToleranceUVRotate = val as float 356 "ToleranceUVTranslate": nw4c.ToleranceUVTrans = val as float 357 "ToleranceColor": nw4c.ToleranceColor= val as float 358 359 "3dsmax_SaveToScene": ( 360 --if isDefault do enableSaveToScene = val as booleanclass 361 ) 362 "SettingsVersion": ( 363 ver = (substituteString val "." "") as integer 364 ) 365 "GeneratorName": () 366 "GeneratorVersion": () 367 "Date": () 368 default: format "WARNING: unknown key found in c3es(%=%)\n" key val 369 ) 370 --detect eof 371 if eof fs do 372 ( 373 isEOF = true 374 ) 375 ) 376 377 return true 378 ), 379 380 fn saveSettingToFile filename isDefault:false = 381 ( 382 local nw4c = nw4cmax 383 if nw4c == undefined do return false 384 if filename == undefined do return false 385 local fs = openFile filename mode:"wt" 386 if fs == undefined do 387 ( 388 format "File Open Error(%)\n" filename 389 return false 390 ) 391 outComment fs "NW4C_Export settings" 392 local ver = nw4c.GetVersion() 393 outVersion fs "SettingsVersion" 130 394 local str = "3ds Max " 395 append str (((maxVersion())[1] / 1000 + 1998) as string) 396 append str " NW4C_Export" 397 outValue fs "GeneratorName" str 398 outVersion fs "GeneratorVersion" ver 399 local dt = getLocalTime() 400 local ss = stringStream "" 401 format "%-%-%T%:%:%" dt[1] dt[2] dt[4] dt[5] dt[6] dt[7] to:ss 402 outValue fs "Date" (ss as string) 403 if isDefault do 404 ( 405 --outValue fs "3dsmax_SaveToScene" enableSaveToScene 406 ) 407 outReturn fs 408 -- 409 outComment fs "Output Options" 410 outValue fs "ExportTarget" (if nw4c.doesExportSelected then "Selection" else "All") 411 outValue fs "OutputFileName" nw4c.filename 412 outValue fs "OutputMode" ( 413 if nw4c.UseCreativeStudio then 414 ( 415 "CreativeStudio" 416 ) 417 else if nw4c.Use3DEditor then 418 ( 419 "3DEditor" 420 ) 421 else 422 ( 423 "File" 424 ) 425 ) 426 outValue fs "OutputFolder" nw4c.outFolder 427 outValue fs "MergeCmdl" nw4c.UseMerge 428 outValue fs "MergeCmdlPath" nw4c.MergeFilename 429 outValue fs "CopyRelatedFiles" nw4c.CopyMergeRelatedFiles 430 outReturn fs 431 -- 432 outComment fs "General Options" 433 outValue fs "Magnify" nw4c.Magnify 434 outValue fs "FrameRange" (if nw4c.doesExportAllFrames then "All" else "Range") 435 outValue fs "StartFrame" nw4c.StartFrame 436 outValue fs "EndFrame" nw4c.EndFrame 437 outValue fs "UseFigureMode" nw4c.useFiguremode 438 outReturn fs 439 -- 440 outComment fs "Output File Selection" 441 outValue fs "OutputCmdl" nw4c.doesExportModel 442 outValue fs "OutputCtex" nw4c.doesExportTexture 443 outValue fs "OutputCskla" nw4c.doesExportAnimation 444 outValue fs "OutputCmata" nw4c.doesExportMtlAnim 445 outValue fs "OutputCcam" nw4c.doesExportCamera 446 outValue fs "OutputClgt" nw4c.doesExportLight 447 outValue fs "OutputCenv" nw4c.doesExportEnv 448 outValue fs "OutputCmdla" nw4c.doesExportModelAnim 449 outValue fs "OutputCmcla" nw4c.doesExportMtlColorAnim 450 outValue fs "OutputCmtpa" nw4c.doesExportMtlTexPatternAnim 451 outValue fs "OutputCmtsa" nw4c.doesExportMtlTexSRTAnim 452 outReturn fs 453 -- 454 outComment fs "Optimization Options" 455 outValue fs "CompressNode" ( case nw4c.CompressNode of 456 ( 457 2: "Cull" 458 3: "CullUninfluential" 459 4: "UniteCompressible" 460 5: "UniteAll" 461 default: "None" 462 ) 463 ) 464 outValue fs "CompressMaterial" nw4c.OptimizeMaterial 465 outValue fs "OptimizePrimitive" nw4c.OptimizePrimitive 466 outValue fs "ConvertToModel" (not nw4c.DisableModelSimplification) 467 outReturn fs 468 -- 469 outComment fs "Quantization Options" 470 outQuantValue fs "QuantizePos" nw4c.QuantPos 471 outQuantValue fs "QuantizeNrm" nw4c.QuantNormal 472 outQuantValue fs "QuantizeTex" nw4c.QuantTex 473 outReturn fs 474 -- 475 outComment fs "Model Options" 476 if useNonUniformScale() do outValue fs "NonUniformScale" nw4c.NonUniformScale 477 outValue fs "MaxReservedUniformRegisters" nw4c.ReservedUniformRegister 478 outValue fs "MeshVisibilityMode" ( if nw4c.VisibilityBindByName then "BindByName" else "BindByIndex") 479 480 481 outValue fs "AdjustSkinning" (nw4c.SkinningMode == 2) 482 483 outReturn fs 484 -- 485 outComment fs "Animation Options" 486 outValue fs "BakeAllAnim" true 487 outValue fs "FramePrecision" (1.0 / nw4c.AnimPrecision) 488 outValue fs "LoopAnim" nw4c.IsLoop 489 outValue fs "FrameFormat" nw4c.IsFrameFormat 490 --outValue fs "BinPrecisionScale" nw4c.PrecisionScale 491 --outValue fs "BinPrecisionRotate" nw4c.PrecisionRotate 492 --outValue fs "BinPrecisionTranslate" nw4c.PrecisionTrans 493 outValue fs "ScaleQuantizeQuality" nw4c.ScaleQuality 494 outValue fs "RotateQuantizeQuality" nw4c.RotateQuality 495 outValue fs "TranslateQuantizeQuality" nw4c.TransQuality 496 outReturn fs 497 -- 498 outComment fs "Tolerance Options" 499 outValue fs "ToleranceScale" nw4c.ToleranceScale 500 outValue fs "ToleranceRotate" nw4c.ToleranceRotate 501 outValue fs "ToleranceTranslate" nw4c.ToleranceTrans 502 outValue fs "ToleranceUVScale" nw4c.ToleranceUVScale 503 outValue fs "ToleranceUVRotate" nw4c.ToleranceUVRotate 504 outValue fs "ToleranceUVTranslate" nw4c.ToleranceUVTrans 505 outValue fs "ToleranceColor" nw4c.ToleranceColor 506 507 close fs 508 return true 509 ), 510 511 fn loadSettingConfig = 512 ( 513 local fname = GetDir #plugcfg 514 append fname "\\nw4cmax.ini" 515 local val = getINISetting fname "nw4c_exporter" "enableSaveToScene" 516 enableSaveToScene = if val == "false" then false else true 517 ), 518 519 fn saveSettingConfig = 520 ( 521 local fname = GetDir #plugcfg 522 append fname "\\nw4cmax.ini" 523 setINISetting fname "nw4c_exporter" "enableSaveToScene" (enableSaveToScene as string) 524 ), 525 526 fn loadSettingDefault = 527 ( 528 local fname = GetDir #plugcfg 529 append fname "\\nw4cmax.c3es" 530 if doesFileExist fname then 531 ( 532 loadSettingFromFile fname isDefault:true 533 loadSettingConfig() 534 ) 535 else 536 ( 537 false 538 ) 539 ), 540 541 fn saveSettingDefault = 542 ( 543 local fname = GetDir #plugcfg 544 append fname "\\nw4cmax.c3es" 545 saveSettingToFile fname isDefault:true 546 saveSettingConfig() 547 ) 548) 549 550-- common user data setting 551nw4cEditUserDataRollout_Value = undefined 552nw4cEditUserDataRollout_ValueSet = undefined 553 554rollout nw4cEditUserDataRollout "NW4C Edit User Data" width:320 height:320 555( 556 editText editName "Name" align:#left 557 radioButtons rdoType "Type" labels:#("String", "Integer", "Float") columns:3 align:#left 558 --label lblString "String" align:#left enabled:false 559 --editText editString "" align:#left 560 label lblNumber "String or Number : (One value per line)" align:#left 561 editText editNumber "" height: 200 align:#left 562 label lbl3 "" across:3 563 button btnOK "Ok" width:80 564 button btnCancel "Cancel" width:80 565 566 fn isValidName n = 567 ( 568 if (classof n) != String do return false 569 local c, f = true 570 for i = 1 to n.count while f do 571 ( 572 c = n[i] 573 f = false 574 f = f or ("A" <= c and c <= "Z") or ("a" <= c and c <= "z") 575 f = f or ("0" <= c and c <= "9") 576 f = f or (c == "-") or (c == "_") or (c == ".") 577 ) 578 if (not f) do 579 ( 580 messagebox ("invalid character used in name(" + c + ")") 581 return false 582 ) 583 -- find same name 584 local list = nw4cEditUserDataRollout_ValueSet.list 585 for d in list do 586 ( 587 if d != nw4cEditUserDataRollout_Value and d.dataname == n do -- �����f�[�^�ւ̎Q�Ƃ͏��� 588 ( 589 messagebox ("Can't use same name") 590 return false 591 ) 592 ) 593 return true 594 ) 595 596 fn isValidString s = 597 ( 598 if (classof s) != String do return false 599 local c, f = true 600 for i = 1 to s.count while f do 601 ( 602 c = s[i] 603 f = (c == "<") or (c == ">") or (c == "&") or (c == "'") or (c == "\"") 604 if f do 605 ( 606 messagebox ("invalid character used in String(" + c + ")") 607 return false 608 ) 609 ) 610 return true 611 ) 612 613 fn updateView = 614 ( 615 if (classof nw4cEditUserDataRollout_Value) == nw4c_userData and \ 616 (classof nw4cEditUserDataRollout_ValueSet) == nw4c_userDataSet do 617 ( 618 local data = nw4cEditUserDataRollout_Value 619 editName.text = data.dataname 620 rdoType.state = case data.type of 621 ( 622 Integer: 2 623 Float: 3 624 default: 1 -- string 625 ) 626/* if data.type == String then 627 ( 628 editString.text = if (classof data.val[1]) == String then data.val[1] else "" 629 ) 630 else 631*/ 632 ( 633 local str = "" 634 for i = 1 to data.val.count do 635 ( 636 str += (data.val[i] as String) + "\n" 637 ) 638 editNumber.text = str 639 ) 640 ) 641 ) 642 643 on nw4cEditUserDataRollout open do 644 ( 645 if (classof nw4cEditUserDataRollout_Value) == nw4c_userData and \ 646 (classof nw4cEditUserDataRollout_ValueSet) == nw4c_userDataSet then 647 ( 648 updateView() 649 ) 650 else 651 ( 652 messagebox "value error" 653 DestroyDialog nw4cEditUserDataRollout 654 ) 655 ) 656 657 on btnOK pressed do 658 ( 659 if (classof nw4cEditUserDataRollout_Value) == nw4c_userData do 660 ( 661 local data = nw4c_userData() 662 data.type = case rdoType.state of 663 ( 664 2: Integer 665 3: Float 666 default: String 667 ) 668 if editName.text.count == 0 do 669 ( 670 messagebox "Name is Empty" 671 return() 672 ) 673 if (not (isValidName editName.text)) do 674 ( 675 return() 676 ) 677 data.dataname = editName.text 678 679 local vs = filterString editNumber.text "\n" 680 if vs.count == 0 do 681 ( 682 messagebox "Number is Empty" 683 return() 684 ) 685 686 for i = 1 to vs.count do 687 ( 688 local v = case data.type of 689 ( 690 Integer: (vs[i] as Integer) 691 Float: (vs[i] as Float) 692 default: (vs[i] as String) 693 ) 694 if v == undefined do 695 ( 696 local mes = "Value is not valid(" + vs[i] + ")" 697 messagebox mes 698 return() 699 ) 700 append data.val v 701 ) 702 if data.val.count == 0 do 703 ( 704 messagebox "Number is Empty" 705 return() 706 ) 707 data.copyTo nw4cEditUserDataRollout_Value 708 ) 709 DestroyDialog nw4cEditUserDataRollout 710 ) 711 712 on btnCancel pressed do 713 ( 714 nw4cEditUserDataRollout_Value = undefined 715 DestroyDialog nw4cEditUserDataRollout 716 ) 717 on rdoType changed val do 718 ( 719/* 720 editString.enabled = (val == 1) 721 lblString.enabled = (val == 1) 722 editNumber.enabled = (val != 1) 723 lblNumber.enabled = (val != 1) 724*/ 725 ) 726) 727