LScript (Layout) to make desk draws and filling cabinets move dynamically in relation to being in an earthquake, it ended up being one of my most used scripts, making objects slide from one place to another fixed along an axis such as a sliding mechanism inside of an office desk draw or the slider a keyboard rests upon. It reacts dynamically as its parents object moves and is baked to curves. Use Master_MotionBaker script to bake motions. *Master_MotionBaker compatible.
Changes
- *Motion Baking implemented for quicker playback and network baking
- Gizmo implemented to improve setting up
- Added Lock / Unlock
- Bake feature can now be used via Master_MotionBaker
- Fixed Threshold bug
- Fixed judder resulting from an equation flipping in unexpected circumstance
- Replaced stabilizer with Damping
Compatible with Newtek LightWave 9.6 and above.
// LScript Item Animation - www.StephenCulley.co.uk // // web address: http://www.stephenculley.co.uk // email address: email@stephenculley.co.uk /* LScript Item Animation - Slider Motion_Slider.ls */ @version 2.2 @warnings @script motion @name *Slider // Title sTitle = "*Slider"; // Version sVersion = "v1.0"; // Item Item = nil; // Constant Scene; // Scene() // Variable aChannel = @"X","Y","Z"@; iChannel = 1; // Channel iIteration = 0; // Iteration vnGravity = <0.0,-1.0,0.0>; // Gravity // Envelope envDamping; // Damping envFriction; // Friction envMass; // Mass envMax; // Max envMin; // Min envMotionBaker; // Motion Baker envParentMotion; // Parent Motion envRandom; // Random envThreshold; // Threshold // Cache aCache; // [1] = i Frame // [2] = n time // [3] = n Position // [4] = n Momentum - // [5] = n Momentum + // [6] = v Parent World Position // [7] = n Parent Momentum +/- // Motion Baker bMotionBakerLocked = false; // Locked bMotionBakerParent = false; // Parent iMotionBakerState = 2; // State // 1 = Disabled // 2 = Reset // 3 = Write // 4 = Read // Requester bRequesterUpdate = false; // Update iRequesterFrame = -1; // Frame ctrl_d0,ctrl_d1,ctrl_d1e,ctrl_d2v,ctrl_d2,ctrl_d2e,ctrl_d3v,ctrl_d3,ctrl_d3e,ctrl_d4,ctrl_d4e, ctrl_d5,ctrl_d5e,ctrl_d6,ctrl_d6e,ctrl_d7,ctrl_d7e,ctrl_d8,ctrl_d8e,ctrl_d9,ctrl_d10,ctrl_d11; // Dynamics ctrl_mb,ctrl_mbe,ctrl_mbl; // Motion Baker /* --------------------------------------------------------------------------------------------------- CREATE --------------------------------------------------------------------------------------------------- */ create: obj { // Item Item = obj; // Constant Scene = Scene(); // Description setdesc(sTitle + " - Channel " + aChannel[iChannel]); // Envelope envDamping = Envelope("Damping (" + sTitle + ")",CHAN_NUMBER,Item.name); // Damping envDamping.persist(false); envDamping.createKey(0,0.8); envFriction = Envelope("Friction (" + sTitle + ")",CHAN_NUMBER,Item.name); // Friction envFriction.persist(false); envFriction.createKey(0,0.25); envMass = Envelope("Mass (" + sTitle + ")",CHAN_NUMBER,Item.name); // Mass envMass.persist(false); envMass.createKey(0,0.05); envMax = Envelope("Max (" + sTitle + ")",CHAN_NUMBER,Item.name); // Max envMax.persist(false); envMax.createKey(0,1.0); envMin = Envelope("Min (" + sTitle + ")",CHAN_NUMBER,Item.name); // Min envMin.persist(false); envMin.createKey(0,-1.0); envMotionBaker = Envelope("Motion Baker (" + sTitle + ")",CHAN_NUMBER,Item.name); // Motion Baker envMotionBaker.persist(false); envParentMotion = Envelope("Parent Motion (" + sTitle + ")",CHAN_NUMBER,Item.name); // Parent Motion envParentMotion.persist(false); envParentMotion.createKey(0,1.0); envRandom = Envelope("Random (" + sTitle + ")",CHAN_NUMBER,Item.name); // Random envRandom.persist(false); envRandom.createKey(0,0.0); envThreshold = Envelope("Threshold (" + sTitle + ")",CHAN_NUMBER,Item.name); // Threshold envThreshold.persist(false); envThreshold.createKey(0,9.8); // Cache aCache[1] = -1; // Frame aCache[2] = 0.0; // Time aCache[3] = 0.0; // Position aCache[4] = 0.0; // Momentum - aCache[5] = 0.0; // Momentum + aCache[6] = <0.0,0.0,0.0>; // Parent World Position aCache[7] = 0.0; // Parent Momentum // Comring comringattach("*MotionBaker","comring_motionbaker"); // Comring *MotionBaker } /* --------------------------------------------------------------------------------------------------- DESTROY --------------------------------------------------------------------------------------------------- */ destroy { // Comring comringdetach("*MotionBaker"); // Comring *MotionBaker } /* --------------------------------------------------------------------------------------------------- COMRING --------------------------------------------------------------------------------------------------- */ comring_motionbaker: event,data { // Parent ParentItem = Item.parent; iParent = 1; while(ParentItem != nil) { iParent++; ParentItem = ParentItem.parent; } if(event != 0 && event != iParent) { return; } sMessage = comringdecode(@"s:200"@,data); if(strlower(sMessage) == "lock") // Lock { bMotionBakerLocked = true; } if(strlower(sMessage) == "unlock") // Unlock { bMotionBakerLocked = false; } if(strlower(sMessage) == "disable" && !bMotionBakerLocked) // Disable { iMotionBakerState = 1; } if(strlower(sMessage) == "reset" && !bMotionBakerLocked) // Reset { iMotionBakerState = 2; } if(strlower(sMessage) == "write" && !bMotionBakerLocked) // Write { iMotionBakerState = 3; } if(strlower(sMessage) == "read" && !bMotionBakerLocked) // Read { iMotionBakerState = 4; } if(strlower(sMessage) == "parent" && !bMotionBakerLocked) // Parent { bMotionBakerParent = true; } if(strlower(sMessage) == "bake" && !bMotionBakerLocked) // Bake { motionbaker_bake(); // Bake iMotionBakerState = 1; // Disable bMotionBakerLocked = true; // Lock } // Requester if(reqisopen()) { bRequesterUpdate = true; // Update setvalue(ctrl_mb,iMotionBakerState); // Motion Baker State setvalue(ctrl_mbl,bMotionBakerLocked); // Motion Baker Locked bRequesterUpdate = false; // Update } } /* --------------------------------------------------------------------------------------------------- BAKE --------------------------------------------------------------------------------------------------- */ motionbaker_bake { if(iChannel == 1){envChannel = Envelope("Position.X",CHAN_NUMBER,Item.name);} // X if(iChannel == 2){envChannel = Envelope("Position.Y",CHAN_NUMBER,Item.name);} // Y if(iChannel == 3){envChannel = Envelope("Position.Z",CHAN_NUMBER,Item.name);} // Z if(envChannel != nil) { for(frame = Scene().previewstart;frame <= Scene().previewend; frame++) { time = (1 / Scene().fps) * frame; iKey = envChannel.keyExists(time); if(iKey == nil) {envChannel.createKey(time, envMotionBaker.value(time));} else {envChannel.setKeyValue(iKey,envMotionBaker.value(time));} } } info(Item.name + " baked"); // Info Refresh(); // Refresh } /* --------------------------------------------------------------------------------------------------- PROCESS --------------------------------------------------------------------------------------------------- */ process: ma, frame, time { /* ------------------------------------------------------------------------------- Item ------------------------------------------------------------------------------- */ // Parent Item ParentItem = Item.parent; // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Requester ------------------------------------------------------------------------------- */ if(reqisopen() && iRequesterFrame != frame) { bRequesterUpdate = true; // Update setvalue(ctrl_d1,envFriction.value(Scene.currenttime)); // Friction setvalue(ctrl_d2,envMin.value(Scene.currenttime)); // Min setvalue(ctrl_d3,envMax.value(Scene.currenttime)); // Max setvalue(ctrl_d4,envMass.value(Scene.currenttime)); // Mass setvalue(ctrl_d5,envRandom.value(Scene.currenttime)); // Random setvalue(ctrl_d6,envDamping.value(Scene.currenttime)); // Damping setvalue(ctrl_d7,envParentMotion.value(Scene.currenttime)); // Parent Motion setvalue(ctrl_d8,envThreshold.value(Scene.currenttime)); // Threshold (m/s) iRequesterFrame = frame; // Frame bRequesterUpdate = false; // Update } // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Iteration ------------------------------------------------------------------------------- */ // Iteration iIteration++; if(aCache[1] <> frame) { iIteration = 1; } // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Motion Baker Disabled ------------------------------------------------------------------------------- */ if(iMotionBakerState == 1) { return; } // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Motion Baker Parent ------------------------------------------------------------------------------- */ if(bMotionBakerParent) { // Parent ParentItem = Item.parent; iParent = 1; while(ParentItem != nil) { iParent++; ParentItem = ParentItem.parent; } sMessage = "*parent"; cMessage = comringencode(@"s:200"@,sMessage); comringmsg("*MotionBaker",iParent,cMessage); bMotionBakerParent = false; } // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Motion Baker Reset ------------------------------------------------------------------------------- */ if(iMotionBakerState == 2) { aCache[1] = frame; // Frame aCache[2] = time; // Time if(iChannel == 1) aCache[3] = clip(envMin.value(time),envMax.value(time),ma.get(POSITION,time).x); // X Channel if(iChannel == 2) aCache[3] = clip(envMin.value(time),envMax.value(time),ma.get(POSITION,time).y); // Y Channel if(iChannel == 3) aCache[3] = clip(envMin.value(time),envMax.value(time),ma.get(POSITION,time).z); // Z Channel aCache[4] = 0.0; // Momentum - aCache[5] = 0.0; // Momentum + if(ParentItem != nil){aCache[6] = ParentItem.getWorldPosition(time);} else {aCache[6] = <0.0,0.0,0.0>;} // Parent World Position aCache[7] = 0.0; // Parent Momentum // Motion Baker Write iKey = envMotionBaker.keyExists((1 / Scene.fps) * frame); if(iKey == nil) {envMotionBaker.createKey((1 / Scene.fps) * frame, aCache[3]);} else {envMotionBaker.setKeyValue(iKey,aCache[3]);} // Motion Baker State iMotionBakerState = 3; // Motion Baker Write if(reqisopen()) { bRequesterUpdate = true; // Update setvalue(ctrl_mb,iMotionBakerState); // Motion Baker bRequesterUpdate = false; // Update } } // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Motion Baker Read ------------------------------------------------------------------------------- */ if(iMotionBakerState == 3 && iIteration > 1) // Write { vPosition = ma.get(POSITION,time); // Position if(iChannel == 1) vPosition.x = aCache[3]; // X Channel if(iChannel == 2) vPosition.y = aCache[3]; // Y Channel if(iChannel == 3) vPosition.z = aCache[3]; // Z Channel ma.set(POSITION,vPosition); return; } if(iMotionBakerState == 4) // Read { vPosition = ma.get(POSITION,time); // Position if(iChannel == 1) vPosition.x = envMotionBaker.value(time); // X Channel if(iChannel == 2) vPosition.y = envMotionBaker.value(time); // Y Channel if(iChannel == 3) vPosition.z = envMotionBaker.value(time); // Z Channel ma.set(POSITION,vPosition); return; } // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Process ------------------------------------------------------------------------------- */ // Variable nDamping = 1.0 - clip(0.0,1.0,envDamping.value(time)); // Damping nMass = envMass.value(time); // Mass nMax = envMax.value(time); nMin = envMin.value(time); nPosition = 0.0; // Position nParentMotion = clip(0,1,envParentMotion.value(time)); // Parent Motion nRandom = 1.0 - (randu() * clip(0.0,1.0,envRandom.value(time))); // Random nThreshold = (1 / Scene().fps) * abs(envThreshold.value(time)); // Threshold vWorldPosition = ma.get(WPOSITION,time); // World Position vPosition = ma.get(POSITION,time); // Position vnRight = normalize3D(Item.getRight(time)); vnUp = normalize3D(Item.getUp(time)); vnForward = normalize3D(Item.getForward(time)); // Angle Motion if(iChannel == 1) nAngleDot = dotproduct3D(normalize3D(vnGravity),vnRight); // X Channel if(iChannel == 2) nAngleDot = dotproduct3D(normalize3D(vnGravity),vnUp); // Y Channel if(iChannel == 3) nAngleDot = dotproduct3D(normalize3D(vnGravity),vnForward); // Z Channel nFriction = 1.0 - clip(0.0,1.0,envFriction.value(time)); // Friction if(nFriction < 1.0) nFriction = linear1D(nFriction,1.0,abs(pow(nAngleDot,3))); // Friction if(nAngleDot < 0.0) { // - nMomentumN = (nMass * nAngleDot * nRandom * nFriction) + aCache[4]; nMomentumP = aCache[5] * nFriction * nDamping; } else { // + nMomentumP = (nMass * nAngleDot * nRandom * nFriction) + aCache[5]; nMomentumN = aCache[4] * nFriction * nDamping; } // Parent Motion if(ParentItem != nil && nParentMotion > 0.0) { vParentWorldPosition = ParentItem.getWorldPosition(time); nParentMotionDistance = distance3D(aCache[6],vParentWorldPosition); vnParentMotionDirection = normalize3D(aCache[6] - vParentWorldPosition); if(iChannel == 1) nParentDot = dotproduct3D(vnParentMotionDirection,vnRight); // X Channel if(iChannel == 2) nParentDot = dotproduct3D(vnParentMotionDirection,vnUp); // Y Channel if(iChannel == 3) nParentDot = dotproduct3D(vnParentMotionDirection,vnForward); // Z Channel nParentMoment = nParentMotionDistance * nParentDot * nParentMotion; nParentMomentum = aCache[7] * nFriction; if(nParentDot > 0.0 && nParentMomentum < nParentMoment) { nParentMomentum = (nParentMotionDistance * (1 - nFriction) * nParentDot * nRandom) + (aCache[7] * nFriction); if(nParentMomentum > nParentMoment) nParentMomentum = nParentMoment; } else if(nParentDot < 0.0 && nParentMomentum > nParentMoment) { nParentMomentum = (nParentMotionDistance * (1 - nFriction) * nParentDot * nRandom) + (aCache[7] * nFriction); if(nParentMomentum < nParentMoment) nParentMomentum = nParentMoment; } nParentMomentum *= nParentMotion; } else { vParentWorldPosition = <0.0,0.0,0.0>; // Parent World Position nParentMoment = 0.0; nParentMomentum = aCache[7] * nFriction; } // Threshold (m/s) if(nMomentumN < -nThreshold) nMomentumN = -nThreshold; if(nMomentumP > nThreshold) nMomentumP = nThreshold; if(nParentMomentum < -nThreshold) nParentMomentum = -nThreshold; if(nParentMomentum > nThreshold) nParentMomentum = nThreshold; // Position nPosition = aCache[3] + nMomentumP + nMomentumN - nParentMomentum + nParentMoment; // Compound Position if(nPosition <= nMin) { nPosition = nMin; nMomentumP = -nMomentumN * nDamping; nMomentumN = 0.0; } if(nPosition >= nMax) { nPosition = nMax; nMomentumN = -nMomentumP * nDamping; nMomentumP = 0.0; } if(iChannel == 1) vPosition.x = nPosition; // X Channel if(iChannel == 2) vPosition.y = nPosition; // Y Channel if(iChannel == 3) vPosition.z = nPosition; // Z Channel // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- MA ------------------------------------------------------------------------------- */ ma.set(POSITION,vPosition); // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Motion Baker Write ------------------------------------------------------------------------------- */ iKey = envMotionBaker.keyExists((1 / Scene.fps) * frame); if(iKey == nil) {envMotionBaker.createKey((1 / Scene.fps) * frame, nPosition);} else {envMotionBaker.setKeyValue(iKey,nPosition);} // ---------------------------------------------------------------------- end - /* ------------------------------------------------------------------------------- Cache ------------------------------------------------------------------------------- */ aCache[1] = frame; // Frame aCache[2] = time; // Time aCache[3] = nPosition; // Position aCache[4] = nMomentumN; // Momentum - aCache[5] = nMomentumP; // Momentum + aCache[6] = vParentWorldPosition; // Parent World Position aCache[7] = nParentMomentum; // Parent Momentum // ---------------------------------------------------------------------- end - } // CLIP clip: min,max,n { if(n < min) n = min; if(n > max) n = max; return(n); } // MAP RANGE maprange01: n1,n2,i { if(n2-n1 == 0.0){return(0.0);} else {return((1/(n2-n1)) * (i-n1));} } // 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); } bicubic1D: n1,n2,n3,n4,i // i = interpolation point (0-1) { i2 = i * i; n_01 = n4 - n3 - n1 + n2; n_02 = n1 - n2 - n_01; n_03 = n3 - n1; n_04 = n2; return(n_01 * i * i2 + n_02 * i2 + n_03 * i + n_04); } // VECTOR 3D crossproduct3D: v1,v2 // v { // Vector return(); } distance3D: v1, v2 // n { // Vector return(sqrt(((v2.x - v1.x) * (v2.x - v1.x)) + ((v2.y - v1.y) * (v2.y - v1.y)) + ((v2.z - v1.z) * (v2.z - v1.z)))); } dotproduct3D: v1,v2 // n { // Vector return(v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); } lineplanedistance3D: v1,vn1,v2,vn2 // n { // Vector - v1 v2 is Vector / vn1 vn2 is Vector Normal nNumerator = dotproduct3D(vn2,v1) + dotproduct3D(-v2,vn2); nDenomimator = dotproduct3D(vn2,vn1); if(nDenomimator <> 0.0){return(-(nNumerator / nDenomimator));} else{return(0.0);} } lineplaneintersect3D: v1,vn1,v2,vn2 // a[1] b (true / false) // a[2] n (distance) // a[3] v (vector) { // Vector - v1 v2 is Vector / vn1 vn2 is Vector Normal nNumerator = dotproduct3D(vn2,v1) + dotproduct3D(-v2,vn2); nDenomimator = dotproduct3D(vn2,vn1); if(nDenomimator <> 0.0){nDistance = -(nNumerator / nDenomimator);} else{ nDistance = 0.0;} if(nDistance >= 0.0){a[1] = true;}else{a[1] = false;} // True / False a[2] = nDistance; // Distance a[3] = v1 + (vn1 * nDistance); // Vector return(a); } pointplane3D: v1,v2,vn2 // v { // Vector - v1 is Vector / v2 is Vector on Plane / vn2 is Vector Normal on Plane return(v1 + (dotproduct3D(vn2,v2) - dotproduct3D(vn2,v1)) * vn2); } normal3D: v1,v2 // vn { // Vector return( ); } magnitude3D: v // n { // Vector return(sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z))); } normalize3D: v // v { // Vector normalize to 0 - 1 nMagnitude = magnitude3D(v); if(nMagnitude <> 0) nMagnitude = 1 / nMagnitude; return(v * nMagnitude); } /* --------------------------------------------------------------------------------------------------- LOAD --------------------------------------------------------------------------------------------------- */ load: what,io { if(what == SCENEMODE) // processing an ASCII scene file { if(io.read().asStr() == sTitle + " " + sVersion) { iChannel = io.read().asInt(); // Channel vnGravity = ; // Gravity // Motion Baker bMotionBakerLocked = io.read().asInt(); // Motion Baker Locked iMotionBakerState = io.read().asInt(); // Motion Baker State // Envelope envDamping.load(); // Damping envFriction.load(); // Friction envMass.load(); // Mass envMax.load(); // Max envMin.load(); // Min envMotionBaker.load(); // Motion Baker envParentMotion.load(); // Parent Motion envRandom.load(); // Random envThreshold.load(); // Threshold (m/s) // Description setdesc(sTitle + " - Channel " + aChannel[iChannel]); } else { info(sTitle + " - Error"); } } } /* --------------------------------------------------------------------------------------------------- SAVE --------------------------------------------------------------------------------------------------- */ save: what,io { if(what == SCENEMODE) { // Header io.writeln(sTitle + " " + sVersion); io.writeln(iChannel); // Channel io.writeln(vnGravity.x); // Gravity X io.writeln(vnGravity.y); // Gravity Y io.writeln(vnGravity.z); // Gravity Z // Motion Baker io.writeln(bMotionBakerLocked); // Motion Baker Locked io.writeln(iMotionBakerState); // Motion Baker State // Envelope envDamping.save(); // Damping envFriction.save(); // Friction envMass.save(); // Mass envMax.save(); // Max envMin.save(); // Min envMotionBaker.save(); // Motion Baker envParentMotion.save(); // Parent Motion envRandom.save(); // Random envThreshold.save(); // Threshold (m/s) } } /* --------------------------------------------------------------------------------------------------- OPTIONS --------------------------------------------------------------------------------------------------- */ options { if(reqisopen()) { reqend(); return; } // Variable iVar = 0; reqbegin(sTitle + " " + sVersion); reqsize(300,307); ctrl_tab = ctltab("Dynamics","*Motion Baker","Developer"); // Dynamics ctrl_d0 = ctlchoice("Channel",iChannel,@"X","Y","Z"@); ctrl_d1 = ctlpercent("Friction",envFriction.value(Scene.currenttime)); // Friction ctrl_d1e = ctlbutton("E",20,"button_d1e"); // Button ctrl_d2v = ctlminislider(" ",iVar,-100,100); ctrl_d2 = ctldistance("Min",envMin.value(Scene.currenttime)); // Min ctrl_d2e = ctlbutton("E",20,"button_d2e"); // Button ctrl_d3v = ctlminislider(" ",iVar,-100,100); ctrl_d3 = ctldistance("Max",envMax.value(Scene.currenttime)); // Max ctrl_d3e = ctlbutton("E",20,"button_d3e"); // Button ctrl_d4 = ctlnumber("Mass",envMass.value(Scene.currenttime)); // Mass ctrl_d4e = ctlbutton("E",20,"button_d4e"); // Button ctrl_d5 = ctlpercent("Random",envRandom.value(Scene.currenttime)); // Random ctrl_d5e = ctlbutton("E",20,"button_d5e"); // Button ctrl_d6 = ctlpercent("Damping",envDamping.value(Scene.currenttime)); // Damping ctrl_d6e = ctlbutton("E",20,"button_d6e"); // Button ctrl_d7 = ctlpercent("Parent Motion",envParentMotion.value(Scene.currenttime)); // Parent Motion ctrl_d7e = ctlbutton("E",20,"button_d7e"); // Button ctrl_d8 = ctldistance("Threshold (m/s)",envThreshold.value(Scene.currenttime)); // Threshold (m/s) ctrl_d8e = ctlbutton("E",20,"button_d8e"); // Button ctrl_d9 = ctlnumber("Gravity X",vnGravity.x); // Gravity X ctrl_d10 = ctlnumber("Y",vnGravity.y); // Gravity Y ctrl_d11 = ctlnumber("Z",vnGravity.z); // Gravity Z ctlposition(ctrl_d0,36,32,212,20,100); // Channel ctlposition(ctrl_d1,36,54,212,20,100); // Friction ctlposition(ctrl_d1e,272,54,20,20); // Friction Button ctlposition(ctrl_d2v,238,76,10,20); // Min ctlposition(ctrl_d2,36,76,212,20,100); ctlposition(ctrl_d2e,272,76,20,20); // Min Button ctlposition(ctrl_d3v,238,98,10,20); // Max ctlposition(ctrl_d3,36,98,212,20,100); ctlposition(ctrl_d3e,272,98,20,20); // Max Button ctlposition(ctrl_d4,36,120,212,20,100); // Mass ctlposition(ctrl_d4e,272,120,20,20); // Mass Button ctlposition(ctrl_d5,36,142,212,20,100); // Random ctlposition(ctrl_d5e,272,142,20,20); // Random Button ctlposition(ctrl_d6,36,164,212,20,100); // Damping ctlposition(ctrl_d6e,272,164,20,20); // Damping Button ctlposition(ctrl_d7,36,186,212,20,100); // Parent Motion ctlposition(ctrl_d7e,272,186,20,20); // Parent Motion Button ctlposition(ctrl_d8,36,208,212,20,100); // Threshold (m/s) ctlposition(ctrl_d8e,272,208,20,20); // Threshold Button ctlposition(ctrl_d9,36,230,212,20,100); // Gravity X ctlposition(ctrl_d10,36,252,212,20,100); // Gravity Y ctlposition(ctrl_d11,36,274,212,20,100); // GRavity Z ctlpage(1,ctrl_d0,ctrl_d1,ctrl_d1e,ctrl_d2v,ctrl_d2,ctrl_d2e,ctrl_d3v,ctrl_d3,ctrl_d3e, ctrl_d4,ctrl_d4e,ctrl_d5,ctrl_d5e,ctrl_d6,ctrl_d6e,ctrl_d7,ctrl_d7e,ctrl_d8,ctrl_d8e,ctrl_d9,ctrl_d10,ctrl_d11); // Dynamics // Motion Baker ctrl_mb = ctlchoice("State",iMotionBakerState,@"Disable","Reset","Write","Read"@); // Choice ctrl_mbe = ctlbutton("E",20,"button_mbe"); // Button ctrl_mbl = ctlcheckbox("Lock",bMotionBakerLocked); // Checkbox ctlposition(ctrl_mb,10,32,260,20,60); // Choice ctlposition(ctrl_mbe,272,32,20,20); // Button ctlposition(ctrl_mbl,220,58,72,20); // Checkbox ctlpage(2,ctrl_mb,ctrl_mbe,ctrl_mbl); // Developer ctrl_dev = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk"); ctlposition(ctrl_dev,10,267,280,20,100); ctlpage(3,ctrl_dev); // Refresh ctlrefresh(ctrl_d0,"refresh_d0"); // Channel ctlrefresh(ctrl_d1,"refresh_d1"); // Friction ctlrefresh(ctrl_d2v,"refresh_d2v"); // Min ctlrefresh(ctrl_d2,"refresh_d2"); ctlrefresh(ctrl_d3v,"refresh_d3v"); // Max ctlrefresh(ctrl_d3,"refresh_d3"); ctlrefresh(ctrl_d4,"refresh_d4"); // Mass ctlrefresh(ctrl_d5,"refresh_d5"); // Random ctlrefresh(ctrl_d6,"refresh_d6"); // Damping ctlrefresh(ctrl_d7,"refresh_d7"); // Parent Motion ctlrefresh(ctrl_d8,"refresh_d8"); // Threshold (m/s) ctlrefresh(ctrl_d9,"refresh_d9"); // Gravity X ctlrefresh(ctrl_d10,"refresh_d10"); // Gravity Y ctlrefresh(ctrl_d11,"refresh_d11"); // Gravity Z ctlrefresh(ctrl_mb,"refresh_mb"); // Motion Baker State ctlrefresh(ctrl_mbl,"refresh_mbl"); // Motion Baker Locked reqopen(); } refresh_d0:value // Channel { iChannel = value; setdesc(sTitle + " - Channel " + aChannel[iChannel]); } refresh_d1:value // Friction { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d1,clip(0.0,1.0,value)); iKey = envFriction.keyExists(Scene.currenttime); if(iKey == nil) {envFriction.createKey(Scene.currenttime,clip(0.0,1.0,value));} else {envFriction.setKeyValue(iKey,clip(0.0,1.0,value));} } button_d1e // Friction { envFriction.edit(); } refresh_d2v:value // Min { setvalue(ctrl_d2,clip(-999.0,envMax.value(Scene.currenttime),envMin.value(Scene.currenttime) + value *.001)); setvalue(ctrl_d2v,0); } refresh_d2:value // Min { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d2,clip(-9999999999.0,envMax.value(Scene.currenttime),value)); iKey = envMin.keyExists(Scene.currenttime); if(iKey == nil) {envMin.createKey(Scene.currenttime,clip(-9999999999.0,envMax.value(Scene.currenttime),value));} else {envMin.setKeyValue(iKey,clip(-9999999999.0,envMax.value(Scene.currenttime),value));} } button_d2e // Min { envMin.edit(); } refresh_d3v:value // Max { setvalue(ctrl_d3,clip(envMin.value(Scene.currenttime),9999999999.0,envMax.value(Scene.currenttime) + value *.001)); setvalue(ctrl_d3v,0); } refresh_d3:value // Max { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d3,clip(envMin.value(Scene.currenttime),9999999999.0,value)); iKey = envMax.keyExists(Scene.currenttime); if(iKey == nil) {envMax.createKey(Scene.currenttime,clip(envMin.value(Scene.currenttime),9999999999.0,value));} else {envMax.setKeyValue(iKey,clip(envMin.value(Scene.currenttime),9999999999.0,value));} } button_d3e // Max { envMax.edit(); } refresh_d4:value // Mass { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d4,max(0.0,value)); iKey = envMass.keyExists(Scene.currenttime); if(iKey == nil) {envMass.createKey(Scene.currenttime,max(0.0,value));} else {envMass.setKeyValue(iKey,max(0.0,value));} } button_d4e // Mass { envMass.edit(); } refresh_d5:value // Random { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d5,clip(0.0,1.0,value)); iKey = envRandom.keyExists(Scene.currenttime); if(iKey == nil) {envRandom.createKey(Scene.currenttime,max(0.0,value));} else {envRandom.setKeyValue(iKey,clip(0.0,1.0,value));} } button_d5e // Random { envRandom.edit(); } refresh_d6:value // Damping { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d6,clip(0.0,1.0,value)); iKey = envDamping.keyExists(Scene.currenttime); if(iKey == nil) {envDamping.createKey(Scene.currenttime,max(0.0,value));} else {envDamping.setKeyValue(iKey,clip(0.0,1.0,value));} } button_d6e // Damping { envDamping.edit(); } refresh_d7:value // Parent Motion { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d7,clip(0.0,1.0,value)); iKey = envParentMotion.keyExists(Scene.currenttime); if(iKey == nil) {envParentMotion.createKey(Scene.currenttime,clip(0.0,1.0,value));} else {envParentMotion.setKeyValue(iKey,clip(0.0,1.0,value));} } button_d7e // Parent Motion { envParentMotion.edit(); } refresh_d8:value // Threshold (m/s) { if(bRequesterUpdate) return; // Requester Update setvalue(ctrl_d8,max(0.0,value)); iKey = envThreshold.keyExists(Scene.currenttime); if(iKey == nil) {envThreshold.createKey(Scene.currenttime,max(0.0,value));} else {envThreshold.setKeyValue(iKey,max(0.0,value));} } button_d8e // Threshold (m/s) { envThreshold.edit(); } refresh_d9:value // Gravity X { vnGravity.x = value; } refresh_d10:value // Gravity Y { vnGravity.y = value; } refresh_d11:value // Gravity Z { vnGravity.z = value; } refresh_mb: value // Motion Baker State { if(bRequesterUpdate) return; // Requester Update iMotionBakerState = value; } button_mbe // Motion Baker Envelope { envMotionBaker.edit(); } refresh_mbl: value // Motion Baker Locked { if(bRequesterUpdate) return; // Requester Update bMotionBakerLocked = value; } /* --------------------------------------------------------------------------------------------------- GIZMO --------------------------------------------------------------------------------------------------- */ gizmodraw: coa { if(!reqisopen()) return; nTimeOffset = -0.0001; vPosition = Item.getPosition(Scene.currenttime + nTimeOffset); // Position vWorldPosition = Item.getWorldPosition(Scene.currenttime + nTimeOffset); // World Position vScaling = Item.getScaling(Scene.currenttime + nTimeOffset); // Scaling vnRight = normalize3D(Item.getRight(Scene.currenttime + nTimeOffset)); vnUp = normalize3D(Item.getUp(Scene.currenttime + nTimeOffset)); vnForward = normalize3D(Item.getForward(Scene.currenttime + nTimeOffset)); nMin = envMin.value(Scene.currenttime + nTimeOffset); nMax = envMax.value(Scene.currenttime + nTimeOffset); if(iChannel == 1) // X { nMin *= vScaling.x; nMax *= vScaling.x; nStabilizer *= vScaling.x; vMin = vWorldPosition + (vnRight * (nMin - vPosition.x)); vMax = vWorldPosition + (vnRight * (nMax - vPosition.x)); coa.setColor(0.78,0.0,0.0,1.0); coa.setPattern("dash"); coa.drawLine(vMin,vMax,"world"); } if(iChannel == 2) // Y { nMin *= vScaling.y; nMax *= vScaling.y; vMin = vWorldPosition + (vnUp * (nMin - vPosition.y)); vMax = vWorldPosition + (vnUp * (nMax - vPosition.y)); coa.setColor(0.0,0.78,0.0,1.0); coa.setPattern("dash"); coa.drawLine(vMin,vMax,"world"); } if(iChannel == 3) // Z { nMin *= vScaling.z; nMax *= vScaling.z; vMin = vWorldPosition + (vnForward * (nMin - vPosition.z)); vMax = vWorldPosition + (vnForward * (nMax - vPosition.z)); coa.setColor(0.0,0.0,0.78,1.0); coa.setPattern("dash"); coa.drawLine(vMin,vMax,"world"); } } gizmodown: te { } gizmomove: te { } gizmoup: te { } gizmodirty { }
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs
No comments:
Post a Comment