script for point cache

Hi all,

I am trying to write a script that can go on a model of a person, where when they move, one point cache is loaded, and when they stop, a different point cache is loaded.

Can anyone help, I’m very stuck!!

Mark

P.S. below is the script I am using to change the colour of the sphere, but I need to edit it to effect the point cache.

t0 = f-1
t1 = f
p0 = at time t0 $sphere.pos
p1 = at time t1 $sphere.pos
if p0==p1 then $sphere.material.diffuse = (color 255 0 0)
else $sphere.material.diffuse = (color 0 255 0)

[1, 1, 1]
Scripted_Colour.zip (19.5 KB)

Alright, I’ll aide you.

First, in maxscript since Point Cache is a modifier we have to get the properties we have access to in a different way that show $.

1. Create a Sphere, name it Sphere001
2. Add a point cache modifier to that sphere
3. in the Listener window type


show $.modifiers[#Point_Cache]

$ - Denotes the current selection
.modifiers - are all of the modifiers applied to the object
[#Point_Cache] - denotes that we only want the properties of the point cache modifier

This will return:


  .filename : filename
  .recordStart (Record_Start) : float
  .recordEnd (Record_End) : float
  .sampleRate (Sample_Rate) : float
  .strength : float
  .relativeOffset (Relative_Offset) : boolean
  .playbackType (Playback_Type) : integer
  .playbackStart (Playback_Start) : float
  .playbackEnd (Playback_End) : float
  .playbackORTbefore (Playback_Out_Of_Range_Before) : integer
  .playbackORTafter (Playback_Out_Of_Range_After) : integer
  .playbackFrame (Playback_Frame) : float
  .interpolationType (Interpolation_Type) : integer
  .applyMeshToSpline (Apply_To_Spline) : boolean
  .preLoadCache (PreLoad_Cache) : boolean
  .clampGraph (Clamp_Graph) : boolean
  .forceUncPath (Force_UNC_Path) : boolean
  .loadType (Load_Type) : integer
  .applyToWholeObject (Apply_To_Whole_Object) : boolean
  .loadTypeSlave (Load_Type_Slave) : integer
  .fileCount (File_Count) : integer

So we want to edit the filename at different times. That property we will be changing is this

$.modifiers[#Point_Cache].filename

Ok, after doing this, I don’t think it’s possible. I’ve tried everything I could to get it to animate this property correctly, but it doesn’t appear to be animate-able.

That is how you approach this type of problem though.

Hope it helped at least a little.

-Colin

Thank Colin, you have actually helped more than you thought! Ill post my scene if it works

m

Could you give me an example of how;

$.modifiers[#Point_Cache].filename

that would be written for a file on a server. I have tried;

$sphere.modifiers[#Point_Cache].“s:\Point Cache Files\casual19_m_walk_inplace_625_Frames.xml”

It doesnt work!!

You probably need to use double slashes in your file name - for some dumb reason maxscript or other languages decided to use the “\” as a method of allowing one line to be broken and continued on the next line. Try doubling up and see if that helps. Another approach could be to have a dummy object and hide / unhide different point cached objects each time?

Or actually would it make more sense to pre process things and get a script to automatically add another point cache mod with the new animation?

Sure,

$.modifiers[#Point_Cache].filename = “C:\\Program Files\\3dsmax 2011\\test.pc2”

or you can use forward slashes

$.modifiers[#Point_Cache].filename = “C:/Program Files/3dsmax 2011/test.pc2”

also note: it supports UNC paths as well

$.modifiers[#Point_Cache].filename = “\\\\serverName\\maps\\pointcaches\\test.pc2”

(Note the quadruple backslash making that in windows “\\serverName\maps\pointcaches\test.pc2”)

Perfect, I think I might have got it to work, Ill just make the changes to do with the file name locations, and tel later.

Ill post if I fix it!

Thanks again
M

Sure,

$.modifiers[#Point_Cache].filename = “C:\\Program Files\\3dsmax 2011\\test.pc2”

or you can use forward slashes

$.modifiers[#Point_Cache].filename = “C:/Program Files/3dsmax 2011/test.pc2”

Many thanks, this did work, and I have added to my test scene attached so you can how I have used it.

Or actually would it make more sense to pre process things and get a script to automatically add another point cache mod with the new animation?

I have got this sort of working, but loading a different PC file through one PC mod if the dummy is moving or not, and it works. But I think I am using the wrong method of applying the script, on the objects scale motion.

Is there a way I could use a script like this to control many people mesh in the scene all linked to different dummys?

Many thanks for your help, does seem to be getting there! File attached, max 2008, without the PC files, they are a few meg.

M
MotionScriptTest.zip (73.5 KB)

How many people are involved in your scene? It might even be a case where you could use a scripted op inside of particle flow for it to do multiple people?

There will be around 200 pre simulated dummies acting as a ped sim.

Any thoughts?

Just thinking would there be any point in doing this in pflow since you could do a lot with collision operators sending particles into events with a speed of 0 and a shape instance op using your standing animation then using an age test on that event, send it to another event with a speed and a shape instance referencing your walking animation?

Just might be handy in terms of giving you control over random spacing, amount and so on?

Hi,

I should have said before, the people sim has been provided already finished, but with dummy objects as the people. I simply want to clone align and link my character to the dummies, and then get the walking/idle motion to swop accordingly.

I now have 3 different solutions, probably all shit bu they work! My latest one is based on having three mesh, one with a point cache of walking, one with PC of idle, and the third with a morpher mod referencing the other two. So I now have my one man moving and stopping with the dummy, and the morph swopping between the two. I now am trying to work out how to code so I can make the value of the top channel in the morpher to blend in, not just subbenly be 100 from 0.

t0 = f-1
t1 = f
p0 = at time t0 $sphere_m.pos
p1 = at time t1 $sphere_m.pos
if p0==p1 then WM3_MC_SetValue $sphere_m.morpher 1 0.0
else WM3_MC_SetValue $sphere_m.morpher 1 100.0

Thats is working so far.

else WM3_MC_SetValue $sphere_m.morpher 1 (0.0 + 10.0) this is where I get stuck how to control the value over time!

Anything spring to mind?!

Thanks,
M

I’d say you could either set a keyframe in the controller of that morphers channel or use the “animate on” command to record changes? Just finished doing an overnight stint to get a shot finished off so I’ll come back to you on it when I’ve got slightly more intelligence than a potato :slight_smile:

You’ll need to put your WM3_MC_SetValue in a for loop to control it over time


[LEFT][FONT=Courier New][SIZE=2][COLOR=#0000ff]animate on[/COLOR][/SIZE][/FONT]
[FONT=Courier New][SIZE=2][COLOR=#0000ff]
[/COLOR][/SIZE][/FONT][/LEFT]
 [LEFT][LEFT][FONT=Courier New][SIZE=2][COLOR=#0000ff]for[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2] t  [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]in[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2] 0 [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]to[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2]  100 [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]by[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2] 5  [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]do (
[/COLOR][/SIZE][/FONT][/LEFT][/LEFT]
 [LEFT][LEFT][FONT=Courier New][SIZE=2][COLOR=#0000ff]     at[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2]  [/SIZE][/FONT][FONT=Courier New][SIZE=2][COLOR=#0000ff]time[/COLOR][/SIZE][/FONT][FONT=Courier New][SIZE=2] t 
[/SIZE][/FONT][/LEFT]
[LEFT][FONT=Courier New][SIZE=2]          WM3_MC_SetValue $sphere_m.morpher 1 t   -- t = 0 the first iteration, then 5, 10, 15, 20...100
[/SIZE][/FONT][/LEFT]
[LEFT][FONT=Courier New][SIZE=2])
[/SIZE][/FONT][/LEFT][/LEFT]

So it’ll put a keyframe on 0,5,10,15..100 with the percentage the time (t)

Thanks Colin, though for the last hour I’ve tried to use your script with no luck!!

I’m a complete beginner I’m afraid! If you have any spare time, would you beable to show me how to incorperate your code with mine?

On a side note, I’m also trying to achieve the same effect through Pflow. Its ok, but I cant get each particle to stay locked to the moving object. I think Ill stick to the method thats working for now!

I did have a thought, at the moment I have to copy this script and amend for every character, as the name of the object is being used in it. I have tried just using $ but this errors on all 4 lines where the $objectname is used.

Then you want to look into the for loop.

It’s pretty simple but gives you the ability to do fairly complex things on lots of objects. In your case the $ sign represents the single current object you have selected. Maxscript can sometimes use multiple objects with this syntax but not always. Instead using something like this:

For i in selection do
(
     i.radius = 20
)

So the first line just means for every object I have selected, do whatever commands are between the brackets to that object. The letter “i” is kind of the same as $ in your scripts, i starts off as meaning object 1 of the collection you have selected, then once it’s looped through all of the commands between the brackets, “i” becomes object 2 and so on. There’s also no particular reason for using the letter “i”, you can use anything in there you want, once it’s consistent in the script. When you start using a for loop inside another for loop, you need to use a unique letter or name for each for loop.

Thanks Jo, that has now worked, but only when I have the object selected. Is there a way to get it working on any object its appied to, but without needing to select it?

Or might there be a way to make this into a pre-render script, and have it effect all objects on a specific layer? No idea how to do that tho!!

Thanks,

Yeah you’ve got to tell maxscript what to work on in the first place. One way to do this is to make a specific name for all your dummy objects and then use maxscript to collect those objects. For this you’ll have to use an array. An array is just a collection of objects, this can be a collection of numbers, a collection of objects or any type of data really. For example if you wanted to select all the spheres in your scene and save them as a collection you can play with later, use Myarray = $sphere* as array which will make a selection of everything that has a name starting with sphere - be careful with this since you might get objects you don’t want to affect. Make sure you use a really specific name for all your dummy objects just in case. Once you’ve got an array of your objects, you loop through them using the following syntax:

Myarray = $sphere* as array

for I = 1 to myarray.count do
(
    myarray.radius = I * 10
)

So it’s similar to the usual for loop with a few tweaks:

Myarray = $sphere* as array - You’re creating a new array called MyArray and loading all the objects in the scene with names that start with sphere. This is pretty much just a way of saving the objects for later access.

For i = 1 to myarray.count do - this means that I is the letter being used as the count of the loop, and when looping through, start off with 1 and go all the way up to the total number of objects in the array called myarray. Similar to you using sphere_m.pos where .pos accesses the position property of an object, “.count” is a property of an array. So in this case the loop will start at 1 and keep going until it reaches the total number of objects in your array.

myarray.radius = I * 10 - Okay so here you see how you pick an object in an array. You type the name of the array, then in square brackets following it, type in the number of the object you want to access. If you were to manually type myArray[1] it’ll tell you the first object that got put into the array. In this particular case, myarray[1] represents the first sphere object, and that has a .radius property. So this line of code is a bit like typing sphere01.radius. Here to make sure it’s working I’ve made the script assign a radius of 10 multiplied by the count number of our for loop so each sphere gets bigger.

And that’s it! There’s a few different ways to use a for loop, some shorter than others, and they all offer different features. For example you’ve got really global ones like “for i in lights do” which will try and run on every object in the light category of objects in max. You’ve got “for i in shapes do” and other such loops for specific types of objects in max, “for i in selection do” for running through selections of objects, and the normal “for i = 1 to whatever do” for looping through data, or objects or things that don’t fit into another category.

wow! Perfect, Ill spend this afternoon going through this and see if I can get it working, many thanks.

Ill be back asking about my morpher, and blending the morph I’m sure!

Hope your late night was successful.

M