Important information: this site is currently scheduled to go offline indefinitely by end of the year.

Dragon Age 2 (PC)

Post questions about game models here, or help out others!
Post Reply
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Dragon Age 2 (PC)

Post by chrrox »

I am working on the mesh format it is going good so far trying to find out how to link all these files together.
You do not have the required permissions to view the files attached to this post.
User avatar
Rimbros
ultra-veteran
ultra-veteran
Posts: 495
Joined: Fri Jul 09, 2010 12:23 am
Has thanked: 41 times
Been thanked: 16 times

Re: Dragon Age 2 (PC)

Post by Rimbros »

Amazing preview chroxxx, good advance. Also i finally kow how the gameassasin tool works any question or help you need only ask. i posted a answer in the section of gameassassin tool too.
Renders Art by Rimbros
http://s303.photobucket.com/albums/nn12 ... E/Renders/

Personal Game repository samples, send PM
Szkaradek123
mega-veteran
mega-veteran
Posts: 292
Joined: Wed May 05, 2010 8:21 pm
Location: Poland Głogów
Has thanked: 21 times
Been thanked: 742 times

Re: Dragon Age 2 (PC)

Post by Szkaradek123 »

Great work
For import .msh files to Blender there is "DragonAge_Tools_020".
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Dragon Age 2 (PC)

Post by chrrox »

they are a new format for the second game.
jaden
mega-veteran
mega-veteran
Posts: 209
Joined: Sat Feb 05, 2011 1:41 am
Been thanked: 1 time

Re: Dragon Age 2 (PC)

Post by jaden »

wow you rock chrrox
sirew
beginner
Posts: 26
Joined: Sun Jan 30, 2011 2:24 pm

Re: Dragon Age 2 (PC)

Post by sirew »

what tools did you use to rip the model?
Erik24
ultra-n00b
Posts: 2
Joined: Sat Jan 22, 2011 12:23 am

Re: Dragon Age 2 (PC)

Post by Erik24 »

sirew wrote:what tools did you use to rip the model?
answer plz
Ares722
veteran
Posts: 154
Joined: Thu Jul 15, 2010 2:15 pm
Has thanked: 25 times
Been thanked: 9 times

Re: Dragon Age 2 (PC)

Post by Ares722 »

Probably he is working at a script to import the Dagon Age2 mesh, uv map and bones format directly into max (max script)...as he usually do.....amazing!!
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Dragon Age 2 (PC)

Post by chrrox »

Here is the script but i cant find any bones they must use a global skeleton somewhere but i don't know where it is.

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
logansan25
veteran
Posts: 138
Joined: Mon Oct 04, 2010 1:15 am
Has thanked: 5 times
Been thanked: 3 times

Re: Dragon Age 2 (PC)

Post by logansan25 »

This script for 3dmax? or extract?
User avatar
Tosyk
double-veteran
double-veteran
Posts: 1027
Joined: Thu Oct 22, 2009 10:24 am
Location: Russia, Siberia
Has thanked: 269 times
Been thanked: 154 times
Contact:

Re: Dragon Age 2 (PC)

Post by Tosyk »

logansan25 wrote:This script for 3dmax? or extract?
Max
Thank you for all you do here
my blog | my forum
figuresculptor
beginner
Posts: 33
Joined: Thu Jan 06, 2011 9:08 pm
Been thanked: 4 times

Re: Dragon Age 2 (PC)

Post by figuresculptor »

Chroxx - you rock.

I hope you don't mind, I ported your script to Blender 2.5.6 , for those without 3DS Max.

Thanks for all your hard work, I dunno how you figure this stuff out.

NB: Updated with fix for problem affecting certain models.

Put the code into a file with a .py extension (I used "io_import_dragon_age_2_msh.py"), then add it using the Add On tab of the User Preferences.
fs


Look later in thread for updated code
Last edited by figuresculptor on Tue Mar 15, 2011 5:02 am, edited 2 times in total.
figuresculptor
beginner
Posts: 33
Joined: Thu Jan 06, 2011 9:08 pm
Been thanked: 4 times

Re: Dragon Age 2 (PC)

Post by figuresculptor »

Python script that will convert .msh to .obj file for those of you who don't like either 3DS Max or Blender, or for those who want to do batch conversions:

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)
Last edited by figuresculptor on Tue Mar 15, 2011 5:03 am, edited 1 time in total.
logansan25
veteran
Posts: 138
Joined: Mon Oct 04, 2010 1:15 am
Has thanked: 5 times
Been thanked: 3 times

Re: Dragon Age 2 (PC)

Post by logansan25 »

Who use this phyton? I am a noob in phyton!
sirew
beginner
Posts: 26
Joined: Sun Jan 30, 2011 2:24 pm

Re: Dragon Age 2 (PC)

Post by sirew »

Actually, what I need to do first, before putting it into blender/max?
Post Reply