[Closed] Scripted material change when objects touch
Total MaxScript n00b just starting to dig through the Max reference and my MAXscript Essentials book. Here’s what I’m trying to do.
-Detect for intersection of objects (in my case I have a large array of small instanced geometry objects that will be intersected by another larger mesh object)
-If intersecting, change material of the small object to that of the larger object
-Once not intersecting anymore, change material back to the original material
Another way to think of it is like this:
I want to control the color and or material of individual LEDS that together make up a large LED array. I want to control the colors by using mesh objects that pass through the array causing the colors to be temporarily inhereted. This would allow me to simple create complex patterns and displays. Keep in mind the LED things is an example, my actual geometry is not as simple as that so calling intersection of bounding boxes is out.
Or maybe there is another way to go about the whole thing.
If I were to do this, I would have used Particle Flow for the LED array or at least for the testing. Checking whether an object is inside a complex mesh is not as trivial as you might think, but the upcoming Krakatoa 1.1 update which is supposed to be released tomorrow (not an April Fools joke!) will provide a bonus Krakatoa Geometry Test which does this very very fast using a kdtree acceleration structure. You can use Krakatoa in Evaluation mode for free and employ its PFlow operators as bonus tools inside of PFlow even if you don’t need the volumetric rendering features.
Using a simple Birth Script, you could place one particle at the pivot of every real LED instance, then use the new Krakatoa Geometry test to detect whether a particle is inside the control mesh and send to another event. A Script Operator would then take the Particle ID and change the material of the corresponding scene object accordingly. Alternatively, you could BUILD the LED array from particles and just switch the particle material, unless there is a specific reason you want to use instanced objects instead of particles.
These are just some ideas, and the Geometry Test operator is still not available, but if you feel this might be a good solution, you could probably wait 24 hours…
(EDIT: Tested it, worked like a charm after less than 5 minutes. I used an array of 100×20 particles for the leds and an extruded text shape for the control mesh.)
Another cool way would be to simply use a bitmap to control the lighting of the LEDs via PFlow. That would work with the simplest version of PFlow that ships with Max and a very little bit of Scripted Operators. Will see if I can prepare a quick example…
EDIT: I tested it and it sort of works with the bitmap approach, but it is not as precise as I expected. Also, if the control object is moved away, the particles will still try to find the closest point on the surface, thus acquiring the edge pixels. I used a checkerboard map so I got an extended tiling, but with a black border it might work well…
See attached Max 9 file.
another option is to abuse the Volume Select modifier, but you have to take care that it does, in fact, select your object correctly.
I can’t for the life of me remember how to get around the self-reference issue in script controllers nicely (would be good if that could get dropped, implosions of the max space/time-continuum through infinite self-references be darned), so the attached file (3ds Maxx 2008) uses a clone of the object for reference.
That clone has its faces selected by the intersecting volume by picking it as the geometry volume, and setting the selection method to ‘crossing’.
The clone is hidden as we won’t be using that.
The original object has a Material modifier added. The Material ID property of that modifier has a script controller that basically sets the Material ID as follows:
if no faces in the clone are selected, then Material ID 1 – grey
if some faces in the clone are selected, then Material ID 2 – blue
if all of the faces in the clone are selected, then Material ID 3 – green
if something went wrong in the script (it’s in a try/catch), then Material ID 4 – red
Not sure if it does what you’d need, though
Wow, thanks Bobo and ZeBoxx! I will check out your examples and report back. Two very different approaches but both looking promising. Thanks!
Well a completely different approach could also be taken and that is a distance based approach… Animate your intersection plane the way you’d like. Get the time per object where the intersection plane is closest to the object… that’s your toggle time.
Now if you have a blend material you could preset keyframes to animate on/off on frame 0 and further… now with the new found time you offset the keyframes of your objects. My approach does involve a bit more work (I think) but you have total control over how the animated textures should behave and not a constantly looping script in the background (which also means it doesn’t update automaticly!)
My 2 cents,
-Johan
Ok, here is a tutorial which explains how the Krakatoa Geometry Test can be used to create the effect.
http://www.franticfilms.com/software/support/krakatoa/using_krakatoa_geometry_test_operator.php
An evaluation version of Krakatoa 1.1 including the Krakatoa Geometry Test operator can be downloaded from our web page.
We just introduced an improvement to our algorithm which removes any leaking – in Krakatoa 1.0, a very small percent of particles could be left behind. I tested today with hundred million particles culled by various geometry objects including misformed ones and got ZERO leaks
😮 Bobo is the master. That is exactly what I’m looking for! I’ll give this a try. You example using PFlow was impressive and simple, I just wish it was more accurate and didn’t bog down in the upper frame numbers.
ZeBoox,
Your solution is clever as well. I plan to mess with it some more and see if I can script up a dynamic array of objects using the Vol select to control the intersections. I like that there is different material for when inside the volume! Cool.
I updated the tutorial once again a minute ago to show what happens if you do 5 million particles inside the volume. I am not sure what you mean with accurate, if the center of a particle is inside the volume, it will be detected. (PFlow does not deal with the meshes of the particles, just with their pivots). Of course, being history-dependent, going to higher frame counts will cause slowdowns, but you can drop a Cache operator in the global event, add one more zero to the memory limit and you will be able to scrub back and forth once pre-cached. If you are doing interactive updates like moving the volume, either go to frame 0 or disable the PFlow until ready.
Hey ZeBoxx,
I was playing some more with your example. At first I was trying out weak ref to get around the Self-Ref issue but then it dawned on me that I could use the referenced geometry as a proxy object for the Vol Selection. That being said. I am now realizing that I am in over my head when It comes to scripting this all up. So what I am going to try to do is create a script that creates an array of objects+ their proxies that have multiple Vol Selects so I can have a fixed number of “control” objects for them to interact with. Each Vol Select is assign a different control object in a user defined list via a gui.
So pick your control objects from the scene – Set the number of objects to create along the X and Y axis (no z needed at this point) – the script loops through creating the reqeusted number of objects and bingo… they can detect multiple control objects.
Sound good in theory anyway. I have some tuts to try before digging into this though. As I have yet to create a fully functioning script of any value by myself.
sounds pretty cool Good luck with it, if you need help, we’ll be here; Bobo’s approach is definitely worth a look as well if you don’t need the distinction between an intersection and an encapsulation; it should run much faster for these cases and be easier to set up