Dragon Age 2 (PC)
Posted: Mon Feb 21, 2011 10:14 pm
I am working on the mesh format it is going good so far trying to find out how to link all these files together.
answer plzsirew wrote:what tools did you use to rip the model?
Code: Select all
if (heapSize < 20000000) then
heapSize = 200000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"
fname = getOpenFileName \
caption:"Open DA2 Model File" \
types:"DA2 Model File(*.msh)|*.msh" \
historyCategory:"DA2ObjectPresets"
f = fopen fname "rb"
fn PrintOffset Var =
(
local Var = Var
print ("This is the offset 0x" + (bit.intAsHex Var) as string)
Var
)
fn PrintCount Var =
(
local Var = Var
print ("This is the Count 0x" + (bit.intAsHex Var) as string)
Var
)
fn Readword fstream = (
return readshort fstream #unsigned
)
fn ReadFixedString bstream fixedLen =
(
local str = ""
for i = 1 to fixedLen do
(
str += bit.intAsChar (ReadByte bstream #unsigned)
)
str
)
fn ReadFixedUString bstream fixedLen =
(
local str = ""
for i = 1 to fixedLen do
(
str += bit.intAsChar (ReadByte bstream #unsigned)
fseek bstream 0x1#seek_cur
)
str
)
fn convertTo32 input16 = (
inputAsInt = input16
sign = bit.get inputAsInt 16
exponent = (bit.shift (bit.and inputAsInt (bit.hexasint "7C00")) -10) as integer - 16
fraction = bit.and inputAsInt (bit.hexasint "03FF")
if sign==true then sign = 1 else sign = 0
exponentF = exponent + 127
--Ouput 32 bit integer representing a 32 bit float
outputAsFloat = bit.or (bit.or (bit.shift fraction 13) (bit.shift exponentF 23)) (bit.shift sign 31)
--Output Check
return bit.intasfloat outputasfloat * 2
)
fn ReadHalfFloat fstream = (
return convertTo32(Readshort fstream)
)
struct Mesh_Info_Struct
(
vertsize,VertCount,FaceCount,VertPos,FacePos
)
fseek f 0x1A0#seek_set
baseoff = (ftell f)
namebase = readlong f
null = readlong f
unkbase = readlong f
vertbase = readlong f
facebase = readlong f
null = readlong f
null = readlong f
MeshCount = readlong f
Mesh_Info_Array = #()
for a = 1 to MeshCount Do (
float01 = readfloat f
float02 = readfloat f
float03 = readfloat f
float04 = readfloat f
float11 = readfloat f
float12 = readfloat f
float13 = readfloat f
float14 = readfloat f
float21 = readfloat f
float22 = readfloat f
float23 = readfloat f
float34 = readfloat f
unk01 = readlong f
vertsize = readlong f
VertCount = readlong f
FaceCount = readlong f
VertPos = readlong f
FacePos = readlong f
unk02 = readlong f
long01 = readlong f
long02 = readlong f
long03 = readlong f
long04 = readlong f
VertCount2 = readlong f
append Mesh_Info_Array (Mesh_Info_Struct vertsize:vertsize VertCount:VertCount FaceCount:FaceCount VertPos:VertPos FacePos:FacePos)
)
print Mesh_Info_Array
FaceStart = (baseoff + facebase) + 4
VertStart = (baseoff + vertbase) + 4
NameStart = (baseoff + namebase)
UnkStart = (baseoff + unkbase)
/*
fseek f UnkStart#seek_set
MeshCount2 = readlong f
for a = 1 to MeshCount2 Do (
unk03 = readlong f
)
FileNameSize = readlong f
MeshFile = ReadFixedUString f FileNameSize
*/
/*
fseek f NameStart#seek_set
MeshName_Array = #()
for a = 1 to MeshCount Do (
MeshNameSize = readlong f
MeshName = ReadFixedUString f MeshNameSize
append MeshName_Array MeshName
test = readshort f
if test != -1 do (
fseek f -2#seek_cur
)
fseek f 0x90#seek_cur
print MeshName
)
print MeshName_Array
*/
for a = 1 to MeshCount Do (
Vert_array = #()
UV_array = #()
Normal_array = #()
Face_array = #()
fseek f (VertStart + Mesh_Info_Array[a].VertPos)#seek_set
for b = 1 to Mesh_Info_Array[a].VertCount Do (
if Mesh_Info_Array[a].vertsize == 40 do (
vx = readfloat f
vy = readfloat f
vz = readfloat f
unk10 = readfloat f
unk11 = readfloat f
unk12 = readfloat f
unk13 = readfloat f
unk13 = readfloat f
tu = ReadHalfFloat f
tv = ReadHalfFloat f * -1
unk13 = readfloat f
append Vert_array [vx,vy,vz]
--append Normal_array [nx,ny,nz]
append UV_array [tu,tv,0]
)
if Mesh_Info_Array[a].vertsize == 36 do (
vx = readfloat f
vy = readfloat f
vz = readfloat f
unk10 = readfloat f
unk11 = readfloat f
unk12 = readfloat f
unk13 = readfloat f
unk13 = readfloat f
tu = ReadHalfFloat f
tv = ReadHalfFloat f * -1
append Vert_array [vx,vy,vz]
--append Normal_array [nx,ny,nz]
append UV_array [tu,tv,0]
)
if Mesh_Info_Array[a].vertsize == 32 do (
vx = readfloat f
vy = readfloat f
vz = readfloat f
unk10 = readfloat f
unk11 = readfloat f
unk12 = readfloat f
unk13 = readfloat f
tu = ReadHalfFloat f
tv = ReadHalfFloat f * -1
append Vert_array [vx,vy,vz]
--append Normal_array [nx,ny,nz]
append UV_array [tu,tv,0]
)
if Mesh_Info_Array[a].vertsize == 28 do (
vx = readfloat f
vy = readfloat f
vz = readfloat f
unk10 = readfloat f
unk11 = readfloat f
unk13 = readfloat f
tu = ReadHalfFloat f
tv = ReadHalfFloat f * -1
append Vert_array [vx,vy,vz]
--append Normal_array [nx,ny,nz]
append UV_array [tu,tv,0]
)
if Mesh_Info_Array[a].vertsize == 24 do (
vx = readfloat f
vy = readfloat f
vz = readfloat f
unk10 = readfloat f
unk11 = readfloat f
tu = ReadHalfFloat f
tv = ReadHalfFloat f * -1
append Vert_array [vx,vy,vz]
--append Normal_array [nx,ny,nz]
append UV_array [tu,tv,0]
)
)
fseek f (FaceStart + (Mesh_Info_Array[a].FacePos * 2))#seek_set
for b = 1 to Mesh_Info_Array[a].FaceCount / 3 do (
f1 = (readshort f) + 1
f2 = (readshort f) + 1
f3 = (readshort f) + 1
append Face_array [f1,f2,f3]
)
msh = mesh vertices:Vert_array faces:Face_array name:(a as string)
msh.numTVerts = UV_array.count
buildTVFaces msh
for j = 1 to UV_array.count do setTVert msh j UV_array[j]
for j = 1 to Face_array.count do setTVFace msh j Face_array[j]
for j = 1 to Normal_array.count do setNormal msh j Normal_array[j]
)
fclose f
Maxlogansan25 wrote:This script for 3dmax? or extract?
Code: Select all
#! /usr/bin/env python
import os
import sys
import string
import math
import re
from string import *
from struct import *
from math import *
LONGSIZE = 4
FLOATSIZE = 4
HALFFLOATSIZE = 2
SHORTSIZE = 2
def unpack_list(list_of_tuples):
l = []
for t in list_of_tuples:
l.extend(t)
return l
def halfToFloatPrivate(h):
s = int((h >> 15) & 0x00000001) # sign
e = int((h >> 10) & 0x0000001f) # exponent
f = int(h & 0x000003ff) # fraction
if e == 0:
if f == 0:
return int(s << 31)
else:
while not (f & 0x00000400):
f <<= 1
e -= 1
e += 1
f &= ~0x00000400
elif e == 31:
if f == 0:
return int((s << 31) | 0x7f800000)
else:
return int((s << 31) | 0x7f800000 | (f << 13))
e = e + (127 -15)
f = f << 13
return int((s << 31) | (e << 23) | f)
def halfToFloat(h):
result = halfToFloatPrivate(h)
str = pack('I',result)
f = unpack('f', str)
return f[0]
def mshImport(infile):
print ("Converting file: ", infile)
mshfile = open(infile,'rb')
objPath = infile.replace(".msh", ".obj")
print("\toutput file: " + objPath)
objfile = open(objPath,'w')
basename = os.path.basename(infile)
# basename = os.path.splitext(infile)[0]
mshfile.seek(0x1A0)
baseoff = 0x1A0
namebase, garbage, unkbase, vertbase, facebase, garbage1, garbage2, meshcount = unpack('<8l', mshfile.read(8*LONGSIZE))
vertSizeArray = []
vertCountArray = []
faceCountArray = []
vertPosArray = []
facePosArray = []
for i in range(meshcount):
float01, float02, float03, float04, float11, float12, float13, float14, float21, float22, float23, float34 = unpack('<12f', mshfile.read(12*FLOATSIZE))
unk01, vertSize, vertCount, faceCount, vertPos, facePos, unk2, long01, long02, long03, long04, vertCount2 = unpack('<12l', mshfile.read(12*LONGSIZE))
vertSizeArray.append(vertSize)
vertCountArray.append(vertCount)
faceCountArray.append(faceCount)
vertPosArray.append(vertPos)
facePosArray.append(facePos)
faceStart = baseoff + facebase + 4
vertStart = baseoff + vertbase + 4
nameStart = baseoff + namebase
unkStart = baseoff + unkbase
vertexOffset = 1
for a in range(meshcount):
objfile.write("o " + basename + str(a) + "\n")
vertArray = []
uvArray = []
normalArray = []
faceArray = []
mshfile.seek(vertStart + vertPosArray[a])
for b in range(vertCountArray[a]):
data = mshfile.read(3*FLOATSIZE)
vx, vy, vz = unpack('<3f', data)
bytesOfUnknown = (vertSizeArray[a] - 16)
unknown = mshfile.read(bytesOfUnknown)
tu_h = unpack('H', mshfile.read(HALFFLOATSIZE))
tv_h = unpack('H', mshfile.read(HALFFLOATSIZE))
tu = halfToFloat(tu_h[0])
tv = halfToFloat(tv_h[0])
vertArray.extend([(vx, vy, vz)])
uvArray.extend([(tu, tv)])
mshfile.seek(faceStart + facePosArray[a] * 2)
faceLen = faceCountArray[a]
for i in range(len(vertArray)):
objfile.write("v " + str(vertArray[i][0]) + " " + str(vertArray[i][1]) + " " + str(vertArray[i][2]) + "\n")
for i in range(len(uvArray)):
objfile.write("vt " + str(uvArray[i][0]) + " " + str(uvArray[i][1]) + "\n")
if (faceLen > 0):
faceLen = faceLen / 3
else:
faceLen = 0
for b in range(int(faceLen)):
f1, f2, f3 = unpack('<3h', mshfile.read(3*SHORTSIZE))
if (f1 < len(vertArray) and f2 < len(vertArray) and f3 < len(vertArray)):
faceArray.extend([(f1, f2, f3)])
for i in range(len(faceArray)):
objfile.write("f " + str(faceArray[i][0] + vertexOffset) + "/" + str(faceArray[i][0] + vertexOffset) + " " + str(faceArray[i][1] + vertexOffset) + "/" + str(faceArray[i][1] + vertexOffset) + " " + str(faceArray[i][2] + vertexOffset) + "/" + str(faceArray[i][2] + vertexOffset) + "\n")
vertexOffset = vertexOffset + (len(vertArray))
for grp in sys.argv[1:]:
mshImport(grp)