PDA

View Full Version : Scaling based on distance to other object?

svdelle
04-05-2004, 06:39 AM
I'm trying to get this ball to scale based on the distance to another object.

Imagine thousands of balls (sized 1m in diameter for easy math) placed in colums and rows (like a grid).

Now I want these balls to scale from 0 (or very close to) to 1 based on the position of a Null. I want each ball to be 1m in diameter if the Null is placed directly at the same position as the ball (that is on the groundplane x,z plane - Y should not be concidered) and slowly decrease in size as the Null moves away from the ball (making other balls scale up as it gets closer to them).

I guess I'll have to calculate the distance (radius in some way) from each balls center to the Null, and based on that distance, set the scale of the ball.

I don't know whether this is a job for LScript or Expressions. I've tried to use Expression in a very simple way, just for testing. [ball.Scale.X] = [manip.Position.X], but this seems to make the ball follow the Null (called manip) instead of scaling it.

Any hints for pointing me in the right direction?

Thanks

Red_Oddity
04-05-2004, 07:40 AM
Forget expression, that won't work as LW Expression need the object name in expression when calculating a vector.
So when you duplicate you object the expression won't work anymore as LW places a number behind a duplicate named object (ball becomes ball(1) and ball(2) )

What LWs expressions should need for a formula like this would be the ability to have an object use a expression using _self or _parent in order to do mass expressions

The only way possible would be a Lscript that calculates the distance to the target object and scales your object accordingly

I'll see what i can come with...shouldn't be too difficult

svdelle
04-06-2004, 01:53 AM
Hi,

This sounds just right in my ears ... But due to my lack of knowledge on how LW handle expressions or LScript for that matter, I thought I'd better ask for direction.

Looking forward to what you can come up with (ü)

I posted this question under LScript, and I gave this response just a minute ago .... (the answer was something about object replacement and having 8 different objects ... ):

I just thought that it would be a good idea to use LW's ability to scale through expressions ... now that it's there.

My problem is basically to choose between expressions or LScript (and in the end how to apply it), 'cause in 'descriptive programming' it could look something like this:

-----
If the distance (the radius) from the center of me to the center of the Null is greater than (let's say) 1 m.

Then scale me to 0

Else Scale me to the negative distance (the radius) from the center of me to the center of the Null
-----

(The object should be at full scale when the distance is 0)

I don't know if this is possible programmatically ... I would guess though.

Red_Oddity
04-06-2004, 02:19 AM
This is very much possible...
This is also a good exersize to get my LScript skills a bit up again, no matter how simple the script...

Red_Oddity
04-06-2004, 08:45 AM
Anyway, this is what i came up with so far

Copy the code, open text editor, and save as scale2distance.ls, and offcourse add that file to your Lscript dir and add the plugin in Layout...

// Scale 2 Distance
// by Sven Neve aka Red_Oddity
//
// Does just what the name says
// Pick a mesh and fill in the values
//
//

@version 2.3
@script motion
@name Scale 2 Distance

var vPick = nil;
var vPickName = nil;
var vMin = 0.0;
var vMax = 1.0;
var vDist = 5.0;

create
{
setdesc("Scale2Distance : None");
}

process: ma, frame, time
{
if(vPickName != nil) //this checks wheter or not the plugin is being called after a load Scene
{ //If this is the case, the vPickName will contain a name and
vPick = Mesh(vPickName); //the plugin will Pick the objID that goes with the name.
vPickName = nil;
}

if(vPick)
{
vector1 = ma.get(WPOSITION,time); //This is how you get a vector from the object the plugin is on.
vector2 = vPick.getWorldPosition(time);//This is how you get a vector from the object you selected in the dropdown menu.
vectordistance = vmag(vector1 - vector2); // return the vector between both vectors

if (vectordistance < vDist)
{
scalemultiply = 1 - (vectordistance / vDist);//creates a multiplier (used for final object scale)
}
else
{
scalemultiply = 0;
}
scalereal = vMax - vMin;//This is done so it is possible to do a decent scale, the minimum value will be added later after the final scale formula.

scale = vMin + (scalereal * scalemultiply);//this is the formula...

ma.set(SCALING,<scale,scale,scale>);
// vstring = string(vectordistance)+" | "+string(scalemultiply)+" | "+string(scale);
// info(vstring);//for debugging purposes, is turned off now
info(vPick);
}
}

options
{
reqbegin("Scale 2 Distance by Sven Neve");
reqsize(320,160);

c1 = ctlme****ems("Distance to",vPick);
c2 = ctlnumber("Minimum Scale",vMin);
c3 = ctlnumber("Maximum Scale",vMax);
c4 = ctlnumber("Distance for MaxScale",vDist);

return if !reqpost();

vPick = getvalue(c1);
vMin = getvalue(c2);
vMax = getvalue(c3);
vDist = getvalue(c4);

reqend();

if (vPick == nil)
{
vTemp = "None";
}
else
{
vTemp = vPick.name;
}
setdesc("Scale2Distance : " + vTemp); //Writes info behind your plugin in the MO window
}

//this part here saves all used values into your Scene file and will be loaded
//next time you open your Scene file again.

{
if(what == SCENEMODE)
{
vPickName = io.read(); //Loads the objects name
setdesc("Scale2Distance : " + vPickName);
}
}

save: what,io
{
if(what == SCENEMODE)
{
io.writeln(vPick!=nil?vPick.name:nil); //Saves away the objects name
io.writeln(vMin);
io.writeln(vMax);
io.writeln(vDist);
}
}

CAUTION

the plugin, for some reason, does not like it when you duplicate the object it is on...not liking, as in, i makes LW crash bigtime...i'll try to figure out why...

Red_Oddity
04-06-2004, 08:48 AM
Okay, vbulletin board sucks...

the above text:

ctlme****ems

should be

ctl mesh items...but then with no spaces offcourse...