Page 2 of 4

Re: Martial Empires / Seven Souls

Posted: Thu Jun 16, 2011 8:45 am
by CriticalError
thanks a lot for the great support but I get problem when try import in MAX 9,2009,2010.

Re: Martial Empires / Seven Souls

Posted: Thu Jun 30, 2011 7:06 pm
by finale00
Here's my guess so far for some BSB files (samples were less than 10 kb)
From the filenames, it appears they contain scenery assets like trees stones and architectures. I don't know what some of the floats could represent. The extent of my knowledge so far is limited to coords, faces, UV's, and normals. Transformations, weights, bones, material properties, and so on are out of my reach.

A couple files already don't follow what I have so far. Probably some of the unknowns explain this.

Works for a couple bsb's, fails for a lot of others. At least I know I'm getting somewhere.

"tree_0124.bsb"

http://i.imgur.com/EcN3j.jpg

EDIT: can load more bsb's now:

http://i.imgur.com/gLskE.jpg

Note1: there may be multiple meshes in a single bsb file. Still looking for the mesh count.
note2: there are two different vertsizes: 56 and 44. Haven't found when they occur. "prop_ex01.bsb" contains vertsize 44 while most others contain vertsize 56

Note3: Not all materials use mask and normal textures (not sure what they're for). There doesn't appear to be any way to figure this out beforehand. We can probably take advantage of the charCount, knowing that there should be at least 5 characters to qualify as a texture name, but it could just as easily be a model with many materials that don't use masks or normal texture..

Note4: the material section really is odd. There are a couple odd ones out that I just can't seem to figure out the pattern. It almost looks as if some of them have multiple material sections...

Note5: although it parses large files successfully, the face count is way off. Not sure why.

Code: Select all

dword BSOB
dword ??? (seems to determine vertsize. If 8, then vertsize 44, else vertsize 56)
dword charCount
charCount model_name.max (maybe there's significance that it is done in max?)

dword_4 ??? 
byte ??? (just to get it to work)
dword ???
dword material_sections
struct mat_section {
   dword section_number
   float_9 ??? 
   dword num_materials (in this section)
   IF dword == 0
      dword charCount
      charCount "NULL"
   ELSE
      struct material { (does not always follow this format)
         dword material_number
         dword charCount
         charCount texture_name
         dword charCount
         charCount texture_mask_name
         dword charCount
         charCount texture_normal_name
      }
   ENDIF
}

dword num_meshes
dword unk

IF unk == 1
   dword_28 ???
ELSE
   dword_9 ???
   dword charCount
   charCount unknownProperty
   dword_9 ???
ENDIF

struct mesh {
   dword charCount
   charCount meshName (?)
   dword charCount
   charCount "property name"
   byte ???
   dword charCount
   charCount "Editable poly"
   dword_3 ???
   byte ???
   dword charCount
   charCount lightingMap
   byte ???

   dword_3 ???
   struct ??? {
      3 * float_16 ???
   }
   byte ???
   dword_10 ???

   dword num_vertices
   struct vertex {
      float_3 x,y,z
      float_11 ??? (might not all be float)
   }
   dword ??? (this value is important, because num_faces is only correct when it is == 1)
   dword num_faces
   struct face {
      word_3 f1, f2, f3
   }
}
[...maybe some more..]

Re: Martial Empires / Seven Souls

Posted: Fri Jul 01, 2011 12:48 am
by finale00
Image

This thing looks like it has multiple material sections o.O

Is that common in 3D objects? If not, what could it represent (besides...corrupt data)

I might treat the first number in the highlighted section as "# material sections" and then do a loop over that. That's pretty much one of the main issues for small files

EDIT: that definitely does seem to be the number of material sections. I don't know what that means.

Re: Martial Empires / Seven Souls

Posted: Sat Jul 09, 2011 7:29 pm
by CriticalError
nobody can give me a hand with it? what is wrong in script? I try with 2 scripts post chrox for Max 9 and 2010 and don't work -.-

Error:

Code: Select all

Welcome to MAXScript.

"201112600"
"C:\Users\Enzo\Des"
"C:\Users\Enzo\Destexture\diffuse\4201112600.dds"
"C:\Users\Enzo\Desbind\g0.bnd"
"BoneFile_0"
39639
39639
-- Error occurred during fileIn in <File:C:\Program Files\Autodesk\3ds Max 9\stdplugs\stdscripts\7souls.ms>
>> MAXScript Auto-load Script Error - C:\Program Files\Autodesk\3ds Max 9\stdplugs\stdscripts\7souls.ms Exception: -- Unable to convert: undefined to type: FileName <<
Script

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 7 Souls Model File" types:"7 Souls Model File(*.msh)|*.msh"
f = fopen fname "rb"   --open file in read only format
base = getFilenamePath fname
basefile = getFilenameFile fname -- returns: "myImage.jpg"
basefile = substring basefile 3 (basefile.count - 2)
ss = substring base 1 (base.count - 5) -- returns "rof"
print basefile
print ss
DiffuseTex = (ss + "texture\diffuse\4" + basefile + ".dds")

print DiffuseTex
fn ReadFixedString bstream fixedLen =
(
	local str = ""
	for i = 1 to fixedLen do
	(
		str += bit.intAsChar (ReadByte bstream #unsigned)
	)
	str
)

struct weight_data
(
	boneids,weights
)

Vert_array = #()
Normal_array = #()
UV_array = #()
Face_Array = #()
Weight_array = #()
VertID_array = #()

idstring2 = ReadFixedString  f 4
if idstring2 != "MESH" do (
BoneFile = readlong f
Skelleton = (ss + "bind\g" + (BoneFile as string) + ".bnd")
print Skelleton
print ("BoneFile" + "_" + (BoneFile as string))
Mesh_Name_Size = readlong f
Mesh_Name = ReadFixedString  f Mesh_Name_Size
vertcount = readlong f
facecount = readlong f
weightcount = readlong f
weightcount2 = readlong f
for i = 1 to vertcount do (
vx = readfloat f      --read xyz coordinates
vy = readfloat f 
vz = readfloat f
nx = readfloat f
ny = readfloat f
nz = readfloat f
tu = readfloat f
tv = readfloat f * -1	
append Vert_array [vx,vy,vz] --save verts to Vert_array
append UV_array [tu,tv,0]
append Normal_array [nx,ny,nz]
)
facedirection = 1
for i = 1 to facecount  do (
f1 = readlong f + 1
f2 = readlong f + 1
f3 = readlong f + 1
append Face_array [f1,f2,f3]
)
for i = 1 to weightcount do (
boneids = ((readlong f) + 1)
VertID = ((readlong f) + 1)
weights = readfloat f
v2 = readlong f
w2 = readfloat f
v3 = readlong f
w3 = readfloat f
v4 = readlong f
w4 = readfloat f
append Weight_array (weight_data boneids:boneids weights:weights)
append VertID_array VertID
)
for i = 1 to weightcount2 do (
bone1 = readlong f
VertID = ((readlong f) + 1)
weight1 = readfloat f
w = (weight_data boneids:#() weights:#())
			w1 = weight1 as float
			append w.boneids (bone1+1)
			append w.weights (w1)
v2 = readlong f
w2 = readfloat f
v3 = readlong f
w3 = readfloat f
v4 = readlong f
w4 = readfloat f
append Weight_array w
append VertID_array VertID
)
print (ftell f)
msh = mesh vertices:Vert_array faces:Face_array   --build mesh
msh.numTVerts = UV_array.count
buildTVFaces msh
meditMaterials[1] = Standardmaterial ()
msh.material = meditMaterials[1]
meditMaterials[1].diffuseMap = Bitmaptexture fileName:DiffuseTex
meditMaterials[1].opacityMap = Bitmaptexture fileName:DiffuseTex
meditMaterials[1].opacityMap.monoOutput = 1
msh.name = Mesh_Name
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]
)
print (ftell f)
usedbones_array = #()
if idstring2 == "MESH" do (
mcount = readlong f
mid = readlong f
BoneFile = readlong f
Skelleton = (ss + "bind\g" + (BoneFile as string) + ".bnd")
print Skelleton
print ("BoneFile" + "_" + (BoneFile as string))
Mesh_Name_Size = readlong f
Mesh_Name = ReadFixedString  f Mesh_Name_Size
vertcount = readlong f
facecount = readlong f
for i = 1 to vertcount do (

vx = readfloat f      --read xyz coordinates
vy = readfloat f 
vz = readfloat f
nx = readfloat f
ny = readfloat f
nz = readfloat f
tu = readfloat f
tv = readfloat f * -1
if mcount == 2 Do (
fseek f 0x10#seek_cur
)
Bone1 = readbyte f#unsigned
Bone2 = readbyte f#unsigned
Bone3 = readbyte f#unsigned
Bone4 = readbyte f#unsigned
weight1 = readfloat f
weight2 = readfloat f
weight3 = readfloat f
weight4 = readfloat f

w = (weight_data boneids:#() weights:#())
maxweight = 0
if(Bone1 != 0) then
	maxweight = maxweight + weight1
if(Bone2 != 0) then
	maxweight = maxweight + weight2
if(Bone3 != 0) then
	maxweight = maxweight + weight3
if(Bone4 != 0) then
	maxweight = maxweight + weight4

if(maxweight != 0) then (
		if(weight1 != 0) then (
			w1 = weight1 as float
			append w.boneids (bone1 + 1)
			append w.weights w1
		)
		if(weight1 != 0) then (
			w2 = weight2 as float
			append w.boneids (bone2 + 1)
			append w.weights w2
		)
		if(weight1 != 0) then (
			w3 = weight3 as float
			append w.boneids (bone3 + 1)
			append w.weights w3
		)
		if(weight1 != 0) then (
			w4 = weight4 as float
			append w.boneids (bone4 + 1)
			append w.weights w4
		)		
	)
append Weight_array w
append Vert_array [vx,vy,vz] --save verts to Vert_array
append UV_array [tu,tv,0]
append Normal_array [nx,ny,nz]
)
if mcount == 2 Do (
usedbones = readbyte f#unsigned
for a = 1 to usedbones do (
bid = readbyte f#unsigned + 1
append usedbones_array bid
)
)
facedirection = 1
if mcount == 2 Do (
for i = 1 to facecount  do (
f1 = readshort f + 1
f2 = readshort f + 1
f3 = readshort f + 1
append Face_array [f1,f2,f3]
)
)
if mcount == 1 Do (
for i = 1 to facecount  do (
f1 = readlong f + 1
f2 = readlong f + 1
f3 = readlong f + 1
append Face_array [f1,f2,f3]
)
)
print (ftell f)
msh = mesh vertices:Vert_array faces:Face_array   --build mesh
msh.numTVerts = UV_array.count
buildTVFaces msh
meditMaterials[1] = Standardmaterial ()
msh.material = meditMaterials[1]
meditMaterials[1].diffuseMap = Bitmaptexture fileName:DiffuseTex
meditMaterials[1].opacityMap = Bitmaptexture fileName:DiffuseTex
meditMaterials[1].opacityMap.monoOutput = 1
msh.name = Mesh_Name
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]
)
actionMan.executeAction 0 "63508"

fclose f
f = fopen Skelleton "rb"
idstring = ReadFixedString f 4
BNArr = #()
if idstring != "BIND" Do (
nsize = readlong f
skelname = ReadFixedString f nsize
bonecount = readlong f
for a = 1 to bonecount Do (
boneid = readlong f + 1
boneparent = readlong f + 1
f1 = readfloat f
f2 = readfloat f
f3 = readfloat f
f4 = readfloat f
f5 = readfloat f
f6 = readfloat f
f7 = readfloat f
tfm = (quat f4 f5 f6 (f7 * -1)) as matrix3
tfm.row4 = [f1,f2,f3]
if isvalidnode (getNodeByName (a as string)) != true then (
if (boneparent != boneid) do (
tfm = tfm * BNArr[boneparent].objecttransform
 )	
newBone = bonesys.createbone	\
				  tfm.row4	\
				  (tfm.row4 + 0.01 * (normalize tfm.row1)) \
				  (normalize tfm.row3)
			newBone.name = (a as string)
			newBone.width  = 0.01
			newBone.height = 0.01
			newBone.transform = tfm
			newBone.setBoneEnable false 0
			newBone.wirecolor = yellow
			newbone.showlinks = true
			newBone.pos.controller      = TCB_position ()
			newBone.rotation.controller = TCB_rotation ()
 if (boneparent != 0) then
 newBone.parent = BNArr[boneparent]
append BNArr newBone
)
)
)

if idstring == "BIND" Do (
fseek f 0x8#seek_cur
nsize = readlong f
skelname = ReadFixedString f nsize
bcount1 = readbyte f#unsigned
bcount2 = readbyte f#unsigned
bonecount  = (bcount1 + bcount2)
for a = 1 to bonecount Do (
boneid = readlong f + 1
boneparent = readlong f + 1
f1 = readfloat f
f2 = readfloat f
f3 = readfloat f
f4 = readfloat f
f5 = readfloat f
f6 = readfloat f
f7 = readfloat f
null = readbyte f#unsigned
tfm = (quat f4 f5 f6 (f7 * -1)) as matrix3
tfm.row4 = [f1,f2,f3]
if isvalidnode (getNodeByName (a as string)) != true then (
if (boneparent != boneid) do (
tfm = tfm * BNArr[boneparent].objecttransform
 )	
newBone = bonesys.createbone	\
				  tfm.row4	\
				  (tfm.row4 + 0.01 * (normalize tfm.row1)) \
				  (normalize tfm.row3)
			newBone.name = (a as string)
			newBone.width  = 0.01
			newBone.height = 0.01
			newBone.transform = tfm
			newBone.setBoneEnable false 0
			newBone.wirecolor = yellow
			newbone.showlinks = true
			newBone.pos.controller      = TCB_position ()
			newBone.rotation.controller = TCB_rotation ()
 if (boneparent != 0) then
 newBone.parent = BNArr[boneparent]
append BNArr newBone
)
)
)
max modify mode
print idstring
if idstring2 != "MESH" do (

select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BNArr.count do
(
	maxbone = getnodebyname BNArr[i].name
	if i != BNArr.count then
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to Weight_array.count do
(
	skinOps.SetVertexWeights skinMod VertID_array[i] Weight_array[i].boneids Weight_array[i].weights
)
)

if idstring2 == "MESH" do (
if mcount == 2 Do (
BNArr = #()
for a = 1 to usedbones_array.count do (
append BNArr (getnodebyname (usedbones_array[a] as string))
)
)
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BNArr.count do
(
	maxbone = getnodebyname BNArr[i].name
	if i != BNArr.count then
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to Weight_array.count do
(
	w = Weight_array[i]
	bi = #()
	wv = #()
	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
)
)

max create mode
max zoomext sel all
fclose f

Re: Martial Empires / Seven Souls

Posted: Sat Jul 09, 2011 7:43 pm
by chrrox
it cant find one of the files mentioned there.

Re: Martial Empires / Seven Souls

Posted: Sat Jul 09, 2011 7:52 pm
by CriticalError
chrrox wrote:it cant find one of the files mentioned there.
yes I know g0.bnd are is bone I think, but in folder are not files with this name just .msh for weapons, and for characters in another folder called bindd are bnd files but for characters not for weapon :( so what I do wrong man, can you tell me? because when get this error the model are imported there, but when try import another need restart max

Re: Martial Empires / Seven Souls

Posted: Sat Jul 09, 2011 8:16 pm
by finale00
Well, it does say the script is to import models with bones and weights.
Though, one can assume the format is similar for unskinned models so one might use chrrox's script as reference.

Re: Martial Empires / Seven Souls

Posted: Sat Jul 09, 2011 8:21 pm
by CriticalError
finale00 wrote:Well, it does say the script is to import models with bones and weights.
Though, one can assume the format is similar for unskinned models so one might use chrrox's script as reference.
I don't know really what I do wrong guys, this make me crazy T_T

Re: Martial Empires / Seven Souls

Posted: Sat Jul 09, 2011 8:27 pm
by finale00
I mean, you won't be able to load weapons because as you've pointed out, they don't have certain files :)

Re: Martial Empires / Seven Souls

Posted: Sat Jul 09, 2011 8:46 pm
by CriticalError
finale00 wrote:I mean, you won't be able to load weapons because as you've pointed out, they don't have certain files :)
I get error with all files, just show a example with weapons but characters have bones and files are there can't get too, anyway thanks for reply

Re: Martial Empires / Seven Souls

Posted: Tue Jul 17, 2012 5:38 am
by Rimbros
Finale the Chroxxx script have trobles and not work fine, maybe u can made one for Noesis man? thanks.

Re: Martial Empires / Seven Souls

Posted: Tue Jul 17, 2012 5:49 am
by finale00
Needs samples.
Someone should put together a sample repository where all samples go so I can just go there for samples.

EDIT: well, here's the start of it since I don't have textures or the associated skeleton file

https://www.dropbox.com/sh/7stlpd4qvkq3 ... uls_msh.py

Image

Note that the file check ASSUMES the filename is the original filename, because the first 4 bytes is an integer equal to the number on that file.

I also noticed that I posted some bsb samples for the map assets, so I looked at it again with those samples:

https://www.dropbox.com/sh/7stlpd4qvkq3 ... uls_bsb.py

Does not load the entire model yet, since one mesh struct seems different from another.
I don't actually know what that "extra" mesh after the first mesh is. It looks like the first mesh is enough for most purposes

Textures don't look right (UV is a big mess).
Maybe I'm not reading the right ones.

Image

Re: Martial Empires / Seven Souls

Posted: Tue Jul 17, 2012 9:08 am
by Rimbros
This man made the plugin in 10 minutes for Noesis, :eek: , Thanks finale its a greath job.
Tomorrow i startmade a game samples repository.

Re: Martial Empires / Seven Souls

Posted: Tue Jul 17, 2012 9:54 pm
by finale00
Chrrox already wrote the maxscript so the format just needs to be parsed in a different language.

Re: Martial Empires / Seven Souls

Posted: Wed Jul 18, 2012 2:56 am
by finale00
msh script updated. Changed the file check to remove all non-digit characters rather than assume the format of the string. Now it should correctly check any of the msh files. After looking at how the data is stored, my plan is to have you copy all of the textures, in their original folders (normal, mask, texture) into the mesh folder. Then I can just assume that's where they are.

The mesh-texture assignment is stored in the "texture-info.txt" file. It is huge, and contains information for all meshes in that particular folder. I'm looking for a way to avoid having to keep selecting that file again and again whenever you want to view a new model.

bsb script updated.
Figured out where the mesh count is, and what the extra stuff at the end is also ("extra meshes" apparently)

It looks like all of the map assets such as buildings, dungeons, and basically entire cities/villages are stored across several bsb files.

Still some files with unknown mesh structs though.
Each vertex is 56 bytes. Some of these meshes would say they have 20 vertices, and so you read 20 vertices. Then they might have another 400k bytes of unknown floats, followed by say 36 faces.

Not sure what those random chunks of bytes are.

Image

Image

Attached two such examples that are breaking the script