shatter help


#81

I will attach my hook to this thread.

Ignore me, but please continue. :slight_smile:


#82

hey sanctuary
that script looks amazing
just a simple questions, is it still usuable as a mel script?
like if you were to upload it now, would we be able to use it, because I have a project comming up, that deals with a lot of shattering and, a voronoui fracture seems to be the best was to destroy something.

Is it possible to upload it?


#83

right now its just a bunch of code scattered on my shelf ... it has a long way ahead before its production ready.

and some speed tests on a polyCube:


#84

well its not production production, its more of a student project.

but I hope sometimes soon, its ready to be used.
thanks alot


#85

Wow,

Good stuff in this thread.

I’m exploring shattering in Houdini, but I see new possibilities in Maya.

subscribed…


#86

is there a voronoi shatter script or otl for Houdini?


#87

Here is our first test illustrating secondary fracture events:

http://www.vimeo.com/3400941

Note that this is real-time and completely procedural.


#88

is that a fracture & RB dynamics plugin ? …

where can i sign-up for beta test :smiley:

meanwhile … here is my progress > http://vimeo.com/3399172


#89

I second Sanctuary
Is there any way we can get these scripts public, just to test it out.


#90

Is there any way we can get these scripts public, just to test it out.

Not yet.

But send me a mail at kevin@td-college.com if you would like to become a beta-tester in the future.


#91

Ill send an email
is it just for windows or all operating systems, cuz I work on a mac


#92

Awesome. Great work man… I hope to be able to actually use one of these solutions in the near future… I saw the 3D Based Voronoi fracturing that ILM uses with Zeno. It is pretty cool and interactive, all procedural texture based. This stuff is pretty sweet guys!

Kevin, you wrote me back but I’ve not received the NDA yet :smiley:


#93

man u just brought back my faith in maya :wink:

the script is so ****ing good :slight_smile: i wish i could test it too

cheers


#94

you will :slight_smile: but i need couple of days to finish rewriteing it in python because i need to have access to API


#95

Lol, i guess it seems that the voronoi algorithm is the new hotness these days. I too have made a particle based voronoi shatter, and im ditching booleans altogether:

I just have to clean the code up a bit and add a different material to the inside of the shards and its good to go.


#96

Eh Screw it, ill just post what I have so far. Keep in mind I still have cleaning up to do on this. So make a particle emitter, then a mesh (it has to be closded to work the best). Then select the particle and then the mesh and run this:

// Voronoi Shatter
    
    proc callVoronoi()
    {
    	// Variables
    	string $s[] = `ls -sl -fl`;
    	string $pRelatives[] = `listRelatives -s $s[0]`;
    	string $p = $pRelatives[0];
    	int $pCount = `getAttr ($p+".count")`;
    	string $obj = $s[1];
    	float $crackOffset = 0.002;
    	
    	$pTName = $s[0];
    	$pSName = $pRelatives[0];
    
    	string $objName = $s[1];
    
    	voronoiShatter($pTName, $pSName, $objName, $crackOffset);
    }
    callVoronoi();
    
    // The main voronoi shatter procedure
    proc voronoiShatter(string $pTName, string $pSName, string $objName, float $crackOffset)
    {
    undoInfo -state off;
    
    	// Create an empty group node to store shards
    	string $shardsGRP = `group -empty -n "shardsGRP"`;
    
    	// Hide particles
    	setAttr ($pTName + ".visibility") 0;
    
    	// Create cut block
    	string $cutBlock = voronoiCreateCutBlock($objName);
    
    	// Convert all the particles to locators
    	string $locGRP = voronoiParticlesToLocators($pSName);
    	setAttr ($locGRP + ".visibility") 0;
    	
    	// Get list of all locators under locator group
    	string $locators[] = `listRelatives -c -type transform $locGRP`;
    
    	// Go thru every locator and compare it to every other locator
    	// Find the midpoint, create shatter cube, and shatter
    	for($a=0;$a<size($locators);$a++)
    	{
    		// Store worldspace translate of a
    		float $aPos[] = `xform -q -ws -t $locators[$a]`;
    	
    		// Variable to store active shard mesh name
    		string $activeShard = "";
    	
    		// Duplicate mesh to shatter
    		string $dupMesh[] = `duplicate -rr $objName`;
    		setAttr ($objName + ".visibility") 0;
    		$activeShard = $dupMesh[0];
    		setAttr ($activeShard + ".visibility") 1;
    	
    		// Go thru each locator
    		for($b=0;$b<size($locators);$b++)
    		{
    			// Check that its not going to itself
    			if($a != $b)
    			{
    				// Store worldspace translate of b
    				float $bPos[] = `xform -q -ws -t $locators[$b]`;
    				
    				// Find the midpoint between locator A and locator B
    				vector $midPoint = <<(($aPos[0] + $bPos[0])/2), (($aPos[1] + $bPos[1])/2), (($aPos[2] + $bPos[2])/2)>>;
    	
    				// Convert to vectors
    				vector $aPosVector = {$aPos[0],$aPos[1],$aPos[2]};
    				vector $bPosVector = {$bPos[0],$bPos[1],$bPos[2]};
    	
    				// Calculate direction vector
    				vector $dir = $aPosVector - $midPoint;
    	
    				// Normalize
    				$dir = $dir / mag($dir);
    	
    				// Calculate new offset midpoint
    				vector $offMidPoint = $midPoint + ($crackOffset * $dir);
    	
    				// Create aim locator
    				string $aimLoc[] = `spaceLocator -p $bPos[0] $bPos[1] $bPos[2]`;
    				xform -cp $aimLoc[0];
    	
    				// Position cut block
    				string $cutCube[] = `duplicate -rr $cutBlock`;
    				setAttr ($cutCube[0] + ".visibility") 1;
    				setAttr ($cutCube[0] + ".translateX") ($offMidPoint.x);
    				setAttr ($cutCube[0] + ".translateY") ($offMidPoint.y);
    				setAttr ($cutCube[0] + ".translateZ") ($offMidPoint.z);
    	
    				// Aim cut cube
    				string $aimConstraint[] = `aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 1 0 -upVector 0 1 0 -worldUpType "vector" -worldUpVector 0 1 0 $aimLoc[0] $cutCube[0]`;
    				for($ac=0;$ac<size($aimConstraint);$ac++)
    				{
    					if(`objExists $aimConstraint[$ac]`)
    					{
    						delete $aimConstraint[$ac];
    					}
    				}
    	
    				// Cleanup
    				for($al=0;$al<size($aimLoc);$al++)
    				{
    					if(`objExists $aimLoc[$al]`)
    					{
    						delete $aimLoc[$al];
    					}
    				}
    	
    				// Do boolean
    				//string $newMesh[] = `polyBoolOp -op 2 -ch 0 $activeShard $cutCube[0]`;
    				
    				// Do Cut procedure
    				vector $cutBlockRot = `xform -q -ws -rotation $cutCube[0]`;
    				int $numFace[] = `polyEvaluate -f $activeShard`;
    				polyCut -ch off -df 1 -pc ($offMidPoint.x) ($offMidPoint.y) ($offMidPoint.z) -ro ($cutBlockRot.x + 90) ($cutBlockRot.y) ($cutBlockRot.z) ($activeShard + ".f[0:" + $numFace[0] + "]");
    				polyCloseBorder -ch 0 $activeShard;
    	
    				// Reset activeShard mesh variable to the new booleaned mesh
    				//$activeShard = $newMesh[0];
    
    				// Cleanup
    				if(`objExists $cutCube[0]`)
    				{
    					delete $cutCube[0];
    				}
    			}
    			else
    			{
    				//delete $dupMesh[0];
    			}
    		}
    
    		// Parent shard under group node
    		parent $activeShard $shardsGRP;
    	
    		// Refresh the viewport
    		//select -cl;
    		refresh();
    	}
    
    	// Delete the cut block
    	delete $cutBlock;
    
    undoInfo -state on;
    }
    
    
    // Creates the cut block
    proc string voronoiCreateCutBlock(string $objName)
    {
    	// Find the bounding box of obj
    	float $bbox[] = `exactWorldBoundingBox $objName`; 
    	float $biggestDimension = abs($bbox[3]-$bbox[0]); 
    	if (abs($bbox[4]-$bbox[1]) > $biggestDimension)
    	{ 
    		$biggestDimension = abs($bbox[4]-$bbox[1]); 
    	} 
    
    	if (abs($bbox[5]-$bbox[2]) > $biggestDimension)
    	{ 
    		$biggestDimension = abs($bbox[5]-$bbox[2]); 
    	}
    	
    	// Now that we have the biggest dimension, lets increase it a bit
    	$biggestDimension = $biggestDimension * 4;
    
    	// Create the cut block geometry and store its name
    	string $cutBlockCreate[] = `polyPlane -w 1 -h 1 -sx 1 -sy 1 -ax 0 1 0 -cuv 2 -ch 0 -n "cutBlock"`;
    	string $cutBlockName = $cutBlockCreate[0];
    
    	// Set the scale of the plane
    	setAttr ($cutBlockName + ".scaleX") $biggestDimension;
    	setAttr ($cutBlockName + ".scaleZ") $biggestDimension;
    
    	// Extrude the plane into a block
    	polyExtrudeFacet -ch 0 -ltz ($biggestDimension * 2) -smoothingAngle 0 ($cutBlockName+".f[0]");
    
    	// Freeze transforms
    	makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $cutBlockName;
    
    	// Hide the cut block
    	setAttr ($cutBlockName + ".visibility") 0;
    
    	select -cl;
    
    	return $cutBlockName;
    }
    
    
    
    // Converts particles to locators
    proc string voronoiParticlesToLocators(string $pName)
    {
    	// Create group to hold locators
    	string $pGRP = `group -empty -n "particleLocatorGrp"`;
    
    	// Get particle count
    	int $pCount = `getAttr ($pName + ".count")`;
    
    	// Go thru each particle
    	for($p=0;$p<$pCount;$p++)
    	{
    		// Store worldspace translate of each particle
    		float $pPos[] = `getParticleAttr -at worldPosition ($pName + ".pt[" + $p + "]")`;
    
    		// Create locator
    		string $pLoc[] = `spaceLocator -n "voronoiPoint_#"`;
    
    		// Set attributes
    		setAttr ($pLoc[0] + ".translateX") $pPos[0];
    		setAttr ($pLoc[0] + ".translateY") $pPos[1];
    		setAttr ($pLoc[0] + ".translateZ") $pPos[2];
    		setAttr ($pLoc[0] + ".scaleX") 0.1;
    		setAttr ($pLoc[0] + ".scaleY") 0.1;
    		setAttr ($pLoc[0] + ".scaleZ") 0.1;
    
    		// Parent locator
    		parent $pLoc[0] $pGRP;
    	}
    
    	// Return the locator group name
    	return $pGRP;
    }
    

Some things I’d like to improve:

Right now im setting the angle between 2 points using constraints. Not as elegant as I would like. Anyone know how to slim this code down and do it all with math instead of using maya nodes? It will help speed it up dramatically. Anyways Enjoy!


#97

I was about to ask how you were all intersecting the cells with the mesh, now I can just dissect your script. All these scripts popping up have kind of taken away my motivation to develop a script of my own though, but I should probably should anyway for the learning experience.


#98

actually the concept of it is pretty easy, once you see whats going on. :wink:


#99

Its all about learning and understanding for me :slight_smile: … I wrote my own simple shatter scripts because I couldn’t find something else to do the job however they’re quite limiting based on their core functionality.

AtrusDni: THANKS! I can’t wait to play with this stuff :slight_smile: … If I am able to help simplify or improve I’ll post my results back up here.

Seth


#100

Azshall, I have to give you credit. At first I was using booleans which were cumbersome at best (you can see from the script) but after thinking about it, I used your cut faces technique and its much faster, less error prone, and better overall.

I want to implement these features, if anyone could help out:

  1. I tried (but failed) at a method to remove all locators that are not inside the mesh. Having them way outside leaves like 3 poly meshes which dont work good.

  2. A way (through code only) to aim an object at another. I need the vector so I can input that into the cut plane. Right now its all constraint based, which is fine, but it’d be nicer to have it as code.

  3. Im thinking about how to assign a new shader to the interior faces, and I think if i query the total number of faces before fill hole, then fill the hole, I can use the total number of faces + 1 to assign a new shard shader to, and hopefully maya doesnt reorder the faces after the fill hole. If it does, then im out of ideas on how to find the newest created face. Any help there would be appreciated.

  4. Cant think of anything else at the moment, but any help would be appreciated :smiley:

Thanks guys.