don't click here

Sonic Generations Hacking (and More!)

Discussion in 'Engineering & Reverse Engineering' started by Andrew75, Jun 23, 2011.

  1. It looks sooo smooth. I wish more games were like this.
     
  2. winterhell

    winterhell

    Member
    1,165
    7
    18
    On a relevant note, can the game be forced to run at 120fps?
     
  3. Twilightzoney

    Twilightzoney

    Tech Member
    353
    0
    16
    Elgin, IL And Hampshire
    Unleashed and Generations Stuff and Custom Works
    Was able to get cutscenes working for the most part few hitches here and there that I would have to actually edit the animations. Since you cannot hide a mesh or state when their animation begins playing at or stopping. Unleashed's cutscene defining had a lot more going on with it.

    The deal with cutscenes not working before is that we had no way of editing the file that controlled the Scene info. They decided to use a compiled file instead of just straight up xml like in Unleashed to define everything. And Dario helped me figure out the rotation and position from the 4x4 Matrix that Unleashed used since Generations just uses XYZ and Y rotation.



    [​IMG]

    You might get something nice, or you get this.

    [​IMG]

    Don't mind the shader issue, apparently in Unleashed they had a shader that refixed their laziness. Making a gloss shader section into a specular. Who puts a specular in the gloss map anyways??
    Thats why models look a bit messed up. And Chip is missing his head due to some morpher issue. Working on fixing all these issues to render out higher quality cutscenes in the end if Dario ends up supporting morphers for exporting. Imagine how much fun that would be to add to character mods.

    I"m going to have to edit some animations to fix up the timing on these to fit with the animations not hard but time consuming to do. Will be neat to see all the cutscenes in good IQ.
     
  4. Falk

    Falk

    Member
    1,570
    15
    18
    The biggest thing you notice immediately is that it has camera pan blur. The Hedgehog Engine used a few quick-and-dirty methods for simulating blur with a moving camera, but not one where it's stationary but panning.

    That aside though I'm of the opinion that there's a sweet spot for the amount of motion blur. (essentially a simulation of shutter angle) Square Enix game cutscenes (Visual Works) typically use something like 0.1 and that's more than enough to inject some movement information into each frame.

    In the case of Sonic though where blur is used for effect, going up to 0.5 is fine. On the flipside, 0.5 does turn everything else into a blurry mess when you may not want it to. Ideally I think if there was the horsepower for it in future, having an adaptive algorithm that scaled from 0.1 to 0.5 based on Sonic's speed for that frame would give the best effect. But I'm getting way ahead of myself here.


    edit: And yes, tl;dr high FPS raw footage is the tits. I even managed to make Call of Duty look good.
     
  5. Not exactly a Generations mod, but Durante (famous for his Dark Souls Fix) has released a general down-sampling tool. I've been running Sonic Generations at 7K and taking screenshots, and my good lord it's gorgeous.

    Check it out, GeDoSaTo.

    From Skyfireblaze in the NeoGAF thread, how to get Sonic Generations working with GeDoSaTo:
    I bumped it up to 7K and took some shots.

     
  6. Falk

    Falk

    Member
    1,570
    15
    18
    All those pixels but 4:3

    For shame :V

    edit: Nevermind, I just received a phone call that I need my eyes checked! Carry on.
     
  7. Nemo

    Nemo

    Member
    18
    0
    0
    EDIT: Seems this is a problem that I've had in the past as well.

    I'm trying to import character models and animations into 3DS Max. The import script on this topic's front page seems to import the model nice and clean, but any .kf animations imported distort the character; rotating all bones' positions 90 degrees around the origin by the X axis.

    Another script I've found online imports a perfectly-functional skeleton that accepts animations really well. But it separates the character's body into a huge mess of separate parts that can't be put together. The result is a character with really ugly "cracks" in his body.

    I'll spend some time analyzing it myself to see if I can fix the problem, but I'm not familiar with the language. If anyone else could help that'd be cool.


    Here's the alternative script I've found online:
    Code (Text):
    1. clearlistener()
    2.     -- script originally written by chroxx, Link, and Kentalin. Modified by Brooks (ItsEasyActually) for Generations :D
    3.  
    4. struct weight_data
    5. (
    6.     boneids,weights
    7. )
    8.  
    9. struct BoneOffset (
    10. BoneTOffset
    11. )
    12.  
    13. struct BoneDataStruc (
    14. BoneID, BoneNameOffset, BoneName, BoneParentID
    15. )
    16.  
    17. fn PrintOffset Var =
    18. (
    19.     local Var = Var
    20. print ("This is the offset 0x" + (bit.intAsHex Var) as string)
    21.     Var
    22. )
    23. y = 180
    24. PrintOffset y
    25. x = 200
    26. print ("This is the number 0x" + (bit.intAsHex x) as string)
    27.  
    28. fn floatSwap2 f =
    29. (
    30.     I = bit.floatAsInt f
    31.     h = bit.intashex I
    32.     while h.count < 8 do h = "0" + h
    33.    
    34.     s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2)
    35.     bit.intAsFloat (bit.hexasint s)
    36. )  
    37.  
    38. fn ReadBEword fstream = (
    39. return (bit.swapBytes (readshort fstream #unsigned) 1 2)
    40. )
    41.  
    42.  fn ReadBEHalfFloat Fstream = (
    43.   local BH  = readByte Fstream #unsigned
    44.   local BL  = readByte Fstream #unsigned
    45.   local N = BH*256 + BL
    46.   local S = floor((mod N 65536) / 32768)
    47.   local Ef = floor((mod N 32768) / 1024)
    48.   local M = mod N 1024
    49.   if (Ef==0)AND(M==0) then return ( (-1.0)^S * 0.0 )
    50.   if (Ef==0)AND(M!=0) then return ( (-1.0)^S * 2.0^-14 * (M / 2.0^10) )
    51.   if (Ef>0)AND(Ef<31) then return ( (-1.0)^S * 2.0^(Ef-15) * (1 + M/2.0^10) )
    52.   if (Ef==31)AND(M==0) then return ( (-1.0)^S * 1/0.0 )
    53.   if (Ef==31)AND(M!=0) then return 0    --hack-- should be #inf  
    54.  )--end fn ReadBEHalfFloat
    55.  
    56. fn ReadBElong fstream = (
    57. long = readlong fstream
    58. long = bit.swapBytes long 1 4
    59. long = bit.swapBytes long 2 3
    60. return long
    61. )
    62.  
    63. fn ReadBEfloat fstream = (
    64. return floatSwap2(readfloat fstream)
    65. )
    66.  
    67. if (heapSize < 20000000) then
    68.     heapSize = 200000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"
    69.  
    70. -- TexDir = getSavePath caption:"Select texture path" initialDir:"C:\Users\Experience\Desktop\Emulators\Games\360\Sonic Generations Demo\disk\bb\Packed\ghz100\TexPack"
    71. -- Textures = getFiles (TexDir+"/*.dds")
    72. -- Materials = getFiles (TexDir+"/*.material")
    73.  
    74. fname = GetOpenFileName caption:"Open Sonic Model File" types:"Sonic Model File(*.model)|*.model"
    75. f = fopen fname "rb"   --open file in read only format
    76.  
    77. filepath = GetFilenamePath fname
    78.  
    79. fseek f 0x18#seek_set
    80. MeshHeaderTotal = ReadBELong f
    81. OffsetMHLoc = ReadBELong f + 0x18
    82. CinematicMesh = ReadBElong f
    83. MorphTargetTable = ReadBElong f + 0x18
    84. BoneCount = ReadBElong f
    85. BoneTableOffset = ReadBElong f + 0x18
    86. BoneTableOffset2 = ReadBElong f + 0x18
    87. BoneTableOffset3 = ReadBElong f + 0x18
    88.  
    89.  
    90. fseek f BoneTableOffset#seek_set
    91. Bone_Offset_array = #()
    92. for I = 1 to BoneCount Do (
    93. BoneTOffset = ReadBElong f + 0x18
    94. append Bone_Offset_array (BoneOffset BoneTOffset:BoneTOffset)
    95. )
    96. print Bone_Offset_array
    97. Bone_Data_array = #()
    98. BoneID = -1
    99. for k in Bone_Offset_array Do (
    100. fseek f k.BoneTOffset#seek_set
    101. BoneID += 1
    102. BoneParentID = ReadBElong f
    103. BoneNameOffset = ReadBElong f
    104. BoneName = readstring f
    105. append Bone_Data_array ( BoneDataStruc BoneID:BoneID BoneNameOffset:BoneNameOffset BoneName:BoneName BoneParentID:BoneParentID )
    106. )
    107. print Bone_Data_array
    108. fseek f BoneTableOffset2 #seek_set
    109. --if CinematicMesh == 1 Do (
    110. --fseek f 0x1#seek_cur
    111. --)
    112. BNArr = #()
    113. disableSceneRedraw()
    114. Bone_root_array = #()
    115. for I = 1 to BoneCount Do (
    116. m11 = ReadBEfloat f; m12 = ReadBEfloat f; m13 = ReadBEfloat f; m14 = ReadBEfloat f
    117. m21 = ReadBEfloat f; m22 = ReadBEfloat f; m23 = ReadBEfloat f; m24 = ReadBEfloat f
    118. m31 = ReadBEfloat f; m32 = ReadBEfloat f; m33 = ReadBEfloat f; m34 = ReadBEfloat f
    119. m41 = ReadBEfloat f; m42 = ReadBEfloat f; m43 = ReadBEfloat f; m44 = ReadBEfloat f
    120. tfm = matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]
    121.    
    122. newBone = bonesys.createbone    \
    123.                   tfm.row4  \
    124.                   (tfm.row4 + 0.01 * (normalize tfm.row1)) \
    125.                   (normalize tfm.row3)
    126.             newBone.name   = Bone_Data_array[I].BoneName
    127.  
    128.             newBone.width  = 0.01
    129.             newBone.height = 0.01
    130.             newBone.transform = tfm
    131.             newBone.wirecolor = yellow
    132.             newbone.showlinks = true
    133.                      
    134.             pos = [m14,m24,m34]
    135.             pos = pos * tfm
    136.  
    137.             newBone.pos.x = (-1)*pos.x
    138.             newBone.pos.y = (-1)*pos.y
    139.             newBone.pos.z = (-1)*pos.z
    140.  
    141.             newBone.setBoneEnable false 0
    142.             newBone.pos.controller      = TCB_position ()
    143.             newBone.rotation.controller = TCB_rotation ()
    144.  
    145.            
    146.             if (Bone_Data_array[I].BoneParentID != -1) then
    147.                       newBone.parent = BNArr[Bone_Data_array[I].BoneParentID+1]
    148.  
    149.             BNArr[I] = newBone
    150.             if I == 1 do (
    151.                 append Bone_root_array newBone
    152.             )
    153.            
    154.                   )
    155. MorphArr = #()
    156. MorphArr2 = #()
    157. Morph_Face_array = #()
    158. Morph_Name_array = #()
    159.  
    160. print "Bones done"
    161.  
    162. if CinematicMesh == 1 Then (
    163. fseek f MorphTargetTable #seek_set
    164. MorphVertCountOffset = ReadBElong f + 0x18
    165. MorphVertCount = ReadBElong f  
    166. MorphTableEnd = ReadBElong f + 0x18
    167. MorphUnkCount1 = ReadBElong f
    168. MorphCount = ReadBElong f
    169. MorphTableStart = ReadBElong f + 0x18
    170. MorphTableNameStart = ReadBElong f + 0x18
    171. MorphFaceSetsCount = ReadBElong f
    172. MorphFaceTableStart = ReadBElong f + 0x18
    173. Null = readlong f
    174. MorphFaceTableEnd = ReadBElong f + 0x18
    175.  
    176. Bone_ids1 = #()
    177.  
    178. fseek f MorphFaceTableStart#seek_set
    179. PrintOffset (ftell f)
    180. MorphFaceSets = #()
    181. for I = 1 to MorphFaceSetsCount Do
    182. (
    183.     FaceSetStart = ReadBElong f + 0x18
    184.     append MorphFaceSets FaceSetStart
    185. )
    186. for I = 1 to MorphFaceSetsCount Do
    187. (
    188. fseek f MorphFaceSets[I] #seek_set
    189. Offset1 = ReadBElong f  + 0x18
    190. MorphFaceCount = ReadBElong f
    191. MorphFaceOffset = ReadBElong f + 0x18
    192. if ( I == 1) then
    193. (
    194.     fseek f 0x10 #seek_cur
    195.     boneidcount = ReadBElong f
    196.     boneidstart = (ReadBElong f) + 0x18
    197.            
    198.     fseek f boneidstart #seek_set
    199.     for j=1 to boneidcount do
    200.     (
    201.         addboneid = (ReadByte f #unsigned)
    202.         append Bone_ids1 (addboneid + 1)
    203.     )
    204. )  
    205. fseek f MorphFaceOffset#seek_set
    206. StartDirection = 1
    207. f1 = (ReadBEword f) + 1
    208. f2 = (ReadBEword f) + 1  
    209. FaceDirection = StartDirection
    210. Do (
    211. f3 = (ReadBEword f)
    212. if (f3==0xFFFF) then (
    213. f1 = (ReadBEword f) + 1
    214. f2 = (ReadBEword f) + 1
    215. FaceDirection = StartDirection
    216. ) else (
    217. f3 += 1
    218. FaceDirection *= -1
    219. if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
    220. if FaceDirection > 0 then append Morph_Face_array [f1,f2,f3]
    221. else append Morph_Face_array [f1,f3,f2]
    222. )
    223. f1 = f2
    224. f2 = f3
    225. )
    226. ) while ((ftell f) != (MorphFaceOffset + (MorphFaceCount * 2)))
    227. )
    228.  
    229. fseek f MorphTableEnd #seek_set
    230.  
    231. Vert_array1 = #() --define arrays for verts, normals, UV and Faces
    232. Normal_array1 = #()
    233. UV_array1 = #()
    234. Weight_array1 = #()
    235.  
    236.  
    237.  
    238. for k = 1 to MorphVertCount Do (
    239. vx = ReadBEfloat f  --read xyz coordinates
    240. vy = ReadBEfloat f
    241. vz = ReadBEfloat f
    242. fseek f 0x24#seek_cur
    243. tu = ReadBEFloat f   --read UV float value
    244. tv = ReadBEFloat f * -1
    245. fseek f 0x28#seek_cur
    246.  
    247. bone1 = readbyte f#unsigned
    248. bone2 = readbyte f#unsigned
    249. bone3 = readbyte f#unsigned
    250. bone4 = readbyte f#unsigned
    251. weight1 = readbyte f#unsigned
    252. weight2 = readbyte f#unsigned
    253. weight3 = readbyte f#unsigned
    254. weight4 = readbyte f#unsigned
    255.  
    256. w = (weight_data boneids:#() weights:#())
    257.  
    258. maxweight = 0
    259.    
    260. if(bone1 != 0xFF) then
    261.     maxweight = maxweight + weight1
    262. if(bone2 != 0xFF) then
    263.     maxweight = maxweight + weight2
    264. if(bone3 != 0xFF) then
    265.     maxweight = maxweight + weight3
    266. if(bone4 != 0xFF) then
    267.     maxweight = maxweight + weight4
    268.  
    269. if(maxweight != 0) then
    270.     (
    271.         mxw = maxweight as float
    272.         if(bone1 != 0xFF) then
    273.         (
    274.             w1 = weight1 as float
    275.             append w.boneids (Bone_ids1[bone1+1])
    276.             append w.weights (w1 / mxw)
    277.         )
    278.         if(bone2 != 0xFF) then
    279.         (
    280.             w2 = weight2 as float
    281.             append w.boneids (Bone_ids1[bone2+1])
    282.             append w.weights (w2 / mxw)
    283.         )
    284.         if(bone3 != 0xFF) then
    285.         (
    286.             w3 = weight3 as float
    287.             append w.boneids (Bone_ids1[bone3+1])
    288.             append w.weights (w3 / mxw)
    289.         )
    290.         if(bone4 != 0xFF) then
    291.         (
    292.             w4 = weight4 as float
    293.             append w.boneids (Bone_ids1[bone4+1])
    294.             append w.weights (w4 / mxw)
    295.         )      
    296.     )
    297.  
    298. append Vert_array1 [vx,vy,vz]
    299. append UV_array1 [tu,tv,0]  --save UVs to UV_array
    300. append Weight_array1 w
    301. )
    302. msh = mesh vertices:Vert_array1 faces:Morph_Face_array --build mesh
    303. msh.numTVerts = UV_array1.count
    304. buildTVFaces msh
    305. msh.name =  "Mouth"
    306. for j = 1 to UV_array1.count do setTVert msh j UV_array1[j]
    307. for j = 1 to Morph_Face_array.count do setTVFace msh j Morph_Face_array[j]
    308. for j = 1 to Normal_array1.count do setNormal msh j Normal_array1[j]
    309. select $Mouth
    310. MorphMod = morpher ()
    311. addModifier $Mouth MorphMod
    312. $Mouth.morpher.Autoload_of_targets = 1
    313. --$Mouth.parent = $Neck
    314.  
    315. fseek f MorphTableStart#seek_set
    316. for I = 1 to MorphCount Do (
    317. append MorphArr (ReadBElong f + 0x18)
    318. )
    319. for I = 1 to MorphCount Do (
    320. append MorphArr2 (ReadBElong f + 0x18)
    321. )  
    322. for I = 1 to MorphCount Do (
    323. fseek f MorphArr[I]#seek_set
    324. MorphName = readstring f
    325. fseek f MorphArr2[I]#seek_set
    326. Morph_Vert_array = #()
    327. Morph_UV_array = #()
    328. Morph_Normal_array = #()
    329. for k = 1 to MorphVertCount Do (
    330. vx = ((ReadBEfloat f) ) + Vert_array1[k].x
    331. vy = ((ReadBEfloat f) ) + Vert_array1[k].y
    332. vz = ((ReadBEfloat f) ) + Vert_array1[k].z
    333. append Morph_Vert_array [vx,vy,vz]
    334. )
    335.  
    336. msh = mesh vertices:Morph_Vert_array faces:Morph_Face_array   --build mesh
    337. msh.numTVerts = UV_array1.count
    338. buildTVFaces msh
    339. msh.name =  MorphName
    340. for j = 1 to UV_array1.count  do setTVert msh j UV_array1[j]
    341. for j = 1 to Morph_Face_array.count  do setTVFace msh j Morph_Face_array[j]
    342. for j = 1 to Morph_Normal_array.count do setNormal msh j Morph_Normal_array[j]
    343. append Morph_Name_array msh
    344. )
    345.  
    346. max modify mode
    347. select $mouth
    348. skinMod = skin ()
    349. addModifier $mouth skinMod
    350. for I = 1 to BNArr.count do
    351. (
    352.     maxbone = getnodebyname BNArr[I].name
    353.     if I != BNArr.count then
    354.         skinOps.addBone skinMod maxbone 0
    355.     else
    356.         skinOps.addBone skinMod maxbone 1
    357.    
    358. )
    359.  
    360. modPanel.setCurrentObject skinMod
    361.  
    362. for I = 1 to Weight_array1.count do
    363. (
    364.     w = Weight_array1[I]
    365.     bi = #() --bone index array
    366.     wv = #() --weight value array
    367.    
    368.     for j = 1 to w.boneids.count do
    369.     (
    370.         boneid = w.boneids[j]
    371.         weight = w.weights[j]
    372.         append bi boneid
    373.         append wv weight
    374.     )  
    375.    
    376.     skinOps.ReplaceVertexWeights skinMod I bi wv
    377. )
    378.  
    379. max create mode
    380.  
    381. )
    382. for b = 1 to Morph_Name_array.count Do (
    383.     WM3_MC_BuildFromNode $Mouth.morpher b Morph_Name_array[b]
    384.     hide Morph_Name_array[b]
    385. )
    386.  
    387. fseek f OffsetMHLoc#seek_set
    388.  
    389. for m = 1 to MeshHeaderTotal Do (
    390. MeshHeader = ReadBELong f + 0x18
    391.     NextHeader = ftell f
    392.    
    393.  
    394. fseek f MeshHeader#seek_set
    395. MeshCount = ReadBElong f
    396. MshLoc = ReadBElong f + 0x18
    397. AddMeshCount = ReadBElong f
    398. AddMeshBegin = ReadBElong f + 0x18
    399. AlphaMeshCount = ReadBELong f
    400. AlphaMeshBegin = ReadBELong f + 0x18
    401.  
    402. fseek f 0x4#seek_cur
    403. TestByte = ReadByte f#unsigned
    404. if TestByte != 0xFF Do (
    405.     fseek f -0x5#seek_cur
    406.     OpaqueCount = ReadBELong f
    407.     OpaqueOffset = ReadBELong f + 0x1C
    408.     fseek f OpaqueOffset#seek_set
    409.     OpOff = ReadBELong f + 0x18
    410.     OpaqueMeshBegin = ReadBELong f + 0x18  
    411.     fseek f OpOff#seek_set
    412.     OpaqueMeshCount = ReadBELong f
    413. )
    414.  
    415. if TestByte == 0xFF Do (
    416.     OpaqueMeshCount = 0
    417. )
    418.  
    419. fseek f MshLoc#seek_set
    420. for c = 1 to MeshCount+AddMeshCount+AlphaMeshCount+OpaqueMeshCount Do (
    421.  
    422. if(c == MeshCount + 1) then (
    423.     fseek f AddMeshBegin #seek_set
    424. )  
    425.  
    426. if(c == (MeshCount+AddMeshCount) + 1) then (
    427.     fseek f AlphaMeshBegin #seek_set
    428. )  
    429.  
    430. if(c == (MeshCount+AddMeshCount+AlphaMeshCount) + 1) then (
    431.     fseek f OpaqueMeshBegin #seek_set
    432. )  
    433.  
    434.     Vert_array = #()
    435.     Normal_array = #()
    436.     UV_array = #()
    437.     Face_array = #()
    438.     Weight_array = #()
    439.     BoneID_array = #()
    440.    
    441. offsetstart = (ReadBElong f) + 0x18
    442. tablestart = ftell f
    443.     fseek f offsetstart#seek_set
    444. TexNameOff = ReadBElong f + 0x18
    445. FaceCount = ReadBElong f   
    446. FaceStart = ReadBElong f    + 0x18
    447. VertCount = ReadBElong f   
    448. VertSize = ReadBElong f
    449. VertStart = ReadBElong f + 0x18
    450. VertEnd = ReadBElong f + 0x18
    451. SecBoneCount = ReadBElong f
    452. SecBoneIDs = (ReadBElong f) + 0x18
    453. MaterialCount = ReadBElong f   
    454. MaterialCountOffset = ReadBElong f
    455.  
    456. BackJump = ftell f
    457.    
    458. fseek f SecBoneIDs #seek_set
    459. for I = 1 to SecBoneCount do
    460. (
    461.     addboneid = (ReadByte f #unsigned)
    462.     append BoneID_array (addboneid + 1)
    463. )
    464.    
    465. fseek f BackJump #seek_set
    466.    
    467. FaceStart = ftell f
    468. VerStart = (FaceCount * 2) + FaceStart
    469.  
    470.  
    471. StartDirection = 1
    472. f1 = (ReadBEword f) + 1
    473. f2 = (ReadBEword f) + 1  
    474. FaceDirection = StartDirection
    475. Do (
    476. f3 = (ReadBEword f)
    477. if (f3==0xFFFF) then (
    478. f1 = (ReadBEword f) + 1
    479. f2 = (ReadBEword f) + 1
    480. FaceDirection = StartDirection
    481. ) else (
    482. f3 += 1
    483. FaceDirection *= -1
    484. if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
    485. if FaceDirection > 0 then append Face_array [f1,f2,f3]
    486. else append Face_array [f1,f3,f2]
    487. )
    488. f1 = f2
    489. f2 = f3
    490. )
    491. ) while ((ftell f) != (VerStart))
    492. fseek f VerStart#seek_set
    493.  test = readshort f
    494.  if test != 0x0000 Do (
    495.          fseek f -2 #seek_cur
    496. )
    497. fseek f VertStart#seek_set
    498. for v = 1 to VertCount Do (
    499. if VertSize == 0x24 Do (
    500. vx = ReadBEfloat f  --read xyz coordinates
    501. vy = ReadBEfloat f
    502. vz = ReadBEfloat f
    503. bone1 = readbyte f#unsigned
    504. bone2 = readbyte f#unsigned
    505. bone3 = readbyte f#unsigned
    506. bone4 = readbyte f#unsigned
    507. weight1 = readbyte f#unsigned
    508. weight2 = readbyte f#unsigned
    509. weight3 = readbyte f#unsigned
    510. weight4 = readbyte f#unsigned
    511. fseek f 0x8#seek_cur
    512. tu = ReadBEHalfFloat f   --read UV float value
    513. tv = ReadBEHalfFloat f * -1
    514. fseek f 0x4#seek_cur
    515. )
    516. if VertSize == 0x28 Do (
    517. vx = ReadBEfloat f  --read xyz coordinates
    518. vy = ReadBEfloat f
    519. vz = ReadBEfloat f
    520. fseek f 0xC#seek_cur
    521. tu = ReadBEHalfFloat f   --read UV float value
    522. tv = ReadBEHalfFloat f * -1
    523. fseek f 0x4#seek_cur
    524.  
    525. bone1 = readbyte f#unsigned
    526. bone2 = readbyte f#unsigned
    527. bone3 = readbyte f#unsigned
    528. bone4 = readbyte f#unsigned
    529. weight1 = readbyte f#unsigned
    530. weight2 = readbyte f#unsigned
    531. weight3 = readbyte f#unsigned
    532. weight4 = readbyte f#unsigned
    533. )
    534. if VertSize == 0x2C Do (
    535. vx = ReadBEfloat f  --read xyz coordinates
    536. vy = ReadBEfloat f
    537. vz = ReadBEfloat f
    538. fseek f 0x10#seek_cur
    539. tu = ReadBEHalfFloat f   --read UV float value
    540. tv = ReadBEHalfFloat f * -1
    541. fseek f 0x4#seek_cur
    542.    
    543. bone1 = readbyte f#unsigned
    544. bone2 = readbyte f#unsigned
    545. bone3 = readbyte f#unsigned
    546. bone4 = readbyte f#unsigned
    547. weight1 = readbyte f#unsigned
    548. weight2 = readbyte f#unsigned
    549. weight3 = readbyte f#unsigned
    550. weight4 = readbyte f#unsigned
    551. )
    552.  
    553. if VertSize == 0x30 Do(
    554. vx = ReadBEFloat f
    555. vy = ReadBEFloat f
    556. vz = ReadBEFloat f
    557. fseek f 0xC#seek_cur
    558. tu = ReadBEHalfFloat f
    559. tv = ReadBEHalfFloat f * -1
    560. fseek f 0xC#seek_cur
    561. bone1 = readbyte f#unsigned
    562. bone2 = readbyte f#unsigned
    563. bone3 = readbyte f#unsigned
    564. bone4 = readbyte f#unsigned
    565. weight1 = readbyte f#unsigned
    566. weight2 = readbyte f#unsigned
    567. weight3 = readbyte f#unsigned
    568. weight4 = readbyte f#unsigned
    569. )
    570.  
    571. if VertSize == 0x34 Do (
    572. vx = ReadBEFloat f
    573. vy = ReadBEFloat f
    574. vz = ReadBEFloat f
    575. fseek f 0x10#seek_cur
    576. tu = ReadBEHalfFloat f
    577. tv = ReadBEHalfFloat f * -1
    578. fseek f 0xC#seek_cur
    579. bone1 = readbyte f#unsigned
    580. bone2 = readbyte f#unsigned
    581. bone3 = readbyte f#unsigned
    582. bone4 = readbyte f#unsigned
    583. weight1 = readbyte f#unsigned
    584. weight2 = readbyte f#unsigned
    585. weight3 = readbyte f#unsigned
    586. weight4 = readbyte f#unsigned
    587. )
    588.  
    589. if VertSize == 0x68 Do (
    590. vx = ReadBEfloat f  --read xyz coordinates
    591. vy = ReadBEfloat f
    592. vz = ReadBEfloat f
    593. fseek f 0x24#seek_cur
    594. tu = ReadBEFloat f   --read UV float value
    595. tv = ReadBEFloat f * -1
    596. fseek f 0x28#seek_cur
    597.    
    598. bone1 = readbyte f#unsigned
    599. bone2 = readbyte f#unsigned
    600. bone3 = readbyte f#unsigned
    601. bone4 = readbyte f#unsigned
    602. weight1 = readbyte f#unsigned
    603. weight2 = readbyte f#unsigned
    604. weight3 = readbyte f#unsigned
    605. weight4 = readbyte f#unsigned
    606. )
    607.  
    608. w = (weight_data boneids:#() weights:#())
    609.  
    610. maxweight = 0
    611.    
    612. if(bone1 != 0xFF) then
    613.     maxweight = maxweight + weight1
    614. if(bone2 != 0xFF) then
    615.     maxweight = maxweight + weight2
    616. if(bone3 != 0xFF) then
    617.     maxweight = maxweight + weight3
    618. if(bone4 != 0xFF) then
    619.     maxweight = maxweight + weight4
    620.  
    621. if(maxweight != 0) then
    622.     (
    623.         mxw = maxweight as float
    624.         if(bone1 != 0xFF) then
    625.         (
    626.             w1 = weight1 as float
    627.             append w.boneids (BoneID_array[bone1+1])
    628.             append w.weights (w1 / mxw)
    629.         )
    630.         if(bone2 != 0xFF) then
    631.         (
    632.             w2 = weight2 as float
    633.             append w.boneids (BoneID_array[bone2+1])
    634.             append w.weights (w2 / mxw)
    635.         )
    636.         if(bone3 != 0xFF) then
    637.         (
    638.             w3 = weight3 as float
    639.             append w.boneids (BoneID_array[bone3+1])
    640.             append w.weights (w3 / mxw)
    641.         )
    642.         if(bone4 != 0xFF) then
    643.         (
    644.             w4 = weight4 as float
    645.             append w.boneids (BoneID_array[bone4+1])
    646.             append w.weights (w4 / mxw)
    647.         )      
    648.     )
    649.  
    650. append Vert_array [vx,vy,vz] --save verts to Vert_array
    651. --append Normal_array [nx,ny,nz] --save normals to Normal_array
    652. append UV_array [tu,tv,0]  --save UVs to UV_array
    653. append Weight_array w
    654.  
    655. )
    656. fseek f TexNameOff#seek_set
    657. TexName = ReadString f
    658. print TexName
    659.  
    660. fseek f tablestart#seek_set
    661.  
    662. MaterialFile = (filepath+"/")+(TexName+".material")
    663.  
    664. msh = mesh vertices:Vert_array faces:Face_array --build mesh
    665. msh.numTVerts = UV_array.count
    666. buildTVFaces msh    
    667. msh.name = TexName
    668. for j = 1 to UV_array.count do setTVert msh j UV_array[j]
    669. for j = 1 to Face_array.count do setTVFace msh j Face_array[j]
    670. for j = 1 to Normal_array.count do setNormal msh j Normal_array[j]
    671.    
    672. max modify mode
    673. select msh
    674. skinMod = skin ()
    675. addModifier msh skinMod
    676. for I = 1 to BNArr.count do
    677. (
    678.     maxbone = getnodebyname BNArr[I].name
    679.     if I != BNArr.count then (
    680.         skinOps.addBone skinMod maxbone 0
    681.     )else(
    682.         skinOps.addBone skinMod maxbone 1
    683.     )
    684. )
    685.  
    686. modPanel.setCurrentObject skinMod
    687.  
    688. for I = 1 to Weight_array.count do
    689. (
    690.     w = Weight_array[I]
    691.     bi = #() --bone index array
    692.     wv = #() --weight value array
    693.    
    694.     for j = 1 to w.boneids.count do
    695.     (
    696.         boneid = w.boneids[j]
    697.         weight = w.weights[j]
    698.         append bi boneid
    699.         append wv weight
    700.     )  
    701.    
    702.     skinOps.ReplaceVertexWeights skinMod I bi wv
    703. )
    704.  
    705. mf = fopen MaterialFile "rb"
    706.  
    707. fseek mf 0x24#seek_set
    708. TextureTable = ReadBELong mf +0x18
    709. fseek mf 0x6#seek_cur
    710. TextureTotal = ReadBEWord mf
    711.  
    712. -- DiffArr = #()
    713. -- BumpArr = #()
    714. -- SpecArr = #()
    715.  
    716. fseek mf TextureTable#seek_set
    717.     m = standardMaterial()
    718. for tex = 1 to 1 Do (
    719.  
    720.     TextureNameOff = ReadBELong mf +0x18
    721.     NextTex = ftell mf
    722.    
    723.     fseek mf TextureNameOff#seek_set
    724.     fseek mf 0xC#seek_cur
    725.     TextureName = ReadString mf +".dds"
    726.     TexType = ReadString mf as name
    727.    
    728.     TextureFile = filepath+"/"+TextureName
    729.    
    730. --  print "TextureType ="
    731. --  print TexType
    732. --  
    733. --  if TexType == "diffuse" Do (
    734. --      bt = BitmapTexture()
    735. --      bt.FileName = TextureFile
    736. --      m.DiffuseMap = bt
    737. --  )
    738. --  
    739. --  if TexType == "normal" Do (
    740. --      nt = BitmapTexture()
    741. --      nt.FileName = TextureFile
    742. --      append BumpArr[nt]
    743. --  )
    744. --  
    745. --  if TexType == "specular" Do (
    746. --      st = BitmapTexture()
    747. --      st.FileName = TextureFile
    748. --      append SpecArr[st]
    749. --  )
    750. --  
    751. --  if TexType == "opacity" Do (
    752. --      ot = BitmapTexture()
    753. --      ot.FileName = TextureFile
    754. --  )
    755. --  
    756. --  if TexType == "reflection" Do (
    757. --      rt = BitmapTexture()
    758. --      rt.FileName = TextureFile
    759. --  )
    760. --  
    761. --  if TexType == "displacement" Do (
    762. --      dt = BitmapTexture()
    763. --      dt.FileName = TextureFile
    764. --  )
    765. --  
    766. --  if TexType == "gloss" Do (
    767. --      gt = BitmapTexture()
    768. --      gt.FileName = TextureFile
    769. --  )
    770.    
    771.     bt = BitmapTexture()
    772.     bt.FileName = TextureFile
    773.     m.DiffuseMap = bt
    774.     print bt
    775.     )
    776.    
    777. --  fseek mf NextTex#seek_set
    778.  
    779. -- m.DiffuseMap = bt
    780. -- m.BumpMap = nt
    781. -- m.SpecularMap = st
    782. -- m.OpacityMap = ot
    783. -- m.ReflectionMap = rt
    784. -- m.DisplacementMap = dt
    785. -- m.GlossinessMap = gt
    786.  
    787. m.showInViewport = true
    788. $.material = m
    789.  
    790.  
    791. max create mode
    792. )
    793. fseek f NextHeader#seek_set
    794. )
    795.  
    796. enableSceneRedraw()
    797. select Bone_root_array[1]
    798. scale $ [36.0,36.0,36.0]
    799. rotate $ (angleaxis 90 [1,0,0])
    800.  
    801.  
    802. fclose mf
    803. fclose f
    804. clearSelection()
    805. actionMan.executeAction 0 "311"  -- Tools: Zoom Extents All Selected
    806.  
     
  8. Dark Sonic

    Dark Sonic

    Member
    14,631
    1,617
    93
    Working on my art!
    So the guy who made the Holoska Adventure pack (And not the Abadat Adventure pack as I have been pointed out) has released the Shamar Adventure pack.

    https://www.youtube.com/watch?v=W1Xphm9-3CM

    Granted they're both a bit shoddier than the Abadat Adventure pack but I certainly don't mind the idea of having all of these ported to Generations.

    EDIT: Oh fun they actually got the chao act working
     
  9. Falk

    Falk

    Member
    1,570
    15
    18
    I chortled at 11s of the video

    Rip the Generations design from somewhere, paste white text over it.
     
  10. Lanzer

    Lanzer

    The saber calls for its master... Member
    6,845
    4
    18
    Glendale, AZ
    Living life.
    Hold the phone, I must not be reading that right are you saying that you got sonic unleashed in-game cut scenes to work in sonic generations?!

    If thats right then holy fucking hell that is a phenomenal feat you 2 did. I can't believe this level of hacking can be done now!!
     
  11. S0LV0

    S0LV0

    Sonic Generations Helpdesk Tech Member
    586
    1
    0
    Spagonia
    Abusing SMPS
    Is a bad thing that I've hesitated to try any sort of expansion or DLC-mod of the Unleashed Project stuff because the probable lack of polish would make me feel dirty?
     
  12. Dark Sonic

    Dark Sonic

    Member
    14,631
    1,617
    93
    Working on my art!
    I mean they aren't perfect, but they certainly aren't bad. Much higher quality than say the 06 project.
     
  13. Twilightzoney

    Twilightzoney

    Tech Member
    353
    0
    16
    Elgin, IL And Hampshire
    Unleashed and Generations Stuff and Custom Works
    Then again they already had a layout to work with to start with. With the 06 stuff the guy was doing it all on his own. So I think more effort went into the 06 Stuff then this. Which is why I would play the 06 stuff and never play this since I can see the 'effort' they put in.
     
  14. Dario FF

    Dario FF

    Tech Support Hotline Tech Member
    Experiment funtimes with real-time previewing in glvl.

    [​IMG]

    [​IMG]
     
  15. Dario FF

    Dario FF

    Tech Support Hotline Tech Member
    Kinda disappointed at the lack of comments, so maybe I didn't show off properly what I meant. :v:

    http://youtu.be/1OorZ6Sjfmg

    Nowhere near done and I have a lot of features to re-implement, but this next update should be really helpful.
     
  16. Twilightzoney

    Twilightzoney

    Tech Member
    353
    0
    16
    Elgin, IL And Hampshire
    Unleashed and Generations Stuff and Custom Works
    I will comment to make you happy.
    Even though you showed me pics of it before, really nice to see it in motion. Looks superb.

    This is a blessing to us all. No longer will we see super shiney/dark sonic now. Or black dash rings. Now we can all enjoy making level layouts now. Now we'll have an easier time with seeing how our GIA will look like without testing in-game right away and setting up shaders to see how they'll look will be so much easier. Hope you get that water shader to work!

    Edit: Boohoo Sarcasm Wasn't detected.
     
  17. Jason

    Jason

    *Results not lab tested. Member
    EDIT: Nope, in retrospect that came off as dickish and uncalled for.

    Yes this feature is cool, and will definitely help me see through my thick canopies of non-displaying-alpha'd leaves when editing.
     
  18. SF94

    SF94

    Tech Member
    778
    4
    18
    Well, I was going to post "Wow, that's really cool!", but I honestly expected somebody else to end up doing it first :v:
     
  19. Aerosol

    Aerosol

    Not here. Moderator
    11,206
    603
    93
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    I don't really have much to say but "that looks cool. Thanks again Dario".

    So that looks cool. Thanks again Dario.
     
  20. Tiller

    Tiller

    Member
    836
    0
    16
    HDK & World Runner
    Every time I turn around Dario goes and shits a rainbow. That's what you wanted to hear right?

    Playing catch-up with all these projects is taking me a while but I'm moving Glvl to the front when I get time.