Automatic rotation of moving objects to match their direction
Hi there. I'm a noob to 3DS Max, and have hit a wall with this. I'm using external position data (csv) to animate objects in 3D space. I've managed to get objects moving ok, but I cannot figure out how to rotate them to face in the direction of travel. I've seen some other problem pages about this, but couldn't get their scripts working.
Very grateful for any assistance. I include my code below for an idea of where I stand.
Robin
------------------
resetMaxFile #noPrompt
(
--Read in the movement data
local theFile = openFile "p:\\data.csv"
global data = #()
global points = #()
while not eof theFile do (
t = [(readValue theFile as integer), (readValue theFile as integer)]
append data t
p = Point3 (readValue theFile as float) (readValue theFile as float) (readValue theFile as float)
append points p
)
close theFile
)
(
--Setup objects
for i = 1 to 50 do
(
Box lengthsegs:1 widthsegs:1 heightsegs:1 length:5 width:5 height:5 mapcoords:on pos:[points[i][1], points[i][2], points[i][3]] isSelected:on
$Box001.name = ((i as integer) as string)
)
)
--Animate objects
animate on
(
k = 1
for t in 1 to 100 do
(
at time (t)
(
for i in 1 to 50 do
(
execute ("select $" + (data[k][2] as integer) as string)
$.pos = points[k]
k = k+1
if k > 5000 do
(
k = 1
)
)
)
)
)
Comments
object orientation
actually is more easy to orient on object and this method will work on all axis:
resetMaxFile #noPrompt
(
--Setup object
Box lengthsegs:1 widthsegs:1 heightsegs:1 length:10 width:30 height:10 mapcoords:on pos:[50, 0, 0] isSelected:on
)
--Animate objects
animate on
(
animationRange = interval 1 360
for t in 1 to 360 do
(
at time (t)
(
$Box001.pos = [cos(t)*50, sin(t)*80, sin(4*t)*20]
now = $Box001.pos
if(t > 1) then
(
dirVec = normalize (now - last)
$Box001.dir = dirVec
)
global last = now
)
)
)
Problem solved..
..by (a) calculating object's current direction from the current and last-frame positions, and (b) rotating using script from Bobo*, as follows:
resetMaxFile #noPrompt
(
--Setup object
Box lengthsegs:1 widthsegs:1 heightsegs:1 length:10 width:30 height:10 mapcoords:on pos:[50, 0, 0] isSelected:on
)
--Animate objects
animate on
(
animationRange = interval 1 360
for t in 1 to 360 do
(
at time (t)
(
$Box001.pos = [cos(t)*50, sin(t)*50, 0]
now = $Box001.pos
if(t > 1) then
(
dirVec = normalize (now - last)
--ang = asin(dirVec[2]/50)
dir = atan (dirVec.y/dirVec.x)
if dirVec.x < 0 and dirVec.y > 0 then dir = 180+dir
if dirVec.x < 0 and dirVec.y < 0 then dir = -180+dir
if(t>2) then
(
ang = dir-lastdir
rot_obj = eulerangles 0 0 ang
)
else rot_obj = eulerangles 0 0 dir
rotate $Box001 rot_obj
)
global last = now
global lastdir = dir
)
)
)
* http://forums.cgsociety.org/archive/index.php/t-13982.html
With my method you are
With my method you are calculating direction from given data on the fly.
And i think is a faster solution then calculating for each object all over again same code. Maybe i'm wrong but check from youself.
By the way your code not working
bga
Any idea how I kill this thread?
There doesn't appear to be an option anywhere
Thanks barigazy
I mostly cracked this problem, but my new post has the updated version..
Here we go
bga
I don't have *.csv to do some
I don't have *.csv to do some test but hope this help
bga
Thanks but not quite!
Thanks for your effort. Unfortunately that killed the animation completely!
I attach the data file so you can test the script (now a txt file so the script will need updating).
can you explain the numbers
can you explain the numbers inside *.txt (first and second in the line).
3rd,4th and 5th are position coords, right?
bga
Sure..
The 1st column is time (frame). I don't think the script uses it: there are exactly 50 objects repeating every frame, so I just used a regular loop instead. The 2nd column is object ID, which is used in the script to select the correct box to update its position.
Apologies if the script is inefficient or unconventional - it is my first maxscript!