brekehan
05-02-2009, 06:57 AM
But it answers your question about which mapping vertex corresponds to a mesh vertex - the mapping faces and the mesh faces have a one-to-one correspondence, and the I-th vertex inside the face`s definition corresponds to the I-th vertex of the map face`s definition.
True. I am getting absorbed with the problem I now face instead of remembering the problems I conquered . I totally got which post I was replying to confused. I've got an explorer window with about 10 tabs open on various forums trying to work my way through an export script. Sorry bout that.
The system (as you probably know already) works like this:
*The object (node level) gets a material assigned.
*If the material is NOT of a Multi-Sub Material class, all faces of the object (if any) get that material.
Ok, lets deal with this scenario for now. We'll worry about sub materials later.
So, if I understand right. When I am not dealing with multi-sub materials I do not have to worry about material IDs at all? For example, I assigned a "standard material" to a cube, the standard material is of type blinn and has a texture mapped to the diffuse from a file. (my current scenario)
*A texture within that material set to explicit texture coordinates will use the mapping face with the same index as the mesh face to access the mapping coordinates at the 3 corners of the face and pin down the texture based on the UVW values stored there.
Makes sense, except for the word explicit. What is the difference between a texture within a material set to use explicit coordinates and inexplicit? Explain how I would know if coordinates are explicitly set.
That being said, these methods are supposed to be used with an Editable Mesh or a TriMesh value. If you have modifiers on the stack like UVW Unwrap and you want to access the mapping data from there, you have several options - snapshot the top of the stack TriMesh state of the geometry using SnapshotAsMesh(), collapse the stack and work with the Editable_Mesh, or deal with the UVW Unwrap methods.
Ok, I did that in my script. I have a TriMesh value from a snapshot
I am not sure this helps if the "Understanding..." chapter didn't, but it was worth a try.
It does, I am getting further.
I am still missing the key ingredient though:
I have a tri mesh
---I don't know how to get the material!!---
I know how to associate the UVWs from map faces with a texture in a material.
All I need is a way to query the trimesh and ask "hey guy, what material is assigned to you?"
Let's assume the cube with a standard material assigned with a texture mapped to diffuse. I want to get the filename of that texture from my tri mesh object, amonst other things.
Here is my script so far (output to file isn't the concenr, getting the data is)
-----------------------------------------------------------------------------------------------------------
-- IsGeometry
--
-- @return - true if the superclass of the parameter is a Geometry class and is not a TargetObject
-- In other words, make sure the selected onject has a mesh
fn IsGeometry selected =
(
Superclassof selected == Geometryclass and classof selected != TargetObject
)
------------------------------------------------------------------------------------------------------------
global positions = #() -- array of all positions
global normals =#() -- array of normals, one per face
global UVs =#(#()) -- 2D array, index 1 - map channel, index 2 - corresponding position index
global faces =#() -- array of all faces
global maxToDirectXVert = matrix3 [1, 0, 0] [0, 0, 1] [0, 1, 0] [0, 0, 0]
global maxToDirectXUVW = matrix3 [1, 1, 0] [0, 0, 0] [0, 0, 0] [0, 0, 0]
-- Check all objects below the mouse pointer and allow objects to be picked that match the filter function
obj = pickobject filter:IsGeometry
if isValidNode obj then
(
-- Take a snapshot of the selected mesh
tmesh = snapshotAsMesh obj
-- get the vertex data
for vertexIndex = 1 to tmesh.numverts do
(
positions[vertexIndex] = getVert tmesh vertexIndex
)
-- get the normals
for f = 1 to getNumFaces tmesh do
(
normals[f] = getFaceNormal tmesh f
)
-- get the UVs
for mapChannel = 1 to meshop.getNumMaps tmesh do
(
if meshop.getMapSupport tmesh mapChannel then
(
for mapFace = 1 to meshop.getNumMapFaces tmesh mapChannel do
(
face = meshop.getMapFace tmesh mapChannel mapFace
for i = 1 to 3 do
(
mapVertIndex = face[i]
UVs[mapChannel][mapVertIndex] = meshop.getMapVert tmesh mapChannel mapVertIndex
)
)
)
)
for materialIndex = 1 to sceneMaterials.count do
(
print sceneMaterials[materialIndex]
print sceneMaterials[materialIndex].shaderName
)
-- How do I get what material is assigned to my mesh????
-- open an output file to write to
out_name = GetSaveFileName()
if out_name != undefined then
(
out_file = createfile out_name
-- write out the data
for faceIndex = 1 to tmesh.numfaces do
(
getFaceMatId tmesh faceIndex
faceVertexIndices = (getFace tmesh faceIndex)
for vertexIndex = 1 to 3 do
(
position = positions[faceVertexIndices[vertexIndex]] * maxToDirectXVert
normal = normals[faceIndex] * maxToDirectXVert
format "\nf[%][%] v% n%" faceIndex vertexIndex position normal to:out_file
for uvSetIndex = 1 to UVs.count do
(
uvw = UVs[uvSetIndex][vertexIndex]
format " u[%] %" uvSetIndex uvw to:out_file
)
)
format "\n" to:out_file
)
-- close the file
close out_file
-- clean up
delete tmesh
-- open the file for viewing
edit out_name
)
)
brekehan
05-02-2009, 08:14 PM
The UVs that resultes from my export script don’t look correct.
I made a unit cube, applied a standard material, mapped a file to the diffuse channel and got these results:
Material
{
Name: 01 - Default
Type: Standard Material
Shader: Max_Blinn
Diffuse Map: C:\Users\cpisz.HOMENETWORK\Documents\evil.png
}
f[1][1] v[-0.5,-0.5,-0.5] n[0,0,-1] u[1] [0,0,0]
f[1][2] v[-0.5,0.5,-0.5] n[0,0,-1] u[1] [1,0,0]
f[1][3] v[0.5,0.5,-0.5] n[0,0,-1] u[1] [0,1,0]
f[2][1] v[0.5,0.5,-0.5] n[0,0,-1] u[1] [0,0,0]
f[2][2] v[0.5,-0.5,-0.5] n[0,0,-1] u[1] [1,0,0]
f[2][3] v[-0.5,-0.5,-0.5] n[0,0,-1] u[1] [0,1,0]
f[3][1] v[-0.5,-0.5,0.5] n[0,0,-1] u[1] [0,0,0]
f[3][2] v[0.5,-0.5,0.5] n[0,0,-1] u[1] [1,0,0]
f[3][3] v[0.5,0.5,0.5] n[0,0,1] u[1] [0,1,0]
f[4][1] v[0.5,0.5,0.5] n[0,0,1] u[1] [0,0,0]
f[4][2] v[-0.5,0.5,0.5] n[0,0,1] u[1] [1,0,0]
f[4][3] v[-0.5,-0.5,0.5] n[0,0,-1] u[1] [0,1,0]
f[5][1] v[-0.5,-0.5,-0.5] n[0,0,-1] u[1] [0,0,0]
f[5][2] v[0.5,-0.5,-0.5] n[0,0,-1] u[1] [1,0,0]
f[5][3] v[0.5,-0.5,0.5] n[0,0,-1] u[1] [0,1,0]
f[6][1] v[0.5,-0.5,0.5] n[0,0,-1] u[1] [0,0,0]
f[6][2] v[-0.5,-0.5,0.5] n[0,0,-1] u[1] [1,0,0]
f[6][3] v[-0.5,-0.5,-0.5] n[0,0,-1] u[1] [0,1,0]
f[7][1] v[0.5,-0.5,-0.5] n[0,0,-1] u[1] [0,0,0]
f[7][2] v[0.5,0.5,-0.5] n[0,0,-1] u[1] [1,0,0]
f[7][3] v[0.5,0.5,0.5] n[0,0,1] u[1] [0,1,0]
f[8][1] v[0.5,0.5,0.5] n[0,0,1] u[1] [0,0,0]
f[8][2] v[0.5,-0.5,0.5] n[0,0,-1] u[1] [1,0,0]
f[8][3] v[0.5,-0.5,-0.5] n[0,0,-1] u[1] [0,1,0]
f[9][1] v[0.5,0.5,-0.5] n[0,0,-1] u[1] [0,0,0]
f[9][2] v[-0.5,0.5,-0.5] n[0,0,-1] u[1] [1,0,0]
f[9][3] v[-0.5,0.5,0.5] n[0,0,1] u[1] [0,1,0]
f[10][1] v[-0.5,0.5,0.5] n[0,0,1] u[1] [0,0,0]
f[10][2] v[0.5,0.5,0.5] n[0,0,1] u[1] [1,0,0]
f[10][3] v[0.5,0.5,-0.5] n[0,0,-1] u[1] [0,1,0]
f[11][1] v[-0.5,0.5,-0.5] n[0,0,-1] u[1] [0,0,0]
f[11][2] v[-0.5,-0.5,-0.5] n[0,0,-1] u[1] [1,0,0]
f[11][3] v[-0.5,-0.5,0.5] n[0,0,-1] u[1] [0,1,0]
f[12][1] v[-0.5,-0.5,0.5] n[0,0,-1] u[1] [0,0,0]
f[12][2] v[-0.5,0.5,0.5] n[0,0,1] u[1] [1,0,0]
f[12][3] v[-0.5,0.5,-0.5] n[0,0,-1] u[1] [0,1,0]
Looking at face 1, it appears to be a triangle on the bottom of the cube. So I went to my perspective viewport and orientate the view to look at the bottom:
(The insert image button isn't working for me on these forums! Here is a link)
ftp://christopherpisz.is-a-geek.com/pub/images/3dsmax/uvs_01.jpg
Looking at the output’s position, face[1][1] looks to be the bottom right vertex.
Looking at the output’s UV, face[1][1] is 0 0 0, which would be the bottom left of the texture.
However, looking at the viewport screenshow, the bottom right vertex is mapped to the bottom right of the texture.
Why aren’t these matching up?
Here is my script so far
-----------------------------------------------------------------------------------------------------------
-- IsGeometry
--
-- @return - true if the superclass of the parameter is a Geometry class and is not a TargetObject
-- In other words, make sure the selected onject has a mesh
fn IsGeometry selected =
(
Superclassof selected == Geometryclass and classof selected != TargetObject
)
-----------------------------------------------------------------------------------------------------------
-- WriteMaterialData
--
-- @param rootMaterial - The root material to be written out to file
-- @param outFile - The opened file to write to
fn WriteMaterialData rootMaterial outFile =
(
format "Material\n{\n" to:outFile
format "Name: %\n" rootMaterial.name to:outFile
unsupported = false
-- Standard Material
if classOf rootMaterial == standardMaterial then
(
format "Type: Standard Material\n" to:outFile
-- Blinn
if rootMaterial.shaderType == 1 then
(
format "Shader: Max_Blinn\n" to:outFile
if rootMaterial.mapEnables[1] then
(
texMap = rootMaterial.maps[1]
if classOf texMap == BitmapTexture then
(
format "Ambient Map: %\n" texMap.filename to:outFile
)
)
if rootMaterial.mapEnables[2] then
(
texMap = rootMaterial.maps[2]
if classOf texMap == BitmapTexture then
(
format "Diffuse Map: %\n" texMap.filename to:outFile
)
)
if rootMaterial.mapEnables[3] then
(
texMap = rootMaterial.maps[3]
if classOf texMap == BitmapTexture then
(
format "Specular Map: %\n" texMap.filename to:outFile
)
)
if rootMaterial.mapEnables[4] then
(
texMap = rootMaterial.maps[4]
if classOf texMap == BitmapTexture then
(
format "Specular Level Map: %\n" texMap.filename to:outFile
)
)
)
)
if unsupported then
(
messageBox "Unsupported Material found, skipping..." "Error"
)
format "}\n\n" to:outFile
)
------------------------------------------------------------------------------------------------------------
-- Main
--
global rootMaterial -- material assigned to the mesh
global positions = #() -- array of all positions
global normals =#() -- array of normals, one per face
global UVs =#(#()) -- 2D array, index 1 - map channel, index 2 - corresponding position index
global faces =#() -- array of all faces, with each face being 3 vertex indices
global maxToDirectXVert = matrix3 [1, 0, 0] [0, 0, 1] [0, 1, 0] [0, 0, 0]
global maxToDirectXUVW = matrix3 [1, 1, 0] [0, 0, 0] [0, 1, 1] [0, 0, 0]
-- Check all objects below the mouse pointer and allow objects to be picked that match the filter function
obj = pickobject filter:IsGeometry
if isValidNode obj then
(
-- Take a snapshot of the selected mesh
tmesh = convertToMesh (snapshot obj)
-- Get the material
rootMaterial = obj.material
-- Get vertices data
for vertexIndex = 1 to tmesh.numverts do
(
position = getVert tmesh vertexIndex
positions[vertexIndex] = position
)
for faceIndex = 1 to tmesh.numFaces do
(
normal = getFaceNormal tmesh faceIndex
for vertexIndex = 1 to 3 do
(
normals[(faceIndex - 1) * 3 + vertexIndex] = normal
)
)
-- Get the UVs
for mapChannel = 1 to meshop.getNumMaps tmesh do
(
if meshop.getMapSupport tmesh mapChannel then
(
for mapFace = 1 to meshop.getNumMapFaces tmesh mapChannel do
(
face = meshop.getMapFace tmesh mapChannel mapFace
for i = 1 to 3 do
(
mapVertIndex = face[i]
texCoord = meshop.getMapVert tmesh mapChannel mapVertIndex
UVs[mapChannel][mapVertIndex] = texCoord
)
)
)
)
-- Get the faces
for faceIndex = 1 to tmesh.numfaces do
(
faceVertexIndices = (getFace tmesh faceIndex)
faces[faceIndex] = faceVertexIndices
)
-- Convert to DirectX coordinate system and draw order
-- v0 v1 v2 -> v0 v2 v3, to draw in clockwise order for DirectX
-- temp = faceVertexIndices[2]
-- faceVertexIndices[2] = faceVertexIndices[3]
-- faceVertexIndices[3] = temp
-- Open an output file to write to
out_name = GetSaveFileName()
if out_name != undefined then
(
out_file = createfile out_name
-- Material info
WriteMaterialData rootMaterial out_file
-- Write out the data
for faceIndex = 1 to faces.count do
(
faceVertexIndices = faces[faceIndex]
for vertexIndex = 1 to 3 do
(
position = positions[faceVertexIndices[vertexIndex]]
normal = normals[faceVertexIndices[vertexIndex]]
format "\nf[%][%] v% n%" faceIndex vertexIndex position normal to:out_file
for uvSetIndex = 1 to UVs.count do
(
uvw = UVs[uvSetIndex][vertexIndex]
format " u[%] %" uvSetIndex uvw to:out_file
)
)
format "\n" to:out_file
)
-- close the file
close out_file
-- clean up
delete tmesh
-- open the file for viewing
edit out_name
)
)
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.