PDA

View Full Version : Export animation with MAXScript


rikardo
11-05-2008, 09:40 AM
Hey!

I have a script (written with MAXScript) that exports a mesh of the current selection in 3DS Max, vertices and faces. And writes that to a file, like this:

vertices 10
faces 15

vertices
[5.1, 4.4, 1.1]
[3.1, 7.3, 1.7]
...

faces
[1, 3, 2]
[3, 5, 4]
...

I want to do the same thing but frame by frame with a animation in 3DS Max. So the output of a maxscript of that kind would look like this:

frames 5
vertices 170
faces 240

frame 1
{
vertices...
faces...
}

frame 2
{
vertices...
faces...
}

frame 3
{
vertices...
faces...
}
...


As I said I already know how to do it with one scene, the actual problem is to step frame by frame. So if anyone have some ideas of how to do this "stepping" I would be pleased.

With Best Regards
Rikardo

ZeBoxx2
11-05-2008, 10:58 AM
something like...


f = createFile "c:\\temp\\exportfile.txt"
startFrame = animationRange.start
endFrame = animationRange.end
format "frames %\n" (endFrame - startFrame + 1) to:f

for frameNum = startFrame to endFrame do (
format "frame % {\n" ((frameNum as integer) / ticksPerFrame) to:f
at time frameNum (
-- your existing code for exporting the mesh data goes here
)
format "}\n" to:f
)
close f


or... (in case something's proving incompatible with 'at time')

f = createFile "c:\\temp\\exportfile.txt"
startFrame = animationRange.start
endFrame = animationRange.end
format "frames %\n" (endFrame - startFrame + 1) to:f

for frameNum = startFrame to endFrame do (
format "frame % {\n" ((frameNum as integer) / ticksPerFrame) to:f
sliderTime = frameNum
forceCompleteRedraw()
-- your existing code for exporting the mesh data goes here
format "}\n" to:f
)
close f

diffx
11-05-2008, 11:16 AM
Shouldn't it be "endFrame = animationRange.end"?

PEN
11-05-2008, 11:37 AM
You can have a look at this as well. There are two example files at the top, the second exports data to an XML file about the scene.

http://paulneale.com/tutorials/dotNet/xml/xml.htm

ZeBoxx2
11-05-2008, 02:16 PM
Shouldn't it be "endFrame = animationRange.end"?
whoops. yes :)

Can be any number, btw - animationRange.start / end just correspond to your current animation range's first and last frames. If you just want frames 10 through 25, you'd set:

startFrame = 10
endFrame = 25

rikardo
11-06-2008, 09:13 AM
Thank you guys VERY much, it really helped me. I will post the full code that exports the animation soon, so other could take use of it.

With Best Regards
Rikardo

rikardo
11-19-2008, 12:41 PM
Sorry for the delay!

As I said here comes the fully working 3DS maxscript animation exporter of the triangle meshes.

out_name = getSaveFileName caption:"Animation filename" types:".dat"
out_file = createfile out_name

-- Defines the start and end of the animation
startFrame = animationRange.start
endFrame = animationRange.end
num_frames = (endFrame - startFrame) + 1;

if (num_frames == 2) do
num_frames = 1

num_verts = 0
num_faces = 0
num_attach = 0

for i = 1 to selection.count do
(
sel_mesh = snapshotAsMesh selection[i]

-- Count all the attachments
if (findString selection[i].name "attachment") != undefined then
num_attach += 1
else
(
num_verts += sel_mesh.numverts
num_faces += sel_mesh.numfaces
)
)

-- Prints the number of frames
format "triangles %\nframesize %\nframes %\nattachments %\nframerate %\n" num_faces num_verts num_frames num_attach frameRate to:out_file

num_jumps = 0

for i = 1 to selection.count do
(
smesh = snapshotAsMesh selection[i]
cnfac = smesh.numfaces

if (findString selection[i].name "attachment") == undefined then
(
-- Writes the face indices
for f = 1 to cnfac do
(
face = getFace smesh f
format "\nf %" (face + ((num_verts / (selection.count - num_attach)) * ((i - 1) - num_jumps))) to:out_file
)
)
else
num_jumps += 1
)

if (num_frames == 1) do
(
endFrame = startFrame
format "\n" to:out_file
)

for f = startFrame to endFrame do
(
format "\n\nframe %" (((f as integer) / ticksPerFrame) + 1) to:out_file

at time f
(
attach_indices = #()

for i = 1 to selection.count do
(
tmesh = snapshotAsMesh selection[i]
cnver = tmesh.numverts

if (findString selection[i].name "attachment") == undefined then
(
-- Writes the vertices
for v = 1 to cnver do
(
vert = getVert tmesh v
norm = getNormal tmesh v
norm = normalize norm

format "\nv % " vert to:out_file
format "n %" norm to:out_file
)
)
else
( append attach_indices i )
)

for i = 1 to attach_indices.count do
(
-- if f == startFrame do
-- (
-- selection[i].transform = identity selection[i].transform
-- )

index = attach_indices[i]
format "\n\na %\nrow1 %\nrow2 %\nrow3 %\nrow4 %" selection[index].name selection[index].transform.row1 selection[index].transform.row2 selection[index].transform.row3 selection[index].transform.row4 to:out_file
)
)
)

-- Closes and finishes the file
close out_file
edit out_name

In order to export a model with animation you select all the objects in the scene you want to export and then run the script, specifies a filename and saves the file.

NOTE!

I've added a support to create attachments to the model, so if you create a model in 3DS, then create a box name it "attachment" and then link it to a part of the model you want it to be attached to. Now the script will export the attachment's transformation matrix for each frame, so it could be used in a animation. For example to make the model hold in a weapon or wear a sheild.

It could be a bit hard to "translate" the code I've written into the actual situation that it solves. That since I've added some "special case situation handlers" to make the script exporting a file that matches my C++ code and my own criterias properly.

So a example code of a animated box with 3 frames could look like this:

triangles 12
framesize 8
frames 3f
attachments 0
framerate 30

f [1,3,4]
f [4,2,1]
f [5,6,8]
f [8,7,5]
f [1,2,6]
f [6,5,1]
f [2,4,8]
f [8,6,2]
f [4,3,7]
f [7,8,4]
f [3,1,5]
f [5,7,3]

frame 1
v [-5,-5,-5] n [0,0,-1]
v [5,-5,-5] n [0,0,-1]
v [-5,5,-5] n [0,0,-1]
v [5,5,-5] n [0,0,-1]
v [-5,-5,5] n [0,0,1]
v [5,-5,5] n [0,0,1]
v [-5,5,5] n [0,0,1]
v [5,5,5] n [0,0,1]

frame 2
v [0,-7.07107,-5] n [0,0,-1]
v [7.07107,0,-5] n [0,0,-1]
v [-7.07107,0,-5] n [0,0,-1]
v [0,7.07107,-5] n [0,0,-1]
v [0,-7.07107,5] n [0,0,1]
v [7.07107,0,5] n [0,0,1]
v [-7.07107,0,5] n [0,0,1]
v [0,7.07107,5] n [0,0,1]

frame 3
v [5,-5,-5] n [0,0,-1]
v [5,5,-5] n [0,0,-1]
v [-5,-5,-5] n [0,0,-1]
v [-5,5,-5] n [0,0,-1]
v [5,-5,5] n [0,0,1]
v [5,5,5] n [0,0,1]
v [-5,-5,5] n [0,0,1]
v [-5,5,5] n [0,0,1]

And the same box with animation but a attachment added to one of the sides:

triangles 12
framesize 8
frames 3f
attachments 1
framerate 30

f [1,3,4]
f [4,2,1]
f [5,6,8]
f [8,7,5]
f [1,2,6]
f [6,5,1]
f [2,4,8]
f [8,6,2]
f [4,3,7]
f [7,8,4]
f [3,1,5]
f [5,7,3]

frame 1
v [-5,-5,-5] n [0,0,-1]
v [5,-5,-5] n [0,0,-1]
v [-5,5,-5] n [0,0,-1]
v [5,5,-5] n [0,0,-1]
v [-5,-5,5] n [0,0,1]
v [5,-5,5] n [0,0,1]
v [-5,5,5] n [0,0,1]
v [5,5,5] n [0,0,1]

a attachment
row1 [-1.62921e-007,-1,0]
row2 [1,-1.62921e-007,0]
row3 [0,0,1]
row4 [20,0,0]

frame 2
v [0,-7.07107,-5] n [0,0,-1]
v [7.07107,0,-5] n [0,0,-1]
v [-7.07107,0,-5] n [0,0,-1]
v [0,7.07107,-5] n [0,0,-1]
v [0,-7.07107,5] n [0,0,1]
v [7.07107,0,5] n [0,0,1]
v [-7.07107,0,5] n [0,0,1]
v [0,7.07107,5] n [0,0,1]

a attachment
row1 [0.707107,-0.707107,0]
row2 [0.707107,0.707107,0]
row3 [0,0,1]
row4 [14.1421,14.1421,0]

frame 3
v [5,-5,-5] n [0,0,-1]
v [5,5,-5] n [0,0,-1]
v [-5,-5,-5] n [0,0,-1]
v [-5,5,-5] n [0,0,-1]
v [5,-5,5] n [0,0,1]
v [5,5,5] n [0,0,1]
v [-5,-5,5] n [0,0,1]
v [-5,5,5] n [0,0,1]

a attachment
row1 [1,-1.19209e-007,0]
row2 [1.19209e-007,1,0]
row3 [0,0,1]
row4 [-8.74228e-007,20,0]

OBS! The attachment translation matrix is relative to the box (or any other object if you want) used to represent the attachment, so when you create the actual model that should be the attachment the "attachment point" lies in the origo! And it would be recommended to change the pivot point on the "attachment box" to lie in the center of that object for proper aligments.

With Best Regards
Rikardo

CGTalk Moderation
11-19-2008, 12:41 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.