Join also our Discord channel! Click here.

Dragon Age 2 (PC)

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

Dragon Age 2 (PC)

Post by chrrox » 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.
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: 13 times

Re: Dragon Age 2 (PC)

Post by Rimbros » Mon Feb 21, 2011 10:23 pm

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: 605 times

Re: Dragon Age 2 (PC)

Post by Szkaradek123 » Wed Feb 23, 2011 5:42 pm

Great work
For import .msh files to Blender there is "DragonAge_Tools_020".

User avatar
chrrox
Moderator
Posts: 2565
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1311 times

Re: Dragon Age 2 (PC)

Post by chrrox » Thu Feb 24, 2011 12:39 am

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 » Thu Feb 24, 2011 12:49 am

wow you rock chrrox

sirew
beginner
Posts: 26
Joined: Sun Jan 30, 2011 2:24 pm

Re: Dragon Age 2 (PC)

Post by sirew » Sat Feb 26, 2011 4:42 am

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 » Fri Mar 11, 2011 11:46 pm

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: 24 times
Been thanked: 9 times

Re: Dragon Age 2 (PC)

Post by Ares722 » Sun Mar 13, 2011 11:51 am

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!!

User avatar
chrrox
Moderator
Posts: 2565
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1311 times

Re: Dragon Age 2 (PC)

Post by chrrox » Mon Mar 14, 2011 3:22 am

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: 2 times

Re: Dragon Age 2 (PC)

Post by logansan25 » Mon Mar 14, 2011 11:30 am

This script for 3dmax? or extract?

User avatar
Tosyk
double-veteran
double-veteran
Posts: 945
Joined: Thu Oct 22, 2009 10:24 am
Location: Russia, Siberia
Has thanked: 225 times
Been thanked: 119 times
Contact:

Re: Dragon Age 2 (PC)

Post by Tosyk » Mon Mar 14, 2011 12:00 pm

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 » Mon Mar 14, 2011 7:49 pm

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 » Mon Mar 14, 2011 11:02 pm

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: 2 times

Re: Dragon Age 2 (PC)

Post by logansan25 » Mon Mar 14, 2011 11:22 pm

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 » Mon Mar 14, 2011 11:47 pm

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

Post Reply