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

Spotlight: Señor Casaroja's Noesis

General game file tools that are useful for more than one game
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: Señor Casaroja's Noesis

Post by MrAdults »

finale00: Already on the list... has been for quite a long time now.

Rimbros: The Kinect doesn't have the resolution to do decent facial tracking. That's something MS apparently has planned though, I don't know whether for a future device or with a firmware update or what.
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: Señor Casaroja's Noesis

Post by finale00 »

While immediate mode rendering is available, is there a way to make it easier to parse and load per-face formats?

I'm assuming for commit triangle, each index points to a vertex, which assumes the number of coords, normals, and uv structs are equal.

How about binding a bunch of these vertex related buffers and using separate function calls to construct vertices using separate indices for coords, normals, and uv? It seems common I think.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: Señor Casaroja's Noesis

Post by MrAdults »

I've noticed you having problems with immediate mode but haven't had time/motivation to inquire further. I haven't exactly understood what your issue is... maybe you're forgetting to 0 out components if they aren't used in subsequent faces. That would cause Noesis to continue assigning invalid/missing attributes to the new vertices you're adding. The functionality is quite identical to drawing in immediate mode with OpenGL. That's why the API is structured the way it is.

If you really wanted, you could do that yourself by making some wrapper functions to generate index buffers and using CommitTriangles behind the scenes. I think that would be a waste of time and effort, but if you really think it would make your life easier, take a shot at it. It's also effectively already what Noesis is doing behind the scenes. The only difference is in immediate mode you're building vertex by vertex where CommitTriangles draws from existing vertex buffers, but both paths end up in the same place and doing the exact same thing with the data.

Oh, and I just shoehorned in texture cycling/animation support in the preview interface. Update if you want it.

Edit: Oh yeah, I also forgot I didn't expose any of the specific rpgVert/etc. types to Python. So you have to do things like convert from short to float yourself. You could easily enough add wrapper functions that do that as well. (like make a myRPGVert3us method that takes the shorts, scales the 0-65535 range to 0.0-1.0, then calls the imm function directly with the converted data) I should probably expose my generic "convert <whatever> to float" and "convert <whatever> to int" functions to Python to make that sort of thing more trivial. I thought I had, but I guess I didn't.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: Señor Casaroja's Noesis

Post by MrAdults »

I just implemented a whole slew of new immediate-mode drawing functions. They will be in the next version of Noesis, but I probably won't get the build up tonight.

Code: Select all

	//immediate-mode drawing in python works by feeding variable-sized component lists and/or tuples.
	//keep in mind that these values will not be normalized for you, even if they are provided as fixed-point.
	{"immBegin", IMMBegin, METH_VARARGS, "begin immediate-mode drawing. (i)"}, //args=primitive type
	{"immEnd", IMMEnd, METH_NOARGS, "end immediate-mode drawing."}, //args=none
	{"immVertex3", IMMVertex3, METH_VARARGS, "feeds a vertex position. (must be called last for each primitive) (O)"}, //args=3-component list
	{"immNormal3", IMMNormal3, METH_VARARGS, "feeds a vertex normal. (O)"}, //args=3-component list
	{"immTangent4", IMMTangent4, METH_VARARGS, "feeds a tangent vector. (O)"}, //args=4-component list, where 4th component is sign (-1 or 1) for bitangent
	{"immUV2", IMMUV2, METH_VARARGS, "feeds a vertex uv. (O)"}, //args=2-component list
	{"immLMUV2", IMMLMUV2, METH_VARARGS, "feeds a vertex lmuv. (O)"}, //args=2-component list
	{"immColor3", IMMColor3, METH_VARARGS, "feeds a vertex color. (O)"}, //args=3-component list
	{"immColor4", IMMColor4, METH_VARARGS, "feeds a vertex color. (O)"}, //args=4-component list
	{"immBoneIndex", IMMBoneIndex, METH_VARARGS, "feeds a vertex bone index. (O)"}, //args=x-component list
	{"immBoneWeight", IMMBoneWeight, METH_VARARGS, "feeds a vertex bone weight. (O)"}, //args=x-component list
	{"immVertMorphIndex", IMMVertMorphIndex, METH_VARARGS, "feeds a vertex morph index. (i)"}, //args=int
	//The following functions take raw bytes and decode them appropriately. Naming convention is #<type>, where # is number of elements and <type> is:
	//f - float
	//hf - half-float
	//b - byte
	//ub - unsigned byte
	//s - short
	//us - unsigned short
	//i - 32-bit int
	//ui - unsigned 32-bit int
	//X - arbitrary, you provide the RPGEODATA_ type and the number of elements.
	//All of these functions can also be called with "Ofs" after the name. Ofs variants require an additional argument (at the end of the argument list) to specify an offset into the array.
	//For example, rapi.immVertex3f(positions[idx*12:idx*12+12]) could instead be rapi.immVertex3fOfs(positions, idx*12), which is significantly less eye-raping and more efficient (as it requires no construction of a separate object for the slice)
	DEFINE_IMM_EX(immVertexX, IMMVertexX, METH_VARARGS, "feeds a vertex position. (must be called last for each primitive) (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immVertex3f, IMMVertex3f, METH_VARARGS, "feeds a vertex position. (must be called last for each primitive) (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immVertex3us, IMMVertex3us, METH_VARARGS, "feeds a vertex position. (must be called last for each primitive) (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immVertex3s, IMMVertex3s, METH_VARARGS, "feeds a vertex position. (must be called last for each primitive) (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immVertex3hf, IMMVertex3hf, METH_VARARGS, "feeds a vertex position. (must be called last for each primitive) (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immNormalX, IMMNormalX, METH_VARARGS, "feeds a vertex normal. (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immNormal3f, IMMNormal3f, METH_VARARGS, "feeds a vertex normal. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immNormal3us, IMMNormal3us, METH_VARARGS, "feeds a vertex normal. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immNormal3s, IMMNormal3s, METH_VARARGS, "feeds a vertex normal. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immNormal3hf, IMMNormal3hf, METH_VARARGS, "feeds a vertex normal. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immTangentX, IMMTangentX, METH_VARARGS, "feeds a tangent vector. (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immTangent4f, IMMTangent4f, METH_VARARGS, "feeds a tangent vector. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immTangent4us, IMMTangent4us, METH_VARARGS, "feeds a tangent vector. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immTangent4s, IMMTangent4s, METH_VARARGS, "feeds a tangent vector. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immTangent4hf, IMMTangent4hf, METH_VARARGS, "feeds a tangent vector. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immUVX, IMMUVX, METH_VARARGS, "feeds a vertex uv. (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immUV2f, IMMUV2f, METH_VARARGS, "feeds a vertex uv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immUV2us, IMMUV2us, METH_VARARGS, "feeds a vertex uv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immUV2s, IMMUV2s, METH_VARARGS, "feeds a vertex uv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immUV2hf, IMMUV2hf, METH_VARARGS, "feeds a vertex uv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immLMUVX, IMMLMUVX, METH_VARARGS, "feeds a vertex lmuv. (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immLMUV2f, IMMLMUV2f, METH_VARARGS, "feeds a vertex lmuv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immLMUV2us, IMMLMUV2us, METH_VARARGS, "feeds a vertex lmuv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immLMUV2s, IMMLMUV2s, METH_VARARGS, "feeds a vertex lmuv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immLMUV2hf, IMMLMUV2hf, METH_VARARGS, "feeds a vertex lmuv. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColorX, IMMColorX, METH_VARARGS, "feeds a vertex color. (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immColor3f, IMMColor3f, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColor3us, IMMColor3us, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColor3s, IMMColor3s, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColor3hf, IMMColor3hf, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColor4f, IMMColor4f, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColor4us, IMMColor4us, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColor4s, IMMColor4s, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immColor4hf, IMMColor4hf, METH_VARARGS, "feeds a vertex color. (O)"), //args=bytes/bytearray of raw data
	DEFINE_IMM_EX(immBoneIndexX, IMMBoneIndexX, METH_VARARGS, "feeds a vertex bone index. (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immBoneIndexub, IMMBoneIndexub, METH_VARARGS, "feeds a vertex bone index. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneIndexb, IMMBoneIndexb, METH_VARARGS, "feeds a vertex bone index. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneIndexus, IMMBoneIndexus, METH_VARARGS, "feeds a vertex bone index. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneIndexs, IMMBoneIndexs, METH_VARARGS, "feeds a vertex bone index. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneIndexui, IMMBoneIndexui, METH_VARARGS, "feeds a vertex bone index. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneIndexi, IMMBoneIndexi, METH_VARARGS, "feeds a vertex bone index. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneWeightX, IMMBoneWeightX, METH_VARARGS, "feeds a vertex bone weight. (Oii)"), //args=bytes/bytearray of raw data, data type, number of elements
	DEFINE_IMM_EX(immBoneWeightf, IMMBoneWeightf, METH_VARARGS, "feeds a vertex bone weight. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneWeightus, IMMBoneWeightus, METH_VARARGS, "feeds a vertex bone weight. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneWeightub, IMMBoneWeightub, METH_VARARGS, "feeds a vertex bone weight. (Oi)"), //args=bytes/bytearray of raw data, number of elements
	DEFINE_IMM_EX(immBoneWeighthf, IMMBoneWeighthf, METH_VARARGS, "feeds a vertex bone weight. (Oi)"), //args=bytes/bytearray of raw data, number of elements
Here's the immediate mode rendering example from __NPExample.txt:

Code: Select all

		#the mesh could also be drawn in immediate mode like this:
		rapi.immBegin(noesis.RPGEO_TRIANGLE)
		for i in range(0, numIdx):
			idx = noeUnpackFrom("<i", triangles, i*4)[0]
			vcmp = noeUnpackFrom("<ff", uvs, idx*12)
			rapi.immUV2(vcmp)
			vcmp = noeUnpackFrom("<fff", normals, idx*12)
			rapi.immNormal3(vcmp)
			vcmp = noeUnpackFrom("<" + "i"*fw.weightsPerVert, fw.flatW, idx*4*fw.weightsPerVert)
			rapi.immBoneIndex(vcmp)
			vcmp = noeUnpackFrom("<" + "f"*fw.weightsPerVert, fw.flatW, fw.weightValOfs + idx*4*fw.weightsPerVert)
			rapi.immBoneWeight(vcmp)
			vcmp = noeUnpackFrom("<fff", positions, idx*12)
			rapi.immVertex3(vcmp)
		rapi.immEnd()
Here's how you would use the new functions to do that so that you don't have to unpack anything (and so that scale-and-biasing is handled for you):

Code: Select all

		rapi.immBegin(noesis.RPGEO_TRIANGLE)
		for i in range(0, numIdx):
			idx = noeUnpackFrom("<i", triangles, i*4)[0]
			rapi.immUV2f(uvs[idx*12:idx*12+8])
			rapi.immNormal3f(normals[idx*12:idx*12+12])
			rapi.immBoneIndexi(fw.flatW[idx*4*fw.weightsPerVert:idx*4*fw.weightsPerVert+4*fw.weightsPerVert], fw.weightsPerVert)
			rapi.immBoneWeightf(fw.flatW[fw.weightValOfs+idx*4*fw.weightsPerVert:fw.weightValOfs+idx*4*fw.weightsPerVert+4*fw.weightsPerVert], fw.weightsPerVert)
			rapi.immVertex3f(positions[idx*12:idx*12+12])
		rapi.immEnd()
Here's how you would use the Ofs variants of those functions to make code that is faster and looks less terrifying:

Code: Select all

		rapi.immBegin(noesis.RPGEO_TRIANGLE)
		for i in range(0, numIdx):
			idx = noeUnpackFrom("<i", triangles, i*4)[0]
			rapi.immUV2fOfs(uvs, idx*12)
			rapi.immNormal3fOfs(normals, idx*12)
			rapi.immBoneIndexiOfs(fw.flatW, fw.weightsPerVert, idx*4*fw.weightsPerVert)
			rapi.immBoneWeightfOfs(fw.flatW, fw.weightsPerVert, fw.weightValOfs+idx*4*fw.weightsPerVert)
			rapi.immVertex3fOfs(positions, idx*12)
		rapi.immEnd()
If anyone could see the C macro code defining all of these methods, they would vomit. But being able to define the Python function and the C function that it attaches to in a single line of code is worth the vomit.
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: Señor Casaroja's Noesis

Post by finale00 »

Cool, now we don't have to do any math. And it should make it easier to follow...

Code: Select all

rapi.immUV2fOfs(uvs, idx*12)
Would it be 8 since it's just two floats?
Last edited by finale00 on Fri Mar 16, 2012 5:52 am, 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: Señor Casaroja's Noesis

Post by MrAdults »

Normally, yes, but that format stores UV's in 3 floats, so the stride is 12.

Edit: Also, I was flipflopping on doing Ofs variants to make it obvious and enforce syntax, or make offset an optional argument. I think I'm going with optional after all. But the example is the same, you can just chop the "Ofs" part off.
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: Señor Casaroja's Noesis

Post by finale00 »

Can I set the encoding of a NoeBitStream so that all reads will use that encoding?
Just so I don't have to open the file again.
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: Señor Casaroja's Noesis

Post by MrAdults »

Encoding? You mean for strings? NoeBitStream doesn't support different character encoding, as it's primarily meant for binary parsing and expects you to readBytes your data out selectively for custom text parsing. You don't have to (and shouldn't) load the file again though. Just don't use the bitstream at all if you're parsing a pure text format - the data object Noesis passes to the handler is a raw array of bytes. You should be able to parse that out as text using whatever Python functions/libraries and encoding you like.
User avatar
Tosyk
double-veteran
double-veteran
Posts: 1027
Joined: Thu Oct 22, 2009 10:24 am
Location: Russia, Siberia
Has thanked: 269 times
Been thanked: 154 times
Contact:

Re: Señor Casaroja's Noesis

Post by Tosyk »

noesis cutting bone names when saving psk, can you solve this MrAdults?

edit: actualy noesis replace 'root' with numbers: 1,2,etc, whyy?
can you solve this one?

edit: my bad, everything working fine
Thank you for all you do here
my blog | my forum
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: Señor Casaroja's Noesis

Post by MrAdults »

PSK has a bone name max length of 64, it's a format issue, not something Noesis can resolve. Sometimes Noesis also has to reorder bones for the format because it has strict hierarchy limitations and can only support 1 root bone. Just a couple of the format's many limitations, it really is not a good format and no one who isn't working with ancient Unreal tech has any reason to be using it. At all. Especially now that Epic is maintaining a FBX import path in the UDK.
pixellegolas
ultra-veteran
ultra-veteran
Posts: 423
Joined: Mon Aug 11, 2008 11:30 pm
Has thanked: 27 times
Been thanked: 15 times

Re: Señor Casaroja's Noesis

Post by pixellegolas »

Maybe I am wrong but when I tried cabal2 model in noesis and exported to fbx and to psk, psk was actually better because it preserved smoothing....don't remember the word, but with fbx it was more a jagged model
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: Señor Casaroja's Noesis

Post by MrAdults »

That would be your FBX importer's fault, then. Which isn't surprising, Autodesk is very inconsistent there and their Max importer still has issues with normals and skinned geometry sometimes. But FBX stores per-vertex normals which is what Noesis natively provides. You can see that if you import your FBX back into Noesis. PSK only supports smoothing groups which are not accurate in many cases. The Noesis PSK exporter attempts to auto-generate smoothing groups from the per-vertex normals, which generally works out ok but it's still wrong and can't simulate actual artist-tweaked normals correctly.
User avatar
Tosyk
double-veteran
double-veteran
Posts: 1027
Joined: Thu Oct 22, 2009 10:24 am
Location: Russia, Siberia
Has thanked: 269 times
Been thanked: 154 times
Contact:

Re: Señor Casaroja's Noesis

Post by Tosyk »

MrAdults wrote:PSK ... really is not a good format and no one who isn't working with ancient Unreal tech has any reason to be using it. At all. Especially now that Epic is maintaining a FBX import path in the UDK.
actually only psk exporter gives me model in the way in which I want:
- all mesh combined in one (cause max viewport working terrible with 27 meshes and 300 bones at once)
- combining feature of noesis doesn't work for me

[q]: do you plan implement support for Street Fighter 4 (and so on, emo format) in noesis?I was surprised when I found no support for SFIV inside :)
Thank you for all you do here
my blog | my forum
MrAdults
Moderator
Posts: 1007
Joined: Mon Mar 23, 2009 2:57 am
Has thanked: 44 times
Been thanked: 505 times

Re: Señor Casaroja's Noesis

Post by MrAdults »

It's rather silly to mangle your model data and throw away your original vertex normals for the sake of rebatching a model. I haven't tried the generic combining functionality in ages though. I'll take a look at it.

No, SF4 seems already very well figured out and it's rather extraneous and proprietary. Which means anyone could do it by writing a plugin or Python script. I don't see any reason for me to spend time on formats like that when I can spend it maintaining core features/functionality instead. I could justify it if it weren't already a well-documented format, but it is.
User avatar
Tosyk
double-veteran
double-veteran
Posts: 1027
Joined: Thu Oct 22, 2009 10:24 am
Location: Russia, Siberia
Has thanked: 269 times
Been thanked: 154 times
Contact:

Re: Señor Casaroja's Noesis

Post by Tosyk »

MrAdults wrote:It's rather silly to mangle your model data and throw away your original vertex normals for the sake of rebatching a model. I haven't tried the generic combining functionality in ages though. I'll take a look at it.
thanks
MrAdults wrote:No, SF4 seems already very well figured out and it's rather extraneous and proprietary. Which means anyone could do it by writing a plugin or Python script. I don't see any reason for me to spend time on formats like that when I can spend it maintaining core features/functionality instead. I could justify it if it weren't already a well-documented format, but it is.
sounds fair enough
if you have a time I attached converter (perl language) from emo to smd
emo2smd_converter.7z
also emz and emb uncompressing and unpacking done with just 2 bms scripts
i just wish that everything will be in one place
You do not have the required permissions to view the files attached to this post.
Thank you for all you do here
my blog | my forum
Post Reply