1-- NW4C Menu Utilities(2010/12/07) 2-- Version 0.5.0d 3-- (c)2010 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 loadSettingFromFile filename isDefault:false = 216 ( 217 local nw4c = nw4cmax 218 if nw4c == undefined do return false 219 if filename == undefined do return false 220 local fs = openFile filename mode:"rt" 221 if fs == undefined do 222 ( 223 format "File Open Error(%)\n" filename 224 return false 225 ) 226 -- read header 227 if (findString (readLine fs) "NW4C_Export settings") == undefined do return false 228 local str, key, val, ver = 0 229 local isEOF = false 230 while isEOF == false do 231 ( 232 str = readLine fs 233 -- skip comment and null line 234 if (str.count < 1) or (str[1] == "#") do continue 235 local elem = filterString str "=" 236 if (classof elem != Array) or elem.count != 2 do continue 237 key = elem[1] 238 val = substituteString elem[2] "\"" "" 239 --format "\"%\"=\"%\"\n" key val 240 case key of 241 ( 242 "ExportTarget": ( 243 nw4c.doesExportSelected = ((stricmp val "Selection") == 0) 244 ) 245 "OutputFileName": nw4c.filename = val 246 "OutputFolder": nw4c.outFolder = val 247 "OutputMode": nw4c.UseCreativeStudio = ((stricmp val "CreativeStudio") == 0) 248 "MergeCmdl": nw4c.UseMerge = val as booleanclass 249 "MergeCmdlPath": nw4c.MergeFilename = val 250 "Magnify": nw4c.Magnify = val as float 251 "FrameRange": nw4c.doesExportAllFrames = ((stricmp val "Range") != 0) 252 "StartFrame": nw4c.StartFrame = val as integer 253 "EndFrame": nw4c.EndFrame = val as integer 254 "UseFigureMode": nw4c.useFiguremode = val as booleanclass 255 "OutputCmdl": nw4c.doesExportModel = val as booleanclass 256 "OutputCtex": nw4c.doesExportTexture = val as booleanclass 257 "OutputCskla": nw4c.doesExportAnimation = val as booleanclass 258 "OutputCmata": nw4c.doesExportMtlAnim = val as booleanclass 259 "OutputCcam": nw4c.doesExportCamera = val as booleanclass 260 "OutputClgt": nw4c.doesExportLight = val as booleanclass 261 "OutputCenv": nw4c.doesExportEnv = val as booleanclass 262 "OutputCmdla": nw4c.doesExportModelAnim = val as booleanclass 263 "CompressNode": ( 264 nw4c.CompressNode = case val of 265 ( 266 "Cull": 2 267 "CullUninfluential": 3 268 "UniteCompressible": 4 269 "UniteAll": 5 270 default: 1 271 ) 272 ) 273 "CompressMaterial": ()--nw4c. 274 "OptimizePrimitive": nw4c.OptimizePrimitive = val as booleanclass 275 "ConvertToModel": ( -- 0.5.0���狓�����ς�����̂ŁA����ȑO�̃t���O�͖��� 276 format "version %\n" ver 277 if ver < 130 then 278 ( 279 --print "old file is load.\n convert to model flag is ignored." 280 nw4c.DisableModelSimplification = true 281 ) 282 else 283 ( 284 nw4c.DisableModelSimplification = not (val as booleanclass) 285 ) 286 ) 287 "QuantizePos": nw4c.QuantPos = QuantStrToInt val 288 "QuantizeNrm": nw4c.QuantNormal = QuantStrToInt val 289 "QuantizeTex": nw4c.QuantTex = QuantStrToInt val 290 "NonUniformScale": nw4c.NonUniformScale = val as booleanclass 291 "MaxReservedUniformRegisters": nw4c.ReservedUniformRegister = val as integer 292 "MeshVisibilityMode": nw4c.VisibilityBindByName = ((stricmp val "BindByName") == 0) 293 "AdjustSkinning": nw4c.SkinningMode = if (val as booleanclass) then 2 else 1 294 295 "BakeAllAnim": () 296 "FramePrecision": ( 297 local fval = val as float 298 if fval > 0.0 do 299 ( 300 local ival = (1.0 / fval) as integer 301 nw4c.AnimPrecision = case of 302 ( 303 (ival <= 1): 1 304 (ival <= 2): 2 305 (ival <= 5): 5 306 default: 10 307 ) 308 ) 309 ) 310 "LoopAnim": nw4c.IsLoop = val as booleanclass 311 "FrameFormat": nw4c.IsFrameFormat = val as booleanclass 312 "BinPrecisionScale": ()--nw4c.PrecisionScale = val as float 313 "BinPrecisionRotate": ()--nw4c.PrecisionRotate = val as float 314 "BinPrecisionTranslate": ()--nw4c.PrecisionTrans = val as float 315 "ScaleQuantizeQuality": nw4c.ScaleQuality = val as integer 316 "RotateQuantizeQuality": nw4c.RotateQuality = val as integer 317 "TranslateQuantizeQuality": nw4c.TransQuality = val as integer 318 319 "ToleranceScale": nw4c.ToleranceScale = val as float 320 "ToleranceRotate": nw4c.ToleranceRotate = val as float 321 "ToleranceTranslate": nw4c.ToleranceTrans = val as float 322 "ToleranceUVScale": nw4c.ToleranceUVScale = val as float 323 "ToleranceUVRotate": nw4c.ToleranceUVRotate = val as float 324 "ToleranceUVTranslate": nw4c.ToleranceUVTrans = val as float 325 "ToleranceColor": nw4c.ToleranceColor= val as float 326 327 "3dsmax_SaveToScene": ( 328 --if isDefault do enableSaveToScene = val as booleanclass 329 ) 330 "SettingsVersion": ( 331 ver = (substituteString val "." "") as integer 332 ) 333 "GeneratorName": () 334 "GeneratorVersion": () 335 "Date": () 336 default: format "WARNING: unknown key found in c3es(%=%)\n" key val 337 ) 338 --detect eof 339 if eof fs do 340 ( 341 isEOF = true 342 ) 343 ) 344 345 return true 346 ), 347 348 fn saveSettingToFile filename isDefault:false = 349 ( 350 local nw4c = nw4cmax 351 if nw4c == undefined do return false 352 if filename == undefined do return false 353 local fs = openFile filename mode:"wt" 354 if fs == undefined do 355 ( 356 format "File Open Error(%)\n" filename 357 return false 358 ) 359 outComment fs "NW4C_Export settings" 360 local ver = nw4c.GetVersion() 361 outVersion fs "SettingsVersion" 130 362 local str = "3ds Max " 363 append str (((maxVersion())[1] / 1000 + 1998) as string) 364 append str " NW4C_Export" 365 outValue fs "GeneratorName" str 366 outVersion fs "GeneratorVersion" ver 367 local dt = getLocalTime() 368 local ss = stringStream "" 369 format "%-%-%T%:%:%" dt[1] dt[2] dt[4] dt[5] dt[6] dt[7] to:ss 370 outValue fs "Date" (ss as string) 371 if isDefault do 372 ( 373 --outValue fs "3dsmax_SaveToScene" enableSaveToScene 374 ) 375 outReturn fs 376 -- 377 outComment fs "Output Options" 378 outValue fs "ExportTarget" (if nw4c.doesExportSelected then "Selection" else "All") 379 outValue fs "OutputFileName" nw4c.filename 380 outValue fs "OutputMode" (if nw4c.UseCreativeStudio then "CreativeStudio" else "File") 381 outValue fs "OutputFolder" nw4c.outFolder 382 outValue fs "MergeCmdl" nw4c.UseMerge 383 outValue fs "MergeCmdlPath" nw4c.MergeFilename 384 outReturn fs 385 -- 386 outComment fs "General Options" 387 outValue fs "Magnify" nw4c.Magnify 388 outValue fs "FrameRange" (if nw4c.doesExportAllFrames then "All" else "Range") 389 outValue fs "StartFrame" nw4c.StartFrame 390 outValue fs "EndFrame" nw4c.EndFrame 391 outValue fs "UseFigureMode" nw4c.useFiguremode 392 outReturn fs 393 -- 394 outComment fs "Output File Selection" 395 outValue fs "OutputCmdl" nw4c.doesExportModel 396 outValue fs "OutputCtex" nw4c.doesExportTexture 397 outValue fs "OutputCskla" nw4c.doesExportAnimation 398 outValue fs "OutputCmata" nw4c.doesExportMtlAnim 399 outValue fs "OutputCcam" nw4c.doesExportCamera 400 outValue fs "OutputClgt" nw4c.doesExportLight 401 outValue fs "OutputCenv" nw4c.doesExportEnv 402 outValue fs "OutputCmdla" nw4c.doesExportModelAnim 403 outReturn fs 404 -- 405 outComment fs "Optimization Options" 406 outValue fs "CompressNode" ( case nw4c.CompressNode of 407 ( 408 2: "Cull" 409 3: "CullUninfluential" 410 4: "UniteCompressible" 411 5: "UniteAll" 412 default: "None" 413 ) 414 ) 415 outValue fs "CompressMaterial" nw4c.OptimizeMaterial 416 outValue fs "OptimizePrimitive" nw4c.OptimizePrimitive 417 outValue fs "ConvertToModel" (not nw4c.DisableModelSimplification) 418 outReturn fs 419 -- 420 outComment fs "Quantization Options" 421 outQuantValue fs "QuantizePos" nw4c.QuantPos 422 outQuantValue fs "QuantizeNrm" nw4c.QuantNormal 423 outQuantValue fs "QuantizeTex" nw4c.QuantTex 424 outReturn fs 425 -- 426 outComment fs "Model Options" 427 outValue fs "NonUniformScale" nw4c.NonUniformScale 428 outValue fs "MaxReservedUniformRegisters" nw4c.ReservedUniformRegister 429 outValue fs "MeshVisibilityMode" ( if nw4c.VisibilityBindByName then "BindByName" else "BindByIndex") 430 431 432 outValue fs "AdjustSkinning" (nw4c.SkinningMode == 2) 433 434 outReturn fs 435 -- 436 outComment fs "Animation Options" 437 outValue fs "BakeAllAnim" true 438 outValue fs "FramePrecision" (1.0 / nw4c.AnimPrecision) 439 outValue fs "LoopAnim" nw4c.IsLoop 440 outValue fs "FrameFormat" nw4c.IsFrameFormat 441 --outValue fs "BinPrecisionScale" nw4c.PrecisionScale 442 --outValue fs "BinPrecisionRotate" nw4c.PrecisionRotate 443 --outValue fs "BinPrecisionTranslate" nw4c.PrecisionTrans 444 outValue fs "ScaleQuantizeQuality" nw4c.ScaleQuality 445 outValue fs "RotateQuantizeQuality" nw4c.RotateQuality 446 outValue fs "TranslateQuantizeQuality" nw4c.TransQuality 447 outReturn fs 448 -- 449 outComment fs "Tolerance Options" 450 outValue fs "ToleranceScale" nw4c.ToleranceScale 451 outValue fs "ToleranceRotate" nw4c.ToleranceRotate 452 outValue fs "ToleranceTranslate" nw4c.ToleranceTrans 453 outValue fs "ToleranceUVScale" nw4c.ToleranceUVScale 454 outValue fs "ToleranceUVRotate" nw4c.ToleranceUVRotate 455 outValue fs "ToleranceUVTranslate" nw4c.ToleranceUVTrans 456 outValue fs "ToleranceColor" nw4c.ToleranceColor 457 458 close fs 459 return true 460 ), 461 462 fn loadSettingConfig = 463 ( 464 local fname = GetDir #plugcfg 465 append fname "\\nw4cmax.ini" 466 local val = getINISetting fname "nw4c_exporter" "enableSaveToScene" 467 enableSaveToScene = if val == "false" then false else true 468 ), 469 470 fn saveSettingConfig = 471 ( 472 local fname = GetDir #plugcfg 473 append fname "\\nw4cmax.ini" 474 setINISetting fname "nw4c_exporter" "enableSaveToScene" (enableSaveToScene as string) 475 ), 476 477 fn loadSettingDefault = 478 ( 479 local fname = GetDir #plugcfg 480 append fname "\\nw4cmax.c3es" 481 if doesFileExist fname then 482 ( 483 loadSettingFromFile fname isDefault:true 484 loadSettingConfig() 485 ) 486 else 487 ( 488 false 489 ) 490 ), 491 492 fn saveSettingDefault = 493 ( 494 local fname = GetDir #plugcfg 495 append fname "\\nw4cmax.c3es" 496 saveSettingToFile fname isDefault:true 497 saveSettingConfig() 498 ) 499) 500 501-- common user data setting 502nw4cEditUserDataRollout_Value = undefined 503nw4cEditUserDataRollout_ValueSet = undefined 504 505rollout nw4cEditUserDataRollout "NW4C Edit User Data" width:320 height:320 506( 507 editText editName "Name" align:#left 508 radioButtons rdoType "Type" labels:#("String", "Integer", "Float") columns:3 align:#left 509 --label lblString "String" align:#left enabled:false 510 --editText editString "" align:#left 511 label lblNumber "String or Number : (One value per line)" align:#left 512 editText editNumber "" height: 200 align:#left 513 label lbl3 "" across:3 514 button btnOK "Ok" width:80 515 button btnCancel "Cancel" width:80 516 517 fn isValidName n = 518 ( 519 if (classof n) != String do return false 520 local c, f = true 521 for i = 1 to n.count while f do 522 ( 523 c = n[i] 524 f = false 525 f = f or ("A" <= c and c <= "Z") or ("a" <= c and c <= "z") 526 f = f or ("0" <= c and c <= "9") 527 f = f or (c == "-") or (c == "_") or (c == ".") 528 ) 529 if (not f) do 530 ( 531 messagebox ("invalid character used in name(" + c + ")") 532 return false 533 ) 534 -- find same name 535 local list = nw4cEditUserDataRollout_ValueSet.list 536 for d in list do 537 ( 538 if d != nw4cEditUserDataRollout_Value and d.dataname == n do -- �����f�[�^�ւ̎Q�Ƃ͏��� 539 ( 540 messagebox ("Can't use same name") 541 return false 542 ) 543 ) 544 return true 545 ) 546 547 fn isValidString s = 548 ( 549 if (classof s) != String do return false 550 local c, f = true 551 for i = 1 to s.count while f do 552 ( 553 c = s[i] 554 f = (c == "<") or (c == ">") or (c == "&") or (c == "'") or (c == "\"") 555 if f do 556 ( 557 messagebox ("invalid character used in String(" + c + ")") 558 return false 559 ) 560 ) 561 return true 562 ) 563 564 fn updateView = 565 ( 566 if (classof nw4cEditUserDataRollout_Value) == nw4c_userData and \ 567 (classof nw4cEditUserDataRollout_ValueSet) == nw4c_userDataSet do 568 ( 569 local data = nw4cEditUserDataRollout_Value 570 editName.text = data.dataname 571 rdoType.state = case data.type of 572 ( 573 Integer: 2 574 Float: 3 575 default: 1 -- string 576 ) 577/* if data.type == String then 578 ( 579 editString.text = if (classof data.val[1]) == String then data.val[1] else "" 580 ) 581 else 582*/ 583 ( 584 local str = "" 585 for i = 1 to data.val.count do 586 ( 587 str += (data.val[i] as String) + "\n" 588 ) 589 editNumber.text = str 590 ) 591 ) 592 ) 593 594 on nw4cEditUserDataRollout open do 595 ( 596 if (classof nw4cEditUserDataRollout_Value) == nw4c_userData and \ 597 (classof nw4cEditUserDataRollout_ValueSet) == nw4c_userDataSet then 598 ( 599 updateView() 600 ) 601 else 602 ( 603 messagebox "value error" 604 DestroyDialog nw4cEditUserDataRollout 605 ) 606 ) 607 608 on btnOK pressed do 609 ( 610 if (classof nw4cEditUserDataRollout_Value) == nw4c_userData do 611 ( 612 local data = nw4c_userData() 613 data.type = case rdoType.state of 614 ( 615 2: Integer 616 3: Float 617 default: String 618 ) 619 if editName.text.count == 0 do 620 ( 621 messagebox "Name is Empty" 622 return() 623 ) 624 if (not (isValidName editName.text)) do 625 ( 626 return() 627 ) 628 data.dataname = editName.text 629 630 local vs = filterString editNumber.text "\n" 631 if vs.count == 0 do 632 ( 633 messagebox "Number is Empty" 634 return() 635 ) 636 637 for i = 1 to vs.count do 638 ( 639 local v = case data.type of 640 ( 641 Integer: (vs[i] as Integer) 642 Float: (vs[i] as Float) 643 default: (vs[i] as String) 644 ) 645 if v == undefined do 646 ( 647 local mes = "Value is not valid(" + vs[i] + ")" 648 messagebox mes 649 return() 650 ) 651 append data.val v 652 ) 653 if data.val.count == 0 do 654 ( 655 messagebox "Number is Empty" 656 return() 657 ) 658 data.copyTo nw4cEditUserDataRollout_Value 659 ) 660 DestroyDialog nw4cEditUserDataRollout 661 ) 662 663 on btnCancel pressed do 664 ( 665 nw4cEditUserDataRollout_Value = undefined 666 DestroyDialog nw4cEditUserDataRollout 667 ) 668 on rdoType changed val do 669 ( 670/* 671 editString.enabled = (val == 1) 672 lblString.enabled = (val == 1) 673 editNumber.enabled = (val != 1) 674 lblNumber.enabled = (val != 1) 675*/ 676 ) 677) 678