Blender 2.7 MD3 Export Script
#1 Posted 21 March 2012 - 05:05 PM
2.78c script - March 2017
io_export_md3.zip (7.31K)
Number of downloads: 1755
version 1.6.6
change log
- invert normals fixing lighting issues
2.7 script - April 2014
io_export_md3.zip (7.42K)
Number of downloads: 2206
version 1.6.4
change log
- default filename blank instead of .blend name
2.63 script
io_export_md3.zip (7.61K)
Number of downloads: 1872
MD3 export script for Blender 2.62
io_export_md3.zip (6.76K)
Number of downloads: 1222
Instructions:
Extract the zip and put the file in scripts/addons.
You'll need to turn it on in the user preferences menu.
Version 1.6.1
Change log:
- added triangulate
- added auto scaling
- added default user settings variables (near top of script)
- changed skin path look up (custom prop., material name, then 'NULL')
io_export_md3.zip (5.72K)
Number of downloads: 1202
Version 1.6
Change log:
- fixed object transform data not being exported.
- added support for armature transform data. (must be named "Armature")
- cut the need for a custom property in order to export uv map. (still supports encoded skin paths)
- cut ignore uv option entirely
- changed default dump all setting to false (no more 40MB logs)
This post has been edited by Drek: 28 March 2017 - 03:43 PM
#2 Posted 21 March 2012 - 10:03 PM
#3 Posted 22 March 2012 - 01:14 AM
Plagman, on 21 March 2012 - 10:03 PM, said:
It still generates normals on export. That's all very old code that I haven't touched. I don't see any mention of face normals at all. Only this one section from the module md3vert mentions normals.
# copied from PhaethonH <phaethon@linux.ucla.edu> md3.py def Encode(self, normal): x = normal[0] y = normal[1] z = normal[2] # normalize l = math.sqrt((x*x) + (y*y) + (z*z)) if l == 0: return 0 x = x/l y = y/l z = z/l if (x == 0.0) & (y == 0.0) : if z > 0.0: return 0 else: return (128 << 8) lng = math.acos(z) * 255 / (2 * math.pi) lat = math.atan2(y, x) * 255 / (2 * math.pi) retval = ((int(lat) & 0xFF) << 8) | (int(lng) & 0xFF) return retval
#4 Posted 22 March 2012 - 09:15 AM
Here is the section from savemd3 that calls nvert.Encode
for vi in vertlist: vert = fobj.vertices[vi] nvert = md3Vert() nvert.xyz = my_matrix * vert.co nvert.xyz[0] = round((nvert.xyz[0] * settings.scale) + settings.offsetx,5) nvert.xyz[1] = round((nvert.xyz[1] * settings.scale) + settings.offsety,5) nvert.xyz[2] = round((nvert.xyz[2] * settings.scale) + settings.offsetz,5) nvert.normal = nvert.Encode(vert.normal)
fobj is the mesh itself at the current frame. The script isn't changing normals here, and I don't think that nvert.Encode actually changes anything either. So I am saying that it does indeed export vert normals as is, then forces face normals to be square to the face itself. Please correct me if I am wrong on any of this, it's a tricky thing to test.
#5 Posted 24 March 2012 - 04:49 AM
#6 Posted 24 March 2012 - 08:25 AM
This is from the blender manual:Blender Wiki
Quote
In the tests I've done with your sample .blend I have, as long as the edge split is put in front of the armature it exports a good md3. The only oddity is that it comes out with more verts than what Blender says should be there. (MD3 15K verts, Blender in object mode says it should be 13K verts.) I can't really explain why that is happening.
I just ran another quick test using array and bevel on the default cube. Array works!! Bevel is a no go as it makes quads, so for the time being at least, some modifiers may need to be applied and triangulated before export.
I would like to publicly thank you Tea Monster for all your time and work beta testing this script with me. Couldn't have done this without you.
#7 Posted 24 March 2012 - 08:48 AM
I'm thinking what is happening is that it is literally splitting the mesh at certain points. So each time you break an edge, you will get twice as many verts in those edges as you now have two, where before there was one.
This post has been edited by Tea Monster: 24 March 2012 - 06:20 PM
#8 Posted 24 March 2012 - 09:30 AM
- How do I set the number of frames to be exported? The dafault seems to be 250.
- I exported a test cube but in md3 compiler it seems there is no object in the file. Is anything more than selecting the object needed?
#9 Posted 24 March 2012 - 09:46 AM
2-a. UV Unwrap.
2-b. Convert to tris
Also, there is some strangeness where you have to scale up your mesh by a factor of 20 or so or you can get some distortion on complex meshes.
#10 Posted 24 March 2012 - 06:05 PM
Also, I never used modifiers much before the past few days. Especially leaving them in the stack like this. I love them!!
#11 Posted 24 March 2012 - 06:31 PM
As to scale, I'm wondering if there is something in how Blender scales objects and how that translates into other soft. You can see the number of files in the HRP that have scale figures in double digits.
Looking forward, have you thought at all about bmesh?
This post has been edited by Tea Monster: 24 March 2012 - 06:32 PM
#12 Posted 24 March 2012 - 06:54 PM
#13 Posted 24 March 2012 - 07:15 PM
This post has been edited by Hendricks266: 24 March 2012 - 07:20 PM
#14 Posted 24 March 2012 - 07:41 PM
Hendricks266, on 24 March 2012 - 07:15 PM, said:
Yes, of course. I would be honored.
#15 Posted 25 March 2012 - 01:47 PM
It will not triangulate a screw modifier for me. Oh well, edge splits, armatures, arrays, curves, and more all work now with quad meshes.
I still recommend exporting with triangles. You can only leave so much up to scripting assumptions before something goes wrong. And you get more control over your results, but this is great for testing work in progress.
More ramblings about Blender scaling and md3 world space:
I added a float slider to the gui to replace the default rounding value of 5 decimal places. With tests up to 30 decimal spots I still get that squarish bouncy vert issue. So I conclude that Blenders microscopic scaling just doesn't export well. Blender is different in that you can scale something infinitely small then infinitely large and lose no detail in the process.
#16 Posted 25 March 2012 - 02:19 PM
Note that you're very lucky, MD2 can only represent coordinates in an 8-bit integer, which is 255 different values at most.
#17 Posted 25 March 2012 - 03:38 PM
Can I ask you to name one sprite, model, or other easy reference place and give it a "height" for me? I will use that as reference for scaling.
io_export_md3.zip (6.11K)
Number of downloads: 1003
Here is my quad to tri version if anyone wants to test it. I will save a big update for after I try out this scaling idea.
#19 Posted 25 March 2012 - 04:27 PM
Drek, on 25 March 2012 - 03:38 PM, said:
I don't like the sound of this idea because:
1. There is no true reference point between in-game and the real world (and it probably varies based on map and mapper).
2. Most people would just throw out a random estimate giving it little actual worth.
3. Regional differences of units (feet vs. meters).
Would it be possible to implement Plagman's idea by cycling through all the animations and finding the model's net boundary coordinates? Really, that is what you should strive for. This would involve no guesswork on the part of the modeler and would be absolutely correct.
This post has been edited by Hendricks266: 25 March 2012 - 04:31 PM
#20 Posted 26 March 2012 - 01:28 AM
1) Find avg. bounding box size for entire scene being exported.
2) Scale scene to fit nicely into md3 world space. From (0,0,0)
3) Return my export scale factor to the user.
Assuming we come up with a good ratio for blender units to build units scaling, and the model is made with this in mind. The scale in def will be 1/export scale. If the model isn't built with an exact in game scale then we are no worse than before.
I'm off to work, will start on this tonight. Does my plan seem sound to you guys?
#21 Posted 26 March 2012 - 05:33 AM
Drek, on 26 March 2012 - 01:28 AM, said:
It is not the average you are looking for, but the actual min/max coordinated over all animations played out. Think of it as a box that expands whenever the model pushes its boundaries when an animation crosses them but never shrinks, and all animations are cycled through causing the box to represent the boundaries of the entire animation set with nothing outside it.
#22 Posted 27 March 2012 - 03:27 PM
I've sent you an MD3
I have found one problem, the Cycloid, with 120 frames of animation, is over 14MB in size! That is without textures, is that right?
This post has been edited by Tea Monster: 27 March 2012 - 03:30 PM
#23 Posted 27 March 2012 - 05:02 PM
An update for where I'm at. I've got min/max sizes out of blender, and I have a min value for "good" md3space. I am getting stuck on finding the max size to export an object. I get errors if actual md3 values exceed binary short format SHRT_MAX, but the error happens with different bounding box values depending on the object being exported. I think I will let the error show for massive objects (1000ish blender units) For now the script will only scale objects up if they are too small.
Next, to find that conversion formula.
x build units = y blender units
#24 Posted 28 March 2012 - 12:07 AM
I'm going to test the model size thing later.
At the moment you get a really ugly python error on top of the screen if you try to export without a UV map, and there is no warning if you don't triangulate.
Now you can argue that if you are doing either of these things, then this is the least of your problems , but you may want to have a more elegant user warning rather than the python default one.
#25 Posted 29 March 2012 - 05:51 PM
Update in the first post.
I want to discuss how I went about scaling.
Code:
En Anglais, I took the largest value of each axis dimension for each frame in each selected object. If the smallest axis ends up with a value less than 25 blender units (approx min size for higher detailed MD3s) then scaling is set to make that axis 25. Unless it makes another axis exceed 750 (educated guess at a max boundry) If scale is set manually on export or if any object is 2D it skips auto scaling.
I am well aware that this is not the most accurate method and may not auto scale when it probably should. I ran loops to get the true min max bounds of every vert in all selected objects. It was slightly more accurate on when it can auto scale, but it doubled run time for the script and crashed blender on me more than once, so I tried a less cpu expensive method and am happy with the results.
If anyone finds something that should be scaled, yet manages to slip through the code, please share it so I can try to improve this feature.
PS. The scale factor used is printed out in the log file.
@Tea Monster, Blender doesn't have a 'more elegant' error message. I've run some scripts that have had this error message "ERROR: for now look in console" It says the same thing in the console HA. Maybe soon they will add something I can control easier. About triangulating, default is now set to True, but will only run if it finds non-tri faces.
Added March 31st: Wow, big post but this isn't bump worthy so I will just tack it on here.
I missed a line of code cancelling auto scale if it just isn't needed, because the export fits properly already. Opps, I updated the first post with it fixed, sorry to the one downloader
This post has been edited by Drek: 31 March 2012 - 06:55 AM
#26 Posted 31 March 2012 - 10:27 AM
Number of downloads: 1336
I've found a blender to build units ratio. 100 blender units = 1024 build units
I included my work, a simple map, duke3d.def, a scale increasing animated cube model, and its .blend but I would appreciate someone with more experience confirming this for me. My ratio is very, very, close, but I don't think it's "perfect."
As an easy reference for people. This makes the default cube equal to about 20 build units, or just a little bigger than a box in the smallest grid in mapster.
From here I am working an Eduke32 export option into the script, where the modeler can use either this ratio or input his own and the script will return a scale value for def code.
#27 Posted 31 March 2012 - 03:11 PM
Drek, on 31 March 2012 - 10:27 AM, said:
I've found a blender to build units ratio. 100 blender units = 1024 build units
I included my work, a simple map, duke3d.def, a scale increasing animated cube model, and its .blend but I would appreciate someone with more experience confirming this for me. My ratio is very, very, close, but I don't think it's "perfect."
As an easy reference for people. This makes the default cube equal to about 20 build units, or just a little bigger than a box in the smallest grid in mapster.
From here I am working an Eduke32 export option into the script, where the modeler can use either this ratio or input his own and the script will return a scale value for def code.
How did you find it? Technically one Blender Unit is supposed to by equivalent to a meter, so my question is what is a Build unit? This is very critical for me, since my models are to 'scale', and the reference you are defining would eliminate guess work.
This post has been edited by Hank: 31 March 2012 - 03:11 PM
#28 Posted 31 March 2012 - 03:24 PM
Hank, on 31 March 2012 - 03:11 PM, said:
I used mapster x,y BLD units as foundhere, lol(I was just reading this page and came back here to correct a mistake I made)
I have my script returning a def code if you tell it which one axis you want to use for scaling and how big you would like it in build units. PM me an email if you'd like to test it with me, it's still WIP to be released when 2.6.3 comes out this month.
#29 Posted 31 March 2012 - 03:37 PM
#30 Posted 31 March 2012 - 03:56 PM
This is going to be harder than I thought, with 3D mode using separate units than 2D it gets to be pretty confusing. My thoughts are that if the user selects to use the z axis as scale reference then the size should be measured in zBLD units. Either that or we agree that a certain value in zBLD units = x,yBLD units. My quick ratio, based on what I just read is that: 1zkey = 1 pgup = 1024 zBLD units = 64 x,yBLD units
Added:
Did some in game tests 32 pgups = 2048 x,yBLD units this verifies the ratio. Now what do you guys want, a script that only uses x,yBLD units or should I allow for one or the other depending on axis used for reference?
Added some more:
I'm going to make a drop box style selector for whatever build unit the modeler wants to use. Say a choice between x,yBLD units, zBLD units, or zKEY aka PGUP units. I will also look into using sprite x,y measurements. That would be good for replacing 8-bit art tiles with models. Built to scale using the tile as a background pic, then just give the exporter the tiles width or height. Def scale in the log.
This post has been edited by Drek: 31 March 2012 - 06:29 PM