hello there,
I'm working on a Maxscript model exporter for my game. it's actually based on someone else's code but I've had to modify it to suit the game and I now got a pretty good understanding of it.
however I'm having some problems with the uwv's. wherever there's a seam in the uwv's I get a weird result, and I can't seem to fix it.
here's a pic of what I'm getting: (in-game vs. max)
you can see it works just fine where there are no seams. also it seems the model needs an Unwrap UWV modifier on top or else the exported uwvs are garbage.
and here's the code I'm using to export the uwv's:
for i=1 to obj.numfaces do
(
face = getFace obj i
for h=1 to 3 do
(
... (here goes some code to export the vertexes) ...
-- get and export vert uwvs
vert = (getTVert obj face[h])
-- 1-vert = we flip the uwv's in Y, the engine needs them that way
verty = 1-vert.y
vert2x = formattedPrint vert.x format:"#.6f"
vert2y = formattedPrint verty format:"#.6f"
format " % %" vert2x vert2y to:outFile
format "\n" to:outFile
)--end of for each face index
)-- end of for each face
as you can see the code loops through all faces and inside that loop it loops for all 3 verts of each face, gets and exports the verts (I skipped that part of the code here) and its uwvs
I use formattedPrint because too often I get way too many numbers resulting in "e-008" stuff, and so I can take those away limiting to 6 decimals (what the engine likes)
any ideas?
thanks
Replies
There was some hack around the UV extraction but I can´t remember anymore what - it had to do something with the order to access the data so that in the end I was forced to do it in a certain way. Anyway this code should work.
may this be of help
the code I posted is the function to output the mesh (function OutputMesh), but I also do that in another section of the code.
the following code happens when the export button is pressed. loops through all objects (skipping hidden and non-mesh-kinds) and then does the following:
you can see it defines a new var, copies the object, snapshots it as mesh, runs the OutputMesh function (which is the code on my previous post), and then deletes that new created mesh.
the weird thing is, it does snapshot the object as mesh (old code used convertToMesh but I changed it to snapshotasmesh and got the same result) and the output does change if I don't add the unwrap uwv modifier (garbage uwv's) as if not adding an unwrap uwv modifier would mean the mesh has no uwv's or something
in the code you posted it does things in a very similar way. differences are that you loop through verts, faces, texture verts and texture verts separately, while I need them in the same loop (the engine's mesh format uses verts (position, normals and uwv's) in the same line, and then makes a list of the faces using the created vert index. so long story short, I do need to loop through faces and for every face loop through its 3 verts (I know this will output redundant verts, which I need)
the other significant difference is how you multiply the texture vertex position * the texture size, which is unnecessary in my code (my format's uwv coordinates go from 0 to 1 like in max, so no matter if I change the texture size it will still work)
--- conclusion
if I replace the part of my code where it exports uwv's and replace it with that part of yours (removing the unnecessary "* texture size" I'll get the same results, as the process really is the same
I'm going to try a few more stuff, see if something else works, but I'm open as to anything that might make my code more max-idioty-proof
That´s odd,-
did you tried to merge the whole stack so that you only have the poly without any modifiers any more on it- and then run the code ?
alternativly but just like you said yourself you could convert or copy it via maxscript yourself, e.g
it seems the amount of TVerts is set by how many verts you have in the uwv's (for example by breaking poly's on unwrap uwv you get more)
now, by needing all vertices in the mesh including redundant ones (num tris * 3) instead of actual all-welded mesh vertices or unwrap-uwv-vertices, there are less TVerts than vertices so when a certain vert (why on-a-seam ones though?) has no TVert it outputs garbage (and why not crash? )
to fix this, my guess would be to have all tris broke apart in the uwv's, as if I selected all tris and used 'break' on them one by one.
any idea on how to do this via maxscript?
thanks again
[edit] on your question, when I tried before I always had my stack collapsed before running the code and got garbage without the unwrap uwv modifier. now I tried adding the unwrap uwv modifier and *then* collapsing the stack again. I don't get garbage everywhere anymore (like when I didn't add unwrap uwv), but I still get garbage on the seams
[edit2] further investigation. I manually broke all verts in an unwrap uwv modifier. the amount of TVerts I now get is the same as my all-full-and-redundant verts (which is numtris * 3). however I still get garbage where there were seams before, like the pic I posted on my first post
however I noticed something. if on unwrap uwv I go to select -> select inverted faces, a number of faces is selected, and it seems it's in the boundaries of these where I'm getting the weirdness.
so how do I invert them back to un-inverted?
[edit3] meh I just took some of the faces from the neck bottom (the stump) which were mirrored when they shouldn't (forgot to fix that some time ago). so if I select the inverted faces that part doesn't get selected anymore. BUT in-game that part is still messed up.
so I guess it's got nothing to do with uwv-inverted faces (could have been backfaces or something, who knows). my loop just decides to hate those certain polygons' uwvs
[edit4] ok I might have figured out why.
while doing tests with some simpler geometry (an 8-segment sphere) I was able to get the uwv's exported just fine if I took all faces and collapsed them from eachother (this way I would have all vertexes as unique). the exported uwv's are fine but of course my normals are as if I applied a 0-value smooth (since faces are actually apart now).
the explanation: on seams, the same vertex appears in more than one position in the uwv's. so when the exporter calls such a vertex for its uwv, it gets its uwv position wherever it finds it first (without caring if it corresponds to the same vertex of the neighbor face, which happens to be somewhere else in the uwv), and so, messing the output uwv's wherever there's a seam
the solution: I'll make yet another copy of the mesh, explode all its faces, and use it for uwv data; while using the first copy for vertex/face/normal data
hopefully it will work, wish me luck!
[edit5] god!!!!! I got it to work just fine on that 8-segment sphere, but my character gets pure garbage uwv's. damn this is getting annoying
for now I got a WIP that kinda works except for vertex positioning. I'm using the vertex UWV positions for vertex world positions so I end up with a (correctly uwv'ed) flat mesh (imagine the texture flattened, that's the mesh).
so what do I need now? to get a vert index from a TVert index.
why? well the indexes are different. since there are seams on the uwvs I have more verts in there than in the mesh.
so what I need is to get, from a TVert index, the corresponding vertex index.
for example when you select a vert on the unwrap uwv dialog, the corresponding vertex is red-highlighted in the viewport mesh, which means the TVert actually knows the Vert index. I need to know that index from maxscript.
with the corresponding vert index I'd be able to get the vert position, and my vengeance to the old broken code would be complete
in my head it would work something like "getVert obj getTVert i" from my i loop. of course things don't really work the way they do in my head (or else I my game would already be complete )
any ideas?
thanks again
That way you can just go through the entire set of UVW verts, get the related geometric vert for each one, and discard it if it already exists.
Can't remember the exact command, I think it's in polyOp, or might even be an unwrapUVW function.
one of the new functions in max2008 seems it could work. it's called "getVertexGeomIndexFromFace" but it says it's exposed via unwrap6 interface which I have no idea (and can't find) how to use
same thing could go if I used the functions selectVertices and then getSelectedGeomVerts, but they work via unwrap6 interface as well
I tried "obj.unwrap_uvw.unwrap6.getVertexGeomIndexFromFace 100 1" but it says -- Unknown property "getVertexGeomIndexFromFace" in <MixinInterface:unwrap6>
it's the same way calling an unwrap or unwrap2 interface works though, it just doesn't seem to like interface 6