|
 |
I used claude.ai to create the following disintegration macro. I really was
just curious if it even knew POVRay, and it turns out it knows it REALLY WELL!
This was the last piece I needed for a very large animation I'm working on for a
music video. Whatever your opinion on AI coding, I gotta say this is damn good
code (I've been a professional programmer for >40 years). Only thing I added
was the optional debug outputs.
Wanted to give it back to the community.
-- Emory
-----
// disintegrate.inc -- tear a solid object apart and blow it along a vector
// POV-Ray 3.7+. Stateless: everything is computed from T, so it animates with
clock.
//
// Disintegrate(Obj, Dir, Step, T, Start, Sweep, Jitter, Life, Min_Scale, Speed,
Spread, Spin, Accel, Seed, Cut_Tex, Shards)
//
// Obj a declared, finite, SOLID object (#declare Obj = ...). Its texture
is kept on the pieces.
// Dir direction the pieces travel; the tear starts at the downstream end
and sweeps back
// Step size of the cubic cells the object is cut into (smaller = more,
finer pieces) -- but also the slice thickness along Dir
// T current time in seconds (e.g. clock * 4)
// Start time the tearing begins
// Sweep seconds for the tear front to cross the whole object
// Jitter random extra delay per piece in seconds (ragged, uneven tearing)
// Life seconds over which a piece shrinks from full size to nothing after
release
// Min_Scale a piece is not drawn once its scale (1 at release, 0 at Life) is
<= this value
// (e.g. 0.05); use 0 to draw until the piece reaches zero size
// Speed average launch speed along Dir (units/sec)
// Spread sideways scatter, as a fraction of Speed (0 = straight, 0.5 = very
chaotic)
// Spin tumble rate in degrees/sec
// Accel constant acceleration vector, e.g. <0,-3,0> for gravity or Dir*2
for wind
// Seed integer random seed
// Cut_Tex texture for the faces created by cutting (and for plain cubes when
Shards = 0)
// Shards 1 = pieces are the real object cut into cubes (keeps its shape and
texture)
// 0 = plain cubes using Cut_Tex (much faster to render)
//
// This code was written by claude.ai, prompted by Emory Stagmer (aka
VAXHeadroom)
// October 2026
//
#ifndef (DISINTEGRATE_DEBUG)
#declare DISINTEGRATE_DEBUG=false;
#end
#declare DISINTEGRATE_DEBUG_2=false;
#include "math.inc" // for clamp()
#macro Disintegrate(Obj, Dir, Step, T, Start, Sweep, Jitter, Life, Min_Scale,
Speed, Spread, Spin, Accel, Seed, Cut_Tex, Cut_Int, Shards)
#local Dn = vnormalize(Dir);
#local Pmin = min_extent(Obj);
#local Pmax = max_extent(Obj);
#local H = Step / 2;
// Extent of the object measured along Dir
#local Smin = 1e9;
#local Smax = -1e9;
#for (C, 0, 7)
#local Q = <(mod(C,2) = 0 ? Pmin.x : Pmax.x),
(mod(floor(C/2),2) = 0 ? Pmin.y : Pmax.y),
(C < 4 ? Pmin.z : Pmax.z)>;
#local Smin = min(Smin, vdot(Q, Dn));
#local Smax = max(Smax, vdot(Q, Dn));
#end
#local Range = max(Smax - Smin, 0.0001);
// 1) The part of the object the tear front hasn't reached yet
#local Front = Smax + 0.001 - clamp((T - Start) / Sweep, 0, 1) * Range;
#if ((T - Start) < Sweep) // once the front has crossed the object, nothing
intact remains
intersection {
object { Obj }
plane { Dn, Front }
texture { Cut_Tex } // only used on the cut face
}
#end
#if( DISINTEGRATE_DEBUG )
#debug concat("DI: Pmin:<",str(Pmin.x,4,4), ",", str(Pmin.y,4,4), ",",
str(Pmin.z,4,4),">\n")
#debug concat("DI: Pmax:<",str(Pmax.x,4,4), ",", str(Pmax.y,4,4), ",",
str(Pmax.z,4,4),">\n")
#debug concat("DI: Front: ",str(Front,4,4),"\n")
#debug concat("DI: Smin: ",str(Smin,4,4),"\n")
#debug concat("DI: Smax: ",str(Smax,4,4),"\n")
#debug concat("DI: Range: ",str(Range,4,4),"\n")
#debug concat("DI: T : ",str(T,4,0),"\n")
#debug concat("DI: Start: ",str(Start,4,0),"\n")
#debug concat("DI: Sweep: ",str(Sweep,4,0),"\n")
#end
// 2) The flying pieces
#local R = seed(Seed);
#local Nx = int(ceil((Pmax.x - Pmin.x) / Step));
#local Ny = int(ceil((Pmax.y - Pmin.y) / Step));
#local Nz = int(ceil((Pmax.z - Pmin.z) / Step));
#for (Ix, 0, Nx-1)
#for (Iy, 0, Ny-1)
#for (Iz, 0, Nz-1)
#local P = Pmin + <Ix + 0.5, Iy + 0.5, Iz + 0.5> * Step;
#if (Shards)
// Real shards: every cell is intersected with the object. Cells that
lie
// outside it come out empty, so no inside() test is needed.
#local Hit = 1;
#else
// Plain cubes: keep cells whose centre or any corner is inside the
object
#local Hit = inside(Obj, P);
#for (C, 0, 7)
#if (Hit = 0)
#local Hit = inside(Obj, P + <mod(C,2) - 0.5, mod(floor(C/2),2) -
0.5, floor(C/4) - 0.5> * Step * 0.98);
#end
#end
#end
#if (Hit)
#local U = (Smax - vdot(P, Dn)) / Range; // 0 = downstream end,
1 = upstream end
#local Tr = Start + U*Sweep + rand(R)*Jitter; // release time
#local Vsp = Speed * (0.5 + rand(R));
#local Jt = <rand(R) - 0.5, rand(R) - 0.5, rand(R) - 0.5> * 2;
#local Rt = <rand(R) - 0.5, rand(R) - 0.5, rand(R) - 0.5> * 2 * Spin;
#local Age = T - Tr;
#local Sc = 1 - Age/Life; // 1 at release, 0 at
Life
#if( DISINTEGRATE_DEBUG_2 & Ix=0 & Iy=0)
#debug concat("DI: Age : ",str(Age,4,4),"\n")
#debug concat("DI: Sc : ",str(Sc,4,4),"\n")
#debug concat("DI: Min_Scale : ",str(Min_Scale,4,4),"\n")
#end
#if ((Age >= 0) & (Sc > Min_Scale))
#local Off = (Dn*Vsp + Spread*Speed*Jt) * Age + 0.5*Accel*Age*Age;
#if (Shards)
intersection {
box { P - <H,H,H>, P + <H,H,H> }
object { Obj }
texture { Cut_Tex }
//interior { Cut_Int }
translate -P
scale Sc
rotate Rt * Age
translate P + Off
}
#else
box {
<-H,-H,-H>, <H,H,H>
texture { Cut_Tex }
scale Sc
rotate Rt * Age
translate P + Off
}
#end
#end
#end
#end
#end
#end
#end
Post a reply to this message
|
 |
|
 |
I was curious and still am, but after 15 minutes of trial and error I didn't get
any result.
Do you have a working example?
Without it, such code snippets with dozens of macro parameters are rather
useless.
The last of my attempts:
#local oTest = sphere { 0,1 translate y*0 pigment { color rgb <1,1,0> } }
#local txCut = texture { pigment { color rgb <1,0,1> } }
//Disintegrate(Obj, Dir, Step, T, Start, Sweep, Jitter, Life, Min_Scale, Speed,
Spread, Spin, Accel, Seed, Cut_Tex, Cut_Int, Shards)
Disintegrate(oTest, <0,1,0>, 100, 1.3, 2, 3, 5, 100, 0.1, 0.1, 5, 20, <0,1,0>,
7, txCut, 10, 100)
m
Post a reply to this message
Attachments:
Download 'disintegrate.png' (9 KB)
Preview of image 'disintegrate.png'

|
 |
|
 |
Am 27.10.26 um 12:38 schrieb Maetes:
> I was curious and still am, but after 15 minutes of trial and error I didn't get
> any result.
> Do you have a working example?
> Without it, such code snippets with dozens of macro parameters are rather
> useless.
>
> The last of my attempts:
>
> #local oTest = sphere { 0,1 translate y*0 pigment { color rgb <1,1,0> } }
> #local txCut = texture { pigment { color rgb <1,0,1> } }
>
> //Disintegrate(Obj, Dir, Step, T, Start, Sweep, Jitter, Life, Min_Scale, Speed,
> Spread, Spin, Accel, Seed, Cut_Tex, Cut_Int, Shards)
>
> Disintegrate(oTest, <0,1,0>, 100, 1.3, 2, 3, 5, 100, 0.1, 0.1, 5, 20, <0,1,0>,
> 7, txCut, 10, 100)
>
> m
If you are interested in a working explode-macro you may have a look at
a very old code by Chris Colefax:
https://geocities.restorativland.org/SiliconValley/Lakes/1434/explode.html
Example code is given there. Thanks to Cousin Ricky for for digging up
the link.
Best regards from 200 km to the southeast,
Michael
Post a reply to this message
|
 |