Sign in to follow this  
Raeldor

Exporting from 3d studio max using maxscript help

Recommended Posts

Hi All, Looks like 3d studio keeps it's vertex UV's seperate from it's vertex co-ordinates which kinda makes sense since flattening a model for mapping I guess can result in more than one UV for a vertex. I am guessing in this case I need to export the vertices by using the texture faces as the starting point then looking up the corresponding face index in the mesh faces to determine the vertex index to pick up the co-ordinate values? Does that mean when I import my model into my engine I need to create multiple vertices for the same point in space so they can have differing UV values. I seem to remember that the UV is part of the vertex structure in directx. Is it better to do that, or just export multiple vertices from 3ds max where they exist, each with their own UV values? Thanks

Share this post


Link to post
Share on other sites
Basically, you'll need to duplicate a vertex whenever ANY of it's properties change. This also happens quite often with normals, and can happen with other properties, like vertex colors as well! Take a cube for instance, in Max you'll only have 8 vertices for the geometry. However, if you have a single stream in DirectX, you'll need 24 vertices to display the geometry identically.

In Max, the only thing you can use reliably to match things up is the face ids. Face #7 of the geometry and face #7 of uv-channel 3 will both refer to the same triangle. Therefore, my suggestion to you is to do this:

1. Create a unique vertex for each vertex of every triangle
2. Get the normal, UV(s), etc for each of those vertices
3. Do a post processing step to remove any identical verts(Where all their components are the same)
4. Run a tri-stripping algorithm to re-order the indices to be more cache-friendly

Other than the ugly step of removing duplicate verts, this will give you a straight-forward method to collect all of the correct information for each vertex. And, in my experience, it's easier to optimize at the end than to try to optimize your verts while in the middle of exporting.

Good luck!

-John

Share this post


Link to post
Share on other sites

Hi guy's,

I posted an identical topic in the DX forum just the other day, i got the opposite answer. Well maybe not....... worded it differently.

http://www.gamedev.net/community/forums/topic.asp?topic_id=342437

Throwing the 32 byte vertex optimisation away. Which would generally be better process.

Giving each vertex 2 uv's for the case where maybe 5% of the mesh requires them. Seems very wasteful, where as splitting the 5% would make a bit more sense.

I'd like to here what people think.


Psyian

Share this post


Link to post
Share on other sites
Looks like max already holds the correct number of vertices for uv's without duplication where it's not needed. I wrote the following code to output the vertices, but haven't tested it yet...


-- really we must output same number of vertices
-- as that of tverts, not verts! this will mean
-- outputing the texture vertices instead of the
-- regular vertices and the texture faces instead
-- of the regular faces
numverts = meshop.getnumtverts mymesh 1
for v=1 to numverts
(
-- find texture faces that uses this vert
vertfaces = vertmeshop.getmapfacesusingmapvert mymesh 1 v
for f=1 to vertfaces.count
(
-- if this face uses the texture vertex
if vertfaces[f] = true then
(
-- find which index in texture face
tvertindexes = meshop.getmapface mymesh 1 f
tvindex = 0
if tvertindexes[1] = v then tvindex=1
if tvertindexes[2] = v then tvindex=2
if tvertindexes[3] = v then tvindex=3

-- find same index in mesh face
vertindexes = getface mymesh f
vindex = vertindexes[tvindex]

-- now we have the real vertex details, output to file
meshvert = getvert mymesh vindex
writefloat outfile meshvert.x
writefloat outfile meshvert.y
writefloat outfile meshvert.z

-- we only need to find the first one
exit
)
)
)

Share this post


Link to post
Share on other sites
Ok, I think I have it working now. I am just working on the code to load the mesh into my engine as proof of the pudding. Here is the main section of export code.


-- open binary file
myfilename = getsavefilename caption:"Export to..." types:"Data(*.dat)|*.dat"
outfile = fopen myfilename "wbS"

-- write out vertex count
numverts = meshop.getnummapverts mymesh 1
writelong outfile numverts #unsigned

-- really we must output same number of vertices
-- as that of tverts, not verts! this will mean
-- outputing the texture vertices instead of the
-- regular vertices and the texture faces instead
-- of the regular faces
for v=1 to numverts do
(
-- find texture faces that uses this vert
tvertfaces = meshop.getmapfacesusingmapvert mymesh 1 v
for f=1 to tvertfaces.count do
(
-- if this face uses the texture vertex
if tvertfaces[f] then
(
-- find which index in texture face
tvertindexes = meshop.getmapface mymesh 1 f
tvindex = 0
if tvertindexes[1] == v then tvindex=1
if tvertindexes[2] == v then tvindex=2
if tvertindexes[3] == v then tvindex=3

-- find same index in mesh face
vertindexes = getface mymesh f
vindex = vertindexes[tvindex]

-- now we have the real vertex details, output to file
meshvert = getvert mymesh vindex
writefloat outfile meshvert.x
writefloat outfile meshvert.y
writefloat outfile meshvert.z

-- now we need to calculate the vertex normal
-- using all the attached polys faces
vertfaces = meshop.getpolysusingvert mymesh vindex
vertnorm = point3 0 0 0
for vf=1 to vertfaces.count do
(
if vertfaces[vf] then
(
-- get the normal for this face
thisnorm = getfacenormal mymesh vf

-- add to running normal
vertnorm = vertnorm + thisnorm
)
)

-- normalize our normal
vertnorm = normalize vertnorm

-- output the vertex normal
writefloat outfile vertnorm.x
writefloat outfile vertnorm.y
writefloat outfile vertnorm.z

-- now get texture vertex and output uv
texvert = meshop.getmapvert mymesh 1 tvindex
writefloat outfile texvert.x
writefloat outfile texvert.y

-- we only need to find the first one
exit
)
)
)

-- write out number of faces
numfaces = meshop.getnummapfaces mymesh 1
writelong outfile numfaces #unsigned

-- now write out mesh faces using texture faces so we get
-- correct corresponding uv's
for f=1 to numfaces do
(
-- use texure vertex index
face=meshop.getmapface mymesh 1 f
writelong outfile face.x #unsigned
writelong outfile face.y #unsigned
writelong outfile face.z #unsigned
)

-- write out the texture name
writestring outfile mymesh.material.diffusemap.filename

-- close file
fclose outfile


Share this post


Link to post
Share on other sites
Here's the final if you are interested. Works great as a starting point, as I have it loading into my engine and rendering too.

--
-- my first export script
--
-- export first selected object
-- written by ray price 8/30/05
--

-- check we have a selected object
if selection.count != 1 then
messagebox "You must have one object selected"
else
(
-- must be an editable mesh
mymesh = selection[1]
if classof mymesh != editable_mesh then
messagebox "Must be an editable mesh type object to export"
else
(
-- mesh must have a standard material
if classof mymesh.material != standardmaterial then
messagebox "Mesh must have a standard material"
else
(
-- open binary file
myfilename = getsavefilename caption:"Export to..." types:"Data(*.dat)|*.dat"
outfile = fopen myfilename "wbS"

-- write out vertex count
numverts = meshop.getnummapverts mymesh 1
writelong outfile numverts #unsigned

-- really we must output same number of vertices
-- as that of tverts, not verts! this will mean
-- outputing the texture vertices instead of the
-- regular vertices and the texture faces instead
-- of the regular faces
for v=1 to numverts do
(
-- find texture faces that uses this vert
tvertfaces = meshop.getmapfacesusingmapvert mymesh 1 v
for f=1 to tvertfaces.count do
(
-- if this face uses the texture vertex
if tvertfaces[f] then
(
-- find which index in texture face
tvertindexes = meshop.getmapface mymesh 1 f
tvindex = 0
if tvertindexes[1] == v then tvindex=1
if tvertindexes[2] == v then tvindex=2
if tvertindexes[3] == v then tvindex=3

-- find same index in mesh face
vertindexes = getface mymesh f
vindex = vertindexes[tvindex]

-- now we have the real vertex details, output to file
meshvert = getvert mymesh vindex
writefloat outfile meshvert.x
writefloat outfile meshvert.y
writefloat outfile meshvert.z

-- now we need to calculate the vertex normal
-- using all the attached polys faces
vertfaces = meshop.getpolysusingvert mymesh vindex
vertnorm = point3 0 0 0
for vf=1 to vertfaces.count do
(
if vertfaces[vf] then
(
-- get the normal for this face
thisnorm = getfacenormal mymesh vf

-- add to running normal
vertnorm = vertnorm + thisnorm
)
)

-- normalize our normal
vertnorm = normalize vertnorm

-- output the vertex normal
writefloat outfile vertnorm.x
writefloat outfile vertnorm.y
writefloat outfile vertnorm.z

-- now get texture vertex and output uv
texvert = meshop.getmapvert mymesh 1 v
writefloat outfile texvert.x
writefloat outfile texvert.y

-- we only need to find the first one
exit
)
)
)

-- write out number of faces
numfaces = meshop.getnummapfaces mymesh 1
writelong outfile numfaces #unsigned

-- now write out mesh faces using texture faces so we get
-- correct corresponding uv's
for f=1 to numfaces do
(
-- use texure vertex index
-- use zero based though, so -1!
face=meshop.getmapface mymesh 1 f
writeshort outfile (face.x-1) #unsigned
writeshort outfile (face.y-1) #unsigned
writeshort outfile (face.z-1) #unsigned
)

-- write out the texture name
writestring outfile mymesh.material.diffusemap.filename

-- close file
fclose outfile
)
)
)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this