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

[Noesis] Plugin to export to a new format

Post questions about game models here, or help out others!
Alsair
advanced
Posts: 66
Joined: Fri Jun 15, 2012 10:55 am
Has thanked: 4 times

Re: [Noesis] Bone Mapping with Skeleton

Post by Alsair »

MrAdults wrote:That's an easy fix. Don't plop the NoeMat44 data into a NoeMat43, use NoeMat44's toMat43() method instead. They aren't the same major, so it's not the same operation.
YES IT WORKS! Damn man, couldn't believe this was the issue. Kinda amazed.

Some models don't have the textures mapped correctly though... Dunno why, the UV positions are correct.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [Noesis] Bone Mapping with Skeleton

Post by MrAdults »

Congratulations, and well done. :)
Alsair
advanced
Posts: 66
Joined: Fri Jun 15, 2012 10:55 am
Has thanked: 4 times

Re: [Noesis] Bone Mapping with Skeleton

Post by Alsair »

MrAdults wrote:Congratulations, and well done. :)
Looks pretty good, now since all the animation data is stored in each key frame, implementing animation support wouldn't be too difficult in Noesis right?


What would be the best approach for this?
Last edited by Alsair on Wed Jul 03, 2013 11:02 pm, edited 1 time in total.
howfie
double-veteran
double-veteran
Posts: 929
Joined: Fri Jul 08, 2011 12:06 pm
Location: Torrance, CA
Has thanked: 10 times
Been thanked: 274 times

Re: [Noesis] Bone Mapping with Skeleton

Post by howfie »

nice, i tell ya, you're amazing rich, despite having no balls lolololl hahahahahahah :)
Alsair
advanced
Posts: 66
Joined: Fri Jun 15, 2012 10:55 am
Has thanked: 4 times

Re: [Noesis] Bone Mapping with Skeleton

Post by Alsair »

Okay, I got pretty much everything fixed and done. I was wondering if there is a way to import each keyframe as an animation into Noesis? Is there any particular method to use?
Last edited by Alsair on Wed Jul 03, 2013 11:04 pm, edited 1 time in total.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [Noesis] Bone Mapping with Skeleton

Post by MrAdults »

Yeah, it should be easy, especially since your hierarchy is flattened. You don't have to worry about whether or not the bones are local to their parents.

NoeAnims are basically just made up NoeMat43's, and a set of bones. You can give it the exact same set of bones you're currently attaching to your model. The matrices are expected to be ordered as yours already are, ( (matrix for each bone) * numframes ), as opposed to ( (matrix for each frame) * numbones ). So you can read all of your matrices into a flat list of NoeMat43 and do something like this:

Code: Select all

frameMats = []
#...
#run through here and build noemat43's for each bone in each frame and frameMats.append(mat) for each one
#...
#NoeAnim args are sequence name, NoeBone list for base skeleton (hierarchy is the only thing these bones are used for, their matrices aren't important), frame count, the whole batch of frame matrices for all bones and all frames, and framerate
anim = NoeAnim("singlesequence", modelBones, numFramesOfAnimation, frameMats, 30.0) 
#mdl is your already-constructed NoeModel
mdl.setAnims([anim])
Alsair
advanced
Posts: 66
Joined: Fri Jun 15, 2012 10:55 am
Has thanked: 4 times

Re: [Noesis] Bone Mapping with Skeleton

Post by Alsair »

MrAdults wrote:Yeah, it should be easy, especially since your hierarchy is flattened. You don't have to worry about whether or not the bones are local to their parents.

NoeAnims are basically just made up NoeMat43's, and a set of bones. You can give it the exact same set of bones you're currently attaching to your model. The matrices are expected to be ordered as yours already are, ( (matrix for each bone) * numframes ), as opposed to ( (matrix for each frame) * numbones ). So you can read all of your matrices into a flat list of NoeMat43 and do something like this:

Code: Select all

frameMats = []
#...
#run through here and build noemat43's for each bone in each frame and frameMats.append(mat) for each one
#...
#NoeAnim args are sequence name, NoeBone list for base skeleton (hierarchy is the only thing these bones are used for, their matrices aren't important), frame count, the whole batch of frame matrices for all bones and all frames, and framerate
anim = NoeAnim("singlesequence", modelBones, numFramesOfAnimation, frameMats, 30.0) 
#mdl is your already-constructed NoeModel
mdl.setAnims([anim])
Awesome, I gotta fix one thing though

Seems like I'm not passing through all of that data correctly in some bones. So I'm going to take a further look at that and find a permanent solution to it.

Edit: Ok I have fixed that issue as well.
Also I was wondering if theres a way to import multiple models into Noesis, like the head body and arms models all together to form a new combined model.

Oh and is it possible to add sound effects support with the anims?

Edit:

Okay, got animations implemented (and they're grouped the same way the model groups them near the header). Just need to figure out how to import SFX data, if that's even possible in Noesis? And is it possible to import collision data into Noesis?

Also, lets say I export my game model as .obj and then made some changes to the obj model, how/what would I have to do to export that obj model back to my game's format (via Noesis)? I have the entire structure of the file already, but I have no idea how to convert it back to normal. I was wondering, since Noesis is able to load all the supported model types, is it possible to read the model data drawn by Noesis and use that to write into the file, rather than parse the obj file directly? This way it would maximize compatibility? Also, would the bone names still be stored, since they are needed to be associated with the original skeleton file.
Last edited by Alsair on Wed Jul 03, 2013 11:10 pm, edited 2 times in total.
User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 4286
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 1147 times
Been thanked: 2242 times

Re: [Noesis] Bone Mapping with Skeleton

Post by shakotay2 »

Alsair wrote:And is it possible to import collision data into Noesis?
Since this is an unanswered question from your start post be informed that in Noesis.dll you'll find:
-decalmesh - generates rendermodel collision/decal meshes
(well, "generate" does not mean "import" but that's all I found.)

Looks to me as if you wished to extend Noesis to a fully featured game engine (like Blender game?).
Maybe you should ask MrAdults whether he's interested in you becoming part of his Noesis project?

Btw on googling for setHandlerWriteModel I found
http://noesis-plugins-official.googleco ... c/3/trunk/

Also, lets say I export my game model as .obj and then made some changes to the obj model, how/what would I have to do to export that obj model back to my game's format (via Noesis)?
First thing imho would be to think about using noepyWriteModel() to export your imported *.bsc data to a bsc again.

The model changing part? Huh, well, would be interested in MrAdults opinion, too.
Last edited by shakotay2 on Thu Jul 04, 2013 11:28 am, edited 1 time in total.
Tuts: a) Bigchillghost, viewtopic.php?f=29&t=17889
b) Extracting simple models: http://forum.xentax.com/viewtopic.php?f=29&t=10894
"Quoting the whole thing. Would u ever stop this nonsense?"
Alsair
advanced
Posts: 66
Joined: Fri Jun 15, 2012 10:55 am
Has thanked: 4 times

Re: [Noesis] Bone Mapping with Skeleton

Post by Alsair »

shakotay2 wrote:
Alsair wrote:And is it possible to import collision data into Noesis?
Since this is an unanswered question from your start post be informed that in Noesis.dll you'll find:
-decalmesh - generates rendermodel collision/decal meshes
(well, "generate" does not mean "import" but that's all I found.)

Looks to my as if you wished to extend Noesis to a fully featured game engine (like Blender game?).
Maybe you should ask MrAdults whether he's interested in you becoming part of his Noesis project?

Btw on googling for setHandlerWriteModel I found
http://noesis-plugins-official.googleco ... c/3/trunk/

Also, lets say I export my game model as .obj and then made some changes to the obj model, how/what would I have to do to export that obj model back to my game's format (via Noesis)?
First thing imho would be to think about using noepyWriteModel() to export your imported *.bsc data to a bsc again.

The model changing part? Huh, well, would be interested in MrAdults opinion, too.
I was curious to know since the SFX data and Collision data are both handled within the .bon file. Also I tried importing the three models by loading the one bone file that all three share and then loading the model each and using mdlList.append on each model. Initially I would only see the first model that I appended until I realized I can cycle through models. When I pressed F6 I think it was, I would see the second model I appended with the distortion of the first model, then when I pressed F6 again I saw the third model perfectly fine; however the previous two models became distorted. So I am not sure why this is occuring but I can guarantee all three models are being transformed with the bone correctly independently, I just cant figure out why they appear correctly when all three models are appended.

I will look into the exporting to bsc stuff as well, any examples would be helpful.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [Noesis] Plugin to export to a new format

Post by MrAdults »

For exporting, you just need to add an export handler, and write the data out from the common Noesis data structures. You can take a look at the __NPExample.txt file, it has import and export for the same format.

There's no specific handling for collision or sound data. You can handle that a couple of ways. You could dump it out next to files or a container next to the model using Python file functions and using rapi functions to get the export path, optionally putting a common RIFF/WAVE header on your sound data.

You could also get really fancy and write a DirectSound implementation as a native plugin that implements itself as a tool and a visualizer, and check the animation frames in your visualizer to know when to trigger your sounds. You could communicate the sound info from the importer to the plugin through a number of means - flat files, IPC (TCP, pipes, etc), or DLL calls. Flat files would be easiest, and should be reliable if you just want to make your own simple parseable format for the visualizer to parse on model load. You could write whatever data you need to that file, like keyframes and their associated sound events. Your plugin checks if the file exists for a model when the model is loaded, and if it does, it parses it, loads the sounds, and plays the sounds for the keyframes while the anim plays as appropriate. For collision, there's not much use of you don't have things to collide *with*, but you could certainly do whatever you want there using a visualizer as well.

This is all possible and fairly painless to do in the existing plugin framework, but it is somewhat advanced. So, remember, baby steps. :)
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [Noesis] Plugin to export to a new format

Post by MrAdults »

Oh, and your model distortion issue is my fault. Apparently I broke weighting on multiple models in a recent update. Thanks for running into it! I'll put an update out to fix it today.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: [Noesis] Plugin to export to a new format

Post by MrAdults »

Nevermind, it wasn't my fault. :) I broke GMO specifically, which is the only multi-model format I had laying around to test.

Not sure off the top of my head what your problem is then. It sounds like the weights don't match the bones, or the anims don't match the bones.
Alsair
advanced
Posts: 66
Joined: Fri Jun 15, 2012 10:55 am
Has thanked: 4 times

Re: [Noesis] Plugin to export to a new format

Post by Alsair »

MrAdults wrote:Nevermind, it wasn't my fault. :) I broke GMO specifically, which is the only multi-model format I had laying around to test.

Not sure off the top of my head what your problem is then. It sounds like the weights don't match the bones, or the anims don't match the bones.
That's funny because all three models load fine using the same skeleton independently, just not together.

As for the export handler, lets say I have a bsc converted to obj file, how would the obj file contain the same original bone name's? Since in order to convert it back to .bsc I would need that data as well.

The sound data itself, only contain references to the actual WAV files stored in the client directory, they're not written within the skeleton file as raw data. I believe it's similar with collision data, since when I altered the data there I was able to attack monsters regardless of what animation was running (usually it only attacks during the attack animation).

Basically, my plan is to completely rewrite the skeleton + bsc files from scratch with all the necessary data (although this would be the last step to do), my first aim is to get the new modified .obj files to convert back to .bsc with all of the proper bone names.

As for the multi-model import, I have PM'd you the code on how I've been attempting to load them. I recoded the entire plugin to make use of classes.
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] Plugin to export to a new format

Post by Demonsangel »

Alsair wrote: As for the export handler, lets say I have a bsc converted to obj file, how would the obj file contain the same original bone name's? Since in order to convert it back to .bsc I would need that data as well.
Is there a reason it has to be .obj and not .fbx or .dae?
You could create an extra NoeBitStream() and write the bone data into that one. Then write the buffer from that stream into a file.

Here's an example of how I rewrote custom texture into the format of a dds. (not what I should have done back then, but ignore that.)

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']))
        if "DXT" in self.header['pixelFormat']['fourCC']:
            file.writeBytes(b"\x44\x58\x54") #write "DXT"
            file.writeBytes(struct.pack('b',48+int(self.header['pixelFormat']['fourCC'][-1]))) #write 1-5
        else:
            file.writeBytes(b"\x00\x00\x00\x00")
        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']))
        try:file.writeBytes(noePack("<1i",self.header['pixelFormat']['ABitMask']))
        except: file.writeBytes(b"\x00\x00\x00\xFF")
        file.writeBytes(noePack("<1i",self.header['caps1']))
        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.Images[0].reverse()
        for l in range(self.Layers):
            for m in range(self.header['mipmapCount']):
                file.writeBytes(self.Images[l][m])
        return file
with this function you could for example write that buffer to a file with:

Code: Select all

bitstream = WriteFixedDDS()# ignore the fact the function was part of a class
texture = open('texture.dds','wb')
texture.write(bitstream.getBuffer())
texture.close()
In inc_noesis.py you'll find: noePack = struct.pack
so for more info you can reference the struct module.

In order for this to work, in your export script(obj >bsc) you'll need to put a check where if the inputfile has extension .obj you open a prompt (ex: rapi.loadPairedFileOptional("Skeleton File","objskel") ) and read the skeleton from there or make it autoread it defined on whatever you wish.
That's how I would do it, not sure if it's the best method.
Alsair
advanced
Posts: 66
Joined: Fri Jun 15, 2012 10:55 am
Has thanked: 4 times

Re: [Noesis] Plugin to export to a new format

Post by Alsair »

Demonsangel wrote:
Alsair wrote: As for the export handler, lets say I have a bsc converted to obj file, how would the obj file contain the same original bone name's? Since in order to convert it back to .bsc I would need that data as well.
Is there a reason it has to be .obj and not .fbx or .dae?
You could create an extra NoeBitStream() and write the bone data into that one. Then write the buffer from that stream into a file.

Here's an example of how I rewrote custom texture into the format of a dds. (not what I should have done back then, but ignore that.)

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']))
        if "DXT" in self.header['pixelFormat']['fourCC']:
            file.writeBytes(b"\x44\x58\x54") #write "DXT"
            file.writeBytes(struct.pack('b',48+int(self.header['pixelFormat']['fourCC'][-1]))) #write 1-5
        else:
            file.writeBytes(b"\x00\x00\x00\x00")
        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']))
        try:file.writeBytes(noePack("<1i",self.header['pixelFormat']['ABitMask']))
        except: file.writeBytes(b"\x00\x00\x00\xFF")
        file.writeBytes(noePack("<1i",self.header['caps1']))
        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.Images[0].reverse()
        for l in range(self.Layers):
            for m in range(self.header['mipmapCount']):
                file.writeBytes(self.Images[l][m])
        return file
with this function you could for example write that buffer to a file with:

Code: Select all

bitstream = WriteFixedDDS()# ignore the fact the function was part of a class
texture = open('texture.dds','wb')
texture.write(bitstream.getBuffer())
texture.close()
In inc_noesis.py you'll find: noePack = struct.pack
so for more info you can reference the struct module.

In order for this to work, in your export script(obj >bsc) you'll need to put a check where if the inputfile has extension .obj you open a prompt (ex: rapi.loadPairedFileOptional("Skeleton File","objskel") ) and read the skeleton from there or make it autoread it defined on whatever you wish.
That's how I would do it, not sure if it's the best method.
Was using obj as an example, but I mean any could be fine. Also, how would I associate the bone names from the exported skeleton file back to the mesh pieces again? Wouldn't this association be lost after it's been exported into a new model format?
Post Reply