Page 3 of 6

Re: [NOESIS] Titan Quest

Posted: Sun Mar 04, 2012 6:10 pm
by Demonsangel
Image

Ok, so Noesis can now load the .tex files (Tamschi's source was a great help!), but I do need some help on Noesis functions on how to load them more efficiently.

After loading the file into memory and correcting the data I don't know what to do with the raw ( DXT5 compressed) pixel data, so I basically write everything back into NoeBitStream, get the buffer from this load that bitstream asif it was a dds file.

Code: Select all

	def WriteFixedDDS(self):
		file=NoeBitStream()
		file.writeBytes(b"\x44\x44\x53\x20")
		file.writeBytes(noePack("<1i",self.header.DefaultSize))
		file.writeBytes(noePack("<1i",self.header.Flags))
		file.writeBytes(noePack("<1i",self.header.Height))
		file.writeBytes(noePack("<1i",self.header.Width))
		file.writeBytes(noePack("<1i",self.header.LinearSize))
		file.writeBytes(noePack("<1i",self.header.Depth))
		file.writeBytes(noePack("<1i",self.header.MipmapCount))
		file.writeBytes(noePack("<11i",*self.header.Reserved1))
		file.writeBytes(noePack("<1i",self.header.PixelFormat.DefaultSize))
		file.writeBytes(noePack("<1i",self.header.PixelFormat.Flags))
		file.writeBytes(b"\x44\x58\x54\x35")
		file.writeBytes(noePack("<1i",self.header.PixelFormat.RGBBitCount))
		file.writeBytes(noePack("<1i",self.header.PixelFormat.RBitMask))
		file.writeBytes(noePack("<1i",self.header.PixelFormat.GBitMask))
		file.writeBytes(noePack("<1i",self.header.PixelFormat.BBitMask))
		file.writeBytes(noePack("<1i",self.header.PixelFormat.ABitMask))
		file.writeBytes(noePack("<1i",self.header.Caps))
		file.writeBytes(noePack("<1i",self.header.Caps2))
		file.writeBytes(noePack("<1i",self.header.Caps3))
		file.writeBytes(noePack("<1i",self.header.Caps4))
		file.writeBytes(noePack("<1i",self.header.Reserved2))
		self.header.Images[0].reverse()
		for l in range(self.header.Layers):
			for m in range(self.header.MipmapCount):
				file.writeBytes(self.header.Images[l][m])
		return file

Code: Select all

buffer=dds.WriteFixedDDS()
tex = rapi.loadTexByHandler(buffer, '.dds')
	if tex: texList.append(tex)
So I have the data, now how do I "decompress" it or whatever I need to do so I could use this instead:

Code: Select all

texList.append(NoeTexture("TQTex",dds.header.Width,dds.header.Height,dds.header.Images[0][10],noesis.NOESISTEX_RGBA32))

Re: [NOESIS] Titan Quest

Posted: Sun Mar 04, 2012 6:33 pm
by Tamschi
I don't know if this works, but there are noesis.NOESISTEX_DXT1, noesis.NOESISTEX_DXT3 and noesis.NOESISTEX_DXT5 constants that you can use instead of noesis.NOESISTEX_RGBA32.
The format should be somewhere in the DDS header.

A few .tex files don't have reversed mip maps, so you have to check that flag to choose the right image.

Re: [NOESIS] Titan Quest

Posted: Sun Mar 04, 2012 7:54 pm
by Demonsangel
Noesis still crashes when trying to display the texture.

Edit: What am I doing wrong to load the texture in my model script? Neither the .dds/.tga/.tex work when trying the following:

Code: Select all

rapi.rpgSetMaterial("AW01")
mdl=rapi.rpgConstructModel()
matList=[]
texList=[]
material = NoeMaterial("AW01","")
material.setTexture("ancestralwarrior02.tga")
matList.append(material)
mdl.setModelMaterials(NoeModelMaterials(texList, matList))
mdl.setBones(self.bones)
mdlList=[]
mdlList.append(mdl)
The material is set in Noesis but no texture appears. After exporting the model to blender/3ds max the UV coordinates are correct.

Re: [NOESIS] Titan Quest

Posted: Tue Mar 06, 2012 5:17 pm
by Demonsangel
Tamschi, I'm having trouble understanding the function you sent to get the vertex weight, especially with the info about shaders. Couldn't I just get the vertex weight out of the vertex data?

Re: [NOESIS] Titan Quest

Posted: Tue Mar 06, 2012 5:37 pm
by Tamschi
Demonsangel wrote:Tamschi, I'm having trouble understanding the function you sent to get the vertex weight, especially with the info about shaders. Couldn't I just get the vertex weight out of the vertex data?
No, that won't work. The bone indices in the vertex data map to the bone slots in the draw call, not the bone array.

For each vertex, you have to find the draw call that uses it and change each bone index in the vertex' weights so that

newBoneIndex = boneListInDrawCall[oldBoneIndex];

If you want to export the mesh, you have to make sure that there aren't more than 27 bones in each draw call's bone list, otherwise Titan Quest and the Viewer crash with an invalid memory access.

The skinning shaders all take exactly 27 matrices for bone transformations. Any more than that and there's an array overflow in the animation code.

Re: [NOESIS] Titan Quest

Posted: Tue Mar 06, 2012 8:08 pm
by Demonsangel
Would it be alright for me to adjust the current NoeBones' indexes (using NoeBone.index) to match the index in the drawcall? I parented them via bonenames and not indexes.
Or would this be asking for disasters to happen.

Re: [NOESIS] Titan Quest

Posted: Tue Mar 06, 2012 8:24 pm
by Tamschi
If there is more than one draw call, the same bone id in the vertex weights can point to different bones. You really need to edit the weights to make it 100% compatible.

A bone id of 255 in the vertex weights means no bone, but the weight value isn't always 0.0 if the id is 255.

Re: [NOESIS] Titan Quest

Posted: Tue Mar 06, 2012 8:45 pm
by Demonsangel
So if I get it right I need to parse the drawcalls.

For each drawcall I need to know which triangles it uses and for each triangle which vertices it uses.
These vertices then belong to the current drawcall and the current drawcall's bonelist?

I need then need to use the boneindex listed in the vertexdata use it to get the correct actual bone index by using the drawcalls bonelist.

Who comes up with this stuff.

Re: [NOESIS] Titan Quest

Posted: Tue Mar 06, 2012 9:01 pm
by Tamschi
It makes perfect sense if you only want to push the mesh to the GPU. Otherwise you'd have to rearrange the weights each time the mesh is loaded into the game.

Re: [NOESIS] Titan Quest

Posted: Wed Mar 07, 2012 12:04 am
by MrAdults
I only just now noticed this thread. It's pretty common for games to use a per-draw bone palette. Bullet Witch does too. You can look at the Bullet Witch Python script with Noesis to see how that's managed, there's already an existing function to let you feed your bone palette into the Noesis RPG interface so you don't even have to deal with mapping the indices yourself.

Also, it looked to me like you ended up doing your own hierarchical bone transforms for the skeleton. You can let Noesis do that for you too. Just set up your NoeBones with standard parent-relative matrices and then call rapi.multiplyBones. (syntax is "boneList = rapi.multiplyBones(boneList)")

Re: [NOESIS] Titan Quest

Posted: Fri Mar 09, 2012 7:04 pm
by Demonsangel
I have a mesh with 2 drawcalls
1) 3041 faces, 27 bones
2) 323 faces, 7bones

My importer errors out when trying to parse vertex 5422 (and others following it)
vertex 5422 belongs to face 3065 which means the second drawcall.
vertex 5422's boneindices are (0,12,4,255) and weights(0.84,0.12,0.04,0)

So this vertex is asking for bone index 12 in drawcall 2 but there are only 7 indices and the weight for the bone is not zero.

What went wrong?

Re: [NOESIS] Titan Quest

Posted: Fri Mar 09, 2012 7:37 pm
by Tamschi
Wich one is it? I'll try to open it in MeshView.

Re: [NOESIS] Titan Quest

Posted: Fri Mar 09, 2012 8:12 pm
by Demonsangel

Re: [NOESIS] Titan Quest

Posted: Fri Mar 09, 2012 8:42 pm
by Tamschi
Face 3065 is {3538, 3537, 3526}.

Re: [NOESIS] Titan Quest

Posted: Fri Mar 09, 2012 8:47 pm
by Demonsangel
Means I can calculate all the triangles myself as well, Noesis gives me Tri 3065(5421,5422,5423)

Edit: okies that worked so far.