LScript (Modeler) to offsets vertices based on chosen parameters such as noise and Brownian motion.
Changes
- Seeded noise
- Seeded fractal Brownian motion
- Added control reset
- Realtime Preview
Compatible with Newtek LightWave 9.6 and above.
// LScript Modeler - www.StephenCulley.co.uk
//
// web address: http://www.stephenculley.co.uk
// email address: email@stephenculley.co.uk
/*
LScript Modeler - Jitter
Modeler_Jitter.ls
*/
@version 2.2
@warnings
@script modeler
@name *Jitter
// Title
sTitle = "*Jitter";
// Version
sVersion = "v2.0";
bDone = false; // Done
bChange = false; // Change
bPreview; // Preview
iType;
bAxisX;
bAxisY;
bAxisZ;
nAmplitude;
iOctaves;
nPersistence;
vScale;
iSeed;
iInterpolation;
ctrl_c0,ctrl_c1,ctrl_c2,ctrl_c3,ctrl_c4,ctrl_c5,ctrl_c6,ctrl_c7,ctrl_c8,ctrl_c9;
ctrl_res0;
ctrl_prev0;
main
{
// Recall
bPreview = recall("bPreview",true);
iType = recall("iType",2);
bAxisX = recall("bAxisX",true);
bAxisY = recall("bAxisY",true);
bAxisZ = recall("bAxisZ",true);
nAmplitude = recall("nAmplitude",0.1);
iOctaves = recall("iOctaves",3);
nPersistence = recall("nPersistence",0.25);
vScale = recall("vScale",<1.0,1.0,1.0>);
iSeed = recall("iSeed",1);
iInterpolation = recall("iInterpolation",3);
reqbegin(sTitle + " " + sVersion);
// Reset / Preview
ctrl_res0 = ctlbutton("Reset",50,"button_reset"); // Button Reset
ctrl_prev0 = ctlcheckbox("Preview",bPreview); // Preview
ctlsep();
// Control
ctrl_c0 = ctlchoice("Type",iType,@"Noise","fBm"@); // Type
ctrl_c1 = ctlcheckbox("X",bAxisX); // X
ctrl_c2 = ctlcheckbox("Y",bAxisY); // Y
ctrl_c3 = ctlcheckbox("Z",bAxisZ); // Z
ctrl_c4 = ctldistance("Amplitude",nAmplitude); // Amplitude
ctrl_c5 = ctlslider("Octaves",iOctaves,1,64); // Octaves
ctrl_c6 = ctlnumber("Persistence",nPersistence); // Persistence
ctrl_c7 = ctlvector("Scale",vScale); // Scale
ctrl_c8 = ctlinteger("Seed",iSeed); // Seed
ctrl_c9 = ctlchoice("Interpolation",iInterpolation,@"None","Linear","Cosine"@); // Interpolation
// Developer
ctlsep();
ctrl_dev0 = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk");
process(); // Process
// Refresh
ctlrefresh(ctrl_prev0,"refresh");
ctlrefresh(ctrl_c0,"refresh");
ctlrefresh(ctrl_c1,"refresh");
ctlrefresh(ctrl_c2,"refresh");
ctlrefresh(ctrl_c3,"refresh");
ctlrefresh(ctrl_c4,"refresh");
ctlrefresh(ctrl_c5,"refresh");
ctlrefresh(ctrl_c6,"refresh");
ctlrefresh(ctrl_c7,"refresh");
ctlrefresh(ctrl_c8,"refresh");
ctlrefresh(ctrl_c9,"refresh");
if (!reqpost())
{
// Cancel
if(bDone){undo();} // Undo
return;
}
else
{
// Ok
if(!bDone || bChange) // Process
{
values(); // Values
process(); // Process
}
// Store
store("bPreview",bPreview);
store("iType",iType);
store("bAxisX",bAxisX);
store("bAxisY",bAxisY);
store("bAxisZ",bAxisZ);
store("nAmplitude",nAmplitude);
store("iOctaves",iOctaves);
store("nPersistence",nPersistence);
store("vScale",vScale);
store("iSeed",iSeed);
store("iInterpoltation",iInterpolation);
}
reqend();
}
refresh:value
{
bChange = true; // Change
values(); // Values
if(bPreview){process();} // Process
}
values
{
bPreview = getvalue(ctrl_prev0); // Preview
iType = getvalue(ctrl_c0); // Type
bAxisX = getvalue(ctrl_c1); // X
bAxisY = getvalue(ctrl_c2); // Y
bAxisZ = getvalue(ctrl_c3); // Z
nAmplitude = getvalue(ctrl_c4); // Amplitude
iOctaves = getvalue(ctrl_c5); // Octaves
nPersistence = getvalue(ctrl_c6); // Persistence
vScale = getvalue(ctrl_c7); // Scale
iSeed = getvalue(ctrl_c8); // Seed
iInterpolation = getvalue(ctrl_c9); // Interpolation
}
button_reset
{
setvalue(ctrl_c0,2); // Type
setvalue(ctrl_c1,true); // X
setvalue(ctrl_c2,true); // Y
setvalue(ctrl_c3,true); // Z
setvalue(ctrl_c4,0.1); // Amplitude
setvalue(ctrl_c5,3); // Octaves
setvalue(ctrl_c6,0.25); // Persistence
setvalue(ctrl_c7,<1.0,1.0,1.0>); // Scale
setvalue(ctrl_c8,1); // Seed
setvalue(ctrl_c9,3); // Interpolation
}
process
{
// Undo
if(bDone){undo();}
undogroupbegin();
// Process
// Selection - Point (DIRECT)
selmode(DIRECT);
iPointCount = pointcount();
if(iPointCount < 1) error("No points selected.");
noiseseed(iSeed); // Noise Seed
for(iO = 1; iO <= 3; iO++)
{
aOffset[iO] = ;
}
editbegin();
if((iType == "1") && (iInterpolation == 1)) // Noise
{
moninit(iPointCount,"Processing..."); // Progress Monitor
for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
{
vOffset = <0.0,0.0,0.0>;
vPoint = pointinfo(points[iCurrentPoint]) * vScale;
if(bAxisX){vOffset.x = noise3D(vPoint + aOffset[1]);}
if(bAxisY){vOffset.y = noise3D(vPoint + aOffset[2]);}
if(bAxisZ){vOffset.z = noise3D(vPoint + aOffset[3]);}
pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point
monstep(); // Progress Monitor
}
monend(); // Progress Monitor
}
else if((iType == "1") && (iInterpolation == 2)) // Linear Noise
{
moninit(iPointCount,"Processing..."); // Progress Monitor
for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
{
vOffset = <0.0,0.0,0.0>;
vPoint = pointinfo(points[iCurrentPoint]) * vScale;
if(bAxisX){vOffset.x = linearnoise3D(vPoint + aOffset[1]);}
if(bAxisY){vOffset.y = linearnoise3D(vPoint + aOffset[2]);}
if(bAxisZ){vOffset.z = linearnoise3D(vPoint + aOffset[3]);}
pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point
monstep(); // Progress Monitor
}
monend(); // Progress Monitor
}
else if((iType == "1") && (iInterpolation == 3)) // Cosine Noise
{
moninit(iPointCount,"Processing..."); // Progress Monitor
for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
{
vOffset = <0.0,0.0,0.0>;
vPoint = pointinfo(points[iCurrentPoint]) * vScale;
if(bAxisX){vOffset.x = cosinenoise3D(vPoint + aOffset[1]);}
if(bAxisY){vOffset.y = cosinenoise3D(vPoint + aOffset[2]);}
if(bAxisZ){vOffset.z = cosinenoise3D(vPoint + aOffset[3]);}
pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point
monstep(); // Progress Monitor
}
monend(); // Progress Monitor
}
else if((iType == "2") && (iInterpolation == 1)) // fBm Noise
{
moninit(iPointCount,"Processing..."); // Progress Monitor
for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
{
vOffset = <0.0,0.0,0.0>;
vPoint = pointinfo(points[iCurrentPoint]) * vScale;
if(bAxisX){vOffset.x = fBmnoise3D(vPoint + aOffset[1],iOctaves,nPersistence);}
if(bAxisY){vOffset.y = fBmnoise3D(vPoint + aOffset[2],iOctaves,nPersistence);}
if(bAxisZ){vOffset.z = fBmnoise3D(vPoint + aOffset[3],iOctaves,nPersistence);}
pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point
monstep(); // Progress Monitor
}
monend(); // Progress Monitor
}
else if((iType == "2") && (iInterpolation == 2)) // Linear fBm Noise
{
moninit(iPointCount,"Processing..."); // Progress Monitor
for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
{
vOffset = <0.0,0.0,0.0>;
vPoint = pointinfo(points[iCurrentPoint]) * vScale;
if(bAxisX){vOffset.x = linearfBmnoise3D(vPoint + aOffset[1],iOctaves,nPersistence);}
if(bAxisY){vOffset.y = linearfBmnoise3D(vPoint + aOffset[2],iOctaves,nPersistence);}
if(bAxisZ){vOffset.z = linearfBmnoise3D(vPoint + aOffset[3],iOctaves,nPersistence);}
pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point
monstep(); // Progress Monitor
}
monend(); // Progress Monitor
}
else if((iType == "2") && (iInterpolation == 3)) // Cosine fBm Noise
{
moninit(iPointCount,"Processing..."); // Progress Monitor
for(iCurrentPoint = 1; iCurrentPoint <= iPointCount; iCurrentPoint++)
{
vOffset = <0.0,0.0,0.0>;
vPoint = pointinfo(points[iCurrentPoint]) * vScale;
if(bAxisX){vOffset.x = cosinefBmnoise3D(vPoint + aOffset[1],iOctaves,nPersistence);}
if(bAxisY){vOffset.y = cosinefBmnoise3D(vPoint + aOffset[2],iOctaves,nPersistence);}
if(bAxisZ){vOffset.z = cosinefBmnoise3D(vPoint + aOffset[3],iOctaves,nPersistence);}
pointmove(points[iCurrentPoint],pointinfo(points[iCurrentPoint]) + (vOffset * nAmplitude)); // Move point
monstep(); // Progress Monitor
}
monend(); // Progress Monitor
}
editend();
// Undo
undogroupend();
bChange = false; // Change
// Done
bDone = true;
}
// INTERPOLATION
linear1D: n1,n2,i // i = interpolation point (0-1)
{
return(n1 * (1 - i) + n2 * i);
}
cosine1D: n1,n2,i // i = interpolation point (0-1)
{
i2 = (1 - cos(i * 3.1415926535)) * 0.5;
return(n1 * (1 - i2) + n2 * i2);
}
// NOISE
_noiseseed = 1;
_noiseresolution = 512;
_noise = nil;
_noiseoffset = nil;
_noiseperm = nil;
noiseinit
{
randomseed(_noiseseed); // Random Seed
for(iN = 1; iN <= _noiseresolution; iN++)
{
_noise[iN] = (random() * 2) - 1; // -1.0..1.0
_noiseperm[iN] = wrap(1,_noiseresolution,integer(random() * _noiseresolution));
}
for(iO = 1; iO <= 64; iO++)
{
_noiseoffset[iO] = ;
}
}
noiseseed: seed
{
_noiseseed = seed;
noiseinit(); // Init
}
noiseresolution: resolution
{
_noiseresolution = resolution;
noiseinit(); // Init
}
noiseperm1D: n // i
{
// ! if(_noiseperm == nil){noiseinit();} // Init
return(_noiseperm[wrap(1,_noiseresolution,integer(n))]);
}
noiseperm2D: v // n
{
return(noiseperm1D(v.y + noiseperm1D(v.x)));
}
noiseperm3D: v // n
{
return(noiseperm1D(v.z + noiseperm2D(v)));
}
noise3D: v // n
{
// ! if(_noise == nil){noiseinit();} // Init
return(_noise[noiseperm3D(v)]);
}
linearnoise3D: v // n
{
v = wrap(1,_noiseresolution,v);
vFrac = frac(v);
vInt = v - vFrac;
nA1 = noise3D();
nA2 = noise3D();
nA3 = noise3D();
nA4 = noise3D();
nA = linear1D(linear1D(nA1,nA2,vFrac.x),linear1D(nA3,nA4,vFrac.x),vFrac.z);
nB1 = noise3D();
nB2 = noise3D();
nB3 = noise3D();
nB4 = noise3D();
nB = linear1D(linear1D(nB1,nB2,vFrac.x),linear1D(nB3,nB4,vFrac.x),vFrac.z);
return(linear1D(nA,nB,vFrac.y));
}
cosinenoise3D: v // n
{
v = wrap(1,_noiseresolution,v);
vFrac = frac(v);
vInt = v - vFrac;
nA1 = noise3D();
nA2 = noise3D();
nA3 = noise3D();
nA4 = noise3D();
nA = cosine1D(cosine1D(nA1,nA2,vFrac.x),cosine1D(nA3,nA4,vFrac.x),vFrac.z);
nB1 = noise3D();
nB2 = noise3D();
nB3 = noise3D();
nB4 = noise3D();
nB = cosine1D(cosine1D(nB1,nB2,vFrac.x),cosine1D(nB3,nB4,vFrac.x),vFrac.z);
return(cosine1D(nA,nB,vFrac.y));
}
fBmnoise3D: v,octaves,persistence // octaves = i | persistence = n (0.25) // n
{
// ! if(_noiseoffset == nil){noiseinit();} // Init
nNoise = 0.0;
for(iO = 1; iO <= octaves; iO++)
{
nNoise += noise3D(<(v.x + _noiseoffset[iO].x) * (2 * iO),(v.y + _noiseoffset[iO].y) * (2 * iO),(v.z + _noiseoffset[iO].z) * (2 * iO)>) * (persistence / iO);
}
return(nNoise);
}
linearfBmnoise3D: v,octaves,persistence // octaves = i | persistence = n (0.25) // n
{
// ! if(_noiseoffset == nil){noiseinit();} // Init
nNoise = 0.0;
for(iO = 1; iO <= octaves; iO++)
{
nNoise += linearnoise3D(<(v.x + _noiseoffset[iO].x) * (2 * iO),(v.y + _noiseoffset[iO].y) * (2 * iO),(v.z + _noiseoffset[iO].z) * (2 * iO)>) * (persistence / iO);
}
return(nNoise);
}
cosinefBmnoise3D: v,octaves,persistence // octaves = i | persistence = n (0.25) // n
{
// ! if(_noiseoffset == nil){noiseinit();} // Init
nNoise = 0.0;
for(iO = 1; iO <= octaves; iO++)
{
nNoise += cosinenoise3D(<(v.x + _noiseoffset[iO].x) * (2 * iO),(v.y + _noiseoffset[iO].y) * (2 * iO),(v.z + _noiseoffset[iO].z) * (2 * iO)>) * (persistence / iO);
}
return(nNoise);
}
// RANDOM
_randomseed = 0; // n Seed
randomseed: seed
{
_randomseed = seed;
}
random
{
n = (_randomseed * 214013 + 2531011) % 2^^24;
_randomseed = n;
n /= 2^^24; // 0..1
return(n);
}
gaussianrandom
{
n1 = random();
n2 = random();
if(n1 == 0.0){n1 = 0.01;}
return(sqrt(-2.0 * log(n1)) * cos(2.0 * 3.1415926535 * n2));
}
// WRAP
wrap: min,max,n
{
n = n - floor((n - min) / (max - min)) * (max - min);
if(n < 0) n = n + max - min; // error check
return(n);
}
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs
You have many great tools. Thank you for sharing your work.
ReplyDelete