darksider 2 import file .dcm with file .o3d in 3d studio max

Skeletons, animations, shaders, texturing, converting, fixing and anything else related to read game models
dibe91
Posts: 3
Joined: Mon Jan 04, 2016 7:07 am

darksider 2 import file .dcm with file .o3d in 3d studio max

Post by dibe91 »

Hello. Posted long ago was one of 3d max studio script to import the models of darksider 2 with skeletons. the script works but the constructs that import meshes without bones and skin. looking in the files of the game I managed to find out the files with missing skeletons are contained in .o3d file. I then thought of trying to change the script so that it tried to load the .dcm file (mesh file) together with the .o3d file. I tried to search for tutorial to understand what to do but I could not do anything. so I was hoping that with this topic to understand how to do. I leave the script text them:

if (heapSize < 200000) then
heapSize = 2000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"

fname = getOpenFileName \
caption:"Open .dcm from Mesh folder" \
types:"Darksiders II Model (*.dcm)|*.dcm" \
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 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