Simple Fracture Script [v 1.01]

[9/09/10] : Version 1.01
Small update concerning Destroy Small After Time and the placement of the center of gravity of fractured objects.

[7/09/10] : Version 1.0
I’ve uploaded a first version of the script with a few more features than in the demo, including minimum dimensions and the ability to split jointed objects with realistic results (the joints are connected to the part they should be after breaking).

Try the demo (outdated) if you want.

Notes :

The biggest problem with this script right now is the way it ‘breaks’ objects; it clones the object, finds a plane based on user variables, and flattens all the points on the other side of the plane onto it, then repeats this with the clone and the other side of the plane. This way of doing things can lead to several different problems, mostly visual.

This method isn’t truly splitting the object, has bad effects on concave objects and textures, and also limits what else I can do with it.
The only real solution I can think of would be writing a new script that would work more like the boolean modifier in blender (and probably other modelers). If I did manage to make a boolean-type way for splitting the objects, It would open a lot of opportunities that could lead to an actual procedural destruction script. :slight_smile: Unfortunately, any way of truly dynamically breaking an object would be really slow, so I haven’t bothered with it at all. :?

To call fractures from a script :

SimpleFracture.FractureAtPoint(point : Vector3,force : Vector3)

Settings:

Fracture To Point : if enabled, the geometry will not be ‘flattened’ to the plane, but be moved to a single point on it, based on the average vertex position. The results aren’t that nice, but it’s a lot faster and eliminates most odd flattening effects from concave objects.

Total Max Fractures : The maximum amount of times an object can be divided. If it’s 1, it will split into a max of 2 pieces. If it’s 2, it will have 2 iterations of splitting at the most, so it will split into a max of 4 pieces. 3 is a max of 8 pieces, etc.
Every time the object is split, this number goes down by 1 for each piece, until it reaches zero.

Force Per Division : The amount of ‘force’ it takes for each division to occur. If you have a max of 3 divisions, and this is 20, then it will mean that any collision with a force bigger than 20 will split it into 2, over 40 into 4, and over 60 into 8 pieces.

Min Breaking Force : The minimum force required for the object to fracture. Objects won’t be fractured unless the collision ‘force’ is higher than this AND force per division. Example of use: if Force Per Division is 1, max fractures is 4, and this is 30, then any collision with a force < 30 will not fracture it, and anything higher will fracture it into 16 pieces.

Max Fractures Per Call : If this is smaller than Total Max Fractures, it is the maximum amount of fractures the object can be split into by a single collision.

Random Offset : The splitting plane from a collision is always on the point of collision (or center of the object, if Fracture At Center is true). However, when this value is higher than 0, it will move the splitting point by this value multiplied by a random InsideUnitSphere multiplied by the mesh’s bounds.

Min Fracture Size : If any of the dimensions of the mesh’s bounding box are smaller than the dimensions specified here, the object will be considered ‘too small’ to split, and the max fractures it can undergo is changed to 0. This can be useful for things like shards of wood: if you set max fractures to a very high number, the only thing stopping the objects from splitting is this.

Grain : The splitting plane of this script splits geometry on a plane with a random vector multiplied by this vector. If this vector is 0,1,0, then the splitting plane will always be on the xz axis (that is, the normal will always be on the z axis). If this is 1,1,0, then the z value of the plane’s normal will never be higher than 0; this means that it will only split in 2 dimensions, like a window breaking.

Use Collision Direction : Between 0 and 1. If this is set to 1, then the normal of the splitting plane will always be perpendicular to the relative velocity of the collision. The closer to 1 this is, the closer to being perpendicular to the relative velocity the splitting plane will be. (I’m bad at explaining these things, sorry.)

Fracture At Center : If true, the object will fracture at it’s center instead of on the collision point. Good for getting things to blow up, etc.

Smart Joints : If there is a joint component in this object and/or if this object is jointed by another object, whatever side of the plane the other body is on will still be connected, while the piece on the opposite side will be disconnected. If this is not on, all joints connected to the object in any way are eliminated upon breaking.

Destroy All After Time : If this isn’t 0, it’s the time after the first fracture until all objects are destroyed. The collider of the objects is destroyed 1 second before this, so that they don’t seem to just disappear instantly.

Destroy Small After Time : If not 0, this is the time after the final possible division of an object until it is destroyed. The collider of the objects is destroyed 1 second before this, so that they don’t seem to just disappear instantly.

Instantiate On Break : This will be instantiated the first time the object is broken.

Total Mass If Static : If the object is static, then all it’s pieces become rigidbodies after splitting. What THIS value does, is define the total mass of the object before it splits, if it doesn’t have a rigidbody attached. (Each time a piece splits, it’s mass is divided in half in each piece.)

If you need any more info, you can take a look at the code or send me a PM, I’ll try to respond as often as I can.

370801–13191–$simplefracture_163.js (9.21 KB)
370801--13192--$simplefracture_114.png

… why are you so awesome?

This was fun! :smile:

Just noticed that player can fly on the stuff it collects, jump by jumping on it. :smile:

I tried to do such thing too : Sawyer Windows game - IndieDB
Before this demo I tried to make sword slicing but I could not split mesh diagonally. I used bounds and vertices above that bound was flattened, same principle as your code. I had calculated angle and aligned splitter cube to that angle unfortunately bounds have always same position it doesn’t rotates and only bounds have contain function. It would be great if colliders have contain function.
Such style isn’t true splitting and if you cut human, you have many unnecessary plys and vertices pushed together, but I think may be such style will be more fast than procedural splitting, because you must create new vertices, triangles and uv arrays and in our style we copy already filled arrays.

You have used this liar splitting very well. :smile:
I noticed that it can’t cut some directions??

Look at this how beautifully cuts everything :slight_smile:

It can cut in any direction, but it also has a grain variable. The script cuts along a plane that goes through the point of contact (or center of the object if you check that setting, like the rocks in the example), and has a random normal. this normal is a random inside sphere vector, multiplied by a grain vector. what the grain variable does is let the user define in what direction they want the object to be sliced in more or less often. for example:

The glass has a grain of (1, 1, 0). This means that it will never split width-wise, but is just as likely to split in any other way.

the wood has a grain of (0.03, 1, 0.001). This means it will split way more one way than any other way. In this case, it splits width-wise, and the planes are still rotated slightly at random.

How are you flattening vertices diagonally?
I used bounds, on main object all vertices Y on top of the splitter cube’s bound was decreasing and if it was in splitter cube’s bound it stopped, on copied object everything was done contrariwise.

I use a plane (which can face any direction), and plane.GetSide.

and you increase or decrease vertices Y as I’m doing?

I move them toward the plane with vertsA[i] -= plane.GetDistanceToPoint(vertsA[i])*plane.normal;

Wow, the plane is amazing, I didn’t know this :slight_smile:

Awesome script! Add some flames and it will be the coolest explosion system available.

No flames, but I’m adding explosions to the example soon :slight_smile:

Can’t wait to see that

Nice!

First version of the script is up. If there are any problems with it, feel free to let me know.

Awesome! Downloading.

this rocks!

Now I can make some explosions look awesome!

Thanks a lot. Very smart script.