PDA

View Full Version : Script Question (mainly for bobo)


Largo39
03-23-2005, 03:37 PM
Alright bobo, was playing with your script:
http://www.scriptspot.com/bobo/mxs5/pflow/pflow__Chunks_Basics.htm

in an effort to disintegrate an object. combined with Alan's quickfrag script it works great! it looks fantastic, although untextured. my question is however, is there some function/command to also inherit the material of the object? my object has multiple materials assigned to the fragments and i was hoping to somehow inherit those (with the material of the fragment to the appropriate particle)...

i saw soemthing called .usemapping which may work to inherit from the object but i DON"T see something like particlemapping (i figured i would just insert like pcont.particlemapping = ChunksArray[i].usemapping but i guess its not that easy)

Largo39
03-23-2005, 03:45 PM
oh wait, can i assign unique ids to the objects and materials and have the particle inherit the ID from the object and thus get that material?

Largo39
03-23-2005, 03:53 PM
of coursse, even if i modified the script correctly... the materials are still reset when things start to move (ie: when the deflector hits them they move to a new event where it moves, spawns little disint particles), so i would have to inherit the matierals from the previous event, grr, how do you do that as well?

galagast
03-24-2005, 04:28 AM
coincidentally i found some sort of workaround in this just yesterday... hehe

what i did was place this script for the Script Ooperator located @ the Global Event:

on ChannelsUsed pCont do
(
pCont.useTM = true
)
on Init pCont do
(
global Orig_ChunksArray = $Orig_Fragment_* as array
)
on Proceed pCont do
(
count = pCont.NumParticles()
for i in 1 to count do
(
pCont.particleIndex = i
if ChunksArray != undefined do
(
ChunksArray[i].Transform = pCont.particleTM
)
)
)
on Release pCont do
(

)



and this code for the Birth Script Operator in the 2nd event:

on ChannelsUsed pCont do
(
pCont.useAge = true
pCont.useTM = true
pCont.useShape = true
)
on Init pCont do
(
global ChunksArray = $Fragment_* as array
)
on Proceed pCont do
(
t = pCont.getTimeStart() as float
if t < 0 do
(
NumChunks = ChunksArray.count
for i = 1 to NumChunks do
(
pCont.AddParticle()
pCont.particleIndex = pCont.NumParticles()
pCont.particleAge = 0
pCont.particleTM = Orig_ChunksArray[i].transform
pCont.particleShape = Orig_ChunksArray[i].mesh
)
)
)


basically its just some sort of hack. You'll need two copies of your fragment collections ... so lets say we have $Orig_Fragment_* as your original collection of fragments (the original mesh with mapping although not entirely needed), and $Fragment_* as another separete collection of fragments (preferably with mapping).

Then as the script evaluates, it would run through all the $Fragment_* collection and place thier transforms individually to each corresponding particle as you move the slider. Now we needed the $Orig_Fragment_ collection in order for us to have an array of transforms, in this case, the original, or starting transforms of our mesh. Coz without this, after going to, say from 15f and back to 0f, the script would evaluate the positions of frame 15! So this is where the original starting positions come in.

The drawback is that you'll have a doubled fragment count since we need two collections..
Although we can always set a separate unalterable final collection for the starting positions, this way, we could delete the $Orig_Fragments_ array.
(i hope i explained this correctly, this has been my weakness... explaining things clearly.. hehe)

I hope this helps!

galagast
03-24-2005, 10:03 AM
ok, after posting this, ive reread what you typred, then noticed that you were using multiple events.. unfortunetly the above scripts wont work on multiple events.. but for some reason, after tweaking with the codes, i got it working... so are the new codes:

Script Operator:

on ChannelsUsed pCont do
(
pCont.useTM = true
)
on Init pCont do ()
on Proceed pCont do
(
count = pCont.NumParticles()
ChunkCheck = (ChunksArray != undefined)
if chunkcheck do
(
for i in 1 to count do
(
pCont.particleIndex = i
-- get the ID if the current particle Index
j = pcont.particleID
-- we needed to use the ID because the value is constant
-- for the particle all throughout
ChunksArray[j].Transform = pCont.particleTM
)
)
)
on Release pCont do ()


and the Birth Script Code:

on ChannelsUsed pCont do
(
pCont.useAge = true
pCont.useTM = true
pCont.useShape = true
)
on Init pCont do
(
-- declare the fragments to manipulate
global ChunksArray = $Fragment_* as array

-- TM_Reset will lock the ChunksArray_TM values
global TM_Reset
-- check for fragments
if ChunksArray != undefined do
(
-- first time running the script will set TM_reset to TRUE
if TM_Reset == undefined do TM_Reset = true
-- once TM_Reset is true, we now get the transform values
-- from the ChunksArray collection and place it in ChunksArray_TM
-- Lastly, set TM_Reset to false so that we wont be defining
-- chunk transforms everytime!
if TM_Reset do
(
Global ChunksArray_TM = for i in ChunksArray collect i.transform
TM_Reset = false
)
)
-- if you want to define new starting/initial transforms for your chunks
-- just type in "TM_Reset = undefined" in the listener
)
on Proceed pCont do
(
t = pCont.getTimeStart() as float
if t < 0 do
(
NumChunks = ChunksArray.count
for i = 1 to NumChunks do
(
pCont.AddParticle()
pCont.particleIndex = pCont.NumParticles()
pCont.particleAge = 0
-- we use the transforms we've collected here
pCont.particleTM = ChunksArray_TM[i]
pCont.particleShape = ChunksArray[i].mesh
)
)
)
on Release pCont do ()


this time, we dont have to duplicate our fragments...

i hope this helps! ... inform me of any troubles, ill try my best to help solve it. :)

galagast
03-24-2005, 10:14 AM
found out another wonderful thing about this!
Turn on the animate button and scrub the timeline, your fragments would have keys automatically created, this way, we can turn off PFlow after creating those keys!
works like a simulation.. hehe
:thumbsup:

Largo39
03-24-2005, 07:42 PM
alright, ill try it tonight, really need to start learning maxscript, maybe after i finish this anim... hmm....

"scrub the timeline" as in.. just move the bar over my timeline? sry, im just having a brain fart right now. bleh.. need.. water...

anyways, just for my better understanding. the birth script is basically a modified version of bobos and then the script operator takes fromt eh birthscrip and keeps the material information? but what functions in the birthscript takes the material information (or id) from the source objects?

galagast
03-25-2005, 09:48 AM
yup, scrub the timeline, hehe. :)

and yup, its a modified version of Bobo's script.

ok, ill try to explain some... the latter script used this function:
pcont.particleShape = chunksArray[i].mesh
this basically means that for every particle, we get a COPY of the ChunkArray i. Where i is the i'th chunk.

here are some basic codes that might help some people reading this what that i is all about:
for i in 1 to 10 do print i
for i in 1 to 10 do
(
the_number = i
print the_number
)

foo = 100
foo_text = foo as string

for i in 1 to 10 do
(
the_number = i
the_text = (the_number as string + " : cgtalker")
print the_text
)


now what i did, instead of getting a COPY of the mesh, we use the mesh itself! coz if we use the COPIED mesh, the function pcont.particleShape won't copy the UV infos. It only copies the mesh.
And since our mesh (presumably) already has mapping in it, i just used this function (pcont.particleTM) to get the particle transformation matrix (which are basically position, scale, rotation values) of the mesh itself... thus, i didnt have to use or look for a function to copy mesh UVs...
now that we have transorm information from the particles, we could just easilly assign each chunk a new transform for each paritcle.

you could try these lines: (but first make a sphere and a box and convert them both to editable meshes)
$sphere01.mesh = $box01.mesh
the sphere just becomes a box.

$sphere01.transform = $box01.transform
the sphere now moves to the box's location, adapting its rotation, and scale.

so, that's basically it.. the script operator just loops through all the particles using thier IDs and place each corresponding chunk to the particles transform.

and some notes:
- particle ID is what you see when you check the "Show Particle ID's" in the Display Operator.
- particle Index... when a particle enters an event, they are given a sequential number, that's thier index value.

well, i hope this helps!:)

Largo39
04-04-2005, 03:31 AM
erm, hmm, still need more help. just restarted working on this (moved) and right now i have a 5X5X5 array of boxes with the moving deflector to try and test it out. and its.. not working

the pflow setup:

event 01:
Birth Script
Collision 01
Display 01

event 02:
Script Operator
Speed Operator 01 (alone icon arrow)
DIsplay 02

all ive done is copied and pasted your code, tried editing it to global ChunksArray = $BOX_*as array but.. no luck. the boxes as of yet have no unique object channel ids other than 0 (and no texture, will be experiementing with that next) but would that effect things?

sry bout this.

Largo39
04-04-2005, 03:38 AM
tried giving texture, making object channel 1, no effect.

in one of the posts you said have the global be the script operator than 2nd event be the birth? i couldn't even link up that, which makes sense (how can you modify particles with operator if they don't exist yet?)

Largo39
04-04-2005, 03:40 AM
hmm, well, it did link if i put the operatore in the source, but.. still to no avail.

galagast
04-04-2005, 06:05 AM
ok, here's a sample file (http://www.geocities.com/jepoy20/files/pflow_fragment_test.zip):) .. ive created a sample scene also with 5x5x5 mapped boxes..

i was also hoping if you could give me your scene file so that I could try and see why its not working..

just post here if u encounter more problems, I'll try my best to help :thumbsup:

Largo39
04-06-2005, 03:25 AM
hmm, alrighty.. messed with things, got a couple of errors.

first of all, what i did was set your array to fragments instead of boxes so taht it would apply to mymesh and it doesn't like that.

heres what it does

1. all the bits get scrunched to down to 0,0 (or as close as they can) and the original shape is lost

2. get a birth script error

-- Error occurred in i loop
-- Frame:
-- i: 125
-- Unable to convert: undefined to type: Matrix

i messed around with blocks, they work fine, then what i did is i DOUBLED the amount of blocks, and guess what? i get the same error. so from what i can tell the script is essentially being overloaded and dies. i tried deleting about half my particles and voilia! they work! (although, they DO stillg et reset)

Largo39
04-06-2005, 03:34 AM
alright, figured out why it all collapsing, it has to do with your TM_reset, it starts out undefined andt hus its resetting everything. however, i DO see its use because its reseting the particles to their original positions. of course, i only need to do this once but still....

Largo39
04-06-2005, 03:52 AM
well, the way to solve the whole thing about all the particles not reseting, just run it through once (i had with with autokeyframe on, may not be necessary), then when your done, just tun the pflow off! simple as that. still question remains at why the pflow freaks out at more than 101 particles....

Largo39
04-06-2005, 04:00 AM
count part solved...

in this code of the script operator

on Proceed pCont do
(
count = pCont.NumParticles()
if count != 0 then
(
for i = 1 to count do
(
pCont.particleIndex = i
j = pcont.particleID
ChunksArray[j].Transform = pCont.particleTM
)
)
)


you had for i IN 1 to count do
change it to = and voila! it works. u should make this a plugin, its pretty cool.

Largo39
04-06-2005, 04:45 AM
hmm, unfortunetly it does NOT like spawning new particles fromt eh geometry ;) ah well, thats something that ill just have to mess around with to see if i can get working... be cool tho.

galagast
04-06-2005, 05:26 AM
i see...
about the TM_reset, this variable is responsible for resetting your transforms...
here's how it goes..
when you first create a scene with fragments, the variable ChunksArray_TM is empty, it has no transform information stored in it... this variable is not the same as the ChunksArray...
ChunksArray: this is the collection of object fragments the we manipulate.
ChunksArray_TM: this is thier transform information (position, scale, rotation)

so say I created a set of boxes...
we now turn on pflow, you noticed that we have a script operator in our global, topmost event.
there is a line there stating this:

count = pCont.NumParticles()
if count != 0 then

initially, if it were to count the particles, there would be none, so it won't evaluate the script because the particle count is initially zero (at the start of the frame). so this is basically unfuncitonal at the start...
now, this is where the birthscript comes in... this is what gets evaluated at the start of the flow.

- so starting off, first we get the array or collection of objects and store it to ChunksArray.
global ChunksArray = $Fragment_* as array

- then we also set another variable as global (this is so that it could be read from anywhere)
global TM_Reset

- this next line will check if there were chunks collected
if ChunksArray != undefined do
(

- so at the start, we defined the global TM_Reset just as is... so right now, it is UNDEFINED
- this next line will check if it is UNDEFINED, if it is, then we set a new value to it, which is the value TRUE.
if TM_Reset == undefined do TM_Reset = true

- now that TM_reset has the value TRUE, this next line will evaluate:
if TM_Reset do
(


- this line will create a new global variable for ChunksArray_TM... and it contains the transform information (the initial transform information) of each chunk.
Global ChunksArray_TM = for i in ChunksArray collect i.transform

- and lastly, we set the variable TM_Reset to false..
TM_Reset = false
)
- the reason is simple, its only because we wouldnt want to overwrite the initial (starting) transform information data everytime we slide back up to frame zero.

so now what we have are:
ChunksArray, with all the fragments, or boxes etc... in it
TM_reset is now false
and
ChunksArray_TM is now defined and is theoretically locked because of TM_reset being false.

the script will now work with these values...:thumbsup:


now comes a time where you'd want to add fragments...
if we add fragments:
1. go to frame 0, and the birthscript will evalute, getting the new fragments and storing it inside ChunksArray.
2. TM_reset is still false so this block of codes wont evalute::sad:
if TM_Reset do
(
Global ChunksArray_TM = for i in ChunksArray collect i.transform
TM_Reset = false
)
3. this will be the cause of chunks going crazy. basically because the data from the ChunksArray_TM is old, it is not updated, it has no transform info from the new ChunksArray collection...
4. the way to fix this is, go to the listener and type in TM_Reset = Undefined...
this way these lines will evaluate accoridngly:
if TM_Reset == undefined do TM_Reset = true
if TM_Reset do
(
Global ChunksArray_TM = for i in ChunksArray collect i.transform
TM_Reset = false
)

thats just it i suppose... whenever you want to add fragments, just make sure you reset the Transform information in ChunksArray_TM by setting the TM_reset to undefined...
this also goes with assigning new framents or boxes etc...

whew.. i hope this helps! (i hope im getting better at explaining stuff.. hehehe):thumbsup:

galagast
04-06-2005, 05:43 AM
hehe, hmm.. im not particularly sure about the "in" and the "=" being any different. although I usually use "in" in my for loops. :thumbsup: I wonder... i'll try and test some later.

im also doing the same thing, setting the playback to a non-realtime mode thus turning animate button on, so that we'd get keys animated for our chunks! hehe. :scream:

Largo39
04-06-2005, 02:00 PM
perhaps the "in" is a type of variable which has a set numerical limit (probably defined by how many verticies, considering the max particles i could do before it crashes was 100 compared to your 125 blocks).

sorta like the difference between an integer in c++ and a float or long.

CGTalk Moderation
04-06-2005, 02:00 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.