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