[Closed] Export animation with MAXScript
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
something like…
f = createFile "c:\ emp\\exportfile.txt"
startFrame = animationRange.start
endFrame = animationRange.end
format "frames %
" (endFrame - startFrame + 1) to:f
for frameNum = startFrame to endFrame do (
format "frame % {
" ((frameNum as integer) / ticksPerFrame) to:f
at time frameNum (
-- your existing code for exporting the mesh data goes here
)
format "}
" to:f
)
close f
or… (in case something’s proving incompatible with ‘at time’)
f = createFile "c:\ emp\\exportfile.txt"
startFrame = animationRange.start
endFrame = animationRange.end
format "frames %
" (endFrame - startFrame + 1) to:f
for frameNum = startFrame to endFrame do (
format "frame % {
" ((frameNum as integer) / ticksPerFrame) to:f
sliderTime = frameNum
forceCompleteRedraw()
-- your existing code for exporting the mesh data goes here
format "}
" to:f
)
close f
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
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.
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
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 %
framesize %
frames %
attachments %
framerate %
" 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 "
f %" (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 "
" to:out_file
)
for f = startFrame to endFrame do
(
format "
frame %" (((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 "
v % " 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 "
a %
row1 %
row2 %
row3 %
row4 %" 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