├── .gitattributes ├── README.md └── Scripts ├── CompileHeart_ISM2.ms ├── CrashNSane_IGZ.ms ├── GoGoHypergrind_AMD.ms ├── KamenRiderPS3_EMD.ms ├── KamenRiderPS3_EMD_2012.ms ├── MegaManPSP_MDL.ms ├── NDCubeWiiU_BNFM.ms ├── Namco_NDWD.ms ├── Namco_NDWD_2012.ms ├── Namco_NDWD_Debug.ms ├── Namco_NDWD_Debug_2012.ms ├── Namco_NDWD_UpdateWIP.ms ├── NieRAutomata_WMB.ms ├── NintendoWiiU-Switch_BFRES.ms ├── OrochiEngine3_MDL.ms ├── PokemonORAS_BCH.ms ├── PokemonORAS_BCH_2012.ms ├── PokemonSwitch_GFBMDL-TRMDL.ms ├── PokemonXY_BCH.ms ├── PokemonXY_BCH_2012.ms ├── SSB4U-TaikoU_NDP3.ms ├── SSB4U-TaikoU_NDP3_Debug.ms ├── SSB4U-TaikoU_NDP3_UpdateWIP.ms ├── SSBUlt-NPS_NUMDLB.ms ├── SegaNNLibrary_NO.ms ├── SegaNNLibrary_NO_Debug.ms ├── Tamsoft_TMD.ms ├── TelltaleGames_D3DMesh.ms └── TelltaleHashDBs ├── BoneNames.HashDB ├── BoneNames.txt ├── TexNames.HashDB └── TexNames.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RTB-3DSMax-Scripts 2 | Home to all of the model-importing scripts I've written for 3DS Max over the years, supplied as-is for the time being until I can get a chance to revamp 'em all. Supported games are listed underneath the respective script names below. 3 | 4 | `CompileHeart_ISM2` (09/26/2017) 5 | - Dark Rose Valkyrie [PC / PS4] 6 | - Fairy Fencer F [PC / PS3] 7 | - Fairy Fencer F Advent Dark Force [PC / PS4] 8 | - Hyperdimension Neptunia mk2 [PS3] 9 | - Hyperdimension Neptunia Re;Birth 1 [PC / Vita] 10 | - Hyperdimension Neptunia Re;Birth 2: Sisters Generation [PC / Vita] 11 | - Hyperdimension Neptunia Re;Birth 3: V Generation [PC / Vita] 12 | - Hyperdimension Neptunia Victory [PS3] 13 | - Mary Skelter: Nightmares [Vita] 14 | - Megadimension Neptunia VII [PC / PS4] 15 | - MeiQ: Labyrinth of Death [Vita] 16 | - Moe Crystal [Vita] 17 | - Moe / Moero Chronicle [PC / Vita] 18 | - Monster Monpiece [PC / Vita] 19 | - Mugen Souls [PC / PS3] 20 | - Mugen Souls Z [PC / PS3] 21 | - Omega Quintet [PC, possibly PS4?] 22 | - Sorcery Saga: Curse of the Great Curry God [PC / Vita] 23 | - Superdimension Neptune VS Sega Hard Girls [PC / Vita] 24 | - Trillion: God of Destruction [PC / Vita] 25 | 26 | (NOTE: Some models have broken rigging, and will be looked into sometime later.) 27 | 28 | `CrashNSane_IGZ` (09/04/2019) 29 | - Crash Bandicoot: N-Sane Trilogy [PC / PS4 / Switch] 30 | - Crash Team Racing Nitro-Fueled [PS4 / Switch] 31 | 32 | `GoGoHypergrind_AMD` (09/09/2016) 33 | - Go! Go! Hypergrind [GameCube] 34 | 35 | `KamenRiderPS3_EMD` (07/09/2014) 36 | - Kamen Rider: Battride War [PS3] 37 | - Kamen Rider: Battride War II [PS3] 38 | - Kamen Rider: Battride War Genesis [PS3] 39 | - Kamen Rider: Summonride [PS3] 40 | 41 | `MegaManPSP_MDL` (09/08/2016) 42 | - Mega Man: Maverick Hunter X [PSP] 43 | - Mega Man: Powered Up [PSP] 44 | 45 | `Namco_NDWD` (09/09/2016) 46 | - Pokkén Tournament / Pokémon Tekken [Wii U] 47 | - Pokkén Tournament DX / Pokémon Tekken DX [Switch] 48 | - Ridge Racer [Vita] 49 | - Touch My Katamari [Vita] 50 | 51 | `NDCubeWiiU_BNFM` (01/10/2016) 52 | - Animal Crossing: amiibo Festival [Wii U] 53 | - Mario Party 10 [Wii U] 54 | - Wii Party U [Wii U] 55 | 56 | `NieRAutomata_WMB` (12/16/2017) 57 | - NieR: Automata [PC] 58 | 59 | `NintendoWiiU-Switch_BFRES` (09/18/2022, original script by ItsEasyActually) 60 | - 1-2-Switch [Switch] 61 | - Animal Crossing Plaza [Wii U] 62 | - Animal Crossing: New Horizons [Switch] 63 | - ARMS [Switch] 64 | - Brain Age / Dr. Kawashima's Brain Training [Switch] 65 | - Captain Toad: Treasure Tracker [Wii U / Switch] 66 | - Club House Games: 51 Worldwide Classics / 51 Worldwide Games [Switch] 67 | - Disney Magical World 2: Enchanted Edition [Switch] 68 | - Endless Ocean: Luminous [Switch] 69 | - Everybody 1-2-Switch! [Switch] 70 | - F-Zero 99 [Switch] 71 | - Game & Wario [Wii U] 72 | - Game Builder Garage [Switch] 73 | - Go Vacation [Switch] 74 | - Kirby and the Forgotten Land [Switch] 75 | - Kirby and the Rainbow Curse [Wii U] 76 | - Kirby Fighters 2 [Switch] 77 | - Kirby's Dream Buffet [Switch] 78 | - Kirby's Return to Dream Land Deluxe [Switch] 79 | - Kirby: Star Allies [Switch] 80 | - Mario & Sonic at the Sochi 2014 Olympic Winter Games [Wii U] 81 | - Mario Golf: Super Rush [Switch] 82 | - Mario Kart 8 [Wii U] 83 | - Mario Kart 8 Deluxe [Switch] 84 | - Mario Party Superstars [Switch] 85 | - Mario Tennis Aces [Switch] 86 | - Mario Tennis: Ultra Smash [Wii U] 87 | - Mario vs. Donkey Kong [Switch] 88 | - Miitopia [Switch] 89 | - New Super Mario Bros. U / New Super Luigi U [Wii U] 90 | - New Super Mario Bros. U Deluxe [Switch] 91 | - Nintendo Labo 01: Variety Kit [Switch] 92 | - Nintendo Labo 02: Robot Kit (somewhat, main game models use a different format) [Switch] 93 | - Nintendo Labo 03: Vehicle Kit [Switch] 94 | - Nintendo Labo 04: VR Kit [Switch] 95 | - Nintendo Land [Wii U] 96 | - Nintendo Switch Sports [Switch] 97 | - Nintendo World Championships: NES Edition [Switch] 98 | - Paper Mario: The Origami King [Switch] 99 | - Paper Mario: The Thousand-Year Door [Switch] 100 | - Pikmin 3 [Wii U] 101 | - Pikmin 3 Deluxe [Switch] 102 | - Pokémon Rumble U [Wii U] 103 | - Pushmo World [Wii U] 104 | - Ring Fit Adventure [Switch] 105 | - Rodea: The Sky Soldier [Wii U] 106 | - Rune Factory 4 Special [Switch] 107 | - Splatoon [Wii U] 108 | - Splatoon 2 [Switch] 109 | - Splatoon 3 [Switch] 110 | - Super Kirby Clash [Switch] 111 | - Super Mario 3D World [Wii U] 112 | - Super Mario 3D World + Bowser's Fury [Switch] 113 | - Super Mario Bros. Wonder [Switch] 114 | - Super Mario Maker [Wii U] 115 | - Super Mario Maker 2 [Switch] 116 | - Super Mario Odyssey [Switch] 117 | - Super Mario Party [Switch] 118 | - Super Mario Party Jamboree [Switch] 119 | - Super Smash Bros. Ultimate (effect files only!) [Switch] 120 | - Sushi Striker: The Way of Sushido [Switch] 121 | - Tank! Tank! Tank! [Wii U] 122 | - Tetris 99 [Switch] 123 | - The Legend of Zelda: Breath of the Wild [Wii U / Switch] 124 | - The Legend of Zelda: Echoes of Wisdom [Switch] 125 | - The Legend of Zelda: Link's Awakening [Switch] 126 | - The Legend of Zelda: Tears of the Kingdom [Switch] 127 | - The Legend of Zelda: Wind Waker HD [Wii U] 128 | - Tokyo Mirage Sessions #FE [Wii U] 129 | - Tokyo Mirage Sessions #FE Encore [Switch] 130 | - Vroom in the Night Sky [Switch] 131 | - WarioWare: Get It Together! [Switch] 132 | - WarioWare: Move It! [Switch] 133 | - Wii Sports Club [Wii U] 134 | - Wii U BIOS [Wii U] 135 | - Yoshi's Woolly World [Wii U] 136 | 137 | `OrochiEngine3_MDL` (12/04/2017) 138 | - World of Final Fantasy [PC / Vita] 139 | 140 | (I had another version of this script which supported more games, but it's currently lost...) 141 | 142 | `PokemonORAS_BCH` (10/26/2016) 143 | - Pokémon Omega Ruby / Alpha Sapphire [3DS] 144 | 145 | (This script is kinda hackishly-done, so don't expect everything to work.) 146 | 147 | `PokemonSwitch_GFBMDL-TRMDL` (11/27/2022) 148 | - Pokémon Legends: Arceus [Switch] 149 | - Pokémon Let's Go: Pikachu! / Eevee! [Switch] 150 | - Pokémon Scarlet / Violet [Switch] 151 | - Pokémon Sword / Shield [Switch] 152 | 153 | `PokemonXY_BCH` (02/24/2016) 154 | - Pokémon X / Y [3DS] 155 | 156 | `SegaNNLibrary_NO` (11/07/2014, original script by ItsEasyActually) 157 | - Sonic and the Black Knight [Wii] 158 | - Sonic and the Secret Rings [Wii] 159 | - Sonic Free Riders [360] 160 | - Sonic Riders: Zero Gravity [Wii] 161 | - Sonic the Hedgehog 4: Episode I [PC] 162 | - Sonic the Hedgehog 4: Episode II [PC] 163 | - Sonic the Hedgehog [360 / PS3] 164 | - Sonic Unleashed [Wii] 165 | - Super Monkey Ball: Banana Blitz [Wii] 166 | - Super Monkey Ball: Step and Roll [Wii] 167 | 168 | (I had another version of this script which supported more games, but it's currently lost...) 169 | 170 | `SSB4U-TaikoU_NDP3` (05/04/2017) 171 | - Super Smash Bros. for Wii U [Wii U] 172 | - Taiko no Tatsujin: Wii U Version [Wii U] 173 | - Taiko no Tatsujin: Tokumori! [Wii U] 174 | - Taiko no Tatsujin: Atsumete Tomodachi Daisakusen! [Wii U] 175 | 176 | `SSBUlt-NPS_NUMDLB` (05/26/2021) 177 | - New Pokémon Snap [Switch] 178 | - Super Smash Bros. Ultimate [Switch] 179 | 180 | `Tamsoft_TMD` (04/05/2017) 181 | - Hyperdimension Neptunia PP: Producing Perfection [Vita] 182 | - Hyperdimension Neptunia U: Action Unleashed [PC / Vita] 183 | - MegaTagmension Blanc + Neptune VS Zombies [PC / Vita] 184 | - Natsuiro High School: Seishun Hakusho [PS3] 185 | - Senran Kagura Burst Re:Newal [PC / PS4, use SK:EV PC option!] 186 | - Senran Kagura: Estival Versus [PC / Vita] 187 | - Senran Kagura: Peach Beach Splash [PC / PS4, use SK:EV PC option!] 188 | - Senran Kagura: Reflexions [Switch, use SK:EV PC option!] 189 | - Senran Kagura: Shinovi Versus [PC / Vita] 190 | 191 | `TelltaleGames_D3DMesh` (04/05/2017) 192 | - Back to the Future: The Game (30th Anniversary Edition) [PS4] 193 | - Batman: The Telltale Series (Season 1) [PC / PS4] 194 | - Batman: The Enemy Within (Season 2) [PC / PS4] 195 | - Bone: Out from Boneville [PC] 196 | - Bone: The Great Cow Race [PC] 197 | - CSI: 3 Dimensions of Murder [PC] 198 | - CSI: Hard Evidence [PC] 199 | - Game of Thrones [PC / PS4] 200 | - Jurassic Park: The Game [PC] 201 | - Law & Order: Legacies [PC] 202 | - Marvel's Guardians of the Galaxy [PC] 203 | - Minecraft: Story Mode (Season 1) [PC / PS4] 204 | - Minecraft: Story Mode Season 2 [PC / PS4] 205 | - Poker Night 2 [PC] 206 | - Sam & Max Season 1 [PC] 207 | - Sam & Max Season 2 [PC] 208 | - Sam & Max Save the World (Season 1) Remastered [PC] (key for TTArchExt: 92CA9A8185E46473A2BFD6D17FC6CB88995A80D8AAC297E796519FA89AD9AE95D776627FB4C4A6B9D6ECA99C6785B3DC92C49E64A0A292) 209 | - Sam & Max Beyond Time and Space (Season 2) Remastered [PC] (key for TTArchExt: 92CA9A8185E46573A2BFD6D17FC6CB89995A80D8AAC297E797519FA89AD9AE95D777627FB4C4A6B9D6ECAA9C6785B3DC92C49E65A0A292) 210 | - Sam & Max The Devil's Playhouse (Season 3) Remastered [PC] (key for TTArchExt: 92CA9A8185E46673A2BFD6D17FC6CB8A995A80D8AAC297E798519FA89AD9AE95D778627FB4C4A6B9D6ECAB9C6785B3DC92C49E66A0A292) 211 | - Strong Bad's Cool Game for Attractive People [PC] 212 | - Tales from the Borderlands [PC / PS4] 213 | - Telltale Texas Hold'em [PC] 214 | - The Walking Dead Season 1 [PC / PS4] 215 | - The Walking Dead Season 2 [PC / PS4] 216 | - The Walking Dead: A New Frontier (Season 3) [PC / PS4] 217 | - The Walking Dead: Michonne [PC] 218 | - The Walking Dead: The Final Season (Season 4) [PC] 219 | - The Walking Dead Collection [PS4] 220 | - The Walking Dead: The Telltale Definitive Series [PC] 221 | - The Wolf Among Us [PC / PS4] 222 | - Wallace and Gromit's Grand Adventures, Episodes 1-3 [PC] 223 | 224 | (This script also requires the "TelltaleHashDBs" folder to be placed in your 3DS Max's `scripts` folder for it to work as intended.) 225 | 226 | "_2012" is a temporary bugfix version if rigging is broken and "Debug" is a version where extra stuff is printed to the Listener window, those will eventually be obsoleted the next time the respective scripts are updated. These things are ancient, yo. -------------------------------------------------------------------------------- /Scripts/CrashNSane_IGZ.ms: -------------------------------------------------------------------------------- 1 | -- Crash Bandicoot: N-Sane Trilogy / Crash Team Racing: Nitro-Fueled (a.k.a. Alchemy Crash) *.IGZ Importer by Random Talking Bush 2 | -- woah 3 | 4 | rollout ModelImporter "Crash Bandicoot NST / CTR:NF Model Importer" width:330 height:210 5 | ( 6 | button btnImport "Import *.IGZ" pos:[7,8] width:316 height:50 7 | groupBox OptionsBox "Options" pos:[7,58] width:316 height:50 8 | radiobuttons tglMdlFormat "Model type:" labels:#("Actors","Models") pos:[18,72] height:10 columns:2 default:1 9 | checkbox tglDebug "Print debug information?" pos:[170,78] checked: false 10 | label lblCred "This work-in-progress script was written by Random Talking Bush for use with Crash Bandicoot: N-Sane Trilogy and Crash Team Racing: Nitro-Fueled. If used, please consider giving thanks to me, Naughty Dog, Vicarious Visions, Beenox and Activision. If something doesn't work right (which is likely for props and levels), please contact me on The VG Resource (Random Talking Bush), XeNTaX, Twitter or Steam (RandomTBush) so I can fix it." pos:[8,112] width:317 height:100 11 | 12 | fn readHalfFloat fstream = ( 13 | local BL = readByte Fstream #unsigned 14 | local BH = readByte Fstream #unsigned 15 | local N = BH*256 + BL 16 | local S = floor((mod N 65536) / 32768) 17 | local Ef = floor((mod N 32768) / 1024) 18 | local M = mod N 1024 19 | if (Ef==0)AND(M==0) then return ( (-1.0)^S * 0.0 ) 20 | if (Ef==0)AND(M!=0) then return ( (-1.0)^S * 2.0^-14 * (M / 2.0^10) ) 21 | if (Ef>0)AND(Ef<31) then return ( (-1.0)^S * 2.0^(Ef-15) * (1 + M/2.0^10) ) 22 | if (Ef==31)AND(M==0) then return ( (-1.0)^S * 1/0.0 ) 23 | if (Ef==31)AND(M!=0) then return 0 24 | ) 25 | 26 | fn printDebug pr = (if tglDebug.state do print(pr)) 27 | 28 | on btnImport pressed do( 29 | clearlistener() 30 | local ModelFormat = tglMdlFormat.state 31 | fname = getOpenFileName \ 32 | caption:"Crash Bandicoot N-Sane Trilogy / Crash Team Racing Nitro-Fueled Model File" \ 33 | types:"Crash Bandicoot *.IGZ Model File|*.igz" \ 34 | historyCategory:"CrashNSaneObjectPresets" 35 | if fname != undefined do( 36 | f = fopen fname "rb" 37 | p = getFilenamePath fname 38 | g = getFilenameFile fname 39 | st = timestamp() 40 | 41 | struct Material_Struct 42 | ( 43 | MatName, MatDep 44 | ) 45 | struct VertBuffer_Struct 46 | ( 47 | VertFormat1, VertFormat2, VertFormat3, VertFormat4, VertType, VertLayer, VertUnk1, VertUnk2, VertShift 48 | ) 49 | struct Bone_Info_Struct 50 | ( 51 | Bone1, Bone2, Bone3, Bone4 52 | ) 53 | struct Weight_Info_Struct 54 | ( 55 | Weight1, Weight2, Weight3, Weight4 56 | ) 57 | struct weight_data 58 | ( 59 | boneids, weights 60 | ) 61 | 62 | BoneArray = #() 63 | BoneName_array = #() 64 | BoneParent_array = #() 65 | String_array = #() 66 | Materials_array = #() 67 | NodeID_array = #() 68 | 69 | IGZMagic = readlong f 70 | fseek f 0x10 #seek_set 71 | IGZMagicCount = readlong f 72 | if IGZMagic == 0x49475A01 do( 73 | fseek f 0x0800 #seek_set 74 | for b = 1 to IGZMagicCount do( 75 | NextOffset = (ftell f) 76 | IGZMagic = readlong f 77 | case IGZMagic of( 78 | default:(throw("Unexpected section type!")) 79 | 0x50454454:( 80 | printDebug ("TDEP: " + NextOffset as string) 81 | TDEPCount = readlong f 82 | TDEPSize = readlong f 83 | TDEPStart = readlong f 84 | NextOffset = (NextOffset + TDEPSize) 85 | print "Dependencies:" 86 | for i = 1 to TDEPCount do( 87 | TDEPStringA = readstring f 88 | CheckByte = readbyte f 89 | if CheckByte != 0x00 do (fseek f -1 #seek_cur) 90 | TDEPStringB = readstring f 91 | CheckByte = readbyte f 92 | if CheckByte != 0x00 do (fseek f -1 #seek_cur) 93 | print TDEPStringA 94 | ) 95 | print "----------" 96 | ) 97 | 0x52545354:( 98 | printDebug ("TSTR: " + NextOffset as string) 99 | TSTRCount = readlong f 100 | TSTRSize = readlong f 101 | TSTRStart = readlong f 102 | NextOffset = (NextOffset + TSTRSize) 103 | for i = 1 to TSTRCount do( 104 | TSTRString = readstring f 105 | CheckByte = readbyte f 106 | if CheckByte != 0x00 do (fseek f -1 #seek_cur) 107 | append String_array TSTRString 108 | ) 109 | printDebug ("Strings:") 110 | printDebug (String_array) 111 | printDebug ("----------") 112 | ) 113 | 0x54454D54:( 114 | printDebug ("TMET: " + NextOffset as string) 115 | TMETCount = readlong f 116 | TMETSize = readlong f 117 | TMETStart = readlong f 118 | NextOffset = (NextOffset + TMETSize) 119 | for i = 1 to TMETCount do( 120 | TMETString = readstring f 121 | CheckByte = readbyte f 122 | if CheckByte != 0x00 do (fseek f -1 #seek_cur) 123 | ) 124 | ) 125 | 0x5A53544D:( 126 | printDebug ("MTSZ: " + NextOffset as string) 127 | MTSZCount = readlong f 128 | MTSZSize = readlong f 129 | MTSZStart = readlong f 130 | NextOffset = (NextOffset + MTSZSize) 131 | for i = 1 to MTSZCount do( 132 | MTSZID = readlong f 133 | ) 134 | ) 135 | 0x44495845:( 136 | printDebug ("EXID: " + NextOffset as string) 137 | EXIDCount = readlong f 138 | EXIDSize = readlong f 139 | EXIDStart = readlong f 140 | NextOffset = (NextOffset + EXIDSize) 141 | for i = 1 to EXIDCount do( 142 | EXIDIDA = readlong f 143 | EXIDIDB = readlong f 144 | ) 145 | ) 146 | 0x4D4E5845:( 147 | printDebug ("EXNM: " + NextOffset as string) 148 | EXNMCount = readlong f 149 | EXNMSize = readlong f 150 | EXNMStart = readlong f 151 | NextOffset = (NextOffset + EXNMSize) 152 | for i = 1 to EXNMCount do( 153 | EXNMStringA = readshort f #unsigned + 1; EXNMStringA2 = readshort f #unsigned; EXNMStringA = String_array[EXNMStringA] 154 | EXNMStringB = readshort f #unsigned + 1; EXNMStringB2 = readshort f #unsigned; EXNMStringB = String_array[EXNMStringB] 155 | append Materials_array (Material_Struct MatName:EXNMStringA MatDep:EXNMStringB) 156 | ) 157 | print "Materials:" 158 | print Materials_array 159 | print "----------" 160 | ) 161 | 0x42545652:( 162 | printDebug ("RVTB: " + NextOffset as string) 163 | RVTBCount = readlong f 164 | RVTBSize = readlong f 165 | RVTBStart = readlong f 166 | NextOffset = (NextOffset + RVTBSize) 167 | for i = 1 to RVTBCount do( 168 | RVTBID = readbyte f 169 | ) 170 | RVTBIDA = readbyte f 171 | RVTBIDB = readbyte f 172 | RVTBIDC = readbyte f 173 | ) 174 | 0x54545352:( 175 | printDebug ("RSTT: " + NextOffset as string) 176 | RSTTCount = readlong f 177 | RSTTSize = readlong f 178 | RSTTStart = readlong f 179 | NextOffset = (NextOffset + RSTTSize) 180 | for i = 1 to RSTTCount do( 181 | RSTTID = readbyte f 182 | ) 183 | RSTTIDA = readbyte f 184 | RSTTIDB = readbyte f 185 | RSTTIDC = readbyte f 186 | RSTTIDD = readbyte f 187 | RSTTIDE = readlong f 188 | ) 189 | 0x53464F52:( 190 | printDebug ("ROFS: " + NextOffset as string) 191 | ROFSCount = readlong f 192 | ROFSSize = readlong f 193 | ROFSStart = readlong f 194 | NextOffset = (NextOffset + ROFSSize) 195 | ) 196 | 0x44495052:( 197 | printDebug ("RPID: " + NextOffset as string) 198 | RPIDCount = readlong f 199 | RPIDSize = readlong f 200 | RPIDStart = readlong f 201 | NextOffset = (NextOffset + RPIDSize) 202 | ) 203 | 0x54584552:( 204 | printDebug ("REXT: " + NextOffset as string) 205 | REXTCount = readlong f 206 | REXTSize = readlong f 207 | REXTStart = readlong f 208 | NextOffset = (NextOffset + REXTSize) 209 | ) 210 | 0x444E4852:( 211 | printDebug ("RHND: " + NextOffset as string) 212 | RHNDCount = readlong f 213 | RHNDSize = readlong f 214 | RHNDStart = readlong f 215 | NextOffset = (NextOffset + RHNDSize) 216 | ) 217 | 0x58454E52:( 218 | printDebug ("RNEX: " + NextOffset as string) 219 | RNEXCount = readlong f 220 | RNEXSize = readlong f 221 | RNEXStart = readlong f 222 | NextOffset = (NextOffset + RNEXSize) 223 | ) 224 | 0x544F4F52:( 225 | printDebug ("ROOT: " + NextOffset as string) 226 | ROOTCount = readlong f 227 | ROOTSize = readlong f 228 | ROOTStart = readlong f 229 | NextOffset = (NextOffset + ROOTSize) 230 | for i = 1 to ROOTCount do( 231 | ROOTID = readlong f 232 | ) 233 | ) 234 | 0x4D414E4F:( 235 | ModelOffset = ((ftell f) - 0x04) 236 | printDebug ("ONAM: " + ModelOffset as string) 237 | ONAMCount = readlong f 238 | ONAMSize = readlong f 239 | ONAMStart = readlong f 240 | ModelOffset = (ModelOffset + ONAMSize) 241 | for i = 1 to ONAMCount do( 242 | ONAMID = readlong f 243 | ) 244 | ModelStart = (ftell f) 245 | BoneCount = 0 246 | 247 | multimat = MultiMaterial() 248 | multimat.name = g as string 249 | multimat.numsubs = Materials_array.count 250 | for m = 1 to Materials_array.count do( 251 | mat = multimat.materialList[m] 252 | mat.name = Materials_array[m].MatName 253 | mat.showinviewport = true 254 | mat.twosided = false 255 | tm = Bitmaptexture filename:(p + (Materials_array[m].MatName as string) + ".png") 256 | tm.alphasource = 0 257 | mat.diffuseMap = tm 258 | mat.opacityMap = tm 259 | mat.opacityMap.monoOutput = 1 260 | ) 261 | 262 | printDebug ("Model Start: " + (ModelStart) as string) 263 | 264 | case ModelFormat of( 265 | 1:( 266 | Blank = readlong f 267 | Blank = readlong f 268 | Blank = readlong f 269 | Unknown = readlong f 270 | 271 | SubSectCount = readlong f 272 | VerCheck = readlong f 273 | if VerCheck == 0x00000002 do(PCVer = "Yes") 274 | SubSectHeaderSize = readlong f 275 | Unknown = readlong f 276 | 277 | SubSectOffset = (readlong f + ModelStart); Pad64Bit = readlong f 278 | fseek f SubSectOffset #seek_set 279 | ModelInfoOffset = #() 280 | 281 | case SubSectCount of( 282 | default:(print "Currently unsupported, sorry."; exit()) 283 | 2:( 284 | InfoOffset = readlong f + ModelStart; Pad64Bit = readlong f 285 | ModelInfoOffset = readlong f + ModelStart; Pad64Bit = readlong f 286 | fseek f ModelInfoOffset #seek_set 287 | ) 288 | ) 289 | 290 | Unknown = readlong f 291 | Blank = readlong f 292 | 293 | Unknown = readlong f 294 | Blank = readlong f 295 | Blank = readlong f 296 | Blank = readlong f 297 | 298 | Blank = readlong f 299 | Blank = readlong f 300 | Unknown = readlong f 301 | Blank = readlong f 302 | 303 | BoneInfoOffset = readlong f + ModelStart; Pad64Bit = readlong f 304 | ModelInfoOffset = readlong f + ModelStart; Pad64Bit = readlong f 305 | 306 | UnknownOffset2 = readlong f + ModelStart; Pad64Bit = readlong f 307 | Blank = readlong f; if Blank != 0 do(print "Try the 'Models' option instead."; exit()) 308 | Blank = readlong f 309 | 310 | BoundMinX = readfloat f 311 | BoundMinY = readfloat f 312 | BoundMinZ = readfloat f 313 | BoundMaxX = readfloat f 314 | 315 | BoundMaxY = readfloat f 316 | BoundMaxZ = readfloat f 317 | Unknown = readlong f 318 | Blank = readlong f 319 | 320 | Unknown = readlong f 321 | Blank = readlong f 322 | Unknown = readlong f 323 | Blank = readlong f 324 | 325 | Unknown = readlong f 326 | Blank = readlong f 327 | BoneMatrixSize = readlong f 328 | Unknown = readlong f 329 | 330 | BoneMatrixStart = readlong f + ModelStart 331 | Blank = readlong f 332 | Unknown = readlong f 333 | Blank = readlong f 334 | 335 | Unknown = readlong f 336 | BoneCountPS4 = readlong f 337 | BoneCount = readlong f 338 | BoneCountPC = readlong f 339 | 340 | BoneHeaderSize = readlong f 341 | Unknown = readlong f 342 | BoneHeaderStart = readlong f + ModelStart 343 | Blank = readlong f 344 | 345 | fseek f BoneHeaderStart #seek_set 346 | 347 | for b = 1 to BoneCount do( 348 | BoneOffset = readlong f + ModelStart; Pad64Bit = readlong f 349 | BoneRet = ftell f 350 | 351 | fseek f BoneOffset #seek_set 352 | Unknown = readlong f 353 | Blank = readlong f 354 | Unknown = readlong f 355 | Blank = readlong f 356 | BoneNameID = readlong f + 1; BoneName = String_array[BoneNameID] 357 | Blank = readlong f 358 | BoneParent = readlong f 359 | BoneNum = readlong f 360 | BoneTX = readfloat f 361 | BoneTY = readfloat f 362 | BoneTZ = readfloat f 363 | Blank = readlong f 364 | append BoneName_array BoneName 365 | append BoneParent_array BoneParent 366 | fseek f BoneRet #seek_set 367 | ) 368 | 369 | fseek f BoneMatrixStart #seek_set 370 | for b = 1 to BoneCount do( 371 | if b == 1 then( 372 | m11 = 1; m12 = 0; m13 = 0; m14 = 0 373 | m21 = 0; m22 = 1; m23 = 0; m24 = 0 374 | m31 = 0; m32 = 0; m33 = 1; m34 = 0 375 | m41 = 0; m42 = 0; m43 = 0; m44 = 1 376 | ) else ( 377 | m11 = readfloat f; m12 = readfloat f; m13 = readfloat f; m14 = readfloat f 378 | m21 = readfloat f; m22 = readfloat f; m23 = readfloat f; m24 = readfloat f 379 | m31 = readfloat f; m32 = readfloat f; m33 = readfloat f; m34 = readfloat f 380 | m41 = readfloat f; m42 = readfloat f; m43 = readfloat f; m44 = readfloat f 381 | ) 382 | tfm = inverse(matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]) 383 | BoneName = BoneName_array[b] 384 | BoneParent = BoneParent_array[b] 385 | 386 | newBone = bonesys.createbone \ 387 | tfm.row4 \ 388 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 389 | (normalize tfm.row3) 390 | newBone.name = BoneName 391 | newBone.width = 0.01 392 | newBone.height = 0.01 393 | newBone.transform = tfm 394 | newBone.setBoneEnable false 0 395 | newBone.wirecolor = yellow 396 | newbone.showlinks = true 397 | newBone.pos.controller = TCB_position () 398 | newBone.rotation.controller = TCB_rotation () 399 | if (BoneParent != -1) then 400 | newBone.parent = BoneArray[(BoneParent + 1)] 401 | append BoneArray newBone 402 | ) 403 | 404 | fseek f UnknownOffset2 #seek_set 405 | 406 | Unknown = readlong f 407 | Blank = readlong f 408 | Unknown = readlong f 409 | Blank = readlong f 410 | Blank = readlong f 411 | Blank = readlong f 412 | Blank = readlong f 413 | Blank = readlong f 414 | Blank = readlong f 415 | Unknown = readlong f 416 | Blank = readlong f 417 | Blank = readlong f 418 | Blank = readlong f 419 | Unknown = readlong f 420 | Unknown = readlong f 421 | Blank = readlong f 422 | Unknown = readlong f 423 | Blank = readlong f 424 | Blank = readlong f 425 | Unknown = readlong f 426 | Unknown = readlong f 427 | Unknown = readlong f 428 | VertPlus = readlong f 429 | Unknown = readlong f 430 | VertStart = readlong f + ModelStart + VertPlus 431 | Blank = readlong f 432 | Unknown = readlong f 433 | Blank = readlong f 434 | Unknown = readlong f 435 | Blank = readlong f 436 | Unknown = readlong f 437 | Blank = readlong f 438 | Unknown = readlong f 439 | Blank = readlong f 440 | 441 | fseek f ModelInfoOffset #seek_set 442 | 443 | Unknown = readlong f 444 | Blank = readlong f 445 | Unknown = readlong f 446 | Blank = readlong f 447 | Blank = readlong f 448 | Blank = readlong f 449 | Blank = readlong f 450 | Blank = readlong f 451 | Unknown = readlong f 452 | Unknown = readlong f 453 | Unknown = readlong f 454 | Blank = readlong f 455 | Unknown = readlong f 456 | Unknown = readlong f 457 | Unknown = readlong f 458 | Unknown = readlong f 459 | Blank = readlong f 460 | Blank = readlong f 461 | Blank = readlong f 462 | Unknown = readlong f 463 | Blank = readlong f 464 | Blank = readlong f 465 | Blank = readlong f 466 | Blank = readlong f 467 | Blank = readlong f 468 | Blank = readlong f 469 | Blank = readlong f 470 | Blank = readlong f 471 | ModelCount = readlong f 472 | printDebug ("PolyGroups: " + ModelCount as string) 473 | Blank = readlong f 474 | ModelBufferSize = readlong f 475 | Unknown = readlong f 476 | SubModelOffset = readlong f + ModelStart; Pad64Bit = readlong f 477 | Unknown = readlong f 478 | Blank = readlong f 479 | Unknown = readlong f 480 | Unknown = readlong f 481 | UnknownModelOffset = readlong f + ModelStart; Pad64Bit = readlong f 482 | Blank = readlong f 483 | Blank = readlong f 484 | Blank = readlong f 485 | Unknown = readlong f 486 | Blank = readlong f 487 | Blank = readlong f 488 | NodeIDCount = readlong f 489 | Blank = readlong f 490 | NodeIDSize = readlong f 491 | Unknown = readlong f 492 | NodeIDOffset = readlong f + ModelStart; Pad64Bit = readlong f 493 | 494 | fseek f NodeIDOffset #seek_set 495 | 496 | for n = 1 to NodeIDCount do( 497 | NodeID = readlong f + 2 498 | append NodeID_array NodeID 499 | ) 500 | 501 | fseek f SubModelOffset #seek_set 502 | 503 | Vert_array = #() 504 | Normal_array = #() 505 | Color_array = #() 506 | Alpha_array = #() 507 | UV_array = #() 508 | UV2_array = #() 509 | UV3_array = #() 510 | UV4_array = #() 511 | Face_array = #() 512 | B1_array = #() 513 | B2_array = #() 514 | W1_array = #() 515 | W2_array = #() 516 | Weight_array = #() 517 | MatID_array = #() 518 | VertAdd = 0 519 | 520 | for y = 1 to ModelCount do( 521 | VertBuffer_array = #() 522 | ModelInfoOffset = (readlong f + ModelStart); Pad64Bit = readlong f 523 | ModelRet = ftell f 524 | 525 | fseek f ModelInfoOffset #seek_set 526 | printDebug ("ModelInfoOffset: " + ftell f as string) 527 | Unknown = readlong f 528 | Blank = readlong f 529 | Unknown = readlong f 530 | Blank = readlong f 531 | ModelNameID = readlong f + 1; ModelName = String_array[ModelNameID] 532 | Blank = readlong f 533 | Blank = readlong f 534 | Blank = readlong f 535 | BoundMinX = readlong f 536 | BoundMinY = readlong f 537 | BoundMinZ = readlong f 538 | Blank = readlong f 539 | BoundMaxX = readlong f 540 | BoundMaxY = readlong f 541 | BoundMaxZ = readlong f 542 | Blank = readlong f 543 | MatID = readshort f #unsigned + 1 544 | Unknown = readshort f #unsigned 545 | Blank = readlong f 546 | VertInfoOffset = (readlong f + ModelStart); Pad64Bit = readlong f 547 | PolyInfoOffset = (readlong f + ModelStart); Pad64Bit = readlong f 548 | Blank = readlong f 549 | Blank = readlong f 550 | NodeIDStart = readshort f #unsigned + 1 551 | NodeIDTotal = readshort f #unsigned 552 | Blank = readlong f 553 | Blank = readlong f 554 | Unknown = readlong f 555 | Blank = readlong f 556 | Blank = readlong f 557 | Unknown = readlong f 558 | Blank = readlong f 559 | Blank = readlong f 560 | Blank = readlong f 561 | Blank = readlong f 562 | Blank = readlong f 563 | Blank = readlong f 564 | Blank = readlong f 565 | Blank = readlong f 566 | Blank = readlong f 567 | 568 | fseek f VertInfoOffset #seek_set 569 | printDebug ("VertInfoOffset: " + ftell f as string) 570 | 571 | Unknown = readlong f 572 | Blank = readlong f 573 | Unknown = readlong f 574 | Blank = readlong f 575 | Blank = readlong f 576 | Blank = readlong f 577 | Unknown = readlong f 578 | Blank = readlong f 579 | InfoOffset1 = (readlong f + ModelStart); Pad64Bit = readlong f 580 | InfoOffset2 = (readlong f + ModelStart); Pad64Bit = readlong f 581 | InfoOffset3 = (readlong f + ModelStart); Pad64Bit = readlong f 582 | 583 | fseek f InfoOffset1 #seek_set 584 | Unknown = readlong f 585 | Blank = readlong f 586 | Unknown = readlong f 587 | if PCVer == "Yes" do(Blank = readlong f) 588 | VertexCount = readlong f 589 | if PCVer == "Yes" do(Blank = readlong f) 590 | Unknown = readlong f 591 | Unknown = readlong f 592 | InfoOffset1B = (readlong f + ModelStart); Pad64Bit = readlong f 593 | VertexBufferSize = readlong f 594 | Unknown = readlong f 595 | VertexBufferStart = (readlong f) - 0x08000000 + VertStart 596 | Blank = readlong f 597 | InfoOffset1C = (readlong f + ModelStart); Pad64Bit = readlong f 598 | Unknown = readlong f 599 | Blank = readlong f 600 | InfoOffset1D = (readlong f + ModelStart); Pad64Bit = readlong f 601 | Blank = readlong f 602 | Blank = readlong f 603 | Blank = readlong f 604 | Blank = readlong f 605 | InfoOffset1E = (readlong f + ModelStart); Pad64Bit = readlong f 606 | 607 | fseek f InfoOffset1B #seek_set 608 | VertexCount2 = readlong f 609 | Blank = readlong f 610 | 611 | fseek f InfoOffset1C #seek_set 612 | Unknown = readlong f 613 | Blank = readlong f 614 | Unknown = readlong f 615 | if PCVer == "Yes" do(Blank = readlong f) 616 | VertexBufferStride = readlong f 617 | if PCVer == "Yes" do(Blank = readlong f) 618 | VertBuffParamASize = readlong f 619 | Unknown = readlong f 620 | VertBuffParamAOffset = (readlong f + ModelStart); Pad64Bit = readlong f 621 | VertBuffParamBSize = readlong f 622 | Unknown = readlong f 623 | VertBuffParamBOffset = (readlong f + ModelStart); Pad64Bit = readlong f 624 | Unknown = readlong f 625 | Unknown = readlong f 626 | InfoOffset1F = (readlong f + ModelStart); Pad64Bit = readlong f 627 | InfoOffset1G = (readlong f + ModelStart); Pad64Bit = readlong f 628 | Unknown = readlong f 629 | Blank = readlong f 630 | Unknown = readlong f 631 | Unknown = readlong f 632 | Blank = readlong f 633 | Blank = readlong f 634 | Blank = readlong f 635 | Blank = readlong f 636 | Unknown = readlong f 637 | Blank = readlong f 638 | InfoOffset1H = (readlong f + ModelStart); Pad64Bit = readlong f 639 | Unknown = readlong f 640 | Unknown = readlong f 641 | 642 | fseek f VertBuffParamAOffset #seek_set 643 | for v = 1 to (VertBuffParamASize / 0x0C) do( 644 | VertFormat1 = readbyte f #unsigned 645 | VertFormat2 = readbyte f #unsigned 646 | VertFormat3 = readbyte f #unsigned 647 | VertFormat4 = readbyte f #unsigned 648 | VertType = readbyte f #unsigned + 1 649 | VertLayer = readbyte f #unsigned + 1 650 | VertUnk1 = readbyte f #unsigned 651 | VertUnk2 = readbyte f #unsigned 652 | VertShift = readlong f #unsigned 653 | printDebug (VertFormat1 as string + " / " + VertFormat2 as string + " / " + VertFormat3 as string + " / " + VertFormat4 as string + ", type: " + VertType as string + ", layer: " + VertLayer as string + ", unk: " + VertUnk1 as string + " / " + VertUnk2 as string + ", shift: " + VertShift as string) 654 | append VertBuffer_array (VertBuffer_Struct VertFormat1:VertFormat1 VertFormat2:VertFormat2 VertFormat3:VertFormat3 VertFormat4:VertFormat4 VertType:VertType VertLayer:VertLayer VertUnk1:VertUnk1 VertUnk2:VertUnk2 VertShift:VertShift) 655 | ) 656 | 657 | fseek f VertBuffParamBOffset #seek_set 658 | for v = 1 to (VertBuffParamBSize / 0x04) do( 659 | VertUnknown = readlong f 660 | ) 661 | 662 | fseek f PolyInfoOffset #seek_set 663 | printDebug ("PolyInfoOffset: " + ftell f as string) 664 | Unknown = readlong f 665 | Blank = readlong f 666 | Unknown = readlong f 667 | Blank = readlong f 668 | Blank = readlong f 669 | Blank = readlong f 670 | Unknown = readlong f 671 | Blank = readlong f 672 | InfoOffset1 = (readlong f + ModelStart); Pad64Bit = readlong f 673 | InfoOffset2 = (readlong f + ModelStart); Pad64Bit = readlong f 674 | InfoOffset3 = (readlong f + ModelStart); Pad64Bit = readlong f 675 | 676 | fseek f InfoOffset1 #seek_set 677 | Unknown = readlong f 678 | Blank = readlong f 679 | Unknown = readlong f 680 | if PCVer == "Yes" do(Blank = readlong f) 681 | FacepointCount = readlong f 682 | if PCVer == "Yes" do(Blank = readlong f) 683 | Unknown = readlong f 684 | Unknown = readlong f 685 | InfoOffset1B = (readlong f + ModelStart); Pad64Bit = readlong f 686 | PolyBufferSize = readlong f 687 | Unknown = readlong f 688 | PolyBufferStart = (readlong f) - 0x08000000 + VertStart 689 | Blank = readlong f 690 | InfoOffset1C = readlong f; Pad64Bit = readlong f 691 | Unknown = readlong f 692 | Blank = readlong f 693 | InfoOffset1D = (readlong f + ModelStart); Pad64Bit = readlong f 694 | Blank = readlong f 695 | Blank = readlong f 696 | Blank = readlong f 697 | Blank = readlong f 698 | InfoOffset1E = (readlong f + ModelStart); Pad64Bit = readlong f 699 | 700 | fseek f InfoOffset1B #seek_set 701 | FacepointCount2 = readlong f 702 | Blank = readlong f 703 | 704 | fseek f InfoOffset1D #seek_set 705 | Unknown = readlong f 706 | Blank = readlong f 707 | Unknown = readlong f 708 | if PCVer == "Yes" do(Blank = readlong f) 709 | VertexBufferStride = readlong f 710 | if PCVer == "Yes" do(Blank = readlong f) 711 | PolyBuffParamASize = readlong f 712 | Unknown = readlong f 713 | PolyBuffParamAOffset = (readlong f + ModelStart); Pad64Bit = readlong f 714 | PolyBuffParamBSize = readlong f 715 | Unknown = readlong f 716 | PolyBuffParamBOffset = (readlong f + ModelStart); Pad64Bit = readlong f 717 | Unknown = readlong f 718 | Unknown = readlong f 719 | InfoOffset1F = (readlong f + ModelStart); Pad64Bit = readlong f 720 | InfoOffset1G = (readlong f + ModelStart); Pad64Bit = readlong f 721 | Unknown = readlong f 722 | Blank = readlong f 723 | Unknown = readlong f 724 | Unknown = readlong f 725 | Blank = readlong f 726 | Blank = readlong f 727 | Blank = readlong f 728 | Blank = readlong f 729 | Unknown = readlong f 730 | Blank = readlong f 731 | InfoOffset1H = (readlong f + ModelStart); Pad64Bit = readlong f 732 | Unknown = readlong f 733 | Unknown = readlong f 734 | 735 | fseek f VertexBufferStart #seek_set 736 | printDebug ("Vertex start: " + ftell f as string + ", size: 0x" + (bit.intAsHex(VertexBufferStride) as string)) 737 | 738 | for v = 1 to VertexCount do( 739 | for w = 1 to VertBuffer_array.count do( 740 | VertType = VertBuffer_array[w].VertType 741 | VertFmt = VertBuffer_array[w].VertFormat1 742 | VertLayer = VertBuffer_array[w].VertLayer 743 | case VertType of( 744 | default:(throw("Unknown vertex type!")) 745 | 1:( 746 | case VertFmt of( 747 | default:(throw("Unknown position format!")) 748 | 2:( 749 | vx = readfloat f 750 | vy = readfloat f 751 | vz = readfloat f 752 | append Vert_array [vx,vy,vz] 753 | ) 754 | 44:() 755 | ) 756 | ) 757 | 2:( 758 | case VertFmt of( 759 | default:(throw("Unknown normals/binormals format!")) 760 | 2:( 761 | nx = readfloat f 762 | ny = readfloat f 763 | nz = readfloat f 764 | if VertLayer == 1 do(append Normal_array [nx,ny,nz]) 765 | ) 766 | ) 767 | ) 768 | 3:( 769 | case VertFmt of( 770 | default:(throw("Unknown tangents(?) format!")) 771 | 2:( 772 | tanx = readfloat f 773 | tany = readfloat f 774 | tanz = readfloat f 775 | ) 776 | ) 777 | ) 778 | 5:( 779 | case VertFmt of( 780 | default:(throw("Unknown colors format!")) 781 | 4:( 782 | colorr = readbyte f #unsigned 783 | colorg = readbyte f #unsigned 784 | colorb = readbyte f #unsigned 785 | colora = (readbyte f #unsigned as float) / 255 786 | if VertLayer == 1 do( 787 | append Color_Array[colorr,colorg,colorb] 788 | append Alpha_Array colora 789 | ) 790 | ) 791 | ) 792 | ) 793 | 6:( 794 | case VertFmt of( 795 | default:(throw("Unknown UVs format!")) 796 | 2:( 797 | tu = readfloat f 798 | tv = (readfloat f * -1) + 1 799 | tw = readfloat f 800 | if VertLayer == 1 do(append UV_array [tu,tv,0]) 801 | if VertLayer == 2 do(append UV2_array [tu,tv,0]) 802 | if VertLayer == 3 do(append UV3_array [tu,tv,0]) 803 | if VertLayer == 4 do(append UV4_array [tu,tv,0]) 804 | ) 805 | 42:( 806 | tu = readhalffloat f 807 | tv = (readhalffloat f * -1) + 1 808 | if VertLayer == 1 do(append UV_array [tu,tv,0]) 809 | if VertLayer == 2 do(append UV2_array [tu,tv,0]) 810 | if VertLayer == 3 do(append UV3_array [tu,tv,0]) 811 | if VertLayer == 4 do(append UV4_array [tu,tv,0]) 812 | ) 813 | ) 814 | ) 815 | 7:( 816 | case VertFmt of( 817 | default:(throw("Unknown weights format!")) 818 | 26:( 819 | Weight1 = (readbyte f #unsigned as float) / 255 820 | Weight2 = (readbyte f #unsigned as float) / 255 821 | Weight3 = (readbyte f #unsigned as float) / 255 822 | Weight4 = (readbyte f #unsigned as float) / 255 823 | if VertLayer == 1 do(append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4)) 824 | if VertLayer == 2 do(append W2_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4)) 825 | ) 826 | ) 827 | ) 828 | 9:( 829 | case VertFmt of( 830 | default:(throw("Unknown bones format!")) 831 | 13:( 832 | Bone1 = NodeID_array[(readlong f) + NodeIDStart] 833 | Bone2 = NodeID_array[(readlong f) + NodeIDStart] 834 | Bone3 = NodeID_array[(readlong f) + NodeIDStart] 835 | Bone4 = NodeID_array[(readlong f) + NodeIDStart] 836 | if Bone1 == undefined do(Bone1 = 1) 837 | if Bone2 == undefined do(Bone2 = 1) 838 | if Bone3 == undefined do(Bone3 = 1) 839 | if Bone4 == undefined do(Bone4 = 1) 840 | if VertLayer == 1 do(append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 841 | if VertLayer == 2 do(append B2_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 842 | ) 843 | 23:( 844 | Bone1 = NodeID_array[(readbyte f) + NodeIDStart] 845 | Bone2 = NodeID_array[(readbyte f) + NodeIDStart] 846 | Bone3 = NodeID_array[(readbyte f) + NodeIDStart] 847 | Bone4 = NodeID_array[(readbyte f) + NodeIDStart] 848 | if Bone1 == undefined do(Bone1 = 1) 849 | if Bone2 == undefined do(Bone2 = 1) 850 | if Bone3 == undefined do(Bone3 = 1) 851 | if Bone4 == undefined do(Bone4 = 1) 852 | if VertLayer == 1 do(append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 853 | if VertLayer == 2 do(append B2_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 854 | ) 855 | ) 856 | ) 857 | ) 858 | ) 859 | ) 860 | printDebug ("Vertex end: " + ftell f as string) 861 | fseek f PolyBufferStart #seek_set 862 | printDebug ("Facepoint start: " + ftell f as string) 863 | 864 | if VertexCount > 65535 then( 865 | for v = 1 to (FacepointCount / 3) do( 866 | fa = readlong f #unsigned + 1 + VertAdd 867 | fb = readlong f #unsigned + 1 + VertAdd 868 | fc = readlong f #unsigned + 1 + VertAdd 869 | append Face_array [fa,fb,fc] 870 | append MatID_array MatID 871 | ) 872 | ) else ( 873 | for v = 1 to (FacepointCount / 3) do( 874 | fa = readshort f #unsigned + 1 + VertAdd 875 | fb = readshort f #unsigned + 1 + VertAdd 876 | fc = readshort f #unsigned + 1 + VertAdd 877 | append Face_array [fa,fb,fc] 878 | append MatID_array MatID 879 | ) 880 | ) 881 | printDebug ("Facepoint end: " + ftell f as string) 882 | 883 | fseek f ModelRet #seek_set 884 | VertAdd = VertAdd + VertexCount 885 | 886 | ) 887 | 888 | if Color_Array.count == 0 do( 889 | For v = 1 to Vert_array.count do( 890 | append Color_Array[255,255,255] 891 | append Alpha_Array 1 892 | ) 893 | ) 894 | 895 | if BoneCount > 0 do( 896 | if B2_Array.count == 0 do( 897 | For v = 1 to B1_array.count do( 898 | append B2_Array (Bone_Info_Struct bone1:1 bone2:1 bone3:1 bone4:1) 899 | append W2_Array (Weight_Info_Struct weight1:0 weight2:0 weight3:0 weight4:0) 900 | ) 901 | ) 902 | for b = 1 to W1_Array.count do( 903 | w = (weight_data boneids:#() weights:#()) 904 | maxweight = 0 905 | 906 | if W1_array[b].Weight1 != 0 do maxweight += W1_array[b].Weight1 907 | if W1_array[b].Weight2 != 0 do maxweight += W1_array[b].Weight2 908 | if W1_array[b].Weight3 != 0 do maxweight += W1_array[b].Weight3 909 | if W1_array[b].Weight4 != 0 do maxweight += W1_array[b].Weight4 910 | if W2_array[b].Weight1 != 0 do maxweight += W2_array[b].Weight1 911 | if W2_array[b].Weight2 != 0 do maxweight += W2_array[b].Weight2 912 | if W2_array[b].Weight3 != 0 do maxweight += W2_array[b].Weight3 913 | if W2_array[b].Weight4 != 0 do maxweight += W2_array[b].Weight4 914 | 915 | if maxweight != 0 then( 916 | if W1_array[b].Weight1 != 0 then( 917 | w1 = W1_array[b].Weight1 as float 918 | append w.boneids (B1_array[b].Bone1) 919 | append w.weights (w1) 920 | ) 921 | if W1_array[b].Weight2 != 0 then( 922 | w2 = W1_array[b].Weight2 as float 923 | append w.boneids (B1_array[b].Bone2) 924 | append w.weights (w2) 925 | ) 926 | if W1_array[b].Weight3 != 0 then( 927 | w3 = W1_array[b].Weight3 as float 928 | append w.boneids (B1_array[b].Bone3) 929 | append w.weights (w3) 930 | ) 931 | if W1_array[b].Weight4 != 0 then( 932 | w4 = W1_array[b].Weight4 as float 933 | append w.boneids (B1_array[b].Bone4) 934 | append w.weights (w4) 935 | ) 936 | if W2_array[b].Weight1 != 0 then( 937 | w5 = W2_array[b].Weight1 as float 938 | append w.boneids (B2_array[b].Bone1) 939 | append w.weights (w5) 940 | ) 941 | if W2_array[b].Weight2 != 0 then( 942 | w6 = W2_array[b].Weight2 as float 943 | append w.boneids (B2_array[b].Bone2) 944 | append w.weights (w6) 945 | ) 946 | if W2_array[b].Weight3 != 0 then( 947 | w7 = W2_array[b].Weight3 as float 948 | append w.boneids (B2_array[b].Bone3) 949 | append w.weights (w7) 950 | ) 951 | if W2_array[b].Weight4 != 0 then( 952 | w8 = W2_array[b].Weight4 as float 953 | append w.boneids (B2_array[b].Bone4) 954 | append w.weights (w8) 955 | ) 956 | ) 957 | append Weight_array w 958 | ) 959 | ) 960 | print MatID_array.count 961 | msh = mesh vertices:Vert_array faces:Face_array 962 | msh.numTVerts = Vert_array.count 963 | buildTVFaces msh 964 | msh.name = g as string 965 | msh.material = multimat 966 | for j = 1 to UV_array.count do setTVert msh j UV_array[j] 967 | for j = 1 to Face_array.count do( 968 | setTVFace msh j Face_array[j] 969 | setFaceMatID msh j MatID_array[j] 970 | ) 971 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 972 | max modify mode 973 | select msh 974 | 975 | addmodifier msh (Edit_Normals ()) ui:off 976 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 977 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 978 | EN_setNormal = msh.Edit_Normals.SetNormal 979 | normID = #{} 980 | 981 | for v = 1 to Normal_array.count do( 982 | free normID 983 | EN_convertVS #{v} &normID 984 | for id in normID do EN_setNormal id Normal_array[v] 985 | ) 986 | 987 | if BoneCount > 0 do ( 988 | skinMod = skin () 989 | boneIDMap = #() 990 | addModifier msh skinMod 991 | msh.Skin.weightAllVertices = false 992 | 993 | for i = 1 to BoneCount do 994 | ( 995 | maxbone = getnodebyname BoneArray[i].name 996 | if i != BoneCount then 997 | skinOps.addBone skinMod maxbone 0 998 | else 999 | skinOps.addBone skinMod maxbone 1 1000 | ) 1001 | 1002 | local numSkinBones = skinOps.GetNumberBones skinMod 1003 | for i = 1 to numSkinBones do 1004 | ( 1005 | local boneName = skinOps.GetBoneName skinMod i 0 1006 | for j = 1 to BoneCount do 1007 | ( 1008 | if boneName == BoneArray[j].Name then 1009 | ( 1010 | boneIDMap[j] = i 1011 | j = BoneCount + 1 1012 | ) 1013 | ) 1014 | ) -- This fixes bone ordering in 3DS Max 2012. Thanks to sunnydavis for the fix! 1015 | 1016 | modPanel.setCurrentObject skinMod 1017 | 1018 | for i = 1 to Vert_array.count do( 1019 | skinOps.SetVertexWeights skinMod i 1 1 1020 | skinOps.unnormalizeVertex skinMod i true 1021 | skinOps.SetVertexWeights skinMod i 1 0 1022 | ) 1023 | skinOps.RemoveZeroWeights skinMod 1024 | for i = 1 to Vert_array.count do( 1025 | skinOps.unnormalizeVertex skinMod i false 1026 | ) -- These fix broken rigging for 3DS Max 2015 and above. 1027 | 1028 | for i = 1 to Weight_array.count do ( 1029 | w = Weight_array[i] 1030 | bi = #() --bone index array 1031 | wv = #() --weight value array 1032 | 1033 | for j = 1 to w.boneids.count do 1034 | ( 1035 | boneid = w.boneids[j] 1036 | weight = w.weights[j] 1037 | append bi boneIDMap[boneid] 1038 | append wv weight 1039 | ) 1040 | skinOps.ReplaceVertexWeights skinMod i bi wv 1041 | ) 1042 | ) 1043 | 1044 | ) 1045 | 2:( 1046 | Blank = readlong f 1047 | Blank = readlong f 1048 | Blank = readlong f 1049 | Unknown = readlong f 1050 | 1051 | SubSectCount = readlong f 1052 | VerCheck = readlong f 1053 | if VerCheck == 0x00000002 do(PCVer = "Yes") 1054 | Unknown = readlong f 1055 | Unknown = readlong f 1056 | 1057 | SubSectOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1058 | fseek f SubSectOffset #seek_set 1059 | ModelInfoOffset = #() 1060 | 1061 | case SubSectCount of( 1062 | default:(print "Currently unsupported, sorry."; exit()) 1063 | 2:( 1064 | InfoOffset = readlong f + ModelStart; Pad64Bit = readlong f 1065 | ModelInfoOffset = readlong f + ModelStart; Pad64Bit = readlong f 1066 | fseek f ModelInfoOffset #seek_set 1067 | ) 1068 | ) 1069 | 1070 | fseek f (ModelStart + 0xE0) #seek_set 1071 | ModelCount = readlong f 1072 | Blank = readlong f 1073 | ModelOffsetBuffSize = readlong f 1074 | Unknown = readlong f 1075 | ModelOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1076 | ModelCount2 = readlong f 1077 | Blank = readlong f 1078 | Unknown = readlong f 1079 | Unknown = readlong f 1080 | ModelOffset2 = readlong f; Pad64Bit = readlong f 1081 | 1082 | fseek f (ModelInfoOffset + 0x50) #seek_set 1083 | ModelJump = readlong f 1084 | Unknown = readlong f 1085 | ModelJumpOffset = readlong f + ModelStart 1086 | fseek f (ModelJumpOffset + ModelJump + 0x18) #seek_set 1087 | VertPlus = readlong f 1088 | Unknown = readlong f 1089 | VertStart = readlong f + ModelStart + VertPlus 1090 | 1091 | fseek f (ModelStart + 0x140) #seek_set 1092 | 1093 | Vert_array = #() 1094 | Normal_array = #() 1095 | Color_array = #() 1096 | Alpha_array = #() 1097 | UV_array = #() 1098 | UV2_array = #() 1099 | UV3_array = #() 1100 | UV4_array = #() 1101 | Face_array = #() 1102 | B1_array = #() 1103 | B2_array = #() 1104 | W1_array = #() 1105 | W2_array = #() 1106 | Weight_array = #() 1107 | MatID_array = #() 1108 | VertAdd = 0 1109 | 1110 | for x = 1 to ModelCount do( 1111 | ModelGrpOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1112 | ModelRet = (ftell f) 1113 | fseek f ModelGrpOffset #seek_set 1114 | 1115 | VertBuffer_array = #() 1116 | printDebug ("Model Offset 1: " + ftell f as string) 1117 | 1118 | Unknown = readlong f 1119 | Blank = readlong f 1120 | Unknown = readlong f 1121 | Blank = readlong f 1122 | Unknown = readlong f 1123 | Blank = readlong f 1124 | Blank = readlong f 1125 | Blank = readlong f 1126 | BoundMinX = readlong f 1127 | BoundMinY = readlong f 1128 | BoundMinZ = readlong f 1129 | Blank = readlong f 1130 | BoundMaxX = readlong f 1131 | BoundMaxY = readlong f 1132 | BoundMaxZ = readlong f 1133 | Blank = readlong f 1134 | MatID = readshort f #unsigned + 1 1135 | Unknown = readshort f #unsigned 1136 | Blank = readlong f 1137 | VertInfoOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1138 | PolyInfoOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1139 | Blank = readlong f 1140 | Blank = readlong f 1141 | Blank = readlong f 1142 | Blank = readlong f 1143 | Blank = readlong f 1144 | Unknown = readlong f 1145 | Blank = readlong f 1146 | Blank = readlong f 1147 | Unknown = readlong f 1148 | Blank = readlong f 1149 | Blank = readlong f 1150 | Blank = readlong f 1151 | Blank = readlong f 1152 | Blank = readlong f 1153 | Blank = readlong f 1154 | Blank = readlong f 1155 | Blank = readlong f 1156 | Blank = readlong f 1157 | 1158 | fseek f VertInfoOffset #seek_set 1159 | printDebug ("VertInfoOffset: " + ftell f as string) 1160 | Unknown = readlong f 1161 | Blank = readlong f 1162 | Unknown = readlong f 1163 | Blank = readlong f 1164 | Blank = readlong f 1165 | Blank = readlong f 1166 | Unknown = readlong f 1167 | Blank = readlong f 1168 | InfoOffset1 = (readlong f + ModelStart); Pad64Bit = readlong f 1169 | InfoOffset2 = (readlong f + ModelStart); Pad64Bit = readlong f 1170 | InfoOffset3 = (readlong f + ModelStart); Pad64Bit = readlong f 1171 | 1172 | fseek f InfoOffset1 #seek_set 1173 | Unknown = readlong f 1174 | Blank = readlong f 1175 | Unknown = readlong f 1176 | if PCVer == "Yes" do(Blank = readlong f) 1177 | VertexCount = readlong f 1178 | if PCVer == "Yes" do(Blank = readlong f) 1179 | Unknown = readlong f 1180 | Unknown = readlong f 1181 | InfoOffset1B = (readlong f + ModelStart); Pad64Bit = readlong f 1182 | VertexBufferSize = readlong f 1183 | Unknown = readlong f 1184 | VertexBufferStart = (readlong f) - 0x08000000 + VertStart 1185 | Blank = readlong f 1186 | InfoOffset1C = (readlong f + ModelStart); Pad64Bit = readlong f 1187 | Unknown = readlong f 1188 | Blank = readlong f 1189 | InfoOffset1D = (readlong f + ModelStart); Pad64Bit = readlong f 1190 | Blank = readlong f 1191 | Blank = readlong f 1192 | Blank = readlong f 1193 | Blank = readlong f 1194 | InfoOffset1E = (readlong f + ModelStart); Pad64Bit = readlong f 1195 | 1196 | fseek f InfoOffset1B #seek_set 1197 | VertexCount2 = readlong f 1198 | Blank = readlong f 1199 | 1200 | fseek f InfoOffset1C #seek_set 1201 | Unknown = readlong f 1202 | Blank = readlong f 1203 | Unknown = readlong f 1204 | if PCVer == "Yes" do(Blank = readlong f) 1205 | VertexBufferStride = readlong f 1206 | if PCVer == "Yes" do(Blank = readlong f) 1207 | VertBuffParamASize = readlong f 1208 | Unknown = readlong f 1209 | VertBuffParamAOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1210 | VertBuffParamBSize = readlong f 1211 | Unknown = readlong f 1212 | VertBuffParamBOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1213 | Unknown = readlong f 1214 | Unknown = readlong f 1215 | InfoOffset1F = (readlong f + ModelStart); Pad64Bit = readlong f 1216 | InfoOffset1G = (readlong f + ModelStart); Pad64Bit = readlong f 1217 | Unknown = readlong f 1218 | Blank = readlong f 1219 | Unknown = readlong f 1220 | Unknown = readlong f 1221 | Blank = readlong f 1222 | Blank = readlong f 1223 | Blank = readlong f 1224 | Blank = readlong f 1225 | Unknown = readlong f 1226 | Blank = readlong f 1227 | InfoOffset1H = (readlong f + ModelStart); Pad64Bit = readlong f 1228 | Unknown = readlong f 1229 | Unknown = readlong f 1230 | 1231 | fseek f VertBuffParamAOffset #seek_set 1232 | for v = 1 to (VertBuffParamASize / 0x0C) do( 1233 | VertFormat1 = readbyte f #unsigned 1234 | VertFormat2 = readbyte f #unsigned 1235 | VertFormat3 = readbyte f #unsigned 1236 | VertFormat4 = readbyte f #unsigned 1237 | VertType = readbyte f #unsigned + 1 1238 | VertLayer = readbyte f #unsigned + 1 1239 | VertUnk1 = readbyte f #unsigned 1240 | VertUnk2 = readbyte f #unsigned 1241 | VertShift = readlong f #unsigned 1242 | printDebug (VertFormat1 as string + " / " + VertFormat2 as string + " / " + VertFormat3 as string + " / " + VertFormat4 as string + ", type: " + VertType as string + ", layer: " + VertLayer as string + ", unk: " + VertUnk1 as string + " / " + VertUnk2 as string + ", shift: " + VertShift as string) 1243 | append VertBuffer_array (VertBuffer_Struct VertFormat1:VertFormat1 VertFormat2:VertFormat2 VertFormat3:VertFormat3 VertFormat4:VertFormat4 VertType:VertType VertLayer:VertLayer VertUnk1:VertUnk1 VertUnk2:VertUnk2 VertShift:VertShift) 1244 | ) 1245 | 1246 | fseek f VertBuffParamBOffset #seek_set 1247 | for v = 1 to (VertBuffParamBSize / 0x04) do( 1248 | VertUnknown = readlong f 1249 | ) 1250 | 1251 | fseek f PolyInfoOffset #seek_set 1252 | printDebug ("PolyInfoOffset: " + ftell f as string) 1253 | Unknown = readlong f 1254 | Blank = readlong f 1255 | Unknown = readlong f 1256 | Blank = readlong f 1257 | Blank = readlong f 1258 | Blank = readlong f 1259 | Unknown = readlong f 1260 | Blank = readlong f 1261 | InfoOffset1 = (readlong f + ModelStart); Pad64Bit = readlong f 1262 | InfoOffset2 = (readlong f + ModelStart); Pad64Bit = readlong f 1263 | InfoOffset3 = (readlong f + ModelStart); Pad64Bit = readlong f 1264 | 1265 | fseek f InfoOffset1 #seek_set 1266 | Unknown = readlong f 1267 | Blank = readlong f 1268 | Unknown = readlong f 1269 | if PCVer == "Yes" do(Blank = readlong f) 1270 | FacepointCount = readlong f 1271 | if PCVer == "Yes" do(Blank = readlong f) 1272 | Unknown = readlong f 1273 | Unknown = readlong f 1274 | InfoOffset1B = (readlong f + ModelStart); Pad64Bit = readlong f 1275 | PolyBufferSize = readlong f 1276 | Unknown = readlong f 1277 | PolyBufferStart = (readlong f) - 0x08000000 + VertStart 1278 | Blank = readlong f 1279 | InfoOffset1C = readlong f; Pad64Bit = readlong f 1280 | Unknown = readlong f 1281 | Blank = readlong f 1282 | InfoOffset1D = (readlong f + ModelStart); Pad64Bit = readlong f 1283 | Blank = readlong f 1284 | Blank = readlong f 1285 | Blank = readlong f 1286 | Blank = readlong f 1287 | InfoOffset1E = (readlong f + ModelStart); Pad64Bit = readlong f 1288 | 1289 | fseek f InfoOffset1B #seek_set 1290 | FacepointCount2 = readlong f 1291 | Blank = readlong f 1292 | 1293 | fseek f InfoOffset1D #seek_set 1294 | Unknown = readlong f 1295 | Blank = readlong f 1296 | Unknown = readlong f 1297 | if PCVer == "Yes" do(Blank = readlong f) 1298 | VertexBufferStride = readlong f 1299 | if PCVer == "Yes" do(Blank = readlong f) 1300 | PolyBuffParamASize = readlong f 1301 | Unknown = readlong f 1302 | PolyBuffParamAOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1303 | PolyBuffParamBSize = readlong f 1304 | Unknown = readlong f 1305 | PolyBuffParamBOffset = (readlong f + ModelStart); Pad64Bit = readlong f 1306 | Unknown = readlong f 1307 | Unknown = readlong f 1308 | InfoOffset1F = (readlong f + ModelStart); Pad64Bit = readlong f 1309 | InfoOffset1G = (readlong f + ModelStart); Pad64Bit = readlong f 1310 | Unknown = readlong f 1311 | Blank = readlong f 1312 | Unknown = readlong f 1313 | Unknown = readlong f 1314 | Blank = readlong f 1315 | Blank = readlong f 1316 | Blank = readlong f 1317 | Blank = readlong f 1318 | Unknown = readlong f 1319 | Blank = readlong f 1320 | InfoOffset1H = (readlong f + ModelStart); Pad64Bit = readlong f 1321 | Unknown = readlong f 1322 | Unknown = readlong f 1323 | 1324 | fseek f VertexBufferStart #seek_set 1325 | printDebug ("Vertex Buffer: " + ftell f as string + ", size: 0x" + (bit.intAsHex(VertexBufferStride) as string)) 1326 | 1327 | for v = 1 to VertexCount do( 1328 | for w = 1 to VertBuffer_array.count do( 1329 | VertType = VertBuffer_array[w].VertType 1330 | VertFmt = VertBuffer_array[w].VertFormat1 1331 | VertLayer = VertBuffer_array[w].VertLayer 1332 | case VertType of( 1333 | default:(throw("Unknown vertex type!")) 1334 | 1:( 1335 | case VertFmt of( 1336 | default:(throw("Unknown position format!")) 1337 | 2:( 1338 | vx = readfloat f 1339 | vy = readfloat f 1340 | vz = readfloat f 1341 | append Vert_array [vx,vy,vz] 1342 | ) 1343 | 44:() 1344 | ) 1345 | ) 1346 | 2:( 1347 | case VertFmt of( 1348 | default:(throw("Unknown normals/binormals format!")) 1349 | 2:( 1350 | nx = readfloat f 1351 | ny = readfloat f 1352 | nz = readfloat f 1353 | if VertLayer == 1 do(append Normal_array [nx,ny,nz]) 1354 | ) 1355 | ) 1356 | ) 1357 | 3:( 1358 | case VertFmt of( 1359 | default:(throw("Unknown tangents(?) format!")) 1360 | 2:( 1361 | tanx = readfloat f 1362 | tany = readfloat f 1363 | tanz = readfloat f 1364 | ) 1365 | ) 1366 | ) 1367 | 5:( 1368 | case VertFmt of( 1369 | default:(throw("Unknown colors format!")) 1370 | 4:( 1371 | colorr = readbyte f #unsigned 1372 | colorg = readbyte f #unsigned 1373 | colorb = readbyte f #unsigned 1374 | colora = (readbyte f #unsigned as float) / 255 1375 | if VertLayer == 1 do( 1376 | append Color_Array[colorr,colorg,colorb] 1377 | append Alpha_Array colora 1378 | ) 1379 | ) 1380 | ) 1381 | ) 1382 | 6:( 1383 | case VertFmt of( 1384 | default:(throw("Unknown UVs format!")) 1385 | 2:( 1386 | tu = readfloat f 1387 | tv = (readfloat f * -1) + 1 1388 | tw = readfloat f 1389 | if VertLayer == 1 do(append UV_array [tu,tv,0]) 1390 | if VertLayer == 2 do(append UV2_array [tu,tv,0]) 1391 | if VertLayer == 3 do(append UV3_array [tu,tv,0]) 1392 | if VertLayer == 4 do(append UV4_array [tu,tv,0]) 1393 | ) 1394 | 42:( 1395 | tu = readhalffloat f 1396 | tv = (readhalffloat f * -1) + 1 1397 | if VertLayer == 1 do(append UV_array [tu,tv,0]) 1398 | if VertLayer == 2 do(append UV2_array [tu,tv,0]) 1399 | if VertLayer == 3 do(append UV3_array [tu,tv,0]) 1400 | if VertLayer == 4 do(append UV4_array [tu,tv,0]) 1401 | ) 1402 | ) 1403 | ) 1404 | 7:( 1405 | case VertFmt of( 1406 | default:(throw("Unknown weights format!")) 1407 | 26:( 1408 | Weight1 = (readbyte f #unsigned as float) / 255 1409 | Weight2 = (readbyte f #unsigned as float) / 255 1410 | Weight3 = (readbyte f #unsigned as float) / 255 1411 | Weight4 = (readbyte f #unsigned as float) / 255 1412 | if VertLayer == 1 do(append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4)) 1413 | if VertLayer == 2 do(append W2_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4)) 1414 | ) 1415 | ) 1416 | ) 1417 | 9:( 1418 | case VertFmt of( 1419 | default:(throw("Unknown bones format!")) 1420 | 13:( 1421 | Bone1 = NodeID_array[(readlong f) + NodeIDStart] 1422 | Bone2 = NodeID_array[(readlong f) + NodeIDStart] 1423 | Bone3 = NodeID_array[(readlong f) + NodeIDStart] 1424 | Bone4 = NodeID_array[(readlong f) + NodeIDStart] 1425 | if Bone1 == undefined do(Bone1 = 1) 1426 | if Bone2 == undefined do(Bone2 = 1) 1427 | if Bone3 == undefined do(Bone3 = 1) 1428 | if Bone4 == undefined do(Bone4 = 1) 1429 | if VertLayer == 1 do(append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 1430 | if VertLayer == 2 do(append B2_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 1431 | ) 1432 | 23:( 1433 | Bone1 = NodeID_array[(readbyte f) + NodeIDStart] 1434 | Bone2 = NodeID_array[(readbyte f) + NodeIDStart] 1435 | Bone3 = NodeID_array[(readbyte f) + NodeIDStart] 1436 | Bone4 = NodeID_array[(readbyte f) + NodeIDStart] 1437 | if Bone1 == undefined do(Bone1 = 1) 1438 | if Bone2 == undefined do(Bone2 = 1) 1439 | if Bone3 == undefined do(Bone3 = 1) 1440 | if Bone4 == undefined do(Bone4 = 1) 1441 | if VertLayer == 1 do(append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 1442 | if VertLayer == 2 do(append B2_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)) 1443 | ) 1444 | ) 1445 | ) 1446 | ) 1447 | ) 1448 | ) 1449 | printDebug ("Vertex end: " + ftell f as string) 1450 | fseek f PolyBufferStart #seek_set 1451 | printDebug ("Poly Buffer: " + ftell f as string) 1452 | 1453 | if VertexCount > 65535 then( 1454 | for v = 1 to (FacepointCount / 3) do( 1455 | fa = readlong f #unsigned + 1 + VertAdd 1456 | fb = readlong f #unsigned + 1 + VertAdd 1457 | fc = readlong f #unsigned + 1 + VertAdd 1458 | append Face_array [fa,fb,fc] 1459 | append MatID_array MatID 1460 | ) 1461 | ) else ( 1462 | for v = 1 to (FacepointCount / 3) do( 1463 | fa = readshort f #unsigned + 1 + VertAdd 1464 | fb = readshort f #unsigned + 1 + VertAdd 1465 | fc = readshort f #unsigned + 1 + VertAdd 1466 | append Face_array [fa,fb,fc] 1467 | append MatID_array MatID 1468 | ) 1469 | ) 1470 | printDebug ("Poly end: " + ftell f as string) 1471 | 1472 | fseek f ModelRet #seek_set 1473 | VertAdd = VertAdd + VertexCount 1474 | 1475 | ) 1476 | 1477 | If Color_Array.count == 0 do( 1478 | For v = 1 to Vert_array.count do( 1479 | append Color_Array[255,255,255] 1480 | append Alpha_Array 1 1481 | ) 1482 | ) 1483 | 1484 | msh = mesh vertices:Vert_array faces:Face_array 1485 | msh.numTVerts = Vert_array.count 1486 | buildTVFaces msh 1487 | msh.name = g as string 1488 | msh.material = multimat 1489 | for j = 1 to UV_array.count do setTVert msh j UV_array[j] 1490 | for j = 1 to Face_array.count do( 1491 | setTVFace msh j Face_array[j] 1492 | setFaceMatID msh j MatID_array[j] 1493 | ) 1494 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 1495 | max modify mode 1496 | select msh 1497 | 1498 | addmodifier msh (Edit_Normals ()) ui:off 1499 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 1500 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 1501 | EN_setNormal = msh.Edit_Normals.SetNormal 1502 | normID = #{} 1503 | 1504 | for v = 1 to Normal_array.count do( 1505 | free normID 1506 | EN_convertVS #{v} &normID 1507 | for id in normID do EN_setNormal id Normal_array[v] 1508 | ) 1509 | 1510 | ) 1511 | ) 1512 | ) 1513 | ) 1514 | fseek f NextOffset #seek_set 1515 | ) 1516 | Print ("Done! ("+((((timestamp())-st)*0.001)as string)+" Seconds)") 1517 | ) 1518 | ) 1519 | ) 1520 | 1521 | ) 1522 | 1523 | CreateDialog ModelImporter -------------------------------------------------------------------------------- /Scripts/GoGoHypergrind_AMD.ms: -------------------------------------------------------------------------------- 1 | -- Go Go Hypergrind! model importer by Random Talking Bush. 2 | 3 | fn floatSwap2 f = 4 | ( 5 | i = bit.floatAsInt f 6 | h = bit.intashex i 7 | while h.count < 8 do h = "0" + h 8 | 9 | s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2) 10 | bit.intAsFloat (bit.hexasint s) 11 | ) 12 | 13 | fn ReadBEword fstream = ( 14 | return (bit.swapBytes (readshort fstream #unsigned) 1 2) 15 | ) 16 | 17 | fn ReadBElong fstream = ( 18 | long = readlong fstream 19 | long = bit.swapBytes long 1 4 20 | long = bit.swapBytes long 2 3 21 | return long 22 | ) 23 | 24 | fn ReadBEHalfFloat fstream = ( 25 | return convertTo32(ReadBEword fstream) 26 | ) 27 | 28 | fn ReadBEfloat fstream = ( 29 | return floatSwap2(readfloat fstream) 30 | ) 31 | 32 | fname = getOpenFileName \ 33 | caption:"Go Go Hypergrind AMD file" \ 34 | types:"Go Go Hypergrind AMD(*.amd)|*.amd" \ 35 | historyCategory:"GoGoHypergrind" 36 | f = fopen fname "rb" 37 | 38 | if fname != undefined do( 39 | 40 | struct Bone_Info_Struct 41 | ( 42 | Bone1, Bone2, Bone3, Bone4 43 | ) 44 | struct Weight_Info_Struct 45 | ( 46 | Weight1, Weight2, Weight3, Weight4 47 | ) 48 | struct weight_data 49 | ( 50 | boneids, weights 51 | ) 52 | 53 | p = getFilenamePath fname 54 | h = getFilenameFile fname 55 | fname2 = p + h + ".skn" 56 | q = fopen fname2 "rb" 57 | fname3 = p + h + ".shp" 58 | shp = fopen fname3 "rb" 59 | 60 | clearlistener() 61 | B1Temp_array = #() 62 | W1Temp_array = #() 63 | BoneArray = #() 64 | BoneCount = 0 65 | 66 | if q != undefined do ( 67 | Trans_array = #() 68 | Rotation_array = #() 69 | Scale_array = #() 70 | Bone_Matrix_Array = #() 71 | BoneName_array = #() 72 | BoneParent_array = #() 73 | BoneFixArray = #() 74 | fseek q 0x08 #seek_set 75 | BoneCount = readBElong q 76 | BoneStart = readBElong q 77 | SingleBindCount = readBElong q 78 | SingleBindStart = readBElong q 79 | DoubleBindCount = readBElong q 80 | DoubleBindStart = readBElong q 81 | TripleBindCount = readBElong q 82 | TripleBindStart = readBElong q 83 | QuadBindCount = readBElong q 84 | QuadBindStart = readBElong q 85 | fseek q BoneStart #seek_set 86 | for x = 1 to BoneCount do( 87 | bonename = ("Bone" + x as string) 88 | boneparent = (readBElong q) + 1 89 | if boneparent == 0 do(boneparent = -1) 90 | rx = readBEfloat q 91 | ry = readBEfloat q 92 | rz = readBEfloat q 93 | rq = readBEfloat q 94 | 95 | tx = readBEfloat q 96 | ty = readBEfloat q 97 | tz = readBEfloat q 98 | 99 | sx = readBEfloat q 100 | sy = readBEfloat q 101 | sz = readBEfloat q 102 | 103 | append Trans_array [tx,ty,tz] 104 | append Rotation_array [rx,ry,rz] 105 | append Scale_array [sx,sy,sz] 106 | append BoneName_array bonename 107 | append BoneParent_array BoneParent 108 | ) 109 | 110 | for x = 1 to BoneCount do( 111 | BoneName = BoneName_array[x] 112 | BoneParent = BoneParent_array[x] 113 | 114 | tfm = scaleMatrix [Scale_array[x].x,Scale_array[x].y,Scale_array[x].z] 115 | tfm = tfm * (rotateXMatrix (radToDeg Rotation_array[x].x)) * (rotateYMatrix (radToDeg Rotation_array[x].y)) * (rotateZMatrix (radToDeg Rotation_array[x].z)) 116 | tfm.row4 = [Trans_array[x].x, Trans_array[x].y, Trans_array[x].z] 117 | 118 | if (BoneParent_array[x] != -1) and (BoneParent_array[x] < x) then ( 119 | tfm = tfm * BoneArray[(BoneParent_array[x])].objecttransform 120 | ) else if (x > 1) and (BoneParent_array[x] > -1) do(append BoneFixArray x) 121 | 122 | newBone = bonesys.createbone \ 123 | tfm.row4 \ 124 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 125 | (normalize tfm.row3) 126 | newBone.name = BoneName 127 | newBone.width = 0.03 128 | newBone.height = 0.03 129 | newBone.transform = tfm 130 | newBone.setBoneEnable false 0 131 | newBone.wirecolor = yellow 132 | newbone.showlinks = true 133 | newBone.pos.controller = TCB_position () 134 | newBone.rotation.controller = TCB_rotation () 135 | if (BoneParent != -1) then 136 | newBone.parent = BoneArray[BoneParent] 137 | append BoneArray newBone 138 | 139 | ) 140 | 141 | for x = 1 to BoneFixArray.count do( 142 | select BoneArray[BoneFixArray[x]] 143 | tfm = scaleMatrix [Scale_array[BoneFixArray[x]].x,Scale_array[BoneFixArray[x]].y,Scale_array[BoneFixArray[x]].z] 144 | tfm = tfm * (rotateXMatrix (radToDeg Rotation_array[BoneFixArray[x]].x)) * (rotateYMatrix (radToDeg Rotation_array[BoneFixArray[x]].y)) * (rotateZMatrix (radToDeg Rotation_array[BoneFixArray[x]].z)) 145 | tfm.row4 = [Trans_array[BoneFixArray[x]].x, Trans_array[BoneFixArray[x]].y, Trans_array[BoneFixArray[x]].z] 146 | tfm = tfm * BoneArray[BoneParent_array[BoneFixArray[x]]].objecttransform 147 | $.transform = tfm 148 | $.parent = BoneArray[BoneParent_array[BoneFixArray[x]]] 149 | ) 150 | 151 | fseek q SingleBindStart #seek_set 152 | for x = 1 to SingleBindCount do( 153 | VertNum = readBElong q + 1 154 | VertNum2 = readBElong q + 1 155 | BoneIDStart = readBElong q 156 | WeightStart = readBElong q 157 | goback = (ftell q) 158 | 159 | fseek q BoneIDStart #seek_set 160 | Bone1 = readBEword q + 1 161 | Bone2 = 1 162 | Bone3 = 1 163 | Bone4 = 1 164 | B1Temp_array[VertNum] = (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 165 | 166 | fseek q WeightStart #seek_set 167 | Weight1 = readBEfloat q 168 | Weight2 = 0 169 | Weight3 = 0 170 | Weight4 = 0 171 | W1Temp_array[VertNum] = (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 172 | 173 | fseek q goback #seek_set 174 | ) 175 | 176 | fseek q DoubleBindStart #seek_set 177 | for x = 1 to DoubleBindCount do( 178 | VertNum = readBElong q + 1 179 | VertNum2 = readBElong q + 1 180 | BoneIDStart = readBElong q 181 | WeightStart = readBElong q 182 | goback = (ftell q) 183 | 184 | fseek q BoneIDStart #seek_set 185 | Bone1 = readBEword q + 1 186 | Bone2 = readBEword q + 1 187 | Bone3 = 1 188 | Bone4 = 1 189 | B1Temp_array[VertNum] = (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 190 | 191 | fseek q WeightStart #seek_set 192 | Weight1 = readBEfloat q 193 | Weight2 = readBEfloat q 194 | Weight3 = 0 195 | Weight4 = 0 196 | W1Temp_array[VertNum] = (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 197 | 198 | fseek q goback #seek_set 199 | ) 200 | 201 | fseek q TripleBindStart #seek_set 202 | for x = 1 to TripleBindCount do( 203 | VertNum = readBElong q + 1 204 | VertNum2 = readBElong q + 1 205 | BoneIDStart = readBElong q 206 | WeightStart = readBElong q 207 | goback = (ftell q) 208 | 209 | fseek q BoneIDStart #seek_set 210 | Bone1 = readBEword q + 1 211 | Bone2 = readBEword q + 1 212 | Bone3 = readBEword q + 1 213 | Bone4 = 1 214 | B1Temp_array[VertNum] = (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 215 | 216 | fseek q WeightStart #seek_set 217 | Weight1 = readBEfloat q 218 | Weight2 = readBEfloat q 219 | Weight3 = readBEfloat q 220 | Weight4 = 0 221 | W1Temp_array[VertNum] = (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 222 | 223 | fseek q goback #seek_set 224 | ) 225 | 226 | fseek q QuadBindStart #seek_set 227 | for x = 1 to QuadBindCount do( 228 | VertNum = readBElong q + 1 229 | VertNum2 = readBElong q + 1 230 | BoneIDStart = readBElong q 231 | WeightStart = readBElong q 232 | goback = (ftell q) 233 | 234 | fseek q BoneIDStart #seek_set 235 | Bone1 = readBEword q + 1 236 | Bone2 = readBEword q + 1 237 | Bone3 = readBEword q + 1 238 | Bone4 = readBEword q + 1 239 | B1Temp_array[VertNum] = (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 240 | 241 | fseek q WeightStart #seek_set 242 | Weight1 = readBEfloat q 243 | Weight2 = readBEfloat q 244 | Weight3 = readBEfloat q 245 | Weight4 = readBEfloat q 246 | W1Temp_array[VertNum] = (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 247 | 248 | fseek q goback #seek_set 249 | ) 250 | 251 | ) 252 | 253 | if f != undefined do ( 254 | fseek f 0x08 #seek_set 255 | ModelCount = readBElong f 256 | fseek f 0x20 #seek_set 257 | -- print ("Model Count = " + (ModelCount as string)) 258 | 259 | for m = 1 to ModelCount do( 260 | VertTemp_array = #() 261 | NormalTemp_array = #() 262 | ColorTemp_array = #() 263 | AlphaTemp_array = #() 264 | UVTemp_array = #() 265 | PolyGroupCount = readBElong f 266 | VertCount = readBEword f 267 | NormalsCount = readBEword f 268 | ColorCount = readBEword f 269 | UVCount = readBEword f 270 | PolyGroupStart = readBElong f 271 | VertStart = readBElong f 272 | NormalsStart = readBElong f 273 | ColorStart = readBElong f 274 | UVStart = readBElong f 275 | fseek f 0x10 #seek_cur 276 | modelreturn = (ftell f) 277 | 278 | fseek f VertStart #seek_set 279 | -- print ("Vertex Start: 0x"+((bit.intAsHex(ftell f))as string) + ", Count = " + VertCount as string) 280 | 281 | for x = 1 to VertCount do( 282 | vx = readBEfloat f 283 | vy = readBEfloat f 284 | vz = readBEfloat f 285 | append VertTemp_array [vx,vy,vz] 286 | ) 287 | 288 | -- print ("Vertex End: 0x"+((bit.intAsHex(ftell f))as string)) 289 | 290 | if NormalsCount > 0 do( 291 | fseek f NormalsStart #seek_set 292 | -- print ("Normals Start: 0x"+((bit.intAsHex(ftell f))as string) + ", Count = " + NormalsCount as string) 293 | for x = 1 to NormalsCount do( 294 | nx = readBEfloat f 295 | ny = readBEfloat f 296 | nz = readBEfloat f 297 | append NormalTemp_array [nx,ny,nz] 298 | ) 299 | 300 | -- print ("Normals End: 0x"+((bit.intAsHex(ftell f))as string)) 301 | ) 302 | 303 | fseek f ColorStart #seek_set 304 | -- print ("Color Start: 0x"+((bit.intAsHex(ftell f))as string) + ", Count = " + ColorCount as string) 305 | for x = 1 to ColorCount do( 306 | colorr = readbyte f #unsigned 307 | colorg = readbyte f #unsigned 308 | colorb = readbyte f #unsigned 309 | colora = readbyte f #unsigned 310 | append ColorTemp_array [colorr,colorg,colorb] 311 | append AlphaTemp_array colora 312 | ) 313 | 314 | -- print ("Color End: 0x"+((bit.intAsHex(ftell f))as string)) 315 | 316 | fseek f UVStart #seek_set 317 | -- print ("UV Start: 0x"+((bit.intAsHex(ftell f))as string) + ", Count = " + UVCount as string) 318 | for x = 1 to UVCount do( 319 | tu = readBEfloat f 320 | tv = readBEfloat f * -1 321 | append UVTemp_array [tu,tv,0] 322 | ) 323 | 324 | -- print ("UV End: 0x"+((bit.intAsHex(ftell f))as string)) 325 | 326 | fseek f PolyGroupStart #seek_set 327 | -- print ("Poly Group Start: 0x"+((bit.intAsHex(ftell f))as string) + ", Count = " + PolyGroupCount as string) 328 | for x = 1 to PolyGroupCount do( 329 | Vert_array = #() 330 | Normal_array = #() 331 | Color_array = #() 332 | UV_array = #() 333 | UV2_array = #() 334 | Face_array = #() 335 | B1_array = #() 336 | W1_array = #() 337 | Weight_array = #() 338 | UVLayers = readBElong f 339 | TexNum = readBEword f 340 | TexNumL2 = readBEword f 341 | fseek f 0x0C #seek_cur 342 | PosX = readBEfloat f 343 | PosY = readBEfloat f 344 | PosZ = readBEfloat f 345 | PolyCount = readBElong f 346 | PolyStart = readBElong f 347 | fseek f 0x08 #seek_cur 348 | goback = (ftell f) 349 | 350 | fseek f PolyStart #seek_set 351 | -- print ("Poly Start " + x as string + " Start: 0x"+((bit.intAsHex(ftell f))as string)) 352 | PolyType = readBEword f 353 | if PolyType > 0 and PolyType != 0x98 do(throw "Error building model!") 354 | 355 | VertAdd = 1 356 | do( 357 | PolyAmt = readBEword f 358 | for z = 1 to PolyAmt do( 359 | VertNum = readBEword f + 1 360 | if NormalsCount > 0 do(NormNum = readBEword f + 1) 361 | ColorNum = readBEword f + 1 362 | UVNum = readBEword f + 1 363 | if UVLayers == 2 do(UV2Num = readBEword f + 1) 364 | VertDat = VertTemp_array[VertNum] 365 | if NormalsCount > 0 do(NormDat = NormalTemp_array[NormNum]) 366 | ColorDat = ColorTemp_array[ColorNum] 367 | UVDat = UVTemp_array[UVNum] 368 | if UVLayers == 2 do(UV2Dat = UVTemp_array[UV2Num]) 369 | VertDat = VertTemp_array[VertNum] 370 | BoneDat = B1Temp_array[VertNum] 371 | WeightDat = W1Temp_array[VertNum] 372 | append Vert_array VertDat 373 | if NormalsCount > 0 do(append Normal_array NormDat) 374 | append Color_array ColorDat 375 | append UV_array UVDat 376 | if UVLayers == 2 do(append UV2_array UV2Dat) 377 | append B1_array BoneDat 378 | append W1_array WeightDat 379 | ) 380 | PolyType = readBEword f 381 | if PolyType > 0 and PolyType != 0x98 do(throw "SCANNER SOMETHING ERROR HAPPEN") 382 | 383 | StartDirection = -1 384 | f1 = VertAdd 385 | f2 = VertAdd + 1 386 | f3 = VertAdd + 1 387 | IndexCounter = 2 388 | FaceDirection = StartDirection 389 | Do ( 390 | f3 += 1 391 | IndexCounter = IndexCounter +1 392 | if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then ( 393 | if FaceDirection > 0 then append Face_Array [f1,f2,f3] 394 | else append Face_Array [f1,f3,f2] 395 | ) 396 | FaceDirection *= -1 397 | f1 = f2 398 | f2 = f3 399 | ) while IndexCounter != PolyAmt 400 | VertAdd = VertAdd + PolyAmt 401 | 402 | ) while PolyType != 0 403 | 404 | fseek f goback #seek_set 405 | 406 | if BoneCount > 0 do( 407 | for b = 1 to W1_array.count Do ( 408 | w = (weight_data boneids:#() weights:#()) 409 | maxweight = 0 410 | 411 | if(W1_array[b].Weight1 != 0) then 412 | maxweight = maxweight + W1_array[b].Weight1 413 | if(W1_array[b].Weight2 != 0) then 414 | maxweight = maxweight + W1_array[b].Weight2 415 | if(W1_array[b].Weight3 != 0) then 416 | maxweight = maxweight + W1_array[b].Weight3 417 | if(W1_array[b].Weight4 != 0) then 418 | maxweight = maxweight + W1_array[b].Weight4 419 | 420 | if(maxweight != 0) then 421 | ( 422 | if(W1_array[b].Weight1 != 0) then 423 | ( 424 | w1 = W1_array[b].Weight1 as float 425 | append w.boneids (B1_array[b].Bone1) 426 | append w.weights (w1) 427 | ) 428 | if(W1_array[b].Weight2 != 0) then 429 | ( 430 | w2 = W1_array[b].Weight2 as float 431 | append w.boneids (B1_array[b].Bone2) 432 | append w.weights (w2) 433 | ) 434 | if(W1_array[b].Weight3 != 0) then 435 | ( 436 | w3 = W1_array[b].Weight3 as float 437 | append w.boneids (B1_array[b].Bone3) 438 | append w.weights (w3) 439 | ) 440 | if(W1_array[b].Weight4 != 0) then 441 | ( 442 | w4 = W1_array[b].Weight4 as float 443 | append w.boneids (B1_array[b].Bone4) 444 | append w.weights (w4) 445 | ) 446 | ) 447 | append Weight_array w 448 | ) 449 | ) 450 | 451 | mat = standardMaterial() 452 | mat.name = (TexNum as string) 453 | mat.showinviewport = true 454 | mat.twosided = false 455 | tm = Bitmaptexture filename:(p + "Texture" + TexNum as string + ".png") 456 | tm.alphasource = 0 457 | mat.diffuseMap = tm 458 | mat.opacityMap = tm 459 | mat.opacityMap.monoOutput = 1 460 | 461 | msh = mesh vertices:Vert_array faces:Face_array 462 | msh.numTVerts = Vert_array.count 463 | setNumCPVVerts msh msh.numTVerts 464 | setCVertMode msh true 465 | setShadeCVerts msh true 466 | defaultVCFaces msh 467 | buildTVFaces msh 468 | 469 | for j = 1 to Color_array.count do setvertcolor msh j Color_array[j] 470 | for j = 1 to UV_array.count do setTVert msh j UV_array[j] 471 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 472 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 473 | msh.name = ("Model " + m as string + " Mesh " + x as string) 474 | msh.material = mat 475 | max modify mode 476 | select msh 477 | 478 | if NormalsCount > 0 do( 479 | addmodifier msh (Edit_Normals ()) ui:off 480 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 481 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 482 | EN_setNormal = msh.Edit_Normals.SetNormal 483 | normID = #{} 484 | for v = 1 to Normal_array.count do 485 | ( 486 | free normID 487 | EN_convertVS #{v} &normID 488 | for id in normID do EN_setNormal id Normal_array[v] 489 | ) 490 | ) 491 | 492 | if BoneCount > 0 do( 493 | skinMod = skin () 494 | addModifier msh skinMod 495 | for i = 1 to BoneCount do ( 496 | maxbone = getnodebyname BoneArray[i].name 497 | if i != BoneCount then 498 | skinOps.addBone skinMod maxbone 0 499 | else 500 | skinOps.addBone skinMod maxbone 1 501 | 502 | ) 503 | 504 | modPanel.setCurrentObject skinMod 505 | 506 | for i = 1 to Weight_array.count do ( 507 | w = Weight_array[i] 508 | bi = #() --bone index array 509 | wv = #() --weight value array 510 | 511 | for j = 1 to w.boneids.count do 512 | ( 513 | boneid = w.boneids[j] 514 | weight = w.weights[j] 515 | append bi boneid 516 | append wv weight 517 | ) 518 | 519 | skinOps.ReplaceVertexWeights skinMod i bi wv 520 | 521 | ) 522 | 523 | ) 524 | 525 | if UV2_array.count > 0 do( 526 | mat = standardMaterial() 527 | mat.name = (TexNumL2 as string) 528 | mat.showinviewport = true 529 | mat.twosided = false 530 | tm = Bitmaptexture filename:(p + "Texture" + TexNumL2 as string + ".png") 531 | tm.alphasource = 0 532 | mat.diffuseMap = tm 533 | mat.opacityMap = tm 534 | mat.opacityMap.monoOutput = 1 535 | 536 | msh = mesh vertices:Vert_array faces:Face_array 537 | msh.numTVerts = Vert_array.count 538 | setNumCPVVerts msh msh.numTVerts 539 | setCVertMode msh true 540 | setShadeCVerts msh true 541 | defaultVCFaces msh 542 | buildTVFaces msh 543 | 544 | for j = 1 to Color_array.count do setvertcolor msh j Color_array[j] 545 | for j = 1 to UV2_array.count do setTVert msh j UV2_array[j] 546 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 547 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 548 | msh.name = ("Model " + m as string + " Mesh " + x as string + " Layer 2") 549 | msh.material = mat 550 | max modify mode 551 | select msh 552 | 553 | if NormalsCount > 0 do( 554 | addmodifier msh (Edit_Normals ()) ui:off 555 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 556 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 557 | EN_setNormal = msh.Edit_Normals.SetNormal 558 | normID = #{} 559 | for v = 1 to Normal_array.count do 560 | ( 561 | free normID 562 | EN_convertVS #{v} &normID 563 | for id in normID do EN_setNormal id Normal_array[v] 564 | ) 565 | ) 566 | 567 | if BoneCount > 0 do( 568 | skinMod = skin () 569 | addModifier msh skinMod 570 | for i = 1 to BoneCount do ( 571 | maxbone = getnodebyname BoneArray[i].name 572 | if i != BoneCount then 573 | skinOps.addBone skinMod maxbone 0 574 | else 575 | skinOps.addBone skinMod maxbone 1 576 | 577 | ) 578 | 579 | modPanel.setCurrentObject skinMod 580 | 581 | for i = 1 to Weight_array.count do ( 582 | w = Weight_array[i] 583 | bi = #() --bone index array 584 | wv = #() --weight value array 585 | 586 | for j = 1 to w.boneids.count do 587 | ( 588 | boneid = w.boneids[j] 589 | weight = w.weights[j] 590 | append bi boneid 591 | append wv weight 592 | ) 593 | 594 | skinOps.ReplaceVertexWeights skinMod i bi wv 595 | 596 | ) 597 | 598 | ) 599 | ) 600 | 601 | 602 | if shp != undefined and x == 1 do( 603 | fseek shp 0x08 #seek_set 604 | SHPCount = readBElong shp 605 | fseek shp 0x04 #seek_cur 606 | 607 | for y = 1 to SHPCount do( 608 | VertSHP_array = #() 609 | VertSHPTemp_array = VertTemp_array 610 | SHPVerts = readBElong shp 611 | SHPStart = readBElong shp 612 | fseek shp 0x08 #seek_cur 613 | returnSHP = (ftell shp) 614 | 615 | fseek shp SHPStart #seek_set 616 | 617 | for z = 1 to SHPVerts do( 618 | VertNum = readBElong shp + 1 619 | vx = readBEfloat shp 620 | vy = readBEfloat shp 621 | vz = readBEfloat shp 622 | VertSHPTemp_array[VertNum] = [vx,vy,vz] 623 | ) 624 | 625 | fseek f PolyStart #seek_set 626 | PolyType = readBEword f 627 | VertAdd = 1 628 | do( 629 | PolyAmt = readBEword f 630 | for z = 1 to PolyAmt do( 631 | VertNum = readBEword f + 1 632 | fseek f 0x06 #seek_cur 633 | VertDat = VertSHPTemp_array[VertNum] 634 | append VertSHP_array VertDat 635 | ) 636 | PolyType = readBEword f 637 | 638 | StartDirection = -1 639 | f1 = VertAdd 640 | f2 = VertAdd + 1 641 | f3 = VertAdd + 1 642 | IndexCounter = 2 643 | FaceDirection = StartDirection 644 | Do ( 645 | f3 += 1 646 | IndexCounter = IndexCounter +1 647 | FaceDirection *= -1 648 | f1 = f2 649 | f2 = f3 650 | ) while IndexCounter != PolyAmt 651 | VertAdd = VertAdd + PolyAmt 652 | 653 | ) while PolyType != 0 654 | 655 | msh = mesh vertices:VertSHP_array faces:Face_array 656 | msh.numTVerts = VertSHP_array.count 657 | setNumCPVVerts msh msh.numTVerts 658 | setCVertMode msh true 659 | setShadeCVerts msh true 660 | defaultVCFaces msh 661 | buildTVFaces msh 662 | 663 | for j = 1 to Color_array.count do setvertcolor msh j Color_array[j] 664 | for j = 1 to UV_array.count do setTVert msh j UV_array[j] 665 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 666 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 667 | msh.name = ("Flex " + y as string) 668 | max modify mode 669 | select msh 670 | 671 | if NormalsCount > 0 do( 672 | addmodifier msh (Edit_Normals ()) ui:off 673 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 674 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 675 | EN_setNormal = msh.Edit_Normals.SetNormal 676 | normID = #{} 677 | for v = 1 to Normal_array.count do 678 | ( 679 | free normID 680 | EN_convertVS #{v} &normID 681 | for id in normID do EN_setNormal id Normal_array[v] 682 | ) 683 | ) 684 | 685 | fseek shp returnSHP #seek_set 686 | 687 | ) 688 | 689 | ) 690 | ) 691 | 692 | fseek f modelreturn #seek_set 693 | 694 | ) 695 | 696 | ) 697 | 698 | fclose f 699 | fclose q 700 | fclose s 701 | 702 | ) -------------------------------------------------------------------------------- /Scripts/KamenRiderPS3_EMD.ms: -------------------------------------------------------------------------------- 1 | -- Script written up by Random Talking Bush. 2 | -- If used, I wouldn't mind getting some thanks out of it. 3 | -- That rigging information wasn't fun to fix up. 4 | -- Yes, I borrowed a couple of things from other scripts, partly 5 | -- because I didn't know how to set up most things myself. Sorry. 6 | 7 | if (heapSize < 20000000) then 8 | heapSize = 200000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory" 9 | 10 | fname = getOpenFileName \ 11 | caption:"Kamen Rider Battride War Model File" \ 12 | types:"Kamen Rider Battride War Model File(*.EMD)|*.EMD" \ 13 | historyCategory:"KRBWEMDObjectPresets" 14 | f = fopen fname "rb" 15 | p = getFilenamePath fname -- return the path "c:\\test\\" 16 | g = getFilenameFile fname -- return the file "test" 17 | clearlistener() 18 | 19 | fn floatSwap2 f = ( 20 | i = bit.floatAsInt f 21 | h = bit.intashex i 22 | while h.count < 8 do h = "0" + h 23 | 24 | s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2) 25 | bit.intAsFloat (bit.hexasint s) 26 | ) 27 | 28 | fn ReadBEword fstream = ( 29 | return (bit.swapBytes (readshort fstream #unsigned) 1 2) 30 | ) 31 | 32 | fn convertTo32 input16 = ( 33 | inputAsInt = input16 34 | sign = bit.get inputAsInt 16 35 | exponent = (bit.shift (bit.and inputAsInt (bit.hexasint "7C00")) -10) as integer - 16 36 | fraction = bit.and inputAsInt (bit.hexasint "03FF") 37 | if sign==true then sign = 1 else sign = 0 38 | exponentF = exponent + 127 39 | --Ouput 32 bit integer representing a 32 bit float 40 | outputAsFloat = bit.or (bit.or (bit.shift fraction 13) (bit.shift exponentF 23)) (bit.shift sign 31) 41 | --Output Check 42 | return bit.intasfloat outputasfloat 43 | ) 44 | 45 | fn ReadBEHalfFloat fstream = ( 46 | return convertTo32(ReadBEword fstream) 47 | ) 48 | 49 | fn ReadBElong fstream = ( 50 | long = readlong fstream 51 | long = bit.swapBytes long 1 4 52 | long = bit.swapBytes long 2 3 53 | return long 54 | ) 55 | 56 | fn ReadBEfloat fstream = ( 57 | return floatSwap2(readfloat fstream) 58 | ) 59 | 60 | for a = 1 to 1 do ( 61 | Bone_Matrix_array = #() 62 | BNArr = #() 63 | MatName_array = #() 64 | SubMatName_array = #() 65 | NodeID_array = #() 66 | struct Bone_Info_Struct 67 | ( 68 | Bone1, Bone2, Bone3, Bone4 69 | ) 70 | struct Weight_Info_Struct 71 | ( 72 | Weight1, Weight2, Weight3, Weight4 73 | ) 74 | struct weight_data 75 | ( 76 | boneids, weights 77 | ) 78 | 79 | fseek f 0x24 #seek_set 80 | PolygonCount = ReadBElong f 81 | nothing = ReadBElong f 82 | BoneCount = ReadBElong f 83 | MatCount = ReadBElong f 84 | nothing = ReadBElong f 85 | nothing = ReadBElong f 86 | something = ReadBElong f 87 | something = ReadBElong f 88 | nothing = ReadBElong f 89 | nothing = ReadBElong f 90 | PolygonOffset = ReadBElong f 91 | nothing = ReadBElong f 92 | BoneOffset = ReadBElong f 93 | MaterialsOffset = ReadBElong f 94 | UVOffset = ReadBElong f 95 | UVOffsetMinus10 = ReadBElong f 96 | UVOffsetLength = ReadBElong f 97 | fseek f BoneOffset #seek_set 98 | if BoneCount != 0 do( 99 | for x = 1 to BoneCount Do ( 100 | headerthing1 = readBEword f 101 | headerthing2 = readBEword f 102 | headerlength = ReadBElong f 103 | bonenum = ReadBElong f 104 | floaty = readBEfloat f 105 | jump = (ftell f as integer) + 32 106 | BoneName = readstring f 107 | fseek f jump #seek_set 108 | fseek f 0xE0 #seek_cur 109 | BoneParent = ReadBElong f 110 | bonechildren = ReadBElong f 111 | nodeID = ReadBElong f + 1 112 | append nodeID_array nodeID 113 | internalnum = ReadBElong f 114 | m11 = ReadBEfloat f; m12 = ReadBEfloat f; m13 = ReadBEfloat f; m14 = ReadBEfloat f 115 | m21 = ReadBEfloat f; m22 = ReadBEfloat f; m23 = ReadBEfloat f; m24 = ReadBEfloat f 116 | m31 = ReadBEfloat f; m32 = ReadBEfloat f; m33 = ReadBEfloat f; m34 = ReadBEfloat f 117 | m41 = ReadBEfloat f; m42 = ReadBEfloat f; m43 = ReadBEfloat f; m44 = ReadBEfloat f 118 | m51 = ReadBEfloat f; m52 = ReadBEfloat f; m53 = ReadBEfloat f; m54 = ReadBEfloat f 119 | m61 = ReadBEfloat f; m62 = ReadBEfloat f; m63 = ReadBEfloat f; m64 = ReadBEfloat f 120 | m71 = ReadBEfloat f; m72 = ReadBEfloat f; m73 = ReadBEfloat f; m74 = ReadBEfloat f 121 | m81 = ReadBEfloat f; m82 = ReadBEfloat f; m83 = ReadBEfloat f; m84 = ReadBEfloat f 122 | tfm = (matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]) 123 | if (getNodeByName BoneName) != undefined do ( 124 | append BNArr (getNodeByName BoneName) 125 | ) 126 | if (getNodeByName BoneName) == undefined do ( 127 | if (BoneParent != -1) do ( 128 | tfm = tfm * BNArr[(boneparent + 1)].objecttransform 129 | ) 130 | ) 131 | append Bone_Matrix_array tfm 132 | 133 | newBone = bonesys.createbone \ 134 | tfm.row4 \ 135 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 136 | (normalize tfm.row3) 137 | newBone.name = BoneName 138 | newBone.width = 0.01 139 | newBone.height = 0.01 140 | newBone.transform = tfm 141 | newBone.setBoneEnable false 0 142 | newBone.wirecolor = yellow 143 | newbone.showlinks = true 144 | newBone.pos.controller = TCB_position () 145 | newBone.rotation.controller = TCB_rotation () 146 | if (BoneParent != -1) then 147 | newBone.parent = BNArr[(BoneParent + 1)] 148 | append BNArr newBone 149 | ) 150 | ) 151 | 152 | print "--------------------" 153 | for x = 1 to MatCount Do ( 154 | headerthing = ReadBElong f 155 | headerlength = ReadBElong f - 8 156 | jumpmat1 = (ftell f as integer) + headerlength 157 | materialnum = ReadBElong f 158 | maybenothing = ReadBElong f 159 | jumpmat2 = (ftell f as integer) + 540 160 | MaterialName = readstring f 161 | print MaterialName 162 | append MatName_array MaterialName 163 | fseek f jumpmat2 #seek_set 164 | submaterialnum = ReadBElong f 165 | if submaterialnum == 0 do( 166 | if g == "CCS00" and MaterialName == "CCS00eye02" do(SubMaterialName = "CCS00eye00_CO") -- This is to fix CCS00.emd 167 | if g == "KAB00" and MaterialName == "eye2" do(SubMaterialName = "KAB00eye00_CO") -- This is to fix KAB00.emd 168 | if g == "GAI01_W01" and MaterialName == "GAI01W04_base" do(SubMaterialName = "GAI01djgun00_CO") -- This is to fix KAB00.emd 169 | if SubMaterialName == undefined do(SubMaterialName = "null") 170 | print (SubMaterialName + " (supplemented texture)") 171 | append SubMatName_array SubMaterialName 172 | ) 173 | fseek f jumpmat1 #seek_set 174 | for y = 1 to submaterialnum Do ( 175 | subheaderthing = ReadBElong f 176 | subheaderlength = ReadBElong f - 8 177 | jumpsubmat1 = (ftell f as integer) + subheaderlength 178 | submaterialnum = ReadBElong f 179 | maybenothing = ReadBElong f 180 | jumpsubmat2 = (ftell f as integer) + 256 181 | SubMaterialName = readstring f 182 | print SubMaterialName 183 | if y == 1 do(append SubMatName_array SubMaterialName) 184 | fseek f jumpsubmat2 #seek_set 185 | float1 = readBEfloat f 186 | materiallink = ReadBElong f 187 | submaterialnum2 = ReadBElong f 188 | maybenothing = ReadBElong f 189 | fseek f jumpsubmat1 #seek_set 190 | ) 191 | 192 | print "--------------------" 193 | ) 194 | fseek f PolygonOffset #seek_set 195 | 196 | for x = 1 to PolygonCount Do ( 197 | headerthing1 = readbyte f #unsigned 198 | headerthing2 = readbyte f #unsigned 199 | headerthing3 = readbyte f #unsigned 200 | headerthing4 = readbyte f #unsigned 201 | headerlength = ReadBElong f 202 | headerjump = ((ftell f as integer) - 8) + headerlength 203 | polynum = ReadBElong f 204 | floaty = readBEfloat f 205 | jump2 = (ftell f as integer) + 32 206 | PolygonName = readstring f 207 | fseek f jump2 #seek_set 208 | fseek f 0xE0 #seek_cur 209 | BoundXMin = readBEfloat f 210 | BoundYMin = readBEfloat f 211 | BoundZMin = readBEfloat f 212 | nothing = ReadBElong f 213 | BoundXMax = readBEfloat f 214 | BoundYMax = readBEfloat f 215 | BoundZMax = readBEfloat f 216 | nothing = ReadBElong f 217 | matgroupnum = readBEword f + 1 218 | headerthing1 = readBEword f 219 | nothing = ReadBElong f 220 | nothing = ReadBElong f 221 | nothing = ReadBElong f 222 | 223 | groups = 1 224 | 225 | if headerthing1 == 0x204 do ( 226 | groups = ReadBEword f 227 | headerthing1 = readBEword f 228 | nothing = ReadBElong f 229 | nothing = ReadBElong f 230 | nothing = ReadBElong f 231 | 232 | anothermaybeusefuloffset = ReadBElong f 233 | nothing = ReadBElong f 234 | nothing = ReadBElong f 235 | nothing = ReadBElong f 236 | ) 237 | 238 | for g = 1 to groups do( 239 | NodeFix_array = #() 240 | Vert_array = #() 241 | Normal_array = #() 242 | Color_Array=#() 243 | Alpha_Array=#() 244 | UV_array = #() 245 | Face_array = #() 246 | W1_array = #() 247 | B1_array = #() 248 | Weight_array = #() 249 | 250 | if g > 1 do (fseek f 0x50 #seek_cur) 251 | 252 | seek = readlong f 253 | while seek == 0 and seek != undefined do(seek = readlong f) 254 | fseek f -0x04 #seek_cur 255 | jump3 = (ftell f as integer) 256 | polystart = ReadBElong f 257 | polyjump = (jump3 + polystart) 258 | polyamount = readBEword f 259 | spacing = readBEword f 260 | vertexstart = ReadBElong f 261 | vertexjump = (jump3 + vertexstart) 262 | maybenormals = ReadBElong f 263 | vertamount = readBEword f 264 | spacing = readBEword f 265 | normalslength = ReadBElong f 266 | somethingamount = readBEword f 267 | spacing = readBEword f 268 | somethingoffset = ReadBElong f 269 | UVlength = ReadBElong f 270 | NodeThing1 = (ReadBEword f / 0x30) 271 | NodeThing2 = (ReadBEword f / 0x30) 272 | NodeThing3 = (ReadBEword f / 0x30) 273 | NodeThing4 = (ReadBEword f / 0x30) 274 | UVamount = ReadBEword f 275 | spacing = readBEword f 276 | BoneWeightStart = ReadBElong f 277 | BoneWeightJump = (jump3 + BoneWeightStart) 278 | ActualUVStart = ReadBElong f 279 | somekindaoffset = readBElong f 280 | nothing = ReadBElong f 281 | nothing = ReadBElong f 282 | nothing = ReadBElong f 283 | nothing = ReadBElong f 284 | nothing = ReadBElong f 285 | nothing = ReadBElong f 286 | nothing = ReadBElong f 287 | anotheroffset1 = ReadBELong f 288 | anotheroffsetlength1 = readBElong f 289 | nothing = readBElong f 290 | anotheroffset2 = ReadBELong f 291 | anotheroffsetlength2 = readBElong f 292 | nothing = readBElong f 293 | nothing = readBElong f 294 | polygonstartagain = readBElong f 295 | nothing = readBElong f 296 | nothing = readBElong f 297 | bytechunk1 = readBEword f 298 | bytechunk2 = readBEword f 299 | bytechunk3 = readBEword f 300 | bytechunk4 = readBEword f 301 | pointamount = readBEword f 302 | UVsize = (UVlength / 4) / pointamount 303 | faceamount = readBEword f 304 | end = readBElong f 305 | 306 | fseek f polyjump #seek_set 307 | for b = 1 to polyamount / 6 do( 308 | f1 = ReadBEword f + 1 309 | f2 = ReadBEword f + 1 310 | f3 = ReadBEword f + 1 311 | if b < (faceamount + 1) do(append Face_array [(f3),(f2),(f1)]) 312 | ) 313 | 314 | fseek f vertexjump #seek_set 315 | for b = 1 to vertamount / 12 do( 316 | vx = ReadBEfloat f 317 | vy = ReadBEfloat f 318 | vz = ReadBEfloat f 319 | if b < (pointamount + 1) do(append Vert_array [vx,vy,vz]) 320 | ) 321 | seek = readlong f 322 | while seek == 0 and seek != undefined do(seek = readlong f) 323 | fseek f -0x04 #seek_cur 324 | 325 | -- This is only a placeholdery thing. Ignore it. 326 | for b = 1 to vertamount / 12 do( 327 | nx = ReadBEFloat f 328 | ny = ReadBEFloat f 329 | nz = ReadBEFloat f 330 | --if b < (pointamount + 1) do(append Normal_array [nx,ny,nz]) 331 | ) 332 | 333 | fseek f UVOffset #seek_set 334 | 335 | for b = 1 to pointamount do( 336 | if UVsize == 2 do( 337 | colora = ReadByte f #unsigned 338 | colorr = ReadByte f #unsigned 339 | colorg = ReadByte f #unsigned 340 | colorb = ReadByte f #unsigned 341 | tu = (ReadBEHalfFloat f) * 2 342 | tv = ((ReadBEHalfFloat f) * -2) + 1 343 | append Color_array [colorr, colorg, colorb] 344 | append Alpha_array colora 345 | append UV_array [tu, tv, 0] 346 | ) 347 | if UVsize == 3 do( 348 | colora = ReadByte f #unsigned 349 | colorr = ReadByte f #unsigned 350 | colorg = ReadByte f #unsigned 351 | colorb = ReadByte f #unsigned 352 | tu = (ReadBEHalfFloat f) * 2 353 | tv = ((ReadBEHalfFloat f) * -2) + 1 354 | tu2 = (ReadBEHalfFloat f) * 2 355 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 356 | append Color_array [colorr, colorg, colorb] 357 | append Alpha_array colora 358 | append UV_array [tu, tv, 0] 359 | ) 360 | if UVsize == 4 do( 361 | colora = ReadByte f #unsigned 362 | colorr = ReadByte f #unsigned 363 | colorg = ReadByte f #unsigned 364 | colorb = ReadByte f #unsigned 365 | tu = (ReadBEHalfFloat f) * 2 366 | tv = ((ReadBEHalfFloat f) * -2) + 1 367 | tu2 = (ReadBEHalfFloat f) * 2 368 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 369 | tu3 = (ReadBEHalfFloat f) * 2 370 | tv3 = ((ReadBEHalfFloat f) * -2) + 1 371 | append Color_array [colorr, colorg, colorb] 372 | append Alpha_array colora 373 | append UV_array [tu, tv, 0] 374 | ) 375 | if UVsize == 5 do( 376 | tu = (ReadBEHalfFloat f) * 2 377 | tv = ((ReadBEHalfFloat f) * -2) + 1 378 | tu2 = (ReadBEHalfFloat f) * 2 379 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 380 | tu3 = (ReadBEHalfFloat f) * 2 381 | tv3 = ((ReadBEHalfFloat f) * -2) + 1 382 | colora = ReadByte f #unsigned 383 | colorr = ReadByte f #unsigned 384 | colorg = ReadByte f #unsigned 385 | colorb = ReadByte f #unsigned 386 | tu4 = (ReadBEHalfFloat f) * 2 387 | tv4 = ((ReadBEHalfFloat f) * -2) + 1 388 | append Color_array [colorr, colorg, colorb] 389 | append Alpha_array colora 390 | append UV_array [tu4, tv4, 0] 391 | ) 392 | if UVsize == 6 do( 393 | tu = (ReadBEHalfFloat f) * 2 394 | tv = ((ReadBEHalfFloat f) * -2) + 1 395 | tu2 = (ReadBEHalfFloat f) * 2 396 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 397 | tu3 = (ReadBEHalfFloat f) * 2 398 | tv3 = ((ReadBEHalfFloat f) * -2) + 1 399 | colora = ReadByte f #unsigned 400 | colorr = ReadByte f #unsigned 401 | colorg = ReadByte f #unsigned 402 | colorb = ReadByte f #unsigned 403 | tu4 = (ReadBEHalfFloat f) * 2 404 | tv4 = ((ReadBEHalfFloat f) * -2) + 1 405 | tu5 = (ReadBEHalfFloat f) * 2 406 | tv5 = ((ReadBEHalfFloat f) * -2) + 1 407 | append Color_array [colorr, colorg, colorb] 408 | append Alpha_array colora 409 | append UV_array [tu4, tv4, 0] 410 | ) 411 | ) 412 | 413 | seek = readlong f 414 | while seek == 0 and seek != undefined do(seek = readlong f) 415 | fseek f -0x04 #seek_cur 416 | 417 | UVOffset = (ftell f as integer) 418 | 419 | if BoneCount != 0 do( 420 | fseek f BoneWeightJump #seek_set 421 | for b = 1 to Vert_array.count do( 422 | Weight1 = (readbyte f #unsigned as float / 255) 423 | Bone1 = #() 424 | IDB1 = (readbyte f #unsigned) + 1 425 | ID1 = IDB1 + NodeThing1 426 | 427 | if IDB1 >= (NodeThing3 + 1) do( 428 | ID1 = IDB1 + NodeThing2 - NodeThing3 429 | ) 430 | 431 | for c = 1 to NodeID_array.count do( 432 | if ID1 == NodeID_array[c] do( 433 | Bone1 = c 434 | ) 435 | ) 436 | 437 | Weight2 = (readbyte f #unsigned as float / 255) 438 | Bone2 = #() 439 | IDB2 = (readbyte f #unsigned) + 1 440 | ID2 = IDB2 + NodeThing1 441 | 442 | if IDB2 >= (NodeThing3 + 1) do( 443 | ID2 = IDB2 + NodeThing2 - NodeThing3 444 | ) 445 | 446 | for c = 1 to NodeID_array.count do( 447 | if ID2 == NodeID_array[c] do( 448 | Bone2 = c 449 | ) 450 | ) 451 | 452 | Weight3 = (readbyte f #unsigned as float / 255) 453 | IDB3 = (readbyte f #unsigned) + 1 454 | ID3 = IDB3 + NodeThing1 455 | Bone3 = #() 456 | 457 | if IDB3 >= (NodeThing3 + 1) do( 458 | ID3 = IDB3 + NodeThing2 - NodeThing3 459 | ) 460 | for c = 1 to NodeID_array.count do( 461 | if ID3 == NodeID_array[c] do( 462 | Bone3 = c 463 | ) 464 | ) 465 | 466 | Weight4 = (readbyte f #unsigned as float / 255) 467 | IDB4 = (readbyte f #unsigned) + 1 468 | ID4 = IDB4 + NodeThing1 469 | Bone4 = #() 470 | 471 | if IDB4 >= (NodeThing3 + 1) do( 472 | ID4 = IDB4 + NodeThing2 - NodeThing3 473 | ) 474 | for c = 1 to NodeID_array.count do( 475 | if ID4 == NodeID_array[c] do( 476 | Bone4 = c 477 | ) 478 | ) 479 | append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 480 | --append B1_array (Bone_Info_Struct Bone1:ID1 Bone2:ID2 Bone3:ID3 Bone4:ID4) 481 | --append B1_array (Bone_Info_Struct Bone1:IDB1 Bone2:IDB2 Bone3:IDB3 Bone4:IDB4) 482 | append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 483 | ) 484 | 485 | for b = 1 to W1_array.count Do ( 486 | w = (weight_data boneids:#() weights:#()) 487 | maxweight = 0 488 | 489 | if(W1_array[b].Weight1 != 0) then 490 | maxweight = maxweight + W1_array[b].Weight1 491 | if(W1_array[b].Weight2 != 0) then 492 | maxweight = maxweight + W1_array[b].Weight2 493 | if(W1_array[b].Weight3 != 0) then 494 | maxweight = maxweight + W1_array[b].Weight3 495 | if(W1_array[b].Weight4 != 0) then 496 | maxweight = maxweight + W1_array[b].Weight4 497 | 498 | if(maxweight != 0) then 499 | ( 500 | if(W1_array[b].Weight1 != 0) then 501 | ( 502 | w1 = W1_array[b].Weight1 as float 503 | append w.boneids (B1_array[b].Bone1) 504 | append w.weights (w1) 505 | ) 506 | if(W1_array[b].Weight2 != 0) then 507 | ( 508 | w2 = W1_array[b].Weight2 as float 509 | append w.boneids (B1_array[b].Bone2) 510 | append w.weights (w2) 511 | ) 512 | if(W1_array[b].Weight3 != 0) then 513 | ( 514 | w3 = W1_array[b].Weight3 as float 515 | append w.boneids (B1_array[b].Bone3) 516 | append w.weights (w3) 517 | ) 518 | if(W1_array[b].Weight4 != 0) then 519 | ( 520 | w4 = W1_array[b].Weight4 as float 521 | append w.boneids (B1_array[b].Bone4) 522 | append w.weights (w4) 523 | ) 524 | ) 525 | append Weight_array w 526 | ) 527 | 528 | ) 529 | 530 | mat = standardMaterial() 531 | mat.name = MatName_array[matgroupnum] 532 | mat.showinviewport = true 533 | mat.twosided = false 534 | tm = Bitmaptexture filename:(p + "/textures/" + SubMatName_array[matgroupnum] + ".dds") 535 | tm.alphasource = 2 536 | mat.diffuseMap = tm 537 | 538 | msh = mesh vertices:Vert_array faces:Face_array 539 | msh.numTVerts = Vert_array.count 540 | -- Coloring stuff. Uncomment if you want stage models to be tutti-frutti. 541 | -- setNumCPVVerts msh msh.numTVerts 542 | -- setCVertMode msh true 543 | -- setShadeCVerts msh true 544 | -- defaultVCFaces msh 545 | -- for p = 1 to Color_array.count do( 546 | -- setvertcolor msh p Color_array[p] 547 | -- ) 548 | buildTVFaces msh 549 | for j = 1 to Vert_array.count do setTVert msh j UV_array[j] 550 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 551 | msh.name = PolygonName 552 | msh.material = mat 553 | max modify mode 554 | select msh 555 | 556 | --set smoothing group of all faces to 1 to get one normal per vertex 557 | for face = 1 to msh.numfaces do setFaceSmoothGroup msh face 1 558 | --set normals via edit normals modifier 559 | 560 | -- If there are in fact normals, then uncomment this. 561 | -- addmodifier msh (Edit_Normals ()) ui:off 562 | -- msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 563 | -- EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 564 | -- EN_setNormal = msh.Edit_Normals.SetNormal 565 | -- normID = #{} 566 | -- --apply normals 567 | -- for v = 1 to Normal_array.count do 568 | -- ( 569 | -- free normID 570 | -- EN_convertVS #{v} &normID 571 | -- for id in normID do EN_setNormal id Normal_array[v] 572 | -- ) 573 | 574 | if BoneCount != 0 do( 575 | skinMod = skin () 576 | addModifier msh skinMod 577 | for i = 1 to BoneCount do 578 | ( 579 | maxbone = getnodebyname BNArr[i].name 580 | if i != BoneCount then 581 | skinOps.addBone skinMod maxbone 0 582 | else 583 | skinOps.addBone skinMod maxbone 1 584 | 585 | ) 586 | 587 | modPanel.setCurrentObject skinMod 588 | 589 | for i = 1 to Weight_array.count do ( 590 | w = Weight_array[i] 591 | bi = #() --bone index array 592 | wv = #() --weight value array 593 | 594 | for j = 1 to w.boneids.count do 595 | ( 596 | boneid = w.boneids[j] 597 | weight = w.weights[j] 598 | append bi boneid 599 | append wv weight 600 | ) 601 | 602 | skinOps.ReplaceVertexWeights skinMod i bi wv 603 | 604 | ) 605 | ) 606 | 607 | ) 608 | 609 | fseek f headerjump #seek_set 610 | 611 | ) 612 | ) 613 | 614 | fclose f -------------------------------------------------------------------------------- /Scripts/KamenRiderPS3_EMD_2012.ms: -------------------------------------------------------------------------------- 1 | -- Script written up by Random Talking Bush. 2 | -- If used, I wouldn't mind getting some thanks out of it. 3 | -- That rigging information wasn't fun to fix up. 4 | -- Yes, I borrowed a couple of things from other scripts, partly 5 | -- because I didn't know how to set up most things myself. Sorry. 6 | 7 | if (heapSize < 20000000) then 8 | heapSize = 200000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory" 9 | 10 | fname = getOpenFileName \ 11 | caption:"Kamen Rider Battride War Model File" \ 12 | types:"Kamen Rider Battride War Model File(*.EMD)|*.EMD" \ 13 | historyCategory:"KRBWEMDObjectPresets" 14 | f = fopen fname "rb" 15 | p = getFilenamePath fname -- return the path "c:\\test\\" 16 | g = getFilenameFile fname -- return the file "test" 17 | clearlistener() 18 | 19 | fn floatSwap2 f = ( 20 | i = bit.floatAsInt f 21 | h = bit.intashex i 22 | while h.count < 8 do h = "0" + h 23 | 24 | s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2) 25 | bit.intAsFloat (bit.hexasint s) 26 | ) 27 | 28 | fn ReadBEword fstream = ( 29 | return (bit.swapBytes (readshort fstream #unsigned) 1 2) 30 | ) 31 | 32 | fn convertTo32 input16 = ( 33 | inputAsInt = input16 34 | sign = bit.get inputAsInt 16 35 | exponent = (bit.shift (bit.and inputAsInt (bit.hexasint "7C00")) -10) as integer - 16 36 | fraction = bit.and inputAsInt (bit.hexasint "03FF") 37 | if sign==true then sign = 1 else sign = 0 38 | exponentF = exponent + 127 39 | --Ouput 32 bit integer representing a 32 bit float 40 | outputAsFloat = bit.or (bit.or (bit.shift fraction 13) (bit.shift exponentF 23)) (bit.shift sign 31) 41 | --Output Check 42 | return bit.intasfloat outputasfloat 43 | ) 44 | 45 | fn ReadBEHalfFloat fstream = ( 46 | return convertTo32(ReadBEword fstream) 47 | ) 48 | 49 | fn ReadBElong fstream = ( 50 | long = readlong fstream 51 | long = bit.swapBytes long 1 4 52 | long = bit.swapBytes long 2 3 53 | return long 54 | ) 55 | 56 | fn ReadBEfloat fstream = ( 57 | return floatSwap2(readfloat fstream) 58 | ) 59 | 60 | for a = 1 to 1 do ( 61 | Bone_Matrix_array = #() 62 | BNArr = #() 63 | MatName_array = #() 64 | SubMatName_array = #() 65 | NodeID_array = #() 66 | struct Bone_Info_Struct 67 | ( 68 | Bone1, Bone2, Bone3, Bone4 69 | ) 70 | struct Weight_Info_Struct 71 | ( 72 | Weight1, Weight2, Weight3, Weight4 73 | ) 74 | struct weight_data 75 | ( 76 | boneids, weights 77 | ) 78 | 79 | fseek f 0x24 #seek_set 80 | PolygonCount = ReadBElong f 81 | nothing = ReadBElong f 82 | BoneCount = ReadBElong f 83 | MatCount = ReadBElong f 84 | nothing = ReadBElong f 85 | nothing = ReadBElong f 86 | something = ReadBElong f 87 | something = ReadBElong f 88 | nothing = ReadBElong f 89 | nothing = ReadBElong f 90 | PolygonOffset = ReadBElong f 91 | nothing = ReadBElong f 92 | BoneOffset = ReadBElong f 93 | MaterialsOffset = ReadBElong f 94 | UVOffset = ReadBElong f 95 | UVOffsetMinus10 = ReadBElong f 96 | UVOffsetLength = ReadBElong f 97 | fseek f BoneOffset #seek_set 98 | if BoneCount != 0 do( 99 | for x = 1 to BoneCount Do ( 100 | headerthing1 = readBEword f 101 | headerthing2 = readBEword f 102 | headerlength = ReadBElong f 103 | bonenum = ReadBElong f 104 | floaty = readBEfloat f 105 | jump = (ftell f as integer) + 32 106 | BoneName = readstring f 107 | if x < 10 do(BoneName = "00" + x as string + " - " + BoneName) 108 | if x > 9 and x < 100 do(BoneName = "0" + x as string + " - " + BoneName) 109 | if x > 99 do(BoneName = x as string + " - " + BoneName) 110 | fseek f jump #seek_set 111 | fseek f 0xE0 #seek_cur 112 | BoneParent = ReadBElong f 113 | bonechildren = ReadBElong f 114 | nodeID = ReadBElong f + 1 115 | append nodeID_array nodeID 116 | internalnum = ReadBElong f 117 | m11 = ReadBEfloat f; m12 = ReadBEfloat f; m13 = ReadBEfloat f; m14 = ReadBEfloat f 118 | m21 = ReadBEfloat f; m22 = ReadBEfloat f; m23 = ReadBEfloat f; m24 = ReadBEfloat f 119 | m31 = ReadBEfloat f; m32 = ReadBEfloat f; m33 = ReadBEfloat f; m34 = ReadBEfloat f 120 | m41 = ReadBEfloat f; m42 = ReadBEfloat f; m43 = ReadBEfloat f; m44 = ReadBEfloat f 121 | m51 = ReadBEfloat f; m52 = ReadBEfloat f; m53 = ReadBEfloat f; m54 = ReadBEfloat f 122 | m61 = ReadBEfloat f; m62 = ReadBEfloat f; m63 = ReadBEfloat f; m64 = ReadBEfloat f 123 | m71 = ReadBEfloat f; m72 = ReadBEfloat f; m73 = ReadBEfloat f; m74 = ReadBEfloat f 124 | m81 = ReadBEfloat f; m82 = ReadBEfloat f; m83 = ReadBEfloat f; m84 = ReadBEfloat f 125 | tfm = (matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]) 126 | if (getNodeByName BoneName) != undefined do ( 127 | append BNArr (getNodeByName BoneName) 128 | ) 129 | if (getNodeByName BoneName) == undefined do ( 130 | if (BoneParent != -1) do ( 131 | tfm = tfm * BNArr[(boneparent + 1)].objecttransform 132 | ) 133 | ) 134 | append Bone_Matrix_array tfm 135 | 136 | newBone = bonesys.createbone \ 137 | tfm.row4 \ 138 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 139 | (normalize tfm.row3) 140 | newBone.name = BoneName 141 | newBone.width = 0.01 142 | newBone.height = 0.01 143 | newBone.transform = tfm 144 | newBone.setBoneEnable false 0 145 | newBone.wirecolor = yellow 146 | newbone.showlinks = true 147 | newBone.pos.controller = TCB_position () 148 | newBone.rotation.controller = TCB_rotation () 149 | if (BoneParent != -1) then 150 | newBone.parent = BNArr[(BoneParent + 1)] 151 | append BNArr newBone 152 | ) 153 | ) 154 | 155 | print "--------------------" 156 | for x = 1 to MatCount Do ( 157 | headerthing = ReadBElong f 158 | headerlength = ReadBElong f - 8 159 | jumpmat1 = (ftell f as integer) + headerlength 160 | materialnum = ReadBElong f 161 | maybenothing = ReadBElong f 162 | jumpmat2 = (ftell f as integer) + 540 163 | MaterialName = readstring f 164 | print MaterialName 165 | append MatName_array MaterialName 166 | fseek f jumpmat2 #seek_set 167 | submaterialnum = ReadBElong f 168 | if submaterialnum == 0 do( 169 | if g == "CCS00" and MaterialName == "CCS00eye02" do(SubMaterialName = "CCS00eye00_CO") -- This is to fix CCS00.emd 170 | if g == "KAB00" and MaterialName == "eye2" do(SubMaterialName = "KAB00eye00_CO") -- This is to fix KAB00.emd 171 | if g == "GAI01_W01" and MaterialName == "GAI01W04_base" do(SubMaterialName = "GAI01djgun00_CO") -- This is to fix KAB00.emd 172 | if SubMaterialName == undefined do(SubMaterialName = "null") 173 | print (SubMaterialName + " (supplemented texture)") 174 | append SubMatName_array SubMaterialName 175 | ) 176 | fseek f jumpmat1 #seek_set 177 | for y = 1 to submaterialnum Do ( 178 | subheaderthing = ReadBElong f 179 | subheaderlength = ReadBElong f - 8 180 | jumpsubmat1 = (ftell f as integer) + subheaderlength 181 | submaterialnum = ReadBElong f 182 | maybenothing = ReadBElong f 183 | jumpsubmat2 = (ftell f as integer) + 256 184 | SubMaterialName = readstring f 185 | print SubMaterialName 186 | if y == 1 do(append SubMatName_array SubMaterialName) 187 | fseek f jumpsubmat2 #seek_set 188 | float1 = readBEfloat f 189 | materiallink = ReadBElong f 190 | submaterialnum2 = ReadBElong f 191 | maybenothing = ReadBElong f 192 | fseek f jumpsubmat1 #seek_set 193 | ) 194 | 195 | print "--------------------" 196 | ) 197 | fseek f PolygonOffset #seek_set 198 | 199 | for x = 1 to PolygonCount Do ( 200 | headerthing1 = readbyte f #unsigned 201 | headerthing2 = readbyte f #unsigned 202 | headerthing3 = readbyte f #unsigned 203 | headerthing4 = readbyte f #unsigned 204 | headerlength = ReadBElong f 205 | headerjump = ((ftell f as integer) - 8) + headerlength 206 | polynum = ReadBElong f 207 | floaty = readBEfloat f 208 | jump2 = (ftell f as integer) + 32 209 | PolygonName = readstring f 210 | fseek f jump2 #seek_set 211 | fseek f 0xE0 #seek_cur 212 | BoundXMin = readBEfloat f 213 | BoundYMin = readBEfloat f 214 | BoundZMin = readBEfloat f 215 | nothing = ReadBElong f 216 | BoundXMax = readBEfloat f 217 | BoundYMax = readBEfloat f 218 | BoundZMax = readBEfloat f 219 | nothing = ReadBElong f 220 | matgroupnum = readBEword f + 1 221 | headerthing1 = readBEword f 222 | nothing = ReadBElong f 223 | nothing = ReadBElong f 224 | nothing = ReadBElong f 225 | 226 | groups = 1 227 | 228 | if headerthing1 == 0x204 do ( 229 | groups = ReadBEword f 230 | headerthing1 = readBEword f 231 | nothing = ReadBElong f 232 | nothing = ReadBElong f 233 | nothing = ReadBElong f 234 | 235 | anothermaybeusefuloffset = ReadBElong f 236 | nothing = ReadBElong f 237 | nothing = ReadBElong f 238 | nothing = ReadBElong f 239 | ) 240 | 241 | for g = 1 to groups do( 242 | NodeFix_array = #() 243 | Vert_array = #() 244 | Normal_array = #() 245 | Color_Array=#() 246 | Alpha_Array=#() 247 | UV_array = #() 248 | Face_array = #() 249 | W1_array = #() 250 | B1_array = #() 251 | Weight_array = #() 252 | 253 | if g > 1 do (fseek f 0x50 #seek_cur) 254 | 255 | seek = readlong f 256 | while seek == 0 and seek != undefined do(seek = readlong f) 257 | fseek f -0x04 #seek_cur 258 | jump3 = (ftell f as integer) 259 | polystart = ReadBElong f 260 | polyjump = (jump3 + polystart) 261 | polyamount = readBEword f 262 | spacing = readBEword f 263 | vertexstart = ReadBElong f 264 | vertexjump = (jump3 + vertexstart) 265 | maybenormals = ReadBElong f 266 | vertamount = readBEword f 267 | spacing = readBEword f 268 | normalslength = ReadBElong f 269 | somethingamount = readBEword f 270 | spacing = readBEword f 271 | somethingoffset = ReadBElong f 272 | UVlength = ReadBElong f 273 | NodeThing1 = (ReadBEword f / 0x30) 274 | NodeThing2 = (ReadBEword f / 0x30) 275 | NodeThing3 = (ReadBEword f / 0x30) 276 | NodeThing4 = (ReadBEword f / 0x30) 277 | UVamount = ReadBEword f 278 | spacing = readBEword f 279 | BoneWeightStart = ReadBElong f 280 | BoneWeightJump = (jump3 + BoneWeightStart) 281 | ActualUVStart = ReadBElong f 282 | somekindaoffset = readBElong f 283 | nothing = ReadBElong f 284 | nothing = ReadBElong f 285 | nothing = ReadBElong f 286 | nothing = ReadBElong f 287 | nothing = ReadBElong f 288 | nothing = ReadBElong f 289 | nothing = ReadBElong f 290 | anotheroffset1 = ReadBELong f 291 | anotheroffsetlength1 = readBElong f 292 | nothing = readBElong f 293 | anotheroffset2 = ReadBELong f 294 | anotheroffsetlength2 = readBElong f 295 | nothing = readBElong f 296 | nothing = readBElong f 297 | polygonstartagain = readBElong f 298 | nothing = readBElong f 299 | nothing = readBElong f 300 | bytechunk1 = readBEword f 301 | bytechunk2 = readBEword f 302 | bytechunk3 = readBEword f 303 | bytechunk4 = readBEword f 304 | pointamount = readBEword f 305 | UVsize = (UVlength / 4) / pointamount 306 | faceamount = readBEword f 307 | end = readBElong f 308 | 309 | fseek f polyjump #seek_set 310 | for b = 1 to polyamount / 6 do( 311 | f1 = ReadBEword f + 1 312 | f2 = ReadBEword f + 1 313 | f3 = ReadBEword f + 1 314 | if b < (faceamount + 1) do(append Face_array [(f3),(f2),(f1)]) 315 | ) 316 | 317 | fseek f vertexjump #seek_set 318 | for b = 1 to vertamount / 12 do( 319 | vx = ReadBEfloat f 320 | vy = ReadBEfloat f 321 | vz = ReadBEfloat f 322 | if b < (pointamount + 1) do(append Vert_array [vx,vy,vz]) 323 | ) 324 | seek = readlong f 325 | while seek == 0 and seek != undefined do(seek = readlong f) 326 | fseek f -0x04 #seek_cur 327 | 328 | -- This is only a placeholdery thing. Ignore it. 329 | for b = 1 to vertamount / 12 do( 330 | nx = ReadBEFloat f 331 | ny = ReadBEFloat f 332 | nz = ReadBEFloat f 333 | --if b < (pointamount + 1) do(append Normal_array [nx,ny,nz]) 334 | ) 335 | 336 | fseek f UVOffset #seek_set 337 | 338 | for b = 1 to pointamount do( 339 | if UVsize == 2 do( 340 | colora = ReadByte f #unsigned 341 | colorr = ReadByte f #unsigned 342 | colorg = ReadByte f #unsigned 343 | colorb = ReadByte f #unsigned 344 | tu = (ReadBEHalfFloat f) * 2 345 | tv = ((ReadBEHalfFloat f) * -2) + 1 346 | append Color_array [colorr, colorg, colorb] 347 | append Alpha_array colora 348 | append UV_array [tu, tv, 0] 349 | ) 350 | if UVsize == 3 do( 351 | colora = ReadByte f #unsigned 352 | colorr = ReadByte f #unsigned 353 | colorg = ReadByte f #unsigned 354 | colorb = ReadByte f #unsigned 355 | tu = (ReadBEHalfFloat f) * 2 356 | tv = ((ReadBEHalfFloat f) * -2) + 1 357 | tu2 = (ReadBEHalfFloat f) * 2 358 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 359 | append Color_array [colorr, colorg, colorb] 360 | append Alpha_array colora 361 | append UV_array [tu, tv, 0] 362 | ) 363 | if UVsize == 4 do( 364 | colora = ReadByte f #unsigned 365 | colorr = ReadByte f #unsigned 366 | colorg = ReadByte f #unsigned 367 | colorb = ReadByte f #unsigned 368 | tu = (ReadBEHalfFloat f) * 2 369 | tv = ((ReadBEHalfFloat f) * -2) + 1 370 | tu2 = (ReadBEHalfFloat f) * 2 371 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 372 | tu3 = (ReadBEHalfFloat f) * 2 373 | tv3 = ((ReadBEHalfFloat f) * -2) + 1 374 | append Color_array [colorr, colorg, colorb] 375 | append Alpha_array colora 376 | append UV_array [tu, tv, 0] 377 | ) 378 | if UVsize == 5 do( 379 | tu = (ReadBEHalfFloat f) * 2 380 | tv = ((ReadBEHalfFloat f) * -2) + 1 381 | tu2 = (ReadBEHalfFloat f) * 2 382 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 383 | tu3 = (ReadBEHalfFloat f) * 2 384 | tv3 = ((ReadBEHalfFloat f) * -2) + 1 385 | colora = ReadByte f #unsigned 386 | colorr = ReadByte f #unsigned 387 | colorg = ReadByte f #unsigned 388 | colorb = ReadByte f #unsigned 389 | tu4 = (ReadBEHalfFloat f) * 2 390 | tv4 = ((ReadBEHalfFloat f) * -2) + 1 391 | append Color_array [colorr, colorg, colorb] 392 | append Alpha_array colora 393 | append UV_array [tu4, tv4, 0] 394 | ) 395 | if UVsize == 6 do( 396 | tu = (ReadBEHalfFloat f) * 2 397 | tv = ((ReadBEHalfFloat f) * -2) + 1 398 | tu2 = (ReadBEHalfFloat f) * 2 399 | tv2 = ((ReadBEHalfFloat f) * -2) + 1 400 | tu3 = (ReadBEHalfFloat f) * 2 401 | tv3 = ((ReadBEHalfFloat f) * -2) + 1 402 | colora = ReadByte f #unsigned 403 | colorr = ReadByte f #unsigned 404 | colorg = ReadByte f #unsigned 405 | colorb = ReadByte f #unsigned 406 | tu4 = (ReadBEHalfFloat f) * 2 407 | tv4 = ((ReadBEHalfFloat f) * -2) + 1 408 | tu5 = (ReadBEHalfFloat f) * 2 409 | tv5 = ((ReadBEHalfFloat f) * -2) + 1 410 | append Color_array [colorr, colorg, colorb] 411 | append Alpha_array colora 412 | append UV_array [tu4, tv4, 0] 413 | ) 414 | ) 415 | 416 | seek = readlong f 417 | while seek == 0 and seek != undefined do(seek = readlong f) 418 | fseek f -0x04 #seek_cur 419 | 420 | UVOffset = (ftell f as integer) 421 | 422 | if BoneCount != 0 do( 423 | fseek f BoneWeightJump #seek_set 424 | for b = 1 to Vert_array.count do( 425 | Weight1 = (readbyte f #unsigned as float / 255) 426 | Bone1 = #() 427 | IDB1 = (readbyte f #unsigned) + 1 428 | ID1 = IDB1 + NodeThing1 429 | 430 | if IDB1 >= (NodeThing3 + 1) do( 431 | ID1 = IDB1 + NodeThing2 - NodeThing3 432 | ) 433 | 434 | for c = 1 to NodeID_array.count do( 435 | if ID1 == NodeID_array[c] do( 436 | Bone1 = c 437 | ) 438 | ) 439 | 440 | Weight2 = (readbyte f #unsigned as float / 255) 441 | Bone2 = #() 442 | IDB2 = (readbyte f #unsigned) + 1 443 | ID2 = IDB2 + NodeThing1 444 | 445 | if IDB2 >= (NodeThing3 + 1) do( 446 | ID2 = IDB2 + NodeThing2 - NodeThing3 447 | ) 448 | 449 | for c = 1 to NodeID_array.count do( 450 | if ID2 == NodeID_array[c] do( 451 | Bone2 = c 452 | ) 453 | ) 454 | 455 | Weight3 = (readbyte f #unsigned as float / 255) 456 | IDB3 = (readbyte f #unsigned) + 1 457 | ID3 = IDB3 + NodeThing1 458 | Bone3 = #() 459 | 460 | if IDB3 >= (NodeThing3 + 1) do( 461 | ID3 = IDB3 + NodeThing2 - NodeThing3 462 | ) 463 | for c = 1 to NodeID_array.count do( 464 | if ID3 == NodeID_array[c] do( 465 | Bone3 = c 466 | ) 467 | ) 468 | 469 | Weight4 = (readbyte f #unsigned as float / 255) 470 | IDB4 = (readbyte f #unsigned) + 1 471 | ID4 = IDB4 + NodeThing1 472 | Bone4 = #() 473 | 474 | if IDB4 >= (NodeThing3 + 1) do( 475 | ID4 = IDB4 + NodeThing2 - NodeThing3 476 | ) 477 | for c = 1 to NodeID_array.count do( 478 | if ID4 == NodeID_array[c] do( 479 | Bone4 = c 480 | ) 481 | ) 482 | append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 483 | --append B1_array (Bone_Info_Struct Bone1:ID1 Bone2:ID2 Bone3:ID3 Bone4:ID4) 484 | --append B1_array (Bone_Info_Struct Bone1:IDB1 Bone2:IDB2 Bone3:IDB3 Bone4:IDB4) 485 | append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 486 | ) 487 | 488 | for b = 1 to W1_array.count Do ( 489 | w = (weight_data boneids:#() weights:#()) 490 | maxweight = 0 491 | 492 | if(W1_array[b].Weight1 != 0) then 493 | maxweight = maxweight + W1_array[b].Weight1 494 | if(W1_array[b].Weight2 != 0) then 495 | maxweight = maxweight + W1_array[b].Weight2 496 | if(W1_array[b].Weight3 != 0) then 497 | maxweight = maxweight + W1_array[b].Weight3 498 | if(W1_array[b].Weight4 != 0) then 499 | maxweight = maxweight + W1_array[b].Weight4 500 | 501 | if(maxweight != 0) then 502 | ( 503 | if(W1_array[b].Weight1 != 0) then 504 | ( 505 | w1 = W1_array[b].Weight1 as float 506 | append w.boneids (B1_array[b].Bone1) 507 | append w.weights (w1) 508 | ) 509 | if(W1_array[b].Weight2 != 0) then 510 | ( 511 | w2 = W1_array[b].Weight2 as float 512 | append w.boneids (B1_array[b].Bone2) 513 | append w.weights (w2) 514 | ) 515 | if(W1_array[b].Weight3 != 0) then 516 | ( 517 | w3 = W1_array[b].Weight3 as float 518 | append w.boneids (B1_array[b].Bone3) 519 | append w.weights (w3) 520 | ) 521 | if(W1_array[b].Weight4 != 0) then 522 | ( 523 | w4 = W1_array[b].Weight4 as float 524 | append w.boneids (B1_array[b].Bone4) 525 | append w.weights (w4) 526 | ) 527 | ) 528 | append Weight_array w 529 | ) 530 | 531 | ) 532 | 533 | mat = standardMaterial() 534 | mat.name = MatName_array[matgroupnum] 535 | mat.showinviewport = true 536 | mat.twosided = false 537 | tm = Bitmaptexture filename:(p + "/textures/" + SubMatName_array[matgroupnum] + ".dds") 538 | tm.alphasource = 2 539 | mat.diffuseMap = tm 540 | 541 | msh = mesh vertices:Vert_array faces:Face_array 542 | msh.numTVerts = Vert_array.count 543 | -- Coloring stuff. Uncomment if you want stage models to be tutti-frutti. 544 | -- setNumCPVVerts msh msh.numTVerts 545 | -- setCVertMode msh true 546 | -- setShadeCVerts msh true 547 | -- defaultVCFaces msh 548 | -- for p = 1 to Color_array.count do( 549 | -- setvertcolor msh p Color_array[p] 550 | -- ) 551 | buildTVFaces msh 552 | for j = 1 to Vert_array.count do setTVert msh j UV_array[j] 553 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 554 | msh.name = PolygonName 555 | msh.material = mat 556 | max modify mode 557 | select msh 558 | 559 | --set smoothing group of all faces to 1 to get one normal per vertex 560 | for face = 1 to msh.numfaces do setFaceSmoothGroup msh face 1 561 | --set normals via edit normals modifier 562 | 563 | -- If there are in fact normals, then uncomment this. 564 | -- addmodifier msh (Edit_Normals ()) ui:off 565 | -- msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 566 | -- EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 567 | -- EN_setNormal = msh.Edit_Normals.SetNormal 568 | -- normID = #{} 569 | -- --apply normals 570 | -- for v = 1 to Normal_array.count do 571 | -- ( 572 | -- free normID 573 | -- EN_convertVS #{v} &normID 574 | -- for id in normID do EN_setNormal id Normal_array[v] 575 | -- ) 576 | 577 | if BoneCount != 0 do( 578 | skinMod = skin () 579 | addModifier msh skinMod 580 | for i = 1 to BoneCount do 581 | ( 582 | maxbone = getnodebyname BNArr[i].name 583 | if i != BoneCount then 584 | skinOps.addBone skinMod maxbone 0 585 | else 586 | skinOps.addBone skinMod maxbone 1 587 | 588 | ) 589 | 590 | modPanel.setCurrentObject skinMod 591 | 592 | for i = 1 to Weight_array.count do ( 593 | w = Weight_array[i] 594 | bi = #() --bone index array 595 | wv = #() --weight value array 596 | 597 | for j = 1 to w.boneids.count do 598 | ( 599 | boneid = w.boneids[j] 600 | weight = w.weights[j] 601 | append bi boneid 602 | append wv weight 603 | ) 604 | 605 | skinOps.ReplaceVertexWeights skinMod i bi wv 606 | 607 | ) 608 | ) 609 | 610 | ) 611 | 612 | fseek f headerjump #seek_set 613 | 614 | ) 615 | ) 616 | 617 | fclose f -------------------------------------------------------------------------------- /Scripts/MegaManPSP_MDL.ms: -------------------------------------------------------------------------------- 1 | -- Mega Man Powered Up / Mega Man Maverick Hunter X model importer by Random Talking Bush. 2 | 3 | fname = getOpenFileName \ 4 | caption:"Mega Man PSP file" \ 5 | types:"Mega Man PSP models (*.MDL)|*.MDL" \ 6 | historyCategory:"MegaManPSP" 7 | if fname != undefined do( 8 | f = fopen fname "rb" 9 | clearlistener() 10 | 11 | for a = 1 to 1 do ( 12 | Bone_Matrix_Array = #() 13 | BoneParent_array = #() 14 | BoneArray = #() 15 | 16 | struct Bone_Info_Struct 17 | ( 18 | Bone1, Bone2, Bone3, Bone4, Bone5, Bone6, Bone7, Bone8 19 | ) 20 | struct Weight_Info_Struct 21 | ( 22 | Weight1, Weight2, Weight3, Weight4, Weight5, Weight6, Weight7, Weight8 23 | ) 24 | struct weight_data 25 | ( 26 | boneids, weights 27 | ) 28 | 29 | fseek f 0x00 #seek_set 30 | 31 | polygroups = readshort f #unsigned 32 | unknown1 = readshort f #unsigned 33 | unknown2 = readshort f #unsigned 34 | unknown3 = readshort f #unsigned 35 | unknown4 = readshort f #unsigned 36 | unknown5 = readshort f #unsigned 37 | boneoffset = readlong f #unsigned 38 | 39 | if boneoffset != 0 do( 40 | 41 | fseek f boneoffset #seek_set 42 | boneunknown1 = readlong f #unsigned 43 | boneunknown2 = readlong f #unsigned 44 | boneheaderlength = readlong f #unsigned 45 | BoneCount = readlong f #unsigned 46 | for b = 1 to BoneCount do( 47 | boneparent = (readbyte f #unsigned) + 1 48 | if boneparent == 256 do(boneparent = 0) 49 | append BoneParent_array boneparent 50 | ) 51 | fseek f (boneoffset + boneheaderlength) #seek_set 52 | 53 | for b = 1 to BoneCount do( 54 | BoneName = "Bone" + (b as string) 55 | BoneParent = BoneParent_array[b] 56 | BoneTX = readfloat f; BoneTY = readfloat f; BoneTZ = readfloat f; BoneTQ = readfloat f 57 | tfm = matrix3 [1,0,0] [0,1,0] [0,0,1] [BoneTX,BoneTY,BoneTZ] 58 | if (getNodeByName BoneName) != undefined do ( 59 | append BoneArray (getNodeByName BoneName) 60 | ) 61 | if (getNodeByName BoneName) == undefined do ( 62 | if (BoneParent != 0) do ( 63 | tfm = tfm * BoneArray[(boneparent)].objecttransform 64 | ) 65 | ) 66 | append Bone_Matrix_array tfm 67 | 68 | newBone = bonesys.createbone \ 69 | tfm.row4 \ 70 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 71 | (normalize tfm.row3) 72 | newBone.name = BoneName 73 | newBone.width = 0.01 74 | newBone.height = 0.01 75 | newBone.transform = tfm 76 | newBone.setBoneEnable false 0 77 | newBone.wirecolor = yellow 78 | newbone.showlinks = true 79 | newBone.pos.controller = TCB_position () 80 | newBone.rotation.controller = TCB_rotation () 81 | if (BoneParent != 0) then 82 | newBone.parent = BoneArray[(BoneParent)] 83 | append BoneArray newBone 84 | ) 85 | 86 | ) 87 | 88 | fseek f 0x10 #seek_set 89 | for p = 1 to polygroups do( 90 | fseek f 0x20 #seek_cur 91 | polyoffset = readlong f #unsigned 92 | polygroupplus = readshort f #unsigned 93 | fseek f 0x26 #seek_cur 94 | polytotal = readlong f #unsigned 95 | hopto = (ftell f) 96 | 97 | for g = 1 to polygroupplus do( 98 | PolyCount_array = #() 99 | StartDirection_array = #() 100 | Vert_array = #() 101 | Normal_array = #() 102 | UV_array = #() 103 | Face_array = #() 104 | W1_array = #() 105 | B1_array = #() 106 | Weight_array = #() 107 | 108 | fseek f polyoffset #seek_set 109 | vertextotal = readshort f #unsigned 110 | textureID = readshort f #unsigned + 1 111 | vertexstart = readlong f #unsigned 112 | polystart = readlong f #unsigned 113 | vertexblank = readlong f #unsigned 114 | Bone1 = readbyte f #unsigned + 1 115 | Bone2 = readbyte f #unsigned + 1 116 | Bone3 = readbyte f #unsigned + 1 117 | Bone4 = readbyte f #unsigned + 1 118 | Bone5 = readbyte f #unsigned + 1 119 | Bone6 = readbyte f #unsigned + 1 120 | Bone7 = readbyte f #unsigned + 1 121 | Bone8 = readbyte f #unsigned + 1 122 | if Bone1 == 0 or Bone1 == 256 do(Bone1 = 1) 123 | if Bone2 == 0 or Bone2 == 256 do(Bone2 = 1) 124 | if Bone3 == 0 or Bone3 == 256 do(Bone3 = 1) 125 | if Bone4 == 0 or Bone4 == 256 do(Bone4 = 1) 126 | if Bone5 == 0 or Bone5 == 256 do(Bone5 = 1) 127 | if Bone6 == 0 or Bone6 == 256 do(Bone6 = 1) 128 | if Bone7 == 0 or Bone7 == 256 do(Bone7 = 1) 129 | if Bone8 == 0 or Bone8 == 256 do(Bone8 = 1) 130 | fseek f 0x04 #seek_cur 131 | polyoffset = (ftell f) 132 | 133 | fseek f (polystart + 0x18) #seek_set 134 | 135 | startdirectionvar = 1 136 | polycheck = readbyte f #unsigned 137 | fseek f -0x01 #seek_cur 138 | 139 | if polycheck > 1 do( 140 | polyfailsafe = 1 141 | ) 142 | 143 | polycounttotal = 0 144 | while polycounttotal < vertextotal do( 145 | if polyfailsafe != 1 do( 146 | startdirectionvar = readbyte f #unsigned 147 | if startdirectionvar == 0 do(startdirectionvar = -1) 148 | fseek f 0x03 #seek_cur 149 | ) 150 | append StartDirection_array (startdirectionvar * -1) 151 | polycount = readshort f #unsigned 152 | fseek f 0x02 #seek_cur 153 | polycounttotal = polycounttotal + polycount 154 | append PolyCount_array polycount 155 | ) 156 | 157 | fseek f vertexstart #seek_set 158 | 159 | for v = 1 to vertextotal do( 160 | if boneoffset != 0 do( 161 | Weight1 = (readbyte f #unsigned as float) / 128 162 | Weight2 = (readbyte f #unsigned as float) / 128 163 | Weight3 = (readbyte f #unsigned as float) / 128 164 | Weight4 = (readbyte f #unsigned as float) / 128 165 | Weight5 = (readbyte f #unsigned as float) / 128 166 | Weight6 = (readbyte f #unsigned as float) / 128 167 | Weight7 = (readbyte f #unsigned as float) / 128 168 | Weight8 = (readbyte f #unsigned as float) / 128 169 | ) 170 | tu = readshort f as float / 128 171 | tv = ((readshort f as float / 128) * -1) + 1 172 | nx = readshort f as float / 32768 173 | ny = readshort f as float / 32768 174 | nz = readshort f as float / 32768 175 | nq = readshort f as float / 32768 176 | vx = readfloat f 177 | vy = readfloat f 178 | vz = readfloat f 179 | append Vert_array [vx,vy,vz] 180 | append Normal_array [nx,ny,nz] 181 | append UV_array [tu,tv,0] 182 | if boneoffset != 0 do( 183 | append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4 Weight5:Weight5 Weight6:Weight6 Weight7:Weight7 Weight8:Weight8) 184 | append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4 Bone5:Bone5 Bone6:Bone6 Bone7:Bone7 Bone8:Bone8) 185 | ) 186 | ) 187 | 188 | VertAdd = 1 189 | 190 | for o = 1 to PolyCount_array.count do( 191 | StartDirection = StartDirection_array[o] 192 | f1 = VertAdd 193 | f2 = VertAdd + 1 194 | f3 = VertAdd + 1 195 | IndexCounter = 2 196 | FaceDirection = StartDirection 197 | Do ( 198 | f3 += 1 199 | IndexCounter = IndexCounter +1 200 | if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then ( 201 | if FaceDirection > 0 then append Face_Array [f1,f2,f3] 202 | else append Face_Array [f1,f3,f2] 203 | ) 204 | FaceDirection *= -1 205 | f1 = f2 206 | f2 = f3 207 | ) while IndexCounter != PolyCount_Array[o] 208 | VertAdd = VertAdd + PolyCount_Array[o] 209 | ) 210 | 211 | if boneoffset != 0 do( 212 | 213 | for b = 1 to W1_array.count Do ( 214 | w = (weight_data boneids:#() weights:#()) 215 | maxweight = 0 216 | 217 | if(W1_array[b].Weight1 != 0) then 218 | maxweight = maxweight + W1_array[b].Weight1 219 | if(W1_array[b].Weight2 != 0) then 220 | maxweight = maxweight + W1_array[b].Weight2 221 | if(W1_array[b].Weight3 != 0) then 222 | maxweight = maxweight + W1_array[b].Weight3 223 | if(W1_array[b].Weight4 != 0) then 224 | maxweight = maxweight + W1_array[b].Weight4 225 | if(W1_array[b].Weight5 != 0) then 226 | maxweight = maxweight + W1_array[b].Weight5 227 | if(W1_array[b].Weight6 != 0) then 228 | maxweight = maxweight + W1_array[b].Weight6 229 | if(W1_array[b].Weight7 != 0) then 230 | maxweight = maxweight + W1_array[b].Weight7 231 | if(W1_array[b].Weight8 != 0) then 232 | maxweight = maxweight + W1_array[b].Weight8 233 | 234 | if(maxweight != 0) then 235 | ( 236 | if(W1_array[b].Weight1 != 0) then 237 | ( 238 | w1 = W1_array[b].Weight1 as float 239 | append w.boneids (B1_array[b].Bone1) 240 | append w.weights (w1) 241 | ) 242 | if(W1_array[b].Weight2 != 0) then 243 | ( 244 | w2 = W1_array[b].Weight2 as float 245 | append w.boneids (B1_array[b].Bone2) 246 | append w.weights (w2) 247 | ) 248 | if(W1_array[b].Weight3 != 0) then 249 | ( 250 | w3 = W1_array[b].Weight3 as float 251 | append w.boneids (B1_array[b].Bone3) 252 | append w.weights (w3) 253 | ) 254 | if(W1_array[b].Weight4 != 0) then 255 | ( 256 | w4 = W1_array[b].Weight4 as float 257 | append w.boneids (B1_array[b].Bone4) 258 | append w.weights (w4) 259 | ) 260 | if(W1_array[b].Weight5 != 0) then 261 | ( 262 | w5 = W1_array[b].Weight5 as float 263 | append w.boneids (B1_array[b].Bone5) 264 | append w.weights (w5) 265 | ) 266 | if(W1_array[b].Weight6 != 0) then 267 | ( 268 | w6 = W1_array[b].Weight6 as float 269 | append w.boneids (B1_array[b].Bone6) 270 | append w.weights (w6) 271 | ) 272 | if(W1_array[b].Weight7 != 0) then 273 | ( 274 | w7 = W1_array[b].Weight7 as float 275 | append w.boneids (B1_array[b].Bone7) 276 | append w.weights (w7) 277 | ) 278 | if(W1_array[b].Weight8 != 0) then 279 | ( 280 | w8 = W1_array[b].Weight8 as float 281 | append w.boneids (B1_array[b].Bone8) 282 | append w.weights (w8) 283 | ) 284 | ) 285 | append Weight_array w 286 | ) 287 | 288 | ) 289 | 290 | msh = mesh vertices:Vert_array faces:Face_array 291 | msh.numTVerts = Vert_array.count 292 | buildTVFaces msh 293 | msh.name = (TextureID as string) 294 | for j = 1 to UV_array.count do setTVert msh j UV_array[j] 295 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 296 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 297 | max modify mode 298 | select msh 299 | 300 | addmodifier msh (Edit_Normals ()) ui:off 301 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 302 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 303 | EN_setNormal = msh.Edit_Normals.SetNormal 304 | normID = #{} 305 | 306 | for v = 1 to Normal_array.count do( 307 | free normID 308 | EN_convertVS #{v} &normID 309 | for id in normID do EN_setNormal id Normal_array[v] 310 | ) 311 | 312 | if boneoffset != 0 do( 313 | 314 | skinMod = skin () 315 | addModifier msh skinMod 316 | for i = 1 to BoneCount do 317 | ( 318 | maxbone = getnodebyname BoneArray[i].name 319 | if i != BoneCount then 320 | skinOps.addBone skinMod maxbone 0 321 | else 322 | skinOps.addBone skinMod maxbone 1 323 | 324 | ) 325 | 326 | modPanel.setCurrentObject skinMod 327 | 328 | for i = 1 to Weight_array.count do ( 329 | w = Weight_array[i] 330 | bi = #() --bone index array 331 | wv = #() --weight value array 332 | 333 | for j = 1 to w.boneids.count do 334 | ( 335 | boneid = w.boneids[j] 336 | weight = w.weights[j] 337 | append bi boneid 338 | append wv weight 339 | ) 340 | 341 | skinOps.ReplaceVertexWeights skinMod i bi wv 342 | 343 | ) 344 | 345 | ) 346 | 347 | ) 348 | 349 | fseek f hopto #seek_set 350 | 351 | ) 352 | ) 353 | 354 | gc() 355 | fclose f 356 | 357 | ) -------------------------------------------------------------------------------- /Scripts/NDCubeWiiU_BNFM.ms: -------------------------------------------------------------------------------- 1 | -- ND Cube model importer (Animal Crossing: amiibo Festival, Mario Party 10 and Wii Party U) by Random Talking Bush. 2 | -- If there are any problems, please contact me at The VG Resource (Random Talking Bush), Steam, Twitter or Tumblr (RandomTBush) so I can fix it up ASAP. 3 | -- Last modified January 10th, 2016. 4 | 5 | fname = getOpenFileName \ 6 | caption:"ND Cube BNFM file" \ 7 | types:"ND Cube Wii U Model (*.BNFM)|*.BNFM" \ 8 | historyCategory:"MarioParty10" 9 | 10 | fn convertTo32 input16 = ( 11 | inputAsInt = input16 12 | sign = bit.get inputAsInt 16 13 | exponent = (bit.shift (bit.and inputAsInt (bit.hexasint "7C00")) -10) as integer - 16 14 | fraction = bit.and inputAsInt (bit.hexasint "03FF") 15 | if sign==true then sign = 1 else sign = 0 16 | exponentF = exponent + 127 17 | --Output 32 bit integer representing a 32 bit float 18 | outputAsFloat = bit.or (bit.or (bit.shift fraction 13) (bit.shift exponentF 23)) (bit.shift sign 31) 19 | --Output Check 20 | return bit.intasfloat outputasfloat 21 | ) 22 | 23 | fn floatSwap2 f = 24 | ( 25 | i = bit.floatAsInt f 26 | h = bit.intashex i 27 | while h.count < 8 do h = "0" + h 28 | 29 | s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2) 30 | bit.intAsFloat (bit.hexasint s) 31 | ) 32 | 33 | fn ReadBEword fstream = ( 34 | return (bit.swapBytes (readshort fstream #unsigned) 1 2) 35 | ) 36 | 37 | fn ReadBElong fstream = ( 38 | long = readlong fstream 39 | long = bit.swapBytes long 1 4 40 | long = bit.swapBytes long 2 3 41 | return long 42 | ) 43 | 44 | fn ReadBEHalfFloat Fstream = ( 45 | local BH = readByte Fstream #unsigned 46 | local BL = readByte Fstream #unsigned 47 | local N = BH*256 + BL 48 | local S = floor((mod N 65536) / 32768) 49 | local Ef = floor((mod N 32768) / 1024) 50 | local M = mod N 1024 51 | if (Ef==0)AND(M==0) then return ( (-1.0)^S * 0.0 ) 52 | if (Ef==0)AND(M!=0) then return ( (-1.0)^S * 2.0^-14 * (M / 2.0^10) ) 53 | if (Ef>0)AND(Ef<31) then return ( (-1.0)^S * 2.0^(Ef-15) * (1 + M/2.0^10) ) 54 | if (Ef==31)AND(M==0) then return ( (-1.0)^S * 1/0.0 ) 55 | if (Ef==31)AND(M!=0) then return 0 --hack-- should be #inf 56 | ) 57 | 58 | fn ReadBEfloat fstream = ( 59 | return floatSwap2(readfloat fstream) 60 | ) 61 | 62 | if fname != undefined do( 63 | t = getFilenameType fname 64 | p = getFilenamePath fname 65 | h = getFilenameFile fname 66 | m = fopen fname "rb" 67 | clearlistener() 68 | for a = 1 to 1 do ( 69 | BoneName_array = #() 70 | BoneParent_array = #() 71 | BNArr = #() 72 | String_array = #() 73 | FaceStart_array = #() 74 | PolyStart_array = #() 75 | VertStart_array = #() 76 | BoneChartStart_array = #() 77 | PolyNameStart_array = #() 78 | FaceCount_array = #() 79 | VertCount_array = #() 80 | PolyGroupCount_array = #() 81 | MatNameStart_array = #() 82 | Mat2NameStart_array = #() 83 | MatNum_array = #() 84 | PolyName_array = #() 85 | 86 | struct Bone_Info_Struct 87 | ( 88 | Bone1, Bone2, Bone3, Bone4 89 | ) 90 | struct Weight_Info_Struct 91 | ( 92 | Weight1, Weight2, Weight3, Weight4 93 | ) 94 | struct weight_data 95 | ( 96 | boneids, weights 97 | ) 98 | fseek m 0x00 #seek_fcur 99 | 100 | HeaderCheck = readBElong m 101 | HeaderStart = readBElong m 102 | Blank = readBElong m 103 | FaceStart = readBElong m 104 | 105 | FaceTotal = (readBElong m) / 6 106 | VertCount = readBElong m / 44 107 | BoneChartStart = readBElong m 108 | Unknown = readBElong m 109 | 110 | VertStart = readBElong m 111 | FaceStartB = readBElong m 112 | Unknown = readBElong m 113 | PolyNameCount = readBElong m 114 | 115 | BoneCount = readBElong m 116 | PolyCount = readBElong m 117 | MatCount = readBElong m / 6 118 | PolyNameCountB = readBElong m 119 | 120 | PolyNameCountC = readBElong m 121 | BoneChartCount = readBElong m 122 | BoneChartCountB = readBElong m 123 | StringCount = readBElong m 124 | 125 | UnknownStart = readBElong m 126 | Unknown = readBElong m 127 | BoneStart = readBElong m 128 | PolyInfoStart = readBElong m 129 | 130 | MaterialStart = readBElong m 131 | UnknownStart = readBElong m 132 | Material2Start = readBElong m 133 | BoneMatrixStart = readBElong m 134 | 135 | BoneMatrixStart = readBElong m 136 | StringStart = readBElong m 137 | 138 | fseek m BoneStart #seek_set 139 | 140 | for x = 1 to BoneCount do( 141 | BoneParent = -1 142 | BoneNameStart = readBElong m 143 | BoneReturn = ftell m 144 | fseek m BoneNameStart #seek_set 145 | BoneName = readstring m 146 | append BoneName_array BoneName 147 | fseek m BoneReturn #seek_set 148 | fseek m 0x04 #seek_cur 149 | BoneParentNameStart = readBElong m 150 | BoneReturn = ftell m 151 | fseek m BoneParentNameStart #seek_set 152 | BoneParentName = readstring m 153 | fseek m BoneReturn #seek_set 154 | for y = 1 to BoneName_array.count do( 155 | if BoneParentName == BoneName_array[y] do(BoneParent = y) 156 | ) 157 | fseek m 0x18 #seek_cur 158 | PosX = readBEfloat m 159 | PosY = readBEfloat m 160 | PosZ = readBEfloat m 161 | ScaleX = readBEfloat m 162 | ScaleY = readBEfloat m 163 | ScaleZ = readBEfloat m 164 | fseek m 0x14 #seek_cur 165 | m11 = readBEfloat m 166 | m12 = readBEfloat m 167 | m13 = readBEfloat m 168 | m14 = readBEfloat m 169 | m21 = readBEfloat m 170 | m22 = readBEfloat m 171 | m23 = readBEfloat m 172 | m24 = readBEfloat m 173 | m31 = readBEfloat m 174 | m32 = readBEfloat m 175 | m33 = readBEfloat m 176 | m34 = readBEfloat m 177 | m41 = readBEfloat m 178 | m42 = readBEfloat m 179 | m43 = readBEfloat m 180 | m44 = readBEfloat m 181 | m51 = readBEfloat m 182 | m52 = readBEfloat m 183 | m53 = readBEfloat m 184 | m54 = readBEfloat m 185 | m61 = readBEfloat m 186 | m62 = readBEfloat m 187 | m63 = readBEfloat m 188 | m64 = readBEfloat m 189 | m71 = readBEfloat m 190 | m72 = readBEfloat m 191 | m73 = readBEfloat m 192 | m74 = readBEfloat m 193 | m81 = readBEfloat m 194 | m82 = readBEfloat m 195 | m83 = readBEfloat m 196 | m84 = readBEfloat m 197 | fseek m 0x0C #seek_cur 198 | tfm = inverse(matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]) 199 | tfm.row4 = [PosX,PosY,PosZ] 200 | 201 | if (getNodeByName BoneName) != undefined do ( 202 | append BNArr (getNodeByName BoneName) 203 | ) 204 | if (getNodeByName BoneName) == undefined do ( 205 | if (BoneParent != -1) do ( 206 | tfm = tfm * BNArr[(BoneParent)].objecttransform 207 | ) 208 | ) 209 | 210 | newBone = bonesys.createbone \ 211 | tfm.row4 \ 212 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 213 | (normalize tfm.row3) 214 | newBone.name = BoneName 215 | newBone.width = 0.01 216 | newBone.height = 0.01 217 | newBone.transform = tfm 218 | newBone.setBoneEnable false 0 219 | newBone.wirecolor = yellow 220 | newbone.showlinks = true 221 | newBone.pos.controller = TCB_position () 222 | newBone.rotation.controller = TCB_rotation () 223 | if (BoneParent != -1) then 224 | newBone.parent = BNArr[(BoneParent)] 225 | append BNArr newBone 226 | ) 227 | 228 | fseek m PolyInfoStart #seek_set 229 | for x = 1 to PolyCount do( 230 | PolyNameStart = readBElong m 231 | fseek m 0x04 #seek_cur 232 | BoneChartStart = readBElong m 233 | PolyStart = readBElong m 234 | fseek m 0x08 #seek_cur 235 | FaceCount = readBElong m / 3 236 | PolyVertCount = readBElong m 237 | BoneIDCount = readBElong m 238 | MatID = readBElong m 239 | fseek m 0x08 #seek_cur 240 | append PolyNameStart_array PolyNameStart 241 | append BoneChartStart_array BoneChartStart 242 | append PolyStart_array PolyStart 243 | append FaceCount_array FaceCount 244 | append VertCount_array PolyVertCount 245 | ) 246 | 247 | fseek m MaterialStart #seek_set 248 | for x = 1 to MatCount do( 249 | MatNameStart = readBElong m 250 | fseek m 0x110 #seek_cur 251 | Mat2NameStart = readBElong m 252 | fseek m 0x110 #seek_cur 253 | append MatNameStart_array MatNameStart 254 | append Mat2NameStart_array Mat2NameStart 255 | ) 256 | 257 | fseek m Material2Start #seek_set 258 | for x = 1 to MatCount do( 259 | PolyNameStart = readBElong m 260 | PolyReturn = ftell m 261 | fseek m PolyNameStart #seek_set 262 | PolyName = readstring m 263 | fseek m PolyReturn #seek_set 264 | fseek m 0x38 #seek_cur 265 | append PolyName_array PolyName 266 | ) 267 | 268 | VertReturn = VertStart 269 | Vert_array = #() 270 | Normal_array = #() 271 | UV_array = #() 272 | UV2_array = #() 273 | B0_array = #() 274 | W1_array = #() 275 | 276 | for z = 1 to PolyCount do( 277 | B1_array = #() 278 | Face_array = #() 279 | Color_array = #() 280 | Weight_array = #() 281 | BoneChart_array = #() 282 | 283 | fseek m BoneChartStart_array[z] #seek_set 284 | 285 | for x = 1 to BoneChartCount do( 286 | BoneID = readBElong m + 1 287 | append BoneChart_array BoneID 288 | ) 289 | 290 | if VertCount_array[z] != 0 do( 291 | Vert_array = #() 292 | Normal_array = #() 293 | UV_array = #() 294 | UV2_array = #() 295 | B0_array = #() 296 | W1_array = #() 297 | fseek m VertReturn #seek_set 298 | for x = 1 to VertCount_array[z] do( 299 | vx = readBEfloat m 300 | vy = readBEfloat m 301 | vz = readBEfloat m 302 | unknown1 = readBEfloat m 303 | colorr = readbyte m #unsigned 304 | colorg = readbyte m #unsigned 305 | colorb = readbyte m #unsigned 306 | colora = readbyte m #unsigned 307 | tu = readBEhalffloat m 308 | tv = readBEhalffloat m 309 | tu2 = readBEhalffloat m 310 | tv2 = readBEhalffloat m 311 | Bone1 = readbyte m #unsigned + 1 312 | Bone2 = readbyte m #unsigned + 1 313 | Bone3 = readbyte m #unsigned + 1 314 | Bone4 = readbyte m #unsigned + 1 315 | Weight1 = (readbyte m #unsigned as float) / 255 316 | Weight2 = (readbyte m #unsigned as float) / 255 317 | Weight3 = (readbyte m #unsigned as float) / 255 318 | Weight4 = (readbyte m #unsigned as float) / 255 319 | unknown2 = readBEfloat m 320 | unknown3 = readBEfloat m 321 | 322 | append Vert_array[vx, vy, vz] 323 | -- append Normal_array[nx, ny, nz] 324 | append UV_array[tu, tv, 0] 325 | append UV2_array[tu2, tv2, 0] 326 | append Color_Array[colorr,colorg,colorb] 327 | append B0_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 328 | append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 329 | ) 330 | VertReturn = (ftell m) 331 | ) 332 | 333 | fseek m FaceStart #seek_set 334 | fseek m PolyStart_array[z] #seek_cur 335 | 336 | for x = 1 to FaceCount_array[z] do( 337 | fa = (readBEword m + 1) 338 | fb = (readBEword m + 1) 339 | fc = (readBEword m + 1) 340 | append Face_array[fa, fb, fc] 341 | ) 342 | 343 | for x = 1 to Vert_array.count do( 344 | ImproperBone1 = B0_array[x].Bone1 345 | ImproperBone2 = B0_array[x].Bone2 346 | ImproperBone3 = B0_array[x].Bone3 347 | ImproperBone4 = B0_array[x].Bone4 348 | Bone1 = BoneChart_array[ImproperBone1] 349 | Bone2 = BoneChart_array[ImproperBone2] 350 | Bone3 = BoneChart_array[ImproperBone3] 351 | Bone4 = BoneChart_array[ImproperBone4] 352 | if Bone1 == undefined or Bone1 > BoneCount do(Bone1 = 1) 353 | if Bone2 == undefined or Bone2 > BoneCount do(Bone2 = 1) 354 | if Bone3 == undefined or Bone3 > BoneCount do(Bone3 = 1) 355 | if Bone4 == undefined or Bone4 > BoneCount do(Bone4 = 1) 356 | append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 357 | ) 358 | 359 | for b = 1 to W1_array.count Do ( 360 | w = (weight_data boneids:#() weights:#()) 361 | maxweight = 0 362 | 363 | if(W1_array[b].Weight1 != 0) then 364 | maxweight = maxweight + W1_array[b].Weight1 365 | if(W1_array[b].Weight2 != 0) then 366 | maxweight = maxweight + W1_array[b].Weight2 367 | if(W1_array[b].Weight3 != 0) then 368 | maxweight = maxweight + W1_array[b].Weight3 369 | if(W1_array[b].Weight4 != 0) then 370 | maxweight = maxweight + W1_array[b].Weight4 371 | 372 | if(maxweight != 0) then 373 | ( 374 | if(W1_array[b].Weight1 != 0) then 375 | ( 376 | w1 = W1_array[b].Weight1 as float 377 | append w.boneids (B1_array[b].Bone1) 378 | append w.weights (w1) 379 | ) 380 | if(W1_array[b].Weight2 != 0) then 381 | ( 382 | w2 = W1_array[b].Weight2 as float 383 | append w.boneids (B1_array[b].Bone2) 384 | append w.weights (w2) 385 | ) 386 | if(W1_array[b].Weight3 != 0) then 387 | ( 388 | w3 = W1_array[b].Weight3 as float 389 | append w.boneids (B1_array[b].Bone3) 390 | append w.weights (w3) 391 | ) 392 | if(W1_array[b].Weight4 != 0) then 393 | ( 394 | w4 = W1_array[b].Weight4 as float 395 | append w.boneids (B1_array[b].Bone4) 396 | append w.weights (w4) 397 | ) 398 | ) 399 | append Weight_array w 400 | ) 401 | 402 | MatID = 1 403 | fseek m PolyNameStart_array[z] #seek_set 404 | PolyName = readstring m 405 | for y = 1 to PolyNameCount do( 406 | if PolyName == PolyName_array[y] do(MatID = y) 407 | ) 408 | fseek m MatNameStart_array[MatID] #seek_set 409 | MatName = readstring m 410 | mat = standardMaterial() 411 | mat.name = MatName 412 | mat.showinviewport = true 413 | mat.twosided = false 414 | tm = Bitmaptexture filename:(p + MatName + ".dds") 415 | tm.alphasource = 2 416 | mat.diffuseMap = tm 417 | msh = mesh vertices:Vert_array faces:Face_array 418 | msh.material = mat 419 | msh.numTVerts = Vert_array.count 420 | buildTVFaces msh 421 | msh.name = PolyName 422 | for j = 1 to UV_array.count do setTVert msh j UV_array[j] 423 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 424 | for j = 1 to Normal_array.count do setNormal msh j Normal_array[j] 425 | max modify mode 426 | select msh 427 | 428 | for face = 1 to msh.numfaces do setFaceSmoothGroup msh face 1 429 | 430 | -- select msh 431 | -- addmodifier msh (Edit_Normals ()) ui:off 432 | -- msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 433 | -- EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 434 | -- EN_setNormal = msh.Edit_Normals.SetNormal 435 | -- normID = #{} 436 | -- --apply normals 437 | -- for v = 1 to Normal_array.count do 438 | -- ( 439 | -- free normID 440 | -- EN_convertVS #{v} &normID 441 | -- for id in normID do EN_setNormal id Normal_array[v] 442 | -- ) 443 | 444 | if BoneCount > 0 do( 445 | skinMod = skin () 446 | addModifier msh skinMod 447 | for i = 1 to BoneCount do 448 | ( 449 | maxbone = getnodebyname BNArr[i].name 450 | if i != BoneCount then 451 | skinOps.addBone skinMod maxbone 0 452 | else 453 | skinOps.addBone skinMod maxbone 1 454 | 455 | ) 456 | 457 | modPanel.setCurrentObject skinMod 458 | 459 | for i = 1 to Weight_array.count do ( 460 | w = Weight_array[i] 461 | bi = #() --bone index array 462 | wv = #() --weight value array 463 | 464 | for j = 1 to w.boneids.count do 465 | ( 466 | boneid = w.boneids[j] 467 | weight = w.weights[j] 468 | append bi boneid 469 | append wv weight 470 | ) 471 | 472 | skinOps.ReplaceVertexWeights skinMod i bi wv 473 | 474 | ) 475 | ) 476 | 477 | fseek m Mat2NameStart_array[MatID] #seek_set 478 | MatName = readstring m 479 | 480 | if MatName != "" do( 481 | mat = standardMaterial() 482 | mat.name = MatName 483 | mat.showinviewport = true 484 | mat.twosided = false 485 | tm = Bitmaptexture filename:(p + MatName + ".dds") 486 | tm.alphasource = 2 487 | mat.diffuseMap = tm 488 | msh = mesh vertices:Vert_array faces:Face_array 489 | msh.material = mat 490 | msh.numTVerts = Vert_array.count 491 | buildTVFaces msh 492 | msh.name = PolyName + " (Layer 2)" 493 | for j = 1 to UV2_array.count do setTVert msh j UV2_array[j] 494 | for j = 1 to Face_array.count do setTVFace msh j Face_array[j] 495 | for j = 1 to Normal_array.count do setNormal msh j Normal_array[j] 496 | max modify mode 497 | select msh 498 | 499 | for face = 1 to msh.numfaces do setFaceSmoothGroup msh face 1 500 | 501 | -- select msh 502 | -- addmodifier msh (Edit_Normals ()) ui:off 503 | -- msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 504 | -- EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 505 | -- EN_setNormal = msh.Edit_Normals.SetNormal 506 | -- normID = #{} 507 | -- --apply normals 508 | -- for v = 1 to Normal_array.count do 509 | -- ( 510 | -- free normID 511 | -- EN_convertVS #{v} &normID 512 | -- for id in normID do EN_setNormal id Normal_array[v] 513 | -- ) 514 | 515 | if BoneCount > 0 do( 516 | skinMod = skin () 517 | addModifier msh skinMod 518 | for i = 1 to BoneCount do 519 | ( 520 | maxbone = getnodebyname BNArr[i].name 521 | if i != BoneCount then 522 | skinOps.addBone skinMod maxbone 0 523 | else 524 | skinOps.addBone skinMod maxbone 1 525 | 526 | ) 527 | 528 | modPanel.setCurrentObject skinMod 529 | 530 | for i = 1 to Weight_array.count do ( 531 | w = Weight_array[i] 532 | bi = #() --bone index array 533 | wv = #() --weight value array 534 | 535 | for j = 1 to w.boneids.count do 536 | ( 537 | boneid = w.boneids[j] 538 | weight = w.weights[j] 539 | append bi boneid 540 | append wv weight 541 | ) 542 | 543 | skinOps.ReplaceVertexWeights skinMod i bi wv 544 | 545 | ) 546 | ) 547 | 548 | ) 549 | 550 | ) 551 | 552 | ) 553 | ) 554 | 555 | gc() 556 | fclose m -------------------------------------------------------------------------------- /Scripts/NieRAutomata_WMB.ms: -------------------------------------------------------------------------------- 1 | -- NieR: Automata model importer by Random Talking Bush. 2 | 3 | rollout NieRAutomataRollout "NieR Automata model importer" width:365 height:165 4 | ( 5 | button btnImport "Import Model" pos:[7,8] width:351 height:50 6 | groupBox OptionsBox "Options" pos:[7,58] width:351 height:40 7 | checkbox tglLODs "Import LODs?" pos:[17,75] tooltip: "Enable this to import Level-of-Detail models" checked: false 8 | checkbox tglDebug "Print debug information?" pos:[213,75] checked: false 9 | label lblCred "This script was written by Random Talking Bush, if you use it, please remember to give me thanks for this. If something doesn't work right, please contact me on The VG Resource (Random Talking Bush), Twitter, Tumblr or Steam (RandomTBush) and let me know, and I'll try to fix it." pos:[8,105] width:355 height:80 10 | 11 | fn convertTo32 input16 = ( 12 | inputAsInt = input16 13 | sign = bit.get inputAsInt 16 14 | exponent = (bit.shift (bit.and inputAsInt (bit.hexasint "7C00")) -10) as integer - 16 15 | fraction = bit.and inputAsInt (bit.hexasint "03FF") 16 | if sign==true then sign = 1 else sign = 0 17 | exponentF = exponent + 127 18 | --Output 32 bit integer representing a 32 bit float 19 | outputAsFloat = bit.or (bit.or (bit.shift fraction 13) (bit.shift exponentF 23)) (bit.shift sign 31) 20 | --Output Check 21 | return bit.intasfloat outputasfloat 22 | ) 23 | 24 | fn readHalfFloat fstream = ( 25 | return convertTo32(Readshort fstream) 26 | ) 27 | 28 | fn ReadFixedString fstream fixedLen = ( 29 | local str = "" 30 | for strlen = 1 to fixedLen do 31 | ( 32 | str += bit.intAsChar (ReadByte fstream #unsigned) 33 | ) 34 | str 35 | ) 36 | 37 | fn printDebug pr = (if tglDebug.state do print(pr)) 38 | 39 | on btnImport pressed do( 40 | fname = getOpenFileName \ 41 | caption:"NieR Automata Model File" \ 42 | types:"NieR Automata Model File(*.wmb)|*.wmb" \ 43 | historyCategory:"NieRAutomataObjectPresets" 44 | 45 | if fname != undefined do( 46 | clearlistener() 47 | 48 | struct Bone_Info_Struct 49 | ( 50 | Bone1, Bone2, Bone3, Bone4 51 | ) 52 | struct Weight_Info_Struct 53 | ( 54 | Weight1, Weight2, Weight3, Weight4 55 | ) 56 | struct weight_data 57 | ( 58 | boneids, weights 59 | ) 60 | struct Poly_Struct 61 | ( 62 | VertexStart, VertexBStart, VertexSize, VertexBSize, VertexCount, UnknownCount, FaceStart, FacePointCount 63 | ) 64 | struct SubGroup_Struct 65 | ( 66 | PolyGroup, RigSet, FacePointStart, VertexEnd, FacePointCount, FaceCount 67 | ) 68 | struct ModelInfo_Struct 69 | ( 70 | ModelGroup, VisGroup, MatID, Unknown2, LODName 71 | ) 72 | struct RigSet_Struct 73 | ( 74 | RigBoneStart, RigBoneCount 75 | ) 76 | struct Material_Struct 77 | ( 78 | MatName1, MatName2, MatType, MatUnk1Count, TexTypeStart, TexTypeCount, MatUnk2Start, MatUnk2Count, MatParamStart, MatParamCount 79 | ) 80 | struct VisGroup_Struct 81 | ( 82 | MaterialIDsStart, MaterialIDsCount, BoneIDsStart, BoneIDsCount, VisName 83 | ) 84 | 85 | f = fopen fname "rb" 86 | p = getFilenamePath fname 87 | h = getFilenameFile fname 88 | 89 | local LODEnable = tglLODs.state 90 | WMB3 = readfixedstring f 4 91 | 92 | if WMB3 == "WMB3" do ( 93 | BoneArray = #() 94 | PolyStruct_array = #() 95 | SubGroupStruct_array = #() 96 | ModelInfoStruct_array = #() 97 | MaterialStruct_array = #() 98 | RigBones_array = #() 99 | RigSetStruct_array = #() 100 | VisGroupStruct_array = #() 101 | Face_array = #() 102 | Vert_array = #() 103 | Normal_array = #() 104 | UV_array = #() 105 | UV2_array = #() 106 | B1_array = #() 107 | W1_array = #() 108 | Weight_array = #() 109 | 110 | fseek f 0x0C #seek_set 111 | FileFlags = readshort f #unsigned 112 | case FileFlags of( 113 | default:(throw("Unexpected format!")) 114 | 0x00:(printDebug("Model is unrigged, has short face values")) 115 | 0x02:(printDebug("Model is rigged, has short face values")) 116 | 0x08:(printDebug("Model is unrigged, has long face values")) 117 | 0x0A:(printDebug("Model is rigged, has long face values")) 118 | ) 119 | SingleBindID = readshort f + 1 120 | BoundMinX = readfloat f 121 | BoundMinY = readfloat f 122 | BoundMinZ = readfloat f 123 | BoundMaxX = readfloat f 124 | 125 | BoundMaxY = readfloat f 126 | BoundMaxZ = readfloat f 127 | BoneStart = readlong f #unsigned 128 | BoneCount = readlong f #unsigned 129 | 130 | Unknown1Start = readlong f #unsigned 131 | Unknown1Count = readlong f #unsigned 132 | PolyStart = readlong f #unsigned 133 | PolyCount = readlong f #unsigned 134 | 135 | SubGroupStart = readlong f #unsigned 136 | SubGroupCount = readlong f #unsigned 137 | ModelInfoStart = readlong f #unsigned 138 | ModelInfoCount = readlong f #unsigned 139 | 140 | BlankStart = readlong f #unsigned 141 | BlankCount = readlong f #unsigned 142 | RigBonesStart = readlong f #unsigned 143 | RigBonesCount = readlong f #unsigned 144 | 145 | RigSetStart = readlong f #unsigned 146 | RigSetCount = readlong f #unsigned 147 | MaterialStart = readlong f #unsigned 148 | MaterialCount = readlong f #unsigned 149 | 150 | VisGroupStart = readlong f #unsigned 151 | VisGroupCount = readlong f #unsigned 152 | Unknown2Start = readlong f #unsigned 153 | Unknown2Count = readlong f #unsigned 154 | 155 | fseek f BoneStart #seek_set 156 | 157 | for b = 1 to BoneCount do( 158 | printDebug("Bone " + (b as string) + " start = 0x"+((bit.intAsHex(ftell f))as string)) 159 | BoneName = "Bone" + (b as string) 160 | BoneUnk1 = readbyte f #unsigned 161 | BoneUnk2 = readbyte f #unsigned 162 | BoneParent = readshort f + 1 163 | 164 | BonePosX = readfloat f 165 | BonePosY = readfloat f 166 | BonePosZ = readfloat f 167 | 168 | BoneRotX = readfloat f 169 | BoneRotY = readfloat f 170 | BoneRotZ = readfloat f 171 | 172 | BoneSclX = readfloat f 173 | BoneSclY = readfloat f 174 | BoneSclZ = readfloat f 175 | 176 | BonePosX2 = readfloat f 177 | BonePosY2 = readfloat f 178 | BonePosZ2 = readfloat f 179 | 180 | BoneRotX2 = readfloat f 181 | BoneRotY2 = readfloat f 182 | BoneRotZ2 = readfloat f 183 | 184 | BoneSclX2 = readfloat f 185 | BoneSclY2 = readfloat f 186 | BoneSclZ2 = readfloat f 187 | 188 | BonePosX3 = readfloat f 189 | BonePosY3 = readfloat f 190 | BonePosZ3 = readfloat f 191 | 192 | tfm = scaleMatrix [BoneSclX,BoneSclY,BoneSclZ] 193 | tfm = tfm * (rotateXMatrix (radToDeg BoneRotX)) * (rotateYMatrix (radToDeg BoneRotY)) * (rotateZMatrix (radToDeg BoneRotZ)) 194 | tfm.row4 = [BonePosX, BonePosY, BonePosZ] 195 | 196 | if (getNodeByName BoneName) != undefined do ( 197 | append BoneArray (getNodeByName BoneName) 198 | ) 199 | 200 | if (getNodeByName BoneName) == undefined do ( 201 | if (BoneParent != 0) do ( 202 | tfm = tfm * BoneArray[(BoneParent)].objecttransform 203 | ) 204 | ) 205 | 206 | newBone = bonesys.createbone \ 207 | tfm.row4 \ 208 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 209 | (normalize tfm.row3) 210 | newBone.name = BoneName 211 | newBone.width = 0.01 212 | newBone.height = 0.01 213 | newBone.transform = tfm 214 | newBone.setBoneEnable false 0 215 | newBone.wirecolor = yellow 216 | newbone.showlinks = true 217 | newBone.pos.controller = TCB_position () 218 | newBone.rotation.controller = TCB_rotation () 219 | if (BoneParent != 0) then 220 | newBone.parent = BoneArray[BoneParent] 221 | append BoneArray newBone 222 | ) 223 | 224 | fseek f SubGroupStart #seek_set 225 | 226 | for b = 1 to SubGroupCount do( 227 | PolyGroup = readlong f #unsigned + 1 228 | RigSet = readlong f #unsigned + 1 229 | Blank = readlong f #unsigned 230 | FacePointStart = readlong f #unsigned + 3 231 | VertexEnd = readlong f #unsigned 232 | FacePointCount = readlong f #unsigned 233 | FaceCount = readlong f #unsigned 234 | append SubGroupStruct_array (SubGroup_Struct PolyGroup:PolyGroup RigSet:RigSet FacePointStart:FacePointStart VertexEnd:VertexEnd FacePointCount:FacePointCount FaceCount:FaceCount) 235 | ) 236 | 237 | fseek f ModelInfoStart #seek_set 238 | 239 | for b = 1 to ModelInfoCount do( 240 | LODNameStart = readlong f #unsigned 241 | Blank = readlong f #unsigned 242 | Blank = readlong f #unsigned 243 | ModelDataStart = readlong f #unsigned 244 | ModelDataCount = readlong f #unsigned 245 | ModRet = (ftell f) 246 | 247 | fseek f LODNameStart #seek_set 248 | 249 | LODName = readstring f 250 | 251 | fseek f ModelDataStart #seek_set 252 | 253 | for c = 1 to ModelDataCount do( 254 | ModelGroup = readlong f #unsigned + 1 255 | VisGroup = readlong f #unsigned + 1 256 | MatID = readlong f #unsigned + 1 257 | FFFFFFFF = readlong f #unsigned 258 | Unknown2 = readlong f #unsigned + 1 259 | FFFFFFFF = readlong f #unsigned 260 | append ModelInfoStruct_array (ModelInfo_Struct ModelGroup:ModelGroup VisGroup:VisGroup MatID:MatID Unknown2:Unknown2 LODName:LODName) 261 | ) 262 | 263 | fseek f ModRet #seek_set 264 | 265 | ) 266 | 267 | fseek f RigBonesStart #seek_set 268 | 269 | for b = 1 to RigBonesCount do( 270 | RigBone = readlong f #unsigned + 1 271 | append RigBones_array RigBone 272 | ) 273 | 274 | fseek f RigSetStart #seek_set 275 | 276 | for b = 1 to RigSetCount do( 277 | RigBoneStart = readlong f #unsigned 278 | RigBoneCount = readlong f #unsigned 279 | append RigSetStruct_array (RigSet_Struct RigBoneStart:RigBoneStart RigBoneCount:RigBoneCount) 280 | ) 281 | 282 | fseek f PolyStart #seek_set 283 | 284 | for b = 1 to PolyCount do( 285 | printDebug("Poly Group " + (b as string) + " start = 0x"+((bit.intAsHex(ftell f))as string)) 286 | VertexStart = readlong f #unsigned 287 | VertexBStart = readlong f #unsigned 288 | Blank = readlong f #unsigned 289 | Blank = readlong f #unsigned 290 | 291 | VertexSize = readlong f #unsigned 292 | VertexBSize = readlong f #unsigned 293 | Blank = readlong f #unsigned 294 | Blank = readlong f #unsigned 295 | 296 | VertexCount = readlong f #unsigned 297 | UnknownCount = readlong f #unsigned 298 | FaceStart = readlong f #unsigned 299 | FacePointCount = readlong f #unsigned 300 | 301 | append PolyStruct_array (Poly_Struct VertexStart:VertexStart VertexBStart:VertexBStart VertexSize:VertexSize VertexBSize:VertexBSize VertexCount:VertexCount UnknownCount:UnknownCount FaceStart:FaceStart FacePointCount:FacePointCount) 302 | ) 303 | 304 | fseek f MaterialStart #seek_set 305 | 306 | for b = 1 to MaterialCount do( 307 | Flags1 = readshort f #unsigned 308 | Flags2 = readshort f #unsigned 309 | Flags3 = readshort f #unsigned 310 | Flags4 = readshort f #unsigned 311 | MatName1Start = readlong f #unsigned 312 | MatName2Start = readlong f #unsigned 313 | MatTypeStart = readlong f #unsigned 314 | MatUnk1Count = readlong f #unsigned 315 | TexTypeStart = readlong f #unsigned 316 | TexTypeCount = readlong f #unsigned 317 | MatUnk2Start = readlong f #unsigned 318 | MatUnk2Count = readlong f #unsigned 319 | MatParamStart = readlong f #unsigned 320 | MatParamCount = readlong f #unsigned 321 | 322 | MatRet = (ftell f) 323 | 324 | fseek f MatName1Start #seek_set 325 | MatName1 = readstring f 326 | fseek f MatName2Start #seek_set 327 | MatName2 = readstring f 328 | fseek f MatTypeStart #seek_set 329 | MatType = readstring f 330 | 331 | fseek f MatRet #seek_set 332 | append MaterialStruct_array (Material_Struct MatName1:MatName1 MatName2:MatName2 MatType:MatType MatUnk1Count:MatUnk1Count TexTypeStart:TexTypeStart TexTypeCount:TexTypeCount MatUnk2Start:MatUnk2Start MatUnk2Count:MatUnk2Count MatParamStart:MatParamStart MatParamCount:MatParamCount) 333 | 334 | ) 335 | 336 | fseek f VisGroupStart #seek_set 337 | 338 | for b = 1 to VisGroupCount do( 339 | printDebug("Rig Set Info " + (b as string) + " start = 0x"+((bit.intAsHex(ftell f))as string)) 340 | StringStart = readlong f #unsigned 341 | BoundMinX = readfloat f 342 | BoundMinY = readfloat f 343 | BoundMinZ = readfloat f 344 | BoundMaxX = readfloat f 345 | BoundMaxY = readfloat f 346 | BoundMaxZ = readfloat f 347 | MaterialIDsStart = readlong f #unsigned 348 | MaterialIDsCount = readlong f #unsigned 349 | BoneIDsStart = readlong f #unsigned 350 | BoneIDsCount = readlong f #unsigned 351 | VisRet = (ftell f) 352 | 353 | fseek f StringStart #seek_set 354 | VisName = readstring f 355 | append VisGroupStruct_array (VisGroup_Struct MaterialIDsStart:MaterialIDsStart MaterialIDsCount:MaterialIDsCount BoneIDsStart:BoneIDsStart BoneIDsCount:BoneIDsCount VisName:VisName) 356 | 357 | fseek f VisRet #seek_set 358 | ) 359 | 360 | fseek f Unknown2Start #seek_set 361 | 362 | for b = 1 to Unknown2Count do( 363 | Unknown1 = readlong f #unsigned 364 | Unknown2 = readlong f #unsigned 365 | ) 366 | 367 | VertCountStart = 1 368 | for m = 1 to SubGroupStruct_array.count do( 369 | Face_array2 = #() 370 | Vert_array2 = #() 371 | Normal_array2 = #() 372 | UV_array2 = #() 373 | Weight_array = #() 374 | Weight_array2 = #() 375 | 376 | if (m > 1 and SubGroupStruct_array[m].PolyGroup != SubGroupStruct_array[m - 1].PolyGroup) or (m == 1) do( 377 | Face_array = #() 378 | Vert_array = #() 379 | Normal_array = #() 380 | UV_array = #() 381 | B1_array = #() 382 | W1_array = #() 383 | VertCountStart = 1 384 | 385 | fseek f PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexStart #seek_set 386 | printDebug("Vertex " + (m as string) + " start = 0x"+((bit.intAsHex(ftell f))as string)) 387 | if FileFlags == 0x02 or FileFlags == 0x0A do( 388 | case of( 389 | default:(throw("Unexpected vertex length!")) 390 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexSize == 0x1C):( 391 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 392 | vx = readfloat f 393 | vy = readfloat f 394 | vz = readfloat f 395 | nx = (readbyte f as float) / 127 396 | ny = (readbyte f as float) / 127 397 | nz = (readbyte f as float) / 127 398 | nq = readbyte f 399 | tu = readhalffloat f * 2 400 | tv = ((readhalffloat f * 2) * -1) + 1 401 | bone1 = (readbyte f #unsigned) + 1 402 | bone2 = (readbyte f #unsigned) + 1 403 | bone3 = (readbyte f #unsigned) + 1 404 | bone4 = (readbyte f #unsigned) + 1 405 | weight1 = (readbyte f #unsigned as float) / 255 406 | weight2 = (readbyte f #unsigned as float) / 255 407 | weight3 = (readbyte f #unsigned as float) / 255 408 | weight4 = (readbyte f #unsigned as float) / 255 409 | append Vert_array [vx,vy,vz] 410 | append UV_array [tu,tv,0] 411 | append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 412 | append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 413 | ) 414 | ) 415 | ) 416 | ) 417 | if FileFlags == 0x00 or FileFlags == 0x08 do( 418 | case of( 419 | default:(throw("Unexpected vertex length!")) 420 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexSize == 0x1C):( 421 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 422 | vx = readfloat f 423 | vy = readfloat f 424 | vz = readfloat f 425 | nx = (readbyte f as float) / 127 426 | ny = (readbyte f as float) / 127 427 | nz = (readbyte f as float) / 127 428 | nq = readbyte f 429 | tu = readhalffloat f * 2 430 | tv = ((readhalffloat f * 2) * -1) + 1 431 | tu2 = readhalffloat f * 2 432 | tv2 = ((readhalffloat f * 2) * -1) + 1 433 | unk1 = readbyte f #unsigned 434 | unk2 = readbyte f #unsigned 435 | unk3 = readbyte f #unsigned 436 | unk4 = readbyte f #unsigned 437 | bone1 = 1 438 | bone2 = 1 439 | bone3 = 1 440 | bone4 = 1 441 | weight1 = 1 442 | weight2 = 0 443 | weight3 = 0 444 | weight4 = 0 445 | append Vert_array [vx,vy,vz] 446 | append UV_array [tu,tv,0] 447 | append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4) 448 | append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4) 449 | ) 450 | ) 451 | ) 452 | ) 453 | printDebug("Vertex " + (m as string) + " end = 0x"+((bit.intAsHex(ftell f))as string)) 454 | 455 | fseek f PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexBStart #seek_set 456 | printDebug("Vertex Plus " + (m as string) + " start = 0x"+((bit.intAsHex(ftell f))as string)) 457 | 458 | if FileFlags == 0x00 or FileFlags == 0x08 do( 459 | case of( 460 | default:(throw("Unexpected vertex length!")) 461 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexBSize == 0x08):( 462 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 463 | nx = readhalffloat f 464 | ny = readhalffloat f 465 | nz = readhalffloat f 466 | nq = readhalffloat f 467 | append Normal_array [nx,ny,nz] 468 | ) 469 | ) 470 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexBSize == 0x0C):( 471 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 472 | nx = readhalffloat f 473 | ny = readhalffloat f 474 | nz = readhalffloat f 475 | nq = readhalffloat f 476 | tu = readhalffloat f * 2 477 | tv = ((readhalffloat f * 2) * -1) + 1 478 | append Normal_array [nx,ny,nz] 479 | ) 480 | ) 481 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexBSize == 0x10):( 482 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 483 | nx = readhalffloat f 484 | ny = readhalffloat f 485 | nz = readhalffloat f 486 | nq = readhalffloat f 487 | tu = readhalffloat f * 2 488 | tv = ((readhalffloat f * 2) * -1) + 1 489 | tu2 = readhalffloat f * 2 490 | tv2 = ((readhalffloat f * 2) * -1) + 1 491 | append Normal_array [nx,ny,nz] 492 | ) 493 | ) 494 | ) 495 | ) 496 | if FileFlags == 0x02 or FileFlags == 0x0A do( 497 | case of( 498 | default:(throw("Unexpected vertex length!")) 499 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexBSize == 0x0C):( 500 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 501 | tu = readhalffloat f * 2 502 | tv = ((readhalffloat f * 2) * -1) + 1 503 | nx = readhalffloat f 504 | ny = readhalffloat f 505 | nz = readhalffloat f 506 | nq = readhalffloat f 507 | append Normal_array [nx,ny,nz] 508 | ) 509 | ) 510 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexBSize == 0x10):( 511 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 512 | tu = readhalffloat f * 2 513 | tv = ((readhalffloat f * 2) * -1) + 1 514 | blank = readshort f #unsigned 515 | unknown1 = readbyte f #unsigned 516 | unknown2 = readbyte f #unsigned 517 | nx = readhalffloat f 518 | ny = readhalffloat f 519 | nz = readhalffloat f 520 | nq = readhalffloat f 521 | append Normal_array [nx,ny,nz] 522 | ) 523 | ) 524 | (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexBSize == 0x14):( 525 | for v = 1 to PolyStruct_array[SubGroupStruct_array[m].PolyGroup].VertexCount do( 526 | tu = readhalffloat f * 2 527 | tv = ((readhalffloat f * 2) * -1) + 1 528 | unk1 = readbyte f #unsigned 529 | unk2 = readbyte f #unsigned 530 | unk3 = readbyte f #unsigned 531 | unk4 = readbyte f #unsigned 532 | nx = readhalffloat f 533 | ny = readhalffloat f 534 | nz = readhalffloat f 535 | nq = readhalffloat f 536 | tu2 = readhalffloat f * 2 537 | tv2 = ((readhalffloat f * 2) * -1) + 1 538 | append Normal_array [nx,ny,nz] 539 | append UV2_array [tu2,tv2,0] 540 | ) 541 | ) 542 | ) 543 | ) 544 | printDebug("Vertex Plus " + (m as string) + " end = 0x"+((bit.intAsHex(ftell f))as string)) 545 | 546 | fseek f PolyStruct_array[SubGroupStruct_array[m].PolyGroup].FaceStart #seek_set 547 | printDebug("Faces " + (m as string) + " start = 0x"+((bit.intAsHex(ftell f))as string)) 548 | case of( 549 | default:( 550 | for p = 1 to (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].FacePointCount / 3) do( 551 | f1 = readlong f #unsigned + 1 552 | f2 = readlong f #unsigned + 1 553 | f3 = readlong f #unsigned + 1 554 | append Face_array [f3,f2,f1] 555 | ) 556 | ) 557 | (FileFlags == 0x00 or FileFlags == 0x02):( 558 | for p = 1 to (PolyStruct_array[SubGroupStruct_array[m].PolyGroup].FacePointCount / 3) do( 559 | f1 = readshort f #unsigned + 1 560 | f2 = readshort f #unsigned + 1 561 | f3 = readshort f #unsigned + 1 562 | append Face_array [f3,f2,f1] 563 | ) 564 | ) 565 | ) 566 | printDebug("Faces " + (m as string) + " end = 0x"+((bit.intAsHex(ftell f))as string)) 567 | 568 | ) 569 | 570 | FixRig_array = #() 571 | 572 | if RigSetCount > 0 then( 573 | fseek f RigSetStruct_array[SubGroupStruct_array[m].RigSet].RigBoneStart #seek_set 574 | for x = 1 to RigSetStruct_array[SubGroupStruct_array[m].RigSet].RigBoneCount do( 575 | RigBone = RigBones_array[readshort f #unsigned + 1] 576 | append FixRig_array RigBone 577 | ) 578 | ) else (append FixRig_array SingleBindID) 579 | 580 | for b = 1 to W1_array.count Do ( 581 | w = (weight_data boneids:#() weights:#()) 582 | maxweight = 0 583 | 584 | if(W1_array[b].Weight1 != 0) then 585 | maxweight = maxweight + W1_array[b].Weight1 586 | if(W1_array[b].Weight2 != 0) then 587 | maxweight = maxweight + W1_array[b].Weight2 588 | if(W1_array[b].Weight3 != 0) then 589 | maxweight = maxweight + W1_array[b].Weight3 590 | if(W1_array[b].Weight4 != 0) then 591 | maxweight = maxweight + W1_array[b].Weight4 592 | 593 | if(maxweight != 0) then 594 | ( 595 | if(W1_array[b].Weight1 != 0) then 596 | ( 597 | w1 = W1_array[b].Weight1 as float 598 | append w.boneids (FixRig_array[B1_array[b].Bone1]) 599 | append w.weights (w1) 600 | ) 601 | if(W1_array[b].Weight2 != 0) then 602 | ( 603 | w2 = W1_array[b].Weight2 as float 604 | append w.boneids (FixRig_array[B1_array[b].Bone2]) 605 | append w.weights (w2) 606 | ) 607 | if(W1_array[b].Weight3 != 0) then 608 | ( 609 | w3 = W1_array[b].Weight3 as float 610 | append w.boneids (FixRig_array[B1_array[b].Bone3]) 611 | append w.weights (w3) 612 | ) 613 | if(W1_array[b].Weight4 != 0) then 614 | ( 615 | w4 = W1_array[b].Weight4 as float 616 | append w.boneids (FixRig_array[B1_array[b].Bone4]) 617 | append w.weights (w4) 618 | ) 619 | ) 620 | append Weight_array w 621 | ) 622 | 623 | for x = VertCountStart to SubGroupStruct_array[m].VertexEnd do( 624 | append Vert_array2 Vert_array[x] 625 | append Normal_array2 Normal_array[x] 626 | append UV_array2 UV_array[x] 627 | append Weight_array2 Weight_array[x] 628 | ) 629 | 630 | for x = (SubGroupStruct_array[m].FacePointStart / 3) to ((SubGroupStruct_array[m].FacePointStart / 3) + (SubGroupStruct_array[m].FacePointCount / 3) - 1) do( 631 | Faces2 = ((Face_array[x] - VertCountStart) + 1) 632 | append Face_array2 Faces2 633 | ) 634 | 635 | VertCountStart = (VertCountStart + (SubGroupStruct_array[m].VertexEnd - VertCountStart) + 1) 636 | 637 | if ModelInfoStruct_array[m].LODName == "LOD0" or LODEnable == true do( 638 | 639 | msh = mesh vertices:Vert_array2 faces:Face_array2 640 | msh.numTVerts = Vert_array2.count 641 | defaultVCFaces msh 642 | buildTVFaces msh 643 | msh.name = (VisGroupStruct_array[ModelInfoStruct_array[m].VisGroup].VisName + " (" + MaterialStruct_array[ModelInfoStruct_array[m].MatID].MatName1 + ") <" + ModelInfoStruct_array[m].LODName + ">") 644 | for j = 1 to UV_array2.count do setTVert msh j UV_array2[j] 645 | for j = 1 to Face_array2.count do setTVFace msh j Face_array2[j] 646 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 647 | max modify mode 648 | select msh 649 | 650 | for face = 1 to msh.numfaces do setFaceSmoothGroup msh face 1 651 | select msh 652 | addmodifier msh (Edit_Normals ()) ui:off 653 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array.count} 654 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 655 | EN_setNormal = msh.Edit_Normals.SetNormal 656 | normID = #{} 657 | for v = 1 to Normal_array2.count do 658 | ( 659 | free normID 660 | EN_convertVS #{v} &normID 661 | for id in normID do EN_setNormal id Normal_array2[v] 662 | ) 663 | 664 | if BoneCount > 0 do( 665 | skinMod = skin () 666 | boneIDMap = #() 667 | addModifier msh skinMod 668 | for i = 1 to BoneCount do 669 | ( 670 | maxbone = getnodebyname BoneArray[i].name 671 | if i != BoneCount then 672 | skinOps.addBone skinMod maxbone 0 673 | else 674 | skinOps.addBone skinMod maxbone 1 675 | 676 | ) 677 | local numSkinBones = skinOps.GetNumberBones skinMod 678 | for i = 1 to numSkinBones do 679 | ( 680 | local boneName = skinOps.GetBoneName skinMod i 0 681 | for j = 1 to BoneCount do 682 | ( 683 | if boneName == BoneArray[j].Name then 684 | ( 685 | boneIDMap[j] = i 686 | j = BoneCount + 1 687 | ) 688 | ) 689 | ) -- This fixes bone ordering in 3DS Max 2012. Thanks to sunnydavis for the fix! 690 | 691 | modPanel.setCurrentObject skinMod 692 | 693 | for i = 1 to Vert_array2.count do( 694 | skinOps.SetVertexWeights skinMod i 1 1 695 | skinOps.unnormalizeVertex skinMod i true 696 | skinOps.SetVertexWeights skinMod i 1 0 697 | ) 698 | skinOps.RemoveZeroWeights skinMod 699 | for i = 1 to Vert_array2.count do( 700 | skinOps.unnormalizeVertex skinMod i false 701 | ) -- These fix broken rigging for 3DS Max 2015 and above. 702 | 703 | for i = 1 to Weight_array2.count do ( 704 | w = Weight_array2[i] 705 | bi = #() 706 | wv = #() 707 | 708 | for j = 1 to w.boneids.count do 709 | ( 710 | boneid = w.boneids[j] 711 | weight = w.weights[j] 712 | append bi boneIDMap[boneid] 713 | append wv weight 714 | ) 715 | skinOps.ReplaceVertexWeights skinMod i bi wv 716 | ) 717 | ) 718 | 719 | ) 720 | 721 | ) 722 | 723 | ) 724 | 725 | fclose f 726 | ) 727 | ) 728 | 729 | ) 730 | 731 | CreateDialog NieRAutomataRollout -------------------------------------------------------------------------------- /Scripts/NintendoWiiU-Switch_BFRES.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/NintendoWiiU-Switch_BFRES.ms -------------------------------------------------------------------------------- /Scripts/OrochiEngine3_MDL.ms: -------------------------------------------------------------------------------- 1 | -- World of Final Fantasy (PC) model importer by Random Talking Bush. 2 | 3 | -- Changelog: 4 | -- December 4th, 2017: 5 | -- Added a check for compressed models so it won't crash if you forget to decompress 'em. 6 | -- Implemented multiple UV mapping layers because I'm a twit and forgot all about it. 7 | 8 | -- November 26th, 2017: Fixed static models not importing. 9 | 10 | fn ReadHalfFloat Fstream = ( 11 | local BL = readByte Fstream #unsigned 12 | local BH = readByte Fstream #unsigned 13 | local N = BH*256 + BL 14 | local S = floor((mod N 65536) / 32768) 15 | local Ef = floor((mod N 32768) / 1024) 16 | local M = mod N 1024 17 | local ret=case of( 18 | ((Ef==0)AND(M==0)): ( (-1.0)^S * 0.0 ) 19 | ((Ef==0)AND(M!=0)): ( (-1.0)^S * 2.0^-14 * (M / 2.0^10) ) 20 | ((Ef>0)AND(Ef<31)): ( (-1.0)^S * 2.0^(Ef-15) * (1 + M/2.0^10) ) 21 | ((Ef==31)AND(M==0)): ( (-1.0)^S * 1/0.0 ) 22 | ((Ef==31)AND(M!=0)): 0 23 | ) 24 | ) 25 | 26 | ModelScale = 10 -- The models are ridiculously small by default, modify this if you want tthe scale to be different. 27 | 28 | fname = getOpenFileName \ 29 | caption:"World of Final Fantasy Model File" \ 30 | types:"World of Final Fantasy Model File(*.mdl)|*.mdl" \ 31 | historyCategory:"WoFFObjectPresets" 32 | 33 | if fname != undefined do( 34 | clearlistener() 35 | f = fopen fname "rb" 36 | p = getFilenamePath fname 37 | g = getFilenameFile fname 38 | 39 | struct BoneGrp_Struct( 40 | PosX, PosY, PosZ, ScaleX, ScaleY, ScaleZ, Unk1, BoneParent, Unk3, Unk4, Unk5, Unk6 41 | ) 42 | 43 | struct VisGrp_Struct( 44 | VISNum, LODNum, Unknown3, VertStart, VertCount, PolyStart, PolyCount, Float1, Float2, Float3 45 | ) 46 | 47 | struct PolyGrp_Struct( 48 | PolyGrpStart, PolyGrpCount, VertStart, VertSize, VertStride, PolyStart, PolySize, Unknown1, Unknown2, NodeIDStart, NodeIDCount, MatID, Unknown6 49 | ) 50 | 51 | struct Bone_Info_Struct( 52 | bone1, bone2, bone3, bone4 53 | ) 54 | 55 | struct Weight_Info_Struct( 56 | weight1, weight2, weight3, weight4 57 | ) 58 | 59 | struct weight_data( 60 | boneids, weights 61 | ) 62 | 63 | String_array = #() 64 | PolyGrp_array = #() 65 | BoneGrp_array = #() 66 | VisGrp_array = #() 67 | Node_array = #() 68 | BoneArray = #() 69 | 70 | fseek f 0x80 #seek_set 71 | ZLIBCheck = readlong f 72 | fseek f 0x00 #seek_set 73 | if ZLIBCheck == 0x5A4C4942 then( 74 | print "Model is compressed! Decompress it and try again." 75 | fclose f 76 | ) else ( 77 | 78 | st = timestamp() 79 | disableSceneRedraw() 80 | 81 | StringBuffSize = readlong f 82 | NodeBuffSize = readlong f 83 | BoneCount = readlong f 84 | UnkCount = readlong f 85 | Blank = readlong f 86 | Unk2Count = readlong f 87 | VisGrpCount = readlong f 88 | MeshCount = readlong f 89 | VertexBuffSize = readlong f 90 | PolyBuffSize = readlong f 91 | VertStrideBuffSize = readlong f 92 | 93 | NodeBuffStart = StringBuffSize + 0x2C 94 | 95 | for s = 1 to BoneCount do( 96 | StringName = readstring f 97 | append String_array StringName 98 | ) 99 | 100 | fseek f NodeBuffStart #seek_set 101 | BoneBuffStart = NodeBuffStart + NodeBuffSize 102 | 103 | for x = 1 to (NodeBuffSize / 2) do( 104 | NodeID = readshort f #unsigned + 1 105 | append Node_array NodeID 106 | ) 107 | 108 | fseek f BoneBuffStart #seek_set 109 | 110 | for x = 1 to BoneCount do( 111 | fseek f 0x10 #seek_cur 112 | PosX = readfloat f 113 | PosY = readfloat f 114 | PosZ = readfloat f 115 | ScaleX = readfloat f 116 | ScaleY = readfloat f 117 | ScaleZ = readfloat f 118 | Unk1 = readlong f 119 | BoneParent = readshort f + 1 120 | Unk3 = readshort f 121 | Unk4 = readshort f 122 | Unk5 = readshort f 123 | Unk6 = readlong f 124 | fseek f 0x08 #seek_cur 125 | append BoneGrp_array (BoneGrp_Struct PosX:PosX PosY:PosY PosZ:PosZ ScaleX:ScaleX ScaleY:ScaleY ScaleZ:ScaleZ Unk1:Unk1 BoneParent:BoneParent Unk3:Unk3 Unk4:Unk4 Unk5:Unk5 Unk6:Unk6) 126 | ) 127 | 128 | for x = 1 to BoneCount do( 129 | m11 = readfloat f; m12 = readfloat f; m13 = readfloat f; m14 = readfloat f 130 | m21 = readfloat f; m22 = readfloat f; m23 = readfloat f; m24 = readfloat f 131 | m31 = readfloat f; m32 = readfloat f; m33 = readfloat f; m34 = readfloat f 132 | m41 = readfloat f * ModelScale; m42 = readfloat f * ModelScale; m43 = readfloat f * ModelScale; m44 = readfloat f 133 | ) 134 | 135 | for x = 1 to BoneCount do( 136 | BoneName = String_array[x] 137 | BoneParent = BoneGrp_array[x].BoneParent 138 | m11 = readfloat f; m12 = readfloat f; m13 = readfloat f; m14 = readfloat f 139 | m21 = readfloat f; m22 = readfloat f; m23 = readfloat f; m24 = readfloat f 140 | m31 = readfloat f; m32 = readfloat f; m33 = readfloat f; m34 = readfloat f 141 | m41 = readfloat f * ModelScale; m42 = readfloat f * ModelScale; m43 = readfloat f * ModelScale; m44 = readfloat f 142 | 143 | tfm = scaleMatrix [BoneGrp_array[x].ScaleX,BoneGrp_array[x].ScaleY,BoneGrp_array[x].ScaleZ] 144 | tfm = matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43] 145 | tfm = inverse(tfm) 146 | 147 | newBone = bonesys.createbone \ 148 | tfm.row4 \ 149 | (tfm.row4 + 0.01 * (normalize tfm.row1)) \ 150 | (normalize tfm.row3) 151 | newBone.name = BoneName 152 | newBone.width = 0.01 153 | newBone.height = 0.01 154 | newBone.transform = tfm 155 | newBone.setBoneEnable false 0 156 | newBone.wirecolor = yellow 157 | newbone.showlinks = true 158 | newBone.pos.controller = TCB_position () 159 | newBone.rotation.controller = TCB_rotation () 160 | if (BoneParent != 0) then 161 | newBone.parent = BoneArray[(BoneParent)] 162 | append BoneArray newBone 163 | ) 164 | 165 | for x = 1 to VisGrpCount do( 166 | VISNum = readlong f 167 | LODNum = readshort f 168 | Unknown3 = readshort f 169 | VertCount = readlong f 170 | PolyStart = readlong f / 3 171 | PolyCount = readlong f / 3 172 | VertStart = readlong f 173 | fseek f 0x08 #seek_cur 174 | Float1 = readfloat f; Float2 = readfloat f; Float3 = readfloat f; Float4 = readfloat f 175 | m11 = readfloat f; m12 = readfloat f; m13 = readfloat f; m14 = readfloat f 176 | m21 = readfloat f; m22 = readfloat f; m23 = readfloat f; m24 = readfloat f 177 | m31 = readfloat f; m32 = readfloat f; m33 = readfloat f; m34 = readfloat f 178 | m41 = readfloat f; m42 = readfloat f; m43 = readfloat f; m44 = readfloat f 179 | append VisGrp_array (VisGrp_Struct VISNum:VISNum LODNum:LODNum Unknown3:Unknown3 VertStart:VertStart VertCount:VertCount PolyStart:PolyStart PolyCount:PolyCount Float1:Float1 Float2:Float2 Float3:Float3) 180 | ) 181 | 182 | for x = 1 to MeshCount do( 183 | PolyArrInfo = (PolyGrp_Struct \ 184 | PolyGrpStart: (readlong f) \ 185 | PolyGrpCount: (readlong f) \ 186 | VertStart: (readlong f) \ 187 | VertSize: (readlong f) \ 188 | VertStride: (readlong f) \ 189 | PolyStart: (readlong f) \ 190 | PolySize: (readlong f) \ 191 | Unknown1: (readlong f) \ 192 | Unknown2: (readlong f) \ 193 | NodeIDStart: (readlong f) \ 194 | NodeIDCount: (readlong f) \ 195 | MatID: (readlong f) \ 196 | Unknown6: (readlong f) \ 197 | ) 198 | append PolyGrp_array PolyArrInfo 199 | ) 200 | 201 | VertBuffStart = (ftell f) 202 | PolyBuffStart = VertBuffStart + VertexBuffSize 203 | VertStrideBuffStart = PolyBuffStart + PolyBuffSize 204 | 205 | for x = 1 to MeshCount do( 206 | Vert_Array = #() 207 | Normal_Array = #() 208 | UV_Array = #() 209 | UV2_Array = #() 210 | UV3_Array = #() 211 | UV4_Array = #() 212 | Color_Array = #() 213 | Alpha_Array = #() 214 | NodeID_array = #() 215 | B1_array = #() 216 | W1_array = #() 217 | Weight_array = #() 218 | Face_array = #() 219 | 220 | fseek f VertStrideBuffStart #seek_set 221 | 222 | HasVertex = 0; HasNormals = 0; HasColors = 0; HasColors2 = 0; HasBones = 0; HasWeights = 0 223 | HasUVs = 0; HasUVs2 = 0; HasUVs3 = 0; HasUVs4 = 0 224 | HasBinormals = 0; HasBinormals2 = 0; HasTangents = 0; HasTangents2 = 0 225 | 226 | EndCheck = 0 227 | Do ( 228 | EndCheck = readshort f 229 | StrideStart = readshort f 230 | VertAmount = readbyte f #unsigned 231 | VertFormat = readbyte f #unsigned 232 | VertFormatPrint = VertFormat 233 | case VertFormat of( 234 | default:(fclose f; throw "Unknown vertex format!") 235 | 0x00:(VertFormatPrint = "Empty") 236 | 0x02:(VertFormatPrint = "Floats") 237 | 0x03:(VertFormatPrint = "Half-Floats") 238 | 0x04:(VertFormatPrint = "Bytes (Weights)") 239 | 0x07:(VertFormatPrint = "Bytes (Node IDs)") 240 | 0x14:(VertFormatPrint = "Bytes (Colors)") 241 | ) 242 | VertType = readbyte f #unsigned 243 | VertTypePrint = VertType 244 | if EndCheck != -1 do( 245 | case VertType of( 246 | default:(fclose f; throw "Unknown vertex type!") 247 | 0x00:( 248 | VertTypePrint = "Positions" 249 | HasVertex = VertFormat 250 | ) 251 | 0x01:( 252 | VertTypePrint = "Weights" 253 | HasWeights = VertFormat 254 | ) 255 | 0x02:( 256 | VertTypePrint = "Normals" 257 | HasNormals = VertFormat 258 | ) 259 | 0x03:( 260 | VertTypePrint = "Colors" 261 | HasColors = VertFormat 262 | ) 263 | 0x04:( 264 | VertTypePrint = "Colors 2?" 265 | HasColors2 = VertFormat 266 | ) 267 | 0x07:( 268 | VertTypePrint = "Node IDs" 269 | HasBones = VertFormat 270 | ) 271 | 0x08:( 272 | VertTypePrint = "UVs" 273 | HasUVs = VertFormat 274 | ) 275 | 0x09:( 276 | VertTypePrint = "UVs (Layer 2)" 277 | HasUVs2 = VertFormat 278 | ) 279 | 0x0A:( 280 | VertTypePrint = "UVs (Layer 3)" 281 | HasUVs3 = VertFormat 282 | ) 283 | 0x0B:( 284 | VertTypePrint = "UVs (Layer 4)" 285 | HasUVs4 = VertFormat 286 | ) 287 | 0x0C:( 288 | VertTypePrint = "Binormals 2?" 289 | HasBinormals2 = VertFormat 290 | ) 291 | 0x0D:( 292 | VertTypePrint = "Tangents 2?" 293 | HasTangents2 = VertFormat 294 | ) 295 | 0x0E:( 296 | VertTypePrint = "Binormals?" 297 | HasBinormals = VertFormat 298 | ) 299 | 0x0F:( 300 | VertTypePrint = "Tangents?" 301 | HasTangents = VertFormat 302 | ) 303 | ) 304 | ) 305 | Unknown = readbyte f #unsigned 306 | if EndCheck != -1 do(print ("0x" + (bit.intAsHex(StrideStart)) as string + ": " + VertFormatPrint as string + ", " + VertTypePrint as string)) 307 | ) while EndCheck != -1 308 | print "----------" 309 | VertStrideBuffStart = (ftell f) 310 | 311 | fseek f (VertBuffStart + (PolyGrp_array[x].VertStart)) #seek_set 312 | VertCount = (PolyGrp_array[x].VertSize) / (PolyGrp_array[x].VertStride) 313 | 314 | for y = 1 to PolyGrp_array[x].NodeIDCount do( 315 | append NodeID_array Node_array[y + PolyGrp_array[x].NodeIDStart] 316 | ) 317 | 318 | for y = 1 to VertCount do( 319 | case HasVertex of( 320 | default:(fclose f; throw "Unknown position format!") 321 | 0x02:( 322 | vx = readfloat f * ModelScale 323 | vy = readfloat f * ModelScale 324 | vz = readfloat f * ModelScale 325 | append Vert_Array[vx,vy,vz] 326 | ) 327 | 0x03:( 328 | vx = readhalffloat f * ModelScale 329 | vy = readhalffloat f * ModelScale 330 | vz = readhalffloat f * ModelScale 331 | vq = readhalffloat f * ModelScale 332 | append Vert_Array[vx,vy,vz] 333 | ) 334 | ) 335 | case HasNormals of( 336 | default:(fclose f; throw "Unknown normals format!") 337 | 0x00:() 338 | 0x02:( 339 | nx = readfloat f 340 | ny = readfloat f 341 | nz = readfloat f 342 | append Normal_Array[nx,ny,nz] 343 | ) 344 | 0x03:( 345 | nx = readhalffloat f 346 | ny = readhalffloat f 347 | nz = readhalffloat f 348 | nq = readhalffloat f 349 | append Normal_Array[nx,ny,nz] 350 | ) 351 | ) 352 | case HasBinormals of( 353 | default:(fclose f; throw "Unknown binormals format!") 354 | 0x00:() 355 | 0x02:( 356 | bnx = readfloat f 357 | bny = readfloat f 358 | bnz = readfloat f 359 | ) 360 | 0x03:( 361 | bnx = readhalffloat f 362 | bny = readhalffloat f 363 | bnz = readhalffloat f 364 | bnq = readhalffloat f 365 | ) 366 | ) 367 | case HasBinormals2 of( 368 | default:(fclose f; throw "Unknown binormals2 format!") 369 | 0x00:() 370 | 0x02:( 371 | bnx2 = readfloat f 372 | bny2 = readfloat f 373 | bnz2 = readfloat f 374 | ) 375 | 0x03:( 376 | bnx2 = readhalffloat f 377 | bny2 = readhalffloat f 378 | bnz2 = readhalffloat f 379 | bnq2 = readhalffloat f 380 | ) 381 | ) 382 | case HasTangents of( 383 | default:(fclose f; throw "Unknown tangents format!") 384 | 0x00:() 385 | 0x02:( 386 | tanx = readfloat f 387 | tany = readfloat f 388 | tanz = readfloat f 389 | ) 390 | 0x03:( 391 | tanx = readhalffloat f 392 | tany = readhalffloat f 393 | tanz = readhalffloat f 394 | tanq = readhalffloat f 395 | ) 396 | ) 397 | case HasTangents2 of( 398 | default:(fclose f; throw "Unknown tangents2 format!") 399 | 0x00:() 400 | 0x02:( 401 | tanx2 = readfloat f 402 | tany2 = readfloat f 403 | tanz2 = readfloat f 404 | ) 405 | 0x03:( 406 | tanx2 = readhalffloat f 407 | tany2 = readhalffloat f 408 | tanz2 = readhalffloat f 409 | tanq2 = readhalffloat f 410 | ) 411 | ) 412 | case HasColors of( 413 | default:(fclose f; throw "Unknown colors format!") 414 | 0x00:( 415 | append Color_Array[255,255,255] 416 | append Alpha_Array 1 417 | ) 418 | 0x14:( 419 | colorr = readbyte f #unsigned 420 | colorg = readbyte f #unsigned 421 | colorb = readbyte f #unsigned 422 | colora = readbyte f #unsigned 423 | append Color_Array[colorr,colorg,colorb] 424 | append Alpha_Array colora 425 | ) 426 | ) 427 | case HasColors2 of( 428 | default:(fclose f; throw "Unknown colors2 format!") 429 | 0x00:() 430 | 0x14:( 431 | colorr2 = readbyte f #unsigned 432 | colorg2 = readbyte f #unsigned 433 | colorb2 = readbyte f #unsigned 434 | colora2 = readbyte f #unsigned 435 | ) 436 | ) 437 | case HasUVs of( 438 | default:(fclose f; throw "Unknown UVs format!") 439 | 0x00:(append UV_Array[0,0,0]) 440 | 0x02:( 441 | tu = readfloat f 442 | tv = (readfloat f * -1) + 1 443 | append UV_Array[tu,tv,0] 444 | ) 445 | 0x03:( 446 | tu = readhalffloat f 447 | tv = (readhalffloat f * -1) + 1 448 | append UV_Array[tu,tv,0] 449 | ) 450 | ) 451 | case HasUVs2 of( 452 | default:(fclose f; throw "Unknown UVs2 format!") 453 | 0x00:() 454 | 0x02:( 455 | tu2 = readfloat f 456 | tv2 = (readfloat f * -1) + 1 457 | append UV2_Array[tu2,tv2,0] 458 | ) 459 | 0x03:( 460 | tu2 = readhalffloat f 461 | tv2 = (readhalffloat f * -1) + 1 462 | append UV2_Array[tu2,tv2,0] 463 | ) 464 | ) 465 | case HasUVs3 of( 466 | default:(fclose f; throw "Unknown UVs3 format!") 467 | 0x00:() 468 | 0x02:( 469 | tu3 = readfloat f 470 | tv3 = (readfloat f * -1) + 1 471 | append UV3_Array[tu3,tv3,0] 472 | ) 473 | 0x03:( 474 | tu3 = readhalffloat f 475 | tv3 = (readhalffloat f * -1) + 1 476 | append UV3_Array[tu3,tv3,0] 477 | ) 478 | ) 479 | case HasUVs4 of( 480 | default:(fclose f; throw "Unknown UVs4 format!") 481 | 0x00:() 482 | 0x02:( 483 | tu4 = readfloat f 484 | tv4 = (readfloat f * -1) + 1 485 | append UV4_Array[tu4,tv4,0] 486 | ) 487 | 0x03:( 488 | tu4 = readhalffloat f 489 | tv4 = (readhalffloat f * -1) + 1 490 | append UV4_Array[tu4,tv4,0] 491 | ) 492 | ) 493 | case HasBones of( 494 | default:(fclose f; throw "Unknown bones format!") 495 | 0x00:(append B1_Array (Bone_Info_Struct bone1:1 bone2:1 bone3:1 bone4:1)) 496 | 0x07:( 497 | bone1 = readbyte f #unsigned + 1 498 | bone2 = readbyte f #unsigned + 1 499 | bone3 = readbyte f #unsigned + 1 500 | bone4 = readbyte f #unsigned + 1 501 | bone1 = NodeID_array[bone1] 502 | bone2 = NodeID_array[bone2] 503 | bone3 = NodeID_array[bone3] 504 | bone4 = NodeID_array[bone4] 505 | append B1_Array (Bone_Info_Struct bone1:bone1 bone2:bone2 bone3:bone3 bone4:bone4) 506 | ) 507 | ) 508 | case HasWeights of( 509 | default:(fclose f; throw "Unknown weights format!") 510 | 0x00:(append W1_Array (Weight_Info_Struct weight1:1 weight2:0 weight3:0 weight4:0)) 511 | 0x04:( 512 | weight1 = (readbyte f #unsigned as float) / 255 513 | weight2 = (readbyte f #unsigned as float) / 255 514 | weight3 = (readbyte f #unsigned as float) / 255 515 | weight4 = (readbyte f #unsigned as float) / 255 516 | append W1_Array (Weight_Info_Struct weight1:weight1 weight2:weight2 weight3:weight3 weight4:weight4) 517 | ) 518 | ) 519 | ) 520 | 521 | fseek f (PolyBuffStart + (PolyGrp_array[x].PolyStart)) #seek_set 522 | PolyCount = (PolyGrp_array[x].PolySize) / 6 523 | 524 | for p = 1 to PolyCount do( 525 | fa = readshort f #unsigned + 1 526 | fb = readshort f #unsigned + 1 527 | fc = readshort f #unsigned + 1 528 | append Face_array[fa,fb,fc] 529 | ) 530 | 531 | for b = 1 to W1_array.count Do ( 532 | w = (weight_data boneids:#() weights:#()) 533 | maxweight = 0 534 | 535 | if(W1_array[b].Weight1 != 0) then 536 | maxweight = maxweight + W1_array[b].Weight1 537 | if(W1_array[b].Weight2 != 0) then 538 | maxweight = maxweight + W1_array[b].Weight2 539 | if(W1_array[b].Weight3 != 0) then 540 | maxweight = maxweight + W1_array[b].Weight3 541 | if(W1_array[b].Weight4 != 0) then 542 | maxweight = maxweight + W1_array[b].Weight4 543 | 544 | if(maxweight != 0) then 545 | ( 546 | if(W1_array[b].Weight1 != 0) then 547 | ( 548 | w1 = W1_array[b].Weight1 as float 549 | append w.boneids (B1_array[b].Bone1) 550 | append w.weights (w1) 551 | ) 552 | if(W1_array[b].Weight2 != 0) then 553 | ( 554 | w2 = W1_array[b].Weight2 as float 555 | append w.boneids (B1_array[b].Bone2) 556 | append w.weights (w2) 557 | ) 558 | if(W1_array[b].Weight3 != 0) then 559 | ( 560 | w3 = W1_array[b].Weight3 as float 561 | append w.boneids (B1_array[b].Bone3) 562 | append w.weights (w3) 563 | ) 564 | if(W1_array[b].Weight4 != 0) then 565 | ( 566 | w4 = W1_array[b].Weight4 as float 567 | append w.boneids (B1_array[b].Bone4) 568 | append w.weights (w4) 569 | ) 570 | ) 571 | append Weight_array w 572 | ) 573 | 574 | VisGrpAdd = PolyGrp_array[x].PolyGrpStart 575 | for v = 1 to PolyGrp_array[x].PolyGrpCount do( 576 | Face_array2 = #() 577 | 578 | for w = 1 to VisGrp_array[v + VisGrpAdd].PolyCount do( 579 | Faces = Face_array[w + VisGrp_array[v + VisGrpAdd].PolyStart] - VisGrp_array[v + VisGrpAdd].VertStart 580 | append Face_array2 Faces 581 | ) 582 | 583 | VertexMin = VisGrp_array[v + VisGrpAdd].VertStart + 1 584 | VertexMax = (VisGrp_array[v + VisGrpAdd].VertStart + VisGrp_array[v + VisGrpAdd].VertCount) 585 | Vert_array2 = #() 586 | Normal_array2 = #() 587 | UV_array2 = #() 588 | UV2_array2 = #() 589 | UV3_array2 = #() 590 | UV4_array2 = #() 591 | Weight_array2 = #() 592 | 593 | for y = VertexMin to VertexMax do( 594 | append Vert_array2 Vert_array[y] 595 | append Normal_array2 Normal_array[y] 596 | -- append Color_array2 Color_array[y] 597 | -- append Alpha_array2 Alpha_array[y] 598 | append UV_array2 UV_array[y] 599 | if UV2_array.count != 0 do(append UV2_array2 UV2_array[y]) 600 | if UV3_array.count != 0 do(append UV3_array2 UV3_array[y]) 601 | if UV4_array.count != 0 do(append UV4_array2 UV4_array[y]) 602 | append Weight_array2 Weight_array[y] 603 | ) 604 | 605 | msh = mesh vertices:Vert_array2 faces:Face_array2 606 | msh.name = (g as string + " (LOD: " + VisGrp_array[v + VisGrpAdd].LODNum as string + ", VIS: " + VisGrp_array[v + VisGrpAdd].VISNum as string + ", MAT: " + PolyGrp_array[x].MatID as string + ")") 607 | msh.numTVerts = Vert_array2.count 608 | -- setNumCPVVerts msh msh.numTVerts 609 | -- setCVertMode msh true 610 | -- setShadeCVerts msh true 611 | defaultVCFaces msh 612 | buildTVFaces msh 613 | -- for j = 1 to Color_array.count do setvertcolor msh j Color_array[j] 614 | -- for j = 1 to Alpha_array.count do(meshop.setVertAlpha msh -2 j Alpha_array[j]) 615 | for j = 1 to UV_array2.count do setTVert msh j UV_array2[j] 616 | for j = 1 to Face_array2.count do setTVFace msh j Face_array2[j] 617 | for j = 1 to msh.numfaces do setFaceSmoothGroup msh j 1 618 | 619 | max modify mode 620 | select msh 621 | 622 | for face = 1 to msh.numfaces do setFaceSmoothGroup msh face 1 623 | select msh 624 | addmodifier msh (Edit_Normals ()) ui:off 625 | msh.Edit_Normals.MakeExplicit selection:#{1..Normal_array2.count} 626 | EN_convertVS = msh.Edit_Normals.ConvertVertexSelection 627 | EN_setNormal = msh.Edit_Normals.SetNormal 628 | normID = #{} 629 | for v = 1 to Normal_array2.count do 630 | ( 631 | free normID 632 | EN_convertVS #{v} &normID 633 | for id in normID do EN_setNormal id Normal_array2[v] 634 | ) 635 | 636 | if BoneCount != 0 do( 637 | skinMod = skin () 638 | boneIDMap = #() 639 | addModifier msh skinMod 640 | for i = 1 to BoneCount do 641 | ( 642 | maxbone = getnodebyname BoneArray[i].name 643 | if i != BoneCount then 644 | skinOps.addBone skinMod maxbone 0 645 | else 646 | skinOps.addBone skinMod maxbone 1 647 | 648 | ) 649 | local numSkinBones = skinOps.GetNumberBones skinMod 650 | for i = 1 to numSkinBones do 651 | ( 652 | local boneName = skinOps.GetBoneName skinMod i 0 653 | for j = 1 to BoneCount do 654 | ( 655 | if boneName == BoneArray[j].Name then 656 | ( 657 | boneIDMap[j] = i 658 | j = BoneCount + 1 659 | ) 660 | ) 661 | ) -- This fixes bone ordering in 3DS Max 2012. Thanks to sunnydavis for the fix! 662 | 663 | modPanel.setCurrentObject skinMod 664 | 665 | for i = 1 to Vert_array2.count do( 666 | skinOps.SetVertexWeights skinMod i 1 1 667 | skinOps.unnormalizeVertex skinMod i true 668 | skinOps.SetVertexWeights skinMod i 1 0 669 | ) 670 | skinOps.RemoveZeroWeights skinMod 671 | for i = 1 to Vert_array2.count do( 672 | skinOps.unnormalizeVertex skinMod i false 673 | ) -- These fix broken rigging for 3DS Max 2015 and above. 674 | 675 | for i = 1 to Weight_array2.count do ( 676 | w = Weight_array2[i] 677 | bi = #() 678 | wv = #() 679 | 680 | for j = 1 to w.boneids.count do 681 | ( 682 | boneid = w.boneids[j] 683 | weight = w.weights[j] 684 | append bi boneIDMap[boneid] 685 | append wv weight 686 | ) 687 | skinOps.ReplaceVertexWeights skinMod i bi wv 688 | ) 689 | ) 690 | 691 | local UVarrays = #(UV2_array2,UV3_array2,UV4_array2) 692 | for uva=1 to UVarrays.count do( 693 | local uvac=UVarrays[uva].count 694 | if uvac > 0 do( 695 | meshop.setNumMaps msh (uva+2) keep:true 696 | for i = 1 to uvac do meshop.setMapVert msh (uva+1) i UVarrays[uva][i] 697 | ) 698 | ) 699 | 700 | ) 701 | 702 | ) 703 | 704 | fclose f 705 | Print ("Done! ("+((((timestamp())-st)*0.001)as string)+" Seconds)") 706 | enableSceneRedraw() 707 | ) 708 | 709 | ) 710 | -------------------------------------------------------------------------------- /Scripts/PokemonORAS_BCH.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/PokemonORAS_BCH.ms -------------------------------------------------------------------------------- /Scripts/PokemonORAS_BCH_2012.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/PokemonORAS_BCH_2012.ms -------------------------------------------------------------------------------- /Scripts/PokemonSwitch_GFBMDL-TRMDL.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/PokemonSwitch_GFBMDL-TRMDL.ms -------------------------------------------------------------------------------- /Scripts/PokemonXY_BCH.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/PokemonXY_BCH.ms -------------------------------------------------------------------------------- /Scripts/PokemonXY_BCH_2012.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/PokemonXY_BCH_2012.ms -------------------------------------------------------------------------------- /Scripts/SSB4U-TaikoU_NDP3.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/SSB4U-TaikoU_NDP3.ms -------------------------------------------------------------------------------- /Scripts/SSB4U-TaikoU_NDP3_Debug.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/SSB4U-TaikoU_NDP3_Debug.ms -------------------------------------------------------------------------------- /Scripts/SSB4U-TaikoU_NDP3_UpdateWIP.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/SSB4U-TaikoU_NDP3_UpdateWIP.ms -------------------------------------------------------------------------------- /Scripts/SSBUlt-NPS_NUMDLB.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/SSBUlt-NPS_NUMDLB.ms -------------------------------------------------------------------------------- /Scripts/TelltaleGames_D3DMesh.ms: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/TelltaleGames_D3DMesh.ms -------------------------------------------------------------------------------- /Scripts/TelltaleHashDBs/BoneNames.HashDB: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/TelltaleHashDBs/BoneNames.HashDB -------------------------------------------------------------------------------- /Scripts/TelltaleHashDBs/TexNames.HashDB: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RandomTBush/RTB-3DSMax-Scripts/7ae89262b01ef3d4b629bcfd1c46402eac8a1cee/Scripts/TelltaleHashDBs/TexNames.HashDB --------------------------------------------------------------------------------