Page 1 of 4

PC Darksiders II: Death Lives maxscript

Posted: Fri Jun 06, 2014 9:15 am
by zaramot
Hi guys! Here's maxscript to import Darksiders II: Death Lives (2012) PC models with bones+weights (3ds max 2009-2012)

P.S. Report bugs

Here's the tool to extract content (DS2Extract)
viewtopic.php?f=16&t=9483&p=79039&hilit ... act#p79039

ImageImage

Re: PC Darksiders II: Death Lives maxscript

Posted: Fri Jun 06, 2014 10:10 am
by HeliosAI
Thank you very much =)

Re: PC Darksiders II: Death Lives maxscript

Posted: Thu Jun 12, 2014 12:57 pm
by amzerof6
that's very awsome !!

Re: PC Darksiders II: Death Lives maxscript

Posted: Sat Jun 21, 2014 11:59 am
by PredatorCZ
I love it!!! :]

Re: PC Darksiders II: Death Lives maxscript

Posted: Mon Oct 19, 2015 5:37 pm
by dibe91
I try to sum up this topic in the hope to have a little 'help. I tried the scrip and there are some problems. first of all the bone skeletons of character are not connected to each other, but this is not a problem, you can do very well in the hand without problems. but the most serious problem concerns the golem. when they charge are no skeleton and are all pieces to the center, while the "Champions" are integers, but no skeleton. same problem as reflected in the Blacksmith crazy in Ward Metals.

Re: PC Darksiders II: Death Lives maxscript

Posted: Mon Jan 11, 2016 5:15 am
by phay008
thank you so much! :)

Re: PC Darksiders II: Death Lives maxscript

Posted: Thu Mar 03, 2016 8:17 am
by Sureno12
Hi, how to use DS2Extract?

I tried putting it in ds2 media and click the exe, it doesnt run.

There's a readme.txt that come with the DS2Extract but i dont know what it means.

"Usage example:
DS2Extract.exe "C:\Steam\steamapps\common\Darksiders 2\media" "/o:C:\DS2Out"

Thanks.

Sorry for bringing this thread back.

Re: PC Darksiders II: Death Lives maxscript

Posted: Fri Mar 04, 2016 12:21 am
by dibe91
Sureno12 wrote:Hi, how to use DS2Extract?

I tried putting it in ds2 media and click the exe, it doesnt run.

There's a readme.txt that come with the DS2Extract but i dont know what it means.

"Usage example:
DS2Extract.exe "C:\Steam\steamapps\common\Darksiders 2\media" "/o:C:\DS2Out"

Thanks.

Sorry for bringing this thread back.
you have to create a folder in c: calling it "DS2Out"

and not worry about it! Indeed, I hope you come back to life this thread! runs to take the golem but do not work well using these scripts :(

Re: PC Darksiders II: Death Lives maxscript

Posted: Sun Jul 10, 2016 6:57 pm
by dibe91
excuse me I have a problemacon constructs that do not have the skeleton. I discovered that the .o3d files are the files that contain the skeleton code. I now wonder is possible to load the model file along with the skeleton files?

Re: PC Darksiders II: Death Lives maxscript

Posted: Tue Jul 12, 2016 5:32 am
by raykingnihong
Hi guys! This game has been updated to the latest version. Darksiders II Deathinitive Edition. Here is the latest tool for ekey. viewtopic.php?f=10&t=13515&hilit=upak It works perfectly. I try to import the model file with maxscript. But there is an error message. Hope to upgrade MAXscript. Thanks again. Here is the model sample.
https://mega.nz/#!6YxSiYJA!_tJrjiatFv0M ... riy57Yy1IY

Re: PC Darksiders II: Death Lives maxscript

Posted: Tue Jul 12, 2016 11:09 am
by zaramot
I'll take a look at models from definite edition. Thanks a lot for the info :)

Re: PC Darksiders II: Death Lives maxscript

Posted: Wed Jul 13, 2016 11:25 am
by raykingnihong
Hi zaramot, my friend, I am looking forward to your great work.

Re: PC Darksiders II: Death Lives maxscript

Posted: Wed Jul 13, 2016 1:03 pm
by dibe91
if I speak, there is always the problem of the constructs without skeletons.

Re: PC Darksiders II: Death Lives maxscript

Posted: Wed Jul 20, 2016 1:34 pm
by dibe91
I'm working on the script of Zaramoth. I'm trying to import the missing bones of the constructs reading .o3d file. I try to start it but it appears this:
Image
I leave the script so you can tell what is wrong:

Code: Select all

 
if (heapSize < 200000) then
        heapSize = 2000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"
gname = getOpenFileName \
caption:"Open .dcm from Mesh folder" \
types:"Darksiders II Model (*.dcm)|*.dcm" \
historyCategory:"DarkSiders2ObjectPresets"
g = fopen gname "rb"
fname = getOpenFileName \
caption:"Open .o3d from Mesh folder" \
types:"Darksiders II Skeleton  (*.o3d)|*.o3d" \
historyCategory:"DarkSiders2ObjectPresets"
f = fopen fname "rb"

clearlistener()
fn readHalfFloat fstream = (
    hf=readshort fstream #unsigned
    sign = bit.get hf 16
    exponent = (bit.shift (bit.and hf (bit.hexasint "7C00")) -10) as integer - 16
    fraction = bit.and hf (bit.hexasint "03FF")
    if sign==true then sign = 1 else sign = 0
    exponentF = exponent + 127
    outputAsFloat = bit.or (bit.or (bit.shift fraction 13) \
    (bit.shift exponentF 23)) (bit.shift sign 31)
    return bit.intasfloat outputasfloat*2
    )
fn readFixedString bstream fixedLen = (
local str = ""
for i = 1 to fixedLen do (
str += bit.intAsChar (ReadByte bstream #unsigned))
str
)
struct o3d_data
(
	boneids,weights
)

struct weight_data
(
	boneids,weights
)

struct mat_info_struct
(
MName, VertCount, FaceCount
)

struct Bone_Info_Struct
(
	Bone1,Bone2,Bone3,Bone4
)

struct Weight_Info_Struct
(
	Weight1,Weight2,Weight3,Weight4
)
clearlistener()

TotallFaceCount = #()
TotallVertCount = #()
ModelType = #()
BoneCount = #()

fseek f 0x0 #seek_set
DataOff = readlong f
MainMeshCount = readlong f
IndBuffCountCount = readlong f	
for x = 1 to IndBuffCountCount do (
AllFaceCount = readlong f
append TotallFaceCount AllFaceCount	
)
VBuffCountCount = readlong f
for x = 1 to VBuffCountCount do (
AllVertCount=readlong f
if AllVertCount<0 then
(
AllVertCount=(AllVertCount*-1)	
)	
append TotallVertCount AllVertCount	
)	
VBuffCountCount2 = (readlong f*-1)
for x = 1 to IndBuffCountCount do (
CountVert=readlong f	
)
for x = 1 to VBuffCountCount do (
CountInd=readlong f	
)	

Print ("Sec End @ 0x"+((bit.intAsHex(ftell f))as string))	

for a = 1 to MainMeshCount do (	
BNArr = #()	
Mat_Info = #()		
	
MType = readbyte f
append ModelType MType
VertType = readbyte f
numVerts = Readlong f
Unk1 = Readlong f
FaceOff = Readlong f	
	
Print ("Count Start @ 0x"+((bit.intAsHex(ftell f))as string))
	
if ModelType[a]==0 then 
(
append BoneCount (Readlong f)	
numMat = Readlong f
fseek f 0x18 #seek_cur
)	

if ModelType[a]==1 then 
(		
numMat = Readlong f
append BoneCount (Readlong f)
	
fseek f 0x18 #seek_cur
	
Print ("Bone Start @ 0x"+((bit.intAsHex(ftell f))as string))
		
for i = 1 to BoneCount[a] do (

BoneByte = readbyte f	
BoneNameSize=readshort f	
BoneName=readFixedString f BoneNameSize
	
c11 = ReadFloat f; c12 = ReadFloat f; c13 = ReadFloat f; c14 = ReadFloat f	
c21 = ReadFloat f; c22 = ReadFloat f; c23 = ReadFloat f; c24 = ReadFloat f	
c31 = ReadFloat f; c32 = ReadFloat f; c33 = ReadFloat f; c34 = ReadFloat f
c41 = ReadFloat f; c42 = ReadFloat f; c43 = ReadFloat f; c44 = ReadFloat f

BoneIdShort =#()
	
append BoneIdShort (readshort f) 

ukk1 = readshort f	
		
tfm = matrix3 [c11,c12,c13] [c21,c22,c23] [c31,c32,c33] [c41,c42,c43]
tfm=(scaleMatrix [-1,-1,1])*tfm
	
newBone = bonesys.createbone	\
				  tfm.row4	\
				  (tfm.row4 + 0.01 * (normalize tfm.row1)) \
				  (normalize tfm.row3)
			newBone.name = BoneName
			newBone.width  = 0.01
			newBone.height = 0.01
			newBone.transform = inverse tfm
			newBone.setBoneEnable false 0
			newBone.wirecolor = white
			newbone.showlinks = true
			newBone.pos.controller      = TCB_position ()
			newBone.rotation.controller = TCB_rotation ()				  
append BNArr newBone				  
)
)

Print ("Bone End @ 0x"+((bit.intAsHex(ftell f))as string))

for a = 1 to numMat do (
MByte = readbyte f	
MNameSize=readshort f	
MName=readFixedString f MNameSize
Long1 = readlong f	
Long2 = readlong f	
VertCount = readlong f	
Null1 = readlong f
FaceCount = readlong f		
Null2 = readlong f	
append Mat_Info (mat_info_struct MName:MName VertCount:VertCount FaceCount:FaceCount )		
)

print Mat_Info

BoneEnd = ftell f

fseek f (DataOff+FaceOff) #seek_set
	
vertArray = #()
Facearray = #()	
UV_array = #()
Weight_array =#()
B1_array =#()
W1_array =#()
		
Print ("Face Start @ 0x"+((bit.intAsHex(ftell f))as string))
	
for x = 1 to TotallFaceCount[a]/3 do 
(
f1 = (Readshort f #unsigned + 1) 
f2 = (Readshort f #unsigned + 1) 
f3 = (Readshort f #unsigned + 1) 
append Facearray [f3,f2,f1]
)

Print ("Face End @ 0x"+((bit.intAsHex(ftell f))as string))

if ModelType[a]==0 then 
(	
	
Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
for x = 1 to TotallVertCount[a] do 
(
getPos = ftell f + 12

bone1 = 0	
weight1 = 1.00	
	
vx = readFloat f
vy = readFloat f
vz = readFloat f

w = (weight_data boneids:#() weights:#())
maxweight = 0
if(weight1 != 0) then
   maxweight = maxweight + weight1

if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 1)
         append w.weights (w1)
      )  
   )
append Weight_array w				
fseek f getPos #seek_set
append vertArray [-vx,-vy,vz]
)	

Print ("Vertex End @ 0x"+((bit.intAsHex(ftell f))as string))
		
for x = 1 to TotallVertCount[a] do 
(
getPos = ftell f + 20
Null = readlong f
FFFF = readlong f
tu = readHalfFloat f
tv = readHalfFloat f*-1
p3 = readshort f
p4 = readshort f
p5 = readshort f
p6 = readshort f
fseek f getPos #seek_set	
append UV_array [tu,tv,0]	 	
)	

Print ("20 Bytes End @ 0x"+((bit.intAsHex(ftell f))as string))

for x = 1 to TotallVertCount[a] do 
(
getPos = ftell f + 16
fseek f getPos #seek_set		
)
msh = mesh vertices:vertArray faces:faceArray
msh.displayByLayer = false
msh.backfacecull = true
msh.wirecolor = (color 230 200 210)
msh.numTVerts = UV_array.count
buildTVFaces msh
-- msh.name=Mat_Info[a].MName
for j = 1 to UV_array.count do setTVert msh j UV_array[j]
for j = 1 to faceArray.count do setTVFace msh j faceArray[j]
	
)

if ModelType[a]==1 then 	
(	
	
Print ("12 Bytes Data Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
for x = 1 to TotallVertCount[a] do 
(
getPos = ftell f + 12
tu = readHalfFloat f
tv = readHalfFloat f*-1
p3 = readshort f
p4 = readshort f
p5 = readshort f
p6 = readshort f
fseek f getPos #seek_set	
append UV_array [tu,tv,0]	 
)	

Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
for x = 1 to TotallVertCount[a] do 
(
getPos = ftell f + 52

WeightCount = readlong f
	
vx = readFloat f
vy = readFloat f
vz = readFloat f
	
fseek f getPos #seek_set
append vertArray [-vx,-vy,vz]
)	

Print ("Vertex End @ 0x"+((bit.intAsHex(ftell f))as string))
	
Print ("Blend Weights @ 0x"+((bit.intAsHex(ftell f))as string))	
	
for x = 1 to TotallVertCount[a] do 
(
weight1 = Readfloat f
weight2 = Readfloat f
weight3 = Readfloat f
weight4 = Readfloat f
append W1_array (Weight_Info_Struct Weight1:Weight1 Weight2:Weight2 Weight3:Weight3 Weight4:Weight4)		
)	

Print ("Blend Indices @ 0x"+((bit.intAsHex(ftell f))as string))

for x = 1 to TotallVertCount[a] do 
(
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned	
append B1_array (Bone_Info_Struct Bone1:Bone1 Bone2:Bone2 Bone3:Bone3 Bone4:Bone4)		
)	

for a = 1 to W1_array.count Do (
w = (weight_data boneids:#() weights:#())
maxweight = 0
if(W1_array[a].Weight1 != 0) then
   maxweight = maxweight + W1_array[a].Weight1
if(W1_array[a].Weight2 != 0) then
   maxweight = maxweight + W1_array[a].Weight2
if(W1_array[a].Weight3 != 0) then
   maxweight = maxweight + W1_array[a].Weight3
if(W1_array[a].Weight4 != 0) then
   maxweight = maxweight + W1_array[a].Weight4

if(maxweight != 0) then
   (
      if(W1_array[a].Weight1 != 0) then
      (
         w1 = W1_array[a].Weight1 as float
         append w.boneids (B1_array[a].Bone1 + 1)
         append w.weights (w1)
      )
      if(W1_array[a].Weight2 != 0) then
      (
         w2 = W1_array[a].Weight2 as float
         append w.boneids (B1_array[a].Bone2 + 1)
         append w.weights (w2)
      )
      if(W1_array[a].Weight3 != 0) then
      (
         w3 = W1_array[a].Weight3 as float
         append w.boneids (B1_array[a].Bone3 + 1)
         append w.weights (w3)
      )
      if(W1_array[a].Weight4 != 0) then
      (
         w4 = W1_array[a].Weight4 as float
         append w.boneids (B1_array[a].Bone4 + 1)
         append w.weights (w4)
      )      
   )
append Weight_array w
)	


msh = mesh vertices:vertArray faces:faceArray
msh.numTVerts = UV_array.count
buildTVFaces msh
-- msh.name=Mat_Info[a].MName
for j = 1 to UV_array.count do setTVert msh j UV_array[j]
for j = 1 to faceArray.count do setTVFace msh j faceArray[j]
msh.displayByLayer = false
msh.backfacecull = true
msh.wirecolor = (color 230 200 210)

max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BoneCount[a] do
(
	maxbone = BNArr[i]
	if i != BoneCount[a] then 
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to TotallVertCount[a] do (
   w = Weight_array[i]
   bi = #() --bone index array
   wv = #() --weight value array
   
   for j = 1 to w.boneids.count do
   (
      boneid = w.boneids[j]
      weight = w.weights[j]
      append bi boneid
      append wv weight
   )   
   
   skinOps.ReplaceVertexWeights skinMod i bi wv
)	
)
fseek f BoneEnd #seek_set
)

Print ("Mesh End @ 0x"+((bit.intAsHex(ftell f))as string))

fclose f 

Re: PC Darksiders II: Death Lives maxscript

Posted: Wed Jul 20, 2016 3:16 pm
by PredatorCZ
Well, to be honnest, .o3d is true header, while .dcm is buffer file. Basically those two files are merged in first game.
Its not only skeleton as you can guess, but its complete information about object (so I assume .o3d means "Object 3D").
So I found when I was researching it, that it contains simple animations aswell. Every information in .dcm like types, counts, etc. should be too in .o3d. 8)