Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Determining the up facing side of a prim

Ravanne Sullivan
Pole Dancer Extraordinair
Join date: 10 Dec 2005
Posts: 674
03-23-2008 12:24
I have tried searching for an answer to this and have seen it mentioned but no true answer.

How can I deternine the face number of the up facing side of a randomly rotated prim?

Any help would be greatly appreciated.
_____________________
Ravanne's Dance Poles and Animations

Available at my Superstore and Showroom on Insula de Somni
http://slurl.com/secondlife/Insula de Somni/94/194/27/
Soen Eber
Registered User
Join date: 3 Aug 2006
Posts: 428
03-23-2008 13:30
I can't give a complete reply without research, but given a zero rotation the "up" face of a prim can be always known - it will always be a fixed value, and you can determine that either through the client menu or through a script which changes each face's texture one at a time, announcing the side. The rest involves knowing the rotation of the random prim. You can investigate by rotating each prim through several rotations and mapping which side is up for a given rotation.
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
03-23-2008 13:54
You can find out where the prims local Z axis is pointing with: llRot2Up( llGetRot() );
I know that was not what you asked but knowing more about the subject Prim would help a lot.
( A basic Sphere has just one side so it is easy to tell what side is up on that )
_____________________
From Studio Dora
Ravanne Sullivan
Pole Dancer Extraordinair
Join date: 10 Dec 2005
Posts: 674
03-23-2008 13:56
That really doesn't help. The key is to be able to determine the up face of a randomly rotated prim such as a rolled die.
_____________________
Ravanne's Dance Poles and Animations

Available at my Superstore and Showroom on Insula de Somni
http://slurl.com/secondlife/Insula de Somni/94/194/27/
Snowman Jiminy
Registered User
Join date: 23 Dec 2007
Posts: 424
03-23-2008 14:05
You could add another prim to one of the faces - a very very small one.....

"the dice were loaded from the start"

Interesting problem though - bear in mind that if the die lands on the edge you could have two prims that are equally up facing.
_____________________
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
03-23-2008 14:47
From: Ravanne Sullivan
That really doesn't help. The key is to be able to determine the up face of a randomly rotated prim such as a rolled die.

It is a 'Box' then?

vector u = llRot2Fwd( llGetRot() );
vector v = llRot2Left( llGetRot() );
vector w = llRot2Up( llGetRot() );

if ( w.z > 0.9 ) llOwnerSay( "Face 0 is UP" );
if ( -w.z > 0.9 ) llOwnerSay( "Face 5 is UP" );
if ( v.z > 0.9 ) llOwnerSay( "Face 3 is UP" );
if ( -v.z > 0.9 ) llOwnerSay( "Face 1 is UP" );
if ( u.z > 0.9 ) llOwnerSay( "Face 2 is UP" );
if ( -u.z > 0.9 ) llOwnerSay( "Face 4 is UP" );

This is not tested but should at least open a way to a solution


The above 'script' is now tested and I can inform you it is working without modifications.
The following script does the same thing in a slightly more streamlined fashion:
// UP Side test script, Sudio Dora, Dora Gustafson 2008-03-24
// For box, can be tailored to other prims
// v1.0 using sort to find the "most" upward face

default
{
touch_start(integer num_detected)
{
vector u = llRot2Fwd( llGetRot() );
vector v = llRot2Left( llGetRot() );
vector w = llRot2Up( llGetRot() );

// Vectors associated with face numbers
list faces = [ w.z, 0, -w.z, 5, v.z, 3, -v.z, 1, u.z, 2, -u.z, 4 ];
// sort for the one with the biggest Z (vertical up) component,
// the associated face is upward
llOwnerSay("Face "+ llList2String( llListSort( faces, 2, FALSE ), 1 ) + " is UP" );
}
}

Get a free copy of the scripts in side numbered boxes at: http://slurl.com/secondlife/Scamp/84/176/71
Look for: 'Side numbers and upside in box' a small white cube with black numbers: 0,1,2,3,4 and 5
_____________________
From Studio Dora
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
03-23-2008 19:17
For a simple scaled and rotated box, you can instead think of yourself as sitting in the box's reference frame as the world rotates around you. The z-axis points in some arbitrary direction, and we have to figure out which face the ray intersects with. This boils down to expressing a vector in the z-direction in the prim's local coordinate frame. For simplicity, we might as well scale according to the box's dimensions as well, thinking of the box as a uniform cube that has been deformed to fit in "normal" space:
CODE

rotation rot = llGetRot();
vector scale = llGetScale();

vector fwd = llRot2Fwd(rot);
vector left = llRot2Left(rot);
vector up = llRot2Up(rot);

float zFwd = fwd.z/scale.x; // Same as dot product: <0.0, 0.0, 1.0>*fwd/scale.x
float zLeft = left.z/scale.y;
float zUp = up.z/scale.z;

float zFwdMag = llFabs(zFwd);
float zLeftMag = llFabs(zLeft);
float zUpMag = llFabs(zUp);

// Find largest magnitude component and its sign
if (zUpMag > zFwdMag)
{
if (zUpMag > zLeftMag)
{
if (zUp > 0.0)
{
// "top" face
} else
{
// "bottom" face
}
} else
{
if (zLeft > 0.0)
{
// "left" face
} else
{
// "right" face
}
}
} else
{
if (zFwdMag > zLeftMag)
{
if (zFwd > 0.0)
{
// "forward" face
} else
{
// "rear" face
}
} else
{
if (zLeft > 0.0)
{
// "left" face
} else
{
// "right" face
}
}
}

This isn't going to help much if you have a cut, tapered, skewed, or non-rectangular-prism prim. You'll just have to tailor your solution to the particular geometry you have. A general solution is not only a matter of very non-trivial logic and geometry, but requires some judgement calls as well (at least for non-convex shapes). To the point where it might be better to simply address your business requirements in some other way.

EDIT: You'll have to look up or test yourself which face number is "top", etc. I'm refering to them in the standard local x is forward, local y is left, local z is up manner.