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