Author Topic: Doing a container search in a rectangular prism with two given points.  (Read 684 times)

Pretty much, I'm wondering how I'd let a player set two corner points and have a container search inside of those two points. (Much like WorldEdit on Minecraft, I guess.)

The only way I can think of is doing some vector math to find the centre of the prism and making the box size the size it'd need to be to fill the area perfectly.


What I currently have is this:

Code: [Select]
function VectorComp(%a, %b)
{
%a = getWord(%a, 0) + getWord(%a, 1) + getWord(%a, 2);
%b = getWord(%b, 0) + getWord(%b, 1) + getWord(%b, 2);
return (%a > %b);
}

function VectorRectPrismCentre(%a, %b)
{
%r1 = vectorSub((VectorComp(%a, %b) ? %a : %b), (VectorComp(%a, %b) ? %b : %a));
%r2 = vectorScale(%r1, 0.5);
return %r2;
}

Except that doesn't work in all cases.

I'm not great with vector math.
« Last Edit: February 10, 2012, 07:14:41 PM by otto-san »

I'm not quite certain what you mean. Could you explain in some other way?

What I'm understanding is, you're taking two vectors representing two corners of a rectangular area and you are trying to find all objects in between those points, correct?

I'm not quite certain what you mean. Could you explain in some other way?

What I'm understanding is, you're taking two vectors representing two corners of a rectangular area and you are trying to find all objects in between those points, correct?
Exactly.

Code: [Select]
function doStuff( %vec0, %vec1, %mask )
{
%center = vectorAdd( %vec0, vectorScale( vectorSub( %vec1, %vec0 ), 0.5 ) );
initContainerRadiusSearch( %center, vectorDist( %vec0, %vec1 ) * 4, %mask );

while ( isObject( %obj = containerSearchNext() )
{
%pos = %obj.getPosition();
%dif0 = vectorSub( %pos, %vec0 );
%dif1 = vectorSub( %pos, %vec1 );

if ( getWord( %dif0, 0 ) < 0 || getWord( %dif0, 1 ) < 0 || getWord( %dif1, 2 ) < 0 )
{
continue;
}

if ( getWord( %dif1, 0 ) < 0 || getWord( %dif1, 1 ) < 0 || getWord( %dif1, 2 ) < 0 )
{
continue;
}

// do stuff with %obj
}
}

There is probably a more efficient way, but this should work. Also, this code assumes that the first point is on the negative axis (e.g. 2 2 2 and 4 4 4, not 4 4 4 and 2 2 2, but that's an easy fix anyway).
« Last Edit: February 10, 2012, 07:33:23 PM by Port »

Alright, I'll test that out.

edit:

Didn't exactly work.

Code: [Select]
function doStuff( %vec0, %vec1, %mask )
{
%center = vectorAdd( %vec0, vectorScale( vectorSub( %vec1, %vec0 ), 0.5 ) );
initContainerRadiusSearch( %center, vectorDist( %vec0, %vec1 ) * 4, %mask );

while ( isObject( %obj = containerSearchNext() ) )
{
%pos = %obj.getPosition();
%dif0 = vectorSub( %pos, %vec0 );
%dif1 = vectorSub( %pos, %vec1 );

if ( getWord( %dif0, 0 ) < 0 || getWord( %dif0, 1 ) < 0 || getWord( %dif1, 2 ) < 0 )
{
continue;
}

if ( getWord( %dif1, 0 ) < 0 || getWord( %dif1, 1 ) < 0 || getWord( %dif1, 2 ) < 0 )
{
continue;
}

%obj.setColor(0);
}
}



edit 2:

Just realised you did this:

initContainerRadiusSearch( %center, vectorDist( %vec0, %vec1 ) * 4, %mask );

The second argument has to be a vector, doesn't it?
« Last Edit: February 10, 2012, 07:41:42 PM by otto-san »

Didn't exactly work.

There is probably a more efficient way, but this should work. Also, this code assumes that the first point is on the negative axis (e.g. 2 2 2 and 4 4 4, not 4 4 4 and 2 2 2, but that's an easy fix anyway).

Just realised you did this:

initContainerRadiusSearch( %center, vectorDist( %vec0, %vec1 ) * 4, %mask );

The second argument has to be a vector, doesn't it?

::initContainerRadiusSearch
usage: (Point3F pos, float radius, bitset mask)Start a search for items within radius of pos, filtering by bitset mask.




Code: [Select]
function getRectCenter( %vec0, %vec1 )
{
if ( vectorLen( %vec0 ) >= vectorLen( %vec1 ) )
{
return vectorAdd( %vec0, vectorScale( vectorSub( %vec1, %vec0 ), 0.5 ) );
}
else
{
return vectorAdd( %vec1, vectorScale( vectorSub( %vec0, %vec1 ), 0.5 ) );
}
}

function doStuff( %vec0, %vec1, %mask )
{
%val = ( vectorLen( %vec0 ) >= vectorLen( %vec1 ) );
%center = getRectCenter( %vec0, %vec1 );

initContainerRadiusSearch( %center, vectorDist( %vec0, %vec1 ) * 4, %mask );

while ( isObject( %obj = containerSearchNext() )
{
%pos = %obj.getPosition();

%dif0 = vectorSub( %pos, %vec0 );
%dif1 = vectorSub( %vec1, %pos );

if ( getWord( %dif0, 0 ) < 0 || getWord( %dif0, 1 ) < 0 || getWord( %dif1, 2 ) < 0 )
{
continue;
}

if ( getWord( %dif1, 0 ) < 0 || getWord( %dif1, 1 ) < 0 || getWord( %dif1, 2 ) < 0 )
{
continue;
}

// do stuff with %obj
}
}
« Last Edit: February 10, 2012, 08:02:48 PM by Port »

OH that was radius search.

I was thinking box search. Maybe I should have read it more carefully, haha.

I'll try that, thanks.

The reason I'm using a radius search instead of box search is because the mathematical formulas that Torque uses for comparing intersections between the search box and object world boxes are really weird.

The reason I'm using a radius search instead of box search is because the mathematical formulas that Torque uses for comparing intersections between the search box and object world boxes are really weird.
I can honestly say I've never had an issue with initContainerBoxSearch. It's always fit my needs, especially with simple things like bricks.