Page 2 of 2

### Re: Approaches of Parsing Bone Representations

Posted: Sun Aug 18, 2019 9:25 pm
Thanks for all the great tips

i feel kind of stupid with this but i cant seem to get the correct numbers for world transformation, and was hoping you could look at the numbers and maybe tell me what i am doing wrong:
I have a picture of debug console of noesis where first line(bones1) is original 4x3 matrix while second line(bones2) in world transformation.
up until i = 2 i get the correct answer by multiplying bone * bone[i-1] etc..
from i =3 no matter what combination i do i dont get the same result.
what i am doing is Matrix[3]*matrix[2]*matrix[1]*matrix[0], i tried a few other combinations including matrix[3]*matrix[2]-world transformation but none give the same result as noesis.

i dont know how important it is to understand this if noesis does this , but it bugs the hell out of me that i cant figure it out

### Re: Approaches of Parsing Bone Representations

Posted: Sun Aug 18, 2019 9:27 pm
couldn't add a second attachment before, here are my matrices:
if i understood correctly:

for i =3
Bones[3] * Bones[2] * Bones[1]* Bones[0] = answer

### Re: Approaches of Parsing Bone Representations

Posted: Mon Aug 19, 2019 5:51 am
jayn23 wrote:
Sun Aug 18, 2019 9:25 pm
what i am doing is Matrix[3]*matrix[2]*matrix[1]*matrix[0]
It should be matrix[0]*matrix[1]*matrix[2]*matrix[3] since it's row-major matrix.
noe.png
jayn23 wrote:
Sun Aug 18, 2019 9:25 pm
i dont know how important it is to understand this if noesis does this , but it bugs the hell out of me that i cant figure it out
Theoretically to convert a parent space tree to world space, you need to premultiply each node in a level with its parent recurrently from the root level down to the last level, or use other methods that have the same effect. So it doesn't matter how Noesis does it, so long as it works as expected. But you should know at least one way to convert it yourself.

### Re: Approaches of Parsing Bone Representations

Posted: Mon Aug 19, 2019 9:11 am
Ill take a look at the numbers when i get home, but i am sure ill get it to work now.

Thanks a lot for all your help and fast reply's i really appreciate it.

### Re: Approaches of Parsing Bone Representations

Posted: Fri Aug 23, 2019 7:17 am
Hello,and sorry to disturb you.
Could you analysis the bigworld engine model?I can't find any ather idears.
http://www.mediafire.com/file/g432vuf89 ... 05408/file
this is a sample. bone file is .visual
Thanks

### Re: Approaches of Parsing Bone Representations

Posted: Wed Oct 09, 2019 9:12 am
chr_body_rank_104_a_slender.zip

Code: Select all

``````# Dump Name: chr_body_rank_104_a_slender.o4a
# From Game: IDOLM@STER One For All
# Platform: PS3
# Bone Format: 4x4 Matrices (inversed)
# Coordinate System: Left-Hand
# Endian: Big
``````
Bone data structure:

Code: Select all

``````long	boneCount
for i = 0 < boneCount
long	boneID
long	structSize
long	unknown
char	boneName[0x20]
long	parentID
byte	skip[0x9C]
float	boneMat[4][4] // Column-major
byte	skip2[0xC]
``````
Same procedure as for Iron Man 2. Probably some kind of "feature" of PS3 games?

Noesis code(lack convertion to right-handed):

Code: Select all

``````#load the model
bs = NoeBitStream(data, NOE_BIGENDIAN)
bones = []
for i in range(0, boneCount):
bs.seek(8, NOESEEK_REL)
if boneName == "":
boneName = "Scene Root"
bs.seek(0x9C, NOESEEK_REL)
Mat44 = NoeMat44.fromBytes( bs.readBytes(0x40), NOE_BIGENDIAN )
boneMat = Mat44.toMat43().inverse()
bs.seek(0x10, NOESEEK_REL)
bones.append( NoeBone(boneID, boneName, boneMat, None, parentID) )

mdl = NoeModel()
mdl.setBones(bones)
mdlList.append(mdl)
return 1
``````

### Re: Approaches of Parsing Bone Representations

Posted: Fri Oct 11, 2019 11:53 am
g_uec.zip

Code: Select all

``````# Dump Name: g_uec.ve1
# From Game: Ben 10 Ultimate Alien: Cosmic Destruction
# Platform: XBOX 360
# Bone Format: Quaternion Rotation, Translation
# Coordinate System: Right-Hand
# Engine: Vicious Engine
# Endian: Big
``````
Bone data structure:

Code: Select all

``````word	boneCount
word	boneCount
byte	itemBoneCount
byte	itemBoneCount
word	skip
for i = 0 < boneCount
float	Rotation[4] // Quaternion Rotation
float	Translation[3]
float	Scaling[3]
char	parentID
byte	skip[3]
for i = 0 < itemBoneCount
float	Rotation[4] // Quaternion Rotation
float	Translation[3]
char	parentID
byte	skip[3]
``````
Similar procedures as previous examples. Just with an extra bone list.

Noesis code:

Code: Select all

``````#load the model
bs = NoeBitStream(data, NOE_BIGENDIAN)
bs.seek(2, NOESEEK_REL)
bs.seek(7, NOESEEK_REL)
bones = []
for i in range(0, boneCount):
bs.seek(3, NOESEEK_REL)
boneMat = Rot.toMat43(transposed = 0)
boneMat[3] = Tran
bones.append( NoeBone(i, "bone%03d"%i, boneMat, None, bonePIndex) )
for i in range(0, itemBoneCount):
bs.seek(3, NOESEEK_REL)
boneMat = Rot.toMat43(transposed = 0)
boneMat[3] = Tran
idx = boneCount + i
bones.append( NoeBone(idx, "bone%03d"%idx, boneMat, None, bonePIndex) )
totalBoneCount = boneCount + itemBoneCount
# Converting local matrix to world space
for i in range(0, totalBoneCount):
j = bones[i].parentIndex
if j != -1:
bones[i].setMatrix( bones[i].getMatrix() * bones[j].getMatrix() )

mdl = NoeModel()
mdl.setBones(bones)
mdlList.append(mdl)
return 1
``````

### Re: Approaches of Parsing Bone Representations

Posted: Fri Oct 11, 2019 12:08 pm
Time for some clarification.

Why would the following method of converting a parent-space bone tree to world space work within Noesis?

Code: Select all

``````for i in range(0, boneCount):
j = bones[i].parentIndex
if j != -1:
bones[i].setMatrix( bones[i].getMatrix() * bones[j].getMatrix() )
``````
It has nothing to do with Noesis' feature but simply because it's logically correct for any organized bone list.

Let's see how the bone nodes are usually stored.

(bone tree of g_uec.ve1 from Ben 10 Ultimate Alien: Cosmic Destruction)

The number of each node equals to its index in the node list, the same below.

And this diagram shows how the nodes are traversed.

As you can see, the traversal order of the nodes is exactly aligned to how they're stored in the bone list.

Bones stored as above are in the so-called depth-first traversal order. However it can also apply to bone list in breadth-first storage.

(bone tree of mermaid_normal.model from GuJian3)

The traversal order of the list:

So long as the bone nodes in the list are organized in a way where any node is stored after its parent node, this method will work correctly.

### Re: Approaches of Parsing Bone Representations

Posted: Wed Apr 01, 2020 3:18 pm
Can you read the bones from forza 4 car? It has 75 bones

### Re: Approaches of Parsing Bone Representations

Posted: Tue May 26, 2020 3:17 pm
anakinhooddown.zip

Code: Select all

``````# Dump Name: anakinhooddown.sw3
# From Game: Star Wars: Episode III – Revenge of the Sith
# Platform: Xbox
# Bone Format: 4x3 Matrices
# Coordinate System: Left-Hand
# Endian: Little
``````
Bone data structure:

Code: Select all

``````long	boneCount
for i = 0 < boneCount
char	boneName[0x20]
float	boneMat[4][3] // Rotation[3][3](column-major), Translation[3]
short	parentID
``````
The rotation matrices are in column-major so transposes are required.
Also similar to Iron Man 2 and IDOLM@STER One For All, they need to be inversed.

Noesis code (lack convertion to right-handed):

Code: Select all

``````#load the model
bs = NoeBitStream(data)
bones = []
for i in range(0, boneCount):
pos = bs.tell() + 0x20
bs.seek(pos, NOESEEK_ABS)
bones.append(NoeBone(i, boneName, boneMat, None, bonePIndex))

mdl = NoeModel()
mdl.setBones(bones)
mdlList.append(mdl)
return 1
``````

### Re: Approaches of Parsing Bone Representations

Posted: Tue May 26, 2020 8:01 pm
Hi Bigchillghost,

Thanks for updating this thread all the time, i still find my self checking it out every now and then to give me ideas how to do things its very useful
Noesis code (lack convertion to right-handed):
apparently rich thought about this to, yesterday i found a built in function for swapping from left to right hand and thought you might be interested.

Code: Select all

``boneMat = NoeMat43.fromBytes(bs.readBytes(48)).transpose().inverse().swapHandedness(0)``
swapHandedness (axis) while axis can be 0,1,2
for anakin it worked with 0

### Re: Approaches of Parsing Bone Representations

Posted: Wed May 27, 2020 4:15 am
jayn23 wrote:
Tue May 26, 2020 8:01 pm
i still find my self checking it out every now and then to give me ideas how to do things its very useful
Good to know.
yesterday i found a built in function for swapping from left to right hand and thought you might be interested.
Yeah I noticed that long time ago but never get it working. It appears that I mistook that function as one that affects the object itself and didn't overwrite the original matrix with the swapped one. I tested the other left-handed formats posted in this thread but some of them seem to be in right-handed already(Aavtar The Game, Iron Man 2 and IDOLM@STER). Not sure if it's because they use a different naming aspect from the others so I'll leave them as they are. Thanks for the hint anyway.