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

[NOESIS] Titan Quest

Post questions about game models here, or help out others!
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [NOESIS] Titan Quest

Post by MrAdults »

multiplyBones performs a hierarchical transform for the bones. If your matrices aren't parent-relative or your hierarchy isn't fed to Noesis correctly, it won't give you the results you're looking for.

Noesis will automatically recognize that 255 is an invalid bone index if it's out of range and you're using noesis.RPGEODATA_UBYTE as the data type when binding your bone index buffer.
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

Guess I'll have to play around with it and see what works.

I tried loading 2 files into noesis which it does by creating a .noesis file

Code: Select all

NOESIS_SCENE_FILE
version 1
physicslib      ""
defaultAxis      "0"
sharedAnims      "1"

object
{
   model      "monster\automatoi\automatoi01.msh"
   offset      "(0 0 0)"
   rotate      "(0 0 0)"
}

object
{
   model      "monster\automatoi\automatoiheada.msh"
   offset      "(0 0 0)"
   rotate      "(0 0 0)"
} 
It imports them correctly but creates a different boneset for each of them. Can I force them to use a joined boneset through the .noesis file or do I have to do it in the .msh script?
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

Tamschi: For the drawcalls is it defined somewhere when I'm supposed to read bone indices? Some files don't have bones and so they skip that part. I'm thinking of looping through the entire file once listing all the sections and then seeing if there's a section 6 for bones in the file, but if it's defined somewhere that might be better.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [NOESIS] Titan Quest

Post by MrAdults »

There isn't a shared skeleton option. I could probably add that functionality without too much effort, though, if you can guarantee that the skeletons match in bone counts and order.
Tamschi
n00b
Posts: 14
Joined: Sun Sep 25, 2011 9:43 pm
Been thanked: 1 time

Re: [NOESIS] Titan Quest

Post by Tamschi »

Demonsangel wrote:Tamschi: For the drawcalls is it defined somewhere when I'm supposed to read bone indices? Some files don't have bones and so they skip that part. I'm thinking of looping through the entire file once listing all the sections and then seeing if there's a section 6 for bones in the file, but if it's defined somewhere that might be better.
I don't think there is a flag, but the bone map in the draw call has length 0 if the mesh isn't skinned. The vertices shouldn't have weight or bone information either; I can't check anything currently though, because I managed to wreck my Visual Studio installation.

It's possible that the game gets some information from the shader files. They seem to be a list of flags and shader code, but I don't know how to read them.
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

Currently I'm looping over the file and if Section 6(bones) the Size UInt() has a size of 4bytes or less I know there is no bonemap.
But I could try and see if the vertex data always precedes the drawcalls and see if the vertex data has bone info.

MrAdults: the models do not have the same amount of bones, it's usually a main file (torso+arms+legs) and then a seperate file (body armor / head / helm / weapon) and these contain only a few of the bones the "main" file has.

I assume "shared skeleton" means the models have to be in 1 "mdl" else each mdl will have its own boneset, so I was thinking of just going through all files at once and adding all the vertex/bone/triangle data to buffers and doing them all at once. Though I don't see how I would do the bonemaps then, unless I try adjusting them to contain the correct link to the main boneset and then committing the bonemap.
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

For loading multiple models into 1 mesh, would it be best to just load all the .msh files in a folder or to create a new sort of file like the .noesis (eg .msh.ini) and tell noesis which models to load from that/a folder based on the ini?
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [NOESIS] Titan Quest

Post by MrAdults »

I bet the game already has data formats which hook all those mesh pieces together and tell where they're bolted and such in varying character configurations. Using that data to decide which mesh files to load into a single model would be the best solution.

Barring that, just take whichever approach makes sense I suppose. If all mesh files in a folder together are meant to go together in a single model, then I would have the script load all meshes in the folder. Otherwise, if you have situations where it isn't appropriate to do that, I would offer the option of letting people use .noesis files, or yeah, you could roll your own .noesis-like file and have them load that if you want. I would go with whichever viable solution requires the least amount of user effort. That's my general design rule for everything in Noesis, even though my laziness sometimes overrides it.
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

https://www.dropbox.com/sh/7pn17bxhwo9gwgu/cORIt1nsc_
TQ_MUL.py (needs TQ_Tex.py to load .tex files)
Loader.mshini

Code: Select all

[MAIN]
path=malepc01.msh
offset=0,0,0
rotate=1,1,1
Image
Loader.mshini

Code: Select all

[MAIN]
path=malepc01.msh
offset=0,0,0
rotate=1,1,1
[MODEL1]
path=c_torso08m.msh
offset=0,0,0
rotate=1,1,1
Image

For now you can only add meshes that are in a subfolder where the *.mshini is located but the textures won't load because the script currently only looks in the .mshini folder for them.

[MAIN] is the root model which contains the complete armature, so for now make sure you put these meshes first.

Loading torso armor meshes can cause an error because I'm still using my own Parenting function which errors out on these.

This is still a WiP so todo:
[*] Add bones from meshes that aren't yet in the global armature and hopefully disable the need for a MAIN model.
[*] Enable the translation to actually do something (mostly for weapons).
[*] Support both relative and absolute Path to Meshes and their Textures.
[*] Whatever comes up.
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

Was trying to get weapons to be imported at the correct offsets according to left or right hand. Figured this info would be stored into the .mif files.

weapon.mif holds:

Code: Select all

AttachPoint
{
    name   = "L Hand"
    parent = "Bone_L_Weapon"
    origin = (0.000000, 0.000000, 0.000000)
    xAxis  = (1.000000, 0.000000, 0.000000)
    yAxis  = (0.000000, 1.000000, 0.000000)
    zAxis  = (0.000000, 0.000000, 1.000000)
}
AttachPoint
{
    name   = "R Hand"
    parent = "Bone_R_Weapon"
    origin = (0.000000, 0.000000, 0.000000)
    xAxis  = (1.000000, 0.000000, 0.000000)
    yAxis  = (0.000000, 1.000000, 0.000000)
    zAxis  = (0.000000, 0.000000, 1.000000)
}
the body mesh.mif holds (along with a loooooot more):

Code: Select all

AttachPoint
{
    name   = "L Hand"
    parent = "Bone_L_Weapon"
    origin = (0.000000, 0.000000, 0.000000)
    xAxis  = (1.000000, 0.000000, 0.000000)
    yAxis  = (0.000000, 1.000000, 0.000000)
    zAxis  = (0.000000, 0.000000, 1.000000)
}


RigidBodyDescription
{
    parentName = "Bone_L_Wrist"
    childName = "Bone_L_Finger01"
    parentOrigin = (-0.061454, 0.003351, -0.001135)
    parentXAxis  = (1.000000, 0.000000, 0.000000)
    parentYAxis  = (0.000000, 1.000000, 0.000000)
    parentZAxis  = (0.000000, 0.000000, 1.000000)
    childOrigin = (0.061453, -0.003351, 0.001135)
    childXAxis  = (0.997545, -0.017286, -0.067870)
    childYAxis  = (-0.067860, 0.001176, -0.997694)
    childZAxis  = (0.017326, 0.999850, 0.000000)
    extents = (0.090000, 0.160000, 0.190000)
    collides = "false"
    density = "50.000000"
    playFallSound = "false"
    FusedBone
    {
        name = "Bone_L_FingerPoint01"
        origin = (0.061997, 0.005730, 0.069628)
        xAxis  = (0.971893, -0.016841, 0.234819)
        yAxis  = (0.234783, -0.004069, -0.972039)
        zAxis  = (0.017326, 0.999850, -0.000001)
    }
    FusedBone
    {
        name = "Bone_L_Thumb01"
        origin = (-0.036732, -0.016195, 0.082482)
        xAxis  = (0.615897, -0.010672, 0.787755)
        yAxis  = (0.787637, -0.013648, -0.615989)
        zAxis  = (0.017326, 0.999850, -0.000001)
    }
    FusedBone
    {
        name = "Bone_L_Weapon"
        origin = (0.022023, -0.037607, 0.015022)
        xAxis  = (0.999889, 0.014922, 0.000000)
        yAxis  = (0.014922, -0.999889, 0.000001)
        zAxis  = (0.000000, 0.000000, -1.000000)
    }
}
The offsets given for the FusedBone "Bone_L_Weapon" are the same as the actual bone offsets given in the bone data.
Would this mean I'd best put a "rpgSetPosScaleBias" with the bone's absolute position and axis as data?

I also found some

Code: Select all

JointDescription
{
    rigidBody0 = "17"
    rigidBody1 = "21"
    jointType = "universal"
    jointConnection = "1"
    jointAxis0 = "y"
    loStop0 = "-2.128240"
    hiStop0 = "2.671010"
    jointAxis1 = "z"
    loStop1 = "-1.775452"
    hiStop1 = "-0.982813"
    breakable = "false"
    breakChance = "0"
}
But don't really know what it does. If anyone has seen anything like this before and could shed some light on the subject it'd be much appreciated.

Then, for animations I get 3 floats for XYZ and 3 floats for axis, but NoeAnim wants a 4*3 matrix. are the axis floats Euler Angles and do i need to "decode" them or something?
Tamschi
n00b
Posts: 14
Joined: Sun Sep 25, 2011 9:43 pm
Been thanked: 1 time

Re: [NOESIS] Titan Quest

Post by Tamschi »

The only things that should matter for weapon attachments are the AttachPoint values in the body mesh. It's basically just another bone that marks the origin of the attached entity.
The matching attachment point in the weapon mesh may be an additional transformation. I don't know anything about that though.

The RigidBodyDescription is only for ragdoll physics. It describes a box that can be simulated more efficiently and the transformations for the mesh that is animated along with the physics ragdoll. The density should be for floating in water, mostly.

The JointDescription is only a ragdoll joint. It's probably not important for animation, but it limits ragdoll movements. There's something very similar in the Source engine's smds.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [NOESIS] Titan Quest

Post by MrAdults »

Demonsangel wrote:Then, for animations I get 3 floats for XYZ and 3 floats for axis, but NoeAnim wants a 4*3 matrix. are the axis floats Euler Angles and do i need to "decode" them or something?
I think Tamschi answered everything but this. (not sure about the accuracy of his answers, but I couldn't answer definitively either, although I know density typically affects a lot more than just water behavior, it affects all forces being applied to the object including gravity in most physics engines) For angles, you can use NoeAngles and convert that to a NoeMat43 using one of the provided conversion functions. Or if your angles are in a convention that doesn't have a method exposed for it (I need to address that at some point) you can do it manually. Something like:

Code: Select all

m = NoeMat43()
m = m.rotate(angles[0], NoeVec3(1.0, 0.0, 0.0))
m = m.rotate(angles[1], NoeVec3(0.0, 1.0, 0.0))
m = m.rotate(angles[2], NoeVec3(0.0, 0.0, 1.0))
You'll have to change the rotation order based on which convention your angles are using. People use all kinds of varying conventions when it comes to Euler angles, but XYZ is most common, so I would try that NoeAngles conversion function first and see if it saves you the trouble.
Tamschi
n00b
Posts: 14
Joined: Sun Sep 25, 2011 9:43 pm
Been thanked: 1 time

Re: [NOESIS] Titan Quest

Post by Tamschi »

You're right, I didn't notice that there was no "mass" parameter.

The animations don't use Euler angles, at least not directly.
I at some point had a program to output an animation where one bone's rotation values would increase at different speeds and the bone was rotating around the axes but also stretched along its axes prior to rotation.

Each frame for each bone in the animations is actually 14 floats: 3 for position, 3 for scaling and 2 * 4 floats that somehow are involved with rotation and shearing but can also scale the bone.
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

Oh, k. I'll try out some stuff and see what happens.
Been occupied so I only fixed some tiny bugs.
Demonsangel
mega-veteran
mega-veteran
Posts: 241
Joined: Fri Aug 05, 2011 9:31 pm
Location: Antwerp
Has thanked: 13 times
Been thanked: 41 times

Re: [NOESIS] Titan Quest

Post by Demonsangel »

For NoeAnim the matrices, would it be for example for a 3bone 2 frame animation:
bone1 bone2 bone3 bone1 bone2 bone3 or bone1 bone1 bone2 bone2 bone3 bone3
Post Reply