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

Martial Empires / Seven Souls

Post questions about game models here, or help out others!
User avatar
CriticalError
double-veteran
double-veteran
Posts: 678
Joined: Sun Jul 05, 2009 2:03 am
Has thanked: 104 times
Been thanked: 41 times

Re: Martial Empires / Seven Souls

Post by CriticalError »

thanks a lot for the great support but I get problem when try import in MAX 9,2009,2010.
You do not have the required permissions to view the files attached to this post.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Martial Empires / Seven Souls

Post 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..]
Last edited by finale00 on Fri Jul 01, 2011 2:07 am, edited 6 times in total.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Martial Empires / Seven Souls

Post 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.
User avatar
CriticalError
double-veteran
double-veteran
Posts: 678
Joined: Sun Jul 05, 2009 2:03 am
Has thanked: 104 times
Been thanked: 41 times

Re: Martial Empires / Seven Souls

Post 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
chrrox
Moderator
Posts: 2602
Joined: Sun May 18, 2008 3:01 pm
Has thanked: 57 times
Been thanked: 1422 times

Re: Martial Empires / Seven Souls

Post by chrrox »

it cant find one of the files mentioned there.
User avatar
CriticalError
double-veteran
double-veteran
Posts: 678
Joined: Sun Jul 05, 2009 2:03 am
Has thanked: 104 times
Been thanked: 41 times

Re: Martial Empires / Seven Souls

Post 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
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Martial Empires / Seven Souls

Post 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.
User avatar
CriticalError
double-veteran
double-veteran
Posts: 678
Joined: Sun Jul 05, 2009 2:03 am
Has thanked: 104 times
Been thanked: 41 times

Re: Martial Empires / Seven Souls

Post 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
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Martial Empires / Seven Souls

Post by finale00 »

I mean, you won't be able to load weapons because as you've pointed out, they don't have certain files :)
User avatar
CriticalError
double-veteran
double-veteran
Posts: 678
Joined: Sun Jul 05, 2009 2:03 am
Has thanked: 104 times
Been thanked: 41 times

Re: Martial Empires / Seven Souls

Post 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
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: Martial Empires / Seven Souls

Post by Rimbros »

Finale the Chroxxx script have trobles and not work fine, maybe u can made one for Noesis man? thanks.
Renders Art by Rimbros
http://s303.photobucket.com/albums/nn12 ... E/Renders/

Personal Game repository samples, send PM
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Martial Empires / Seven Souls

Post 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
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: Martial Empires / Seven Souls

Post 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.
Renders Art by Rimbros
http://s303.photobucket.com/albums/nn12 ... E/Renders/

Personal Game repository samples, send PM
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Martial Empires / Seven Souls

Post by finale00 »

Chrrox already wrote the maxscript so the format just needs to be parsed in a different language.
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Martial Empires / Seven Souls

Post 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
You do not have the required permissions to view the files attached to this post.
Post Reply