AWS Thinkbox Discussion Forums

First sample

Here’s the result of my endeavor last week–its a scene with cells populated by lipids. In reality, each cell has about 5 billion on the surface, but here each cell is 50K lipids. There are 25 cells in this scene. RAM usage was around 4GB. Rendertime was about 20min/frame. Heavy use of Krakatoa to populate and clone.

I want to implement the multi material to get some lipid variation. Also plan on getting them to spin on their pole axis.

The big green shapes or D2 receptors and proteins would need to lock and dock to. Is there maxscript access to get the position of a PRT particle that I could put into a position expression on a dummy object?

It’ll also be interesting to do a single cell and see how many lipids I can cram on there. I’m saving to PRT via keep apart and with that many particles it takes a while to save out.
dynamic_lipid_surface.mp4 (1.78 MB)

Looks exciting!

Is there scripting capability to retrieve the position of a particle loaded from a PRT loader? Something like PRTLOader.getParticlePos int
I need to link a dummy to a particle.

There is particle data access from both PRT files, and PRT objects (all of them, not just PRT Loader). However, due to the streaming nature of the beast, the access is not random, but sequential. However, there is a function to skip to particle N, so if you are interested in the Nth by index, it would be rather fast. But looking for a particle with a specific ID would require looping through all particles until you find it, and it would be rather slow.

I will prototype something and let you know.

The alternative would be to bake keyframes for your object instead of doing it dynamically.

I just set up a scripted controller in an object that moves two (or any number of) other objects to specific indices in the particle cloud. It works. but if you prefer to just run a script once that bakes the position to keyframes, and you don’t change the underlying motion often, that would be even easier to script.

The particle count doesn’t change so finding the Nth particle would be viable. The baking method would also be ok.

Here is the baking script:

macroScript BakeObjectTransformsFromPRT category:"Krakatoa Tools"
(
global BakeObjectTransformsFromPRT_Rollout
try(destroyDialog BakeObjectTransformsFromPRT_Rollout)catch()
rollout BakeObjectTransformsFromPRT_Rollout "Bake Object Transforms To PRT"
(
	local thePRTTarget = undefined
	local theSourceObject = undefined
	fn pickPRT obj = (
		local theInt = FranticParticles.GetPRTObjectIStream obj false false
		if theInt != undefined then 
		(
			theInt.close()
			true
		)
		else false
	)
	pickbutton btn_PRTSystem "Target PRT Object" width:200 align:#center filter:pickPRT autoDisplay:true
	pickbutton btn_objectToBake "Source Object To Bake" width:200 align:#center autoDisplay:true
	spinner spn_targetIndex "Target Index:" range:[1,1000,1] type:#integer fieldwidth:50 align:#right
	checkbox chk_orientByNormal "Align Z to Normal" checked:false
	button btn_bake "BAKE!" width:200 height:30 align:#center 
	
	on btn_PRTSystem picked obj do 
	(
		if obj != undefined do 
		(
			thePRTTarget = obj
			local theInt = FranticParticles.GetPRTObjectIStream thePRTTarget true false
			spn_targetIndex.range = [1,theInt.getCount(),spn_targetIndex.value]
			theInt.close()
		)
	)
	on btn_objectToBake picked obj do if obj != undefined do theSourceObject = obj
	on btn_bake  pressed do
	(
		local theInt = FranticParticles.GetPRTObjectIStream thePRTTarget true false
		local theChannels = theInt.getChannels()
		
		local posIndex = 0
		for i = 1 to theChannels.count where matchPattern theChannels[i] pattern:"Position *" do posIndex = i
		local normalIndex = 0
		for i = 1 to theChannels.count where matchPattern theChannels[i] pattern:"Normal *" do normalIndex = i
		
		theInt.close()
		if posIndex > 0 do
		(
			local targetParticleIndex = spn_targetIndex.value
			for t = animationRange.start to animationRange.end do
			(
				at time t with animate on 
				(
					local theInt = FranticParticles.GetPRTObjectIStream thePRTTarget true false
					if targetParticleIndex <= theInt.getCount() do
					(
						theInt.skipParticles (targetParticleIndex-1)
						local theParticle = theInt.readParticle()
						theSourceObject.pos = theParticle[posIndex]
						if chk_orientByNormal.checked and normalIndex > 0 do 
						(
							local theNormal = theParticle[normalIndex]
							local upVector = [0,0,1]
							if theNormal == [0,0,1] do upVector = [1,0,0]
							theX = normalize (cross theNormal upVector	)
							theY = normalize (cross theX theNormal)
							theSourceObject.transform = matrix3 theX theY theNormal theParticle[posIndex]
						)
					)
					theInt.close()
				)
			)
		)
	)
)--end rollout
createDialog BakeObjectTransformsFromPRT_Rollout 220 140 
)--end script

I could expand it to work by ID if you want, should be trivial, but it will make it slower as it would have to loop through all particles until it finds the ID. Now it just skips the first N-1 particles and reads the Nth.

Awesome, I’ll give it a whirl. Hope to get a new build out before the weekend?

Yes! We should have a new build for you by the end of the week.

Privacy | Site terms | Cookie preferences