Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Library: Stackable Graph Cubes

Pedro McMillan
SLOODLE Developer
Join date: 28 Jul 2007
Posts: 231
12-01-2008 06:39
I made this script so that you could have a series of cubes lying around, and have anybody drag-move them together, such that they would 'snap' into alignment by adjusting position/rotation. The original idea was to let folks build bar graphs, although it can be useful for other stuff too... like re-creating classic moments from Tetris. :)

I've put more details and screenshots online here:

http://www.avid-insight.co.uk/projects/stackable-graph-cubes/

Version 1.1 of the script is below, although it's still a little bit buggy at low framerates. Just create a 0.5x0.5x0.5 cube, put this script inside it, and duplicate it however many times you need. (Make sure all the cubes have the same name, and remember to check the box "Allow anybody to move" if you want other people to move them as well).


CODE

//////////
// Stackable Graph Cube script
//
// Author: Peter R. Bloomfield (SL: Pedro McMillan)
//
// Place this script inside several independent cubes.
// You can then drag the cubes around, and they will 'snap' to each other neatly.
//
//
// Note regarding object naming:
// You can name the cubes whatever you like, but make sure all cubes which need
// stack together have the SAME name.
//
// Note regarding scaling:
// This is currently setup for a cube of size 0.5x0.5x0.5.
// If you want to use a different scale, then change the "cubeSize" variable below.
// Also update the "scanRange" variable to roughly double the width of a cube.
//
//
// Known problems:
// - can end up with 2 cubes occupying same space
// - does not always detect when it has been moved
//
// Versions:
// 1.0 - original version with physics... buggy and vertical stacking only
// 1.1 - physics disabled by default, but cubes snap in all dimensions, with correct rotations
//
//
//////////
// GPL:
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//////////

// What size are all cubes expected to be?
vector cubeSize = <0.5, 0.5, 0.5>;
// How far should we scan for other cubes?
float scanRange = 1.0;

// This will store the position after our last movement
vector lastMove = <0.0, 0.0, 0.0>;


// Should we use physics?
// (Note: physics makes dragging cube around more fun, but is also prone to bugs)
integer USE_PHYSICS = FALSE;


default
{
state_entry()
{
// Whether we will use physics or not, disable it until we are moved
llSetPrimitiveParams([PRIM_PHYSICS, FALSE]);
}

moving_start()
{
// Activate physics for as long as the cube is being moved
if (USE_PHYSICS) llSetPrimitiveParams([PRIM_PHYSICS, TRUE]);
}

moving_end()
{
// Store our current position (in case the sensor is delayed)
lastMove = llGetPos();
// Look around for other nearby graph cubes
llSensor(llGetObjectName(), NULL_KEY, SCRIPTED | PASSIVE, scanRange, PI);

// Deactivate physics so we don't get a feedback loop
// (aligns self -> physics moves it slightly -> realigns self -> etc..)
if (USE_PHYSICS) llSetPrimitiveParams([PRIM_PHYSICS, FALSE]);
}

sensor(integer num_detected)
{
// Go through each sensed object to find the nearest one
integer i = 0;
float nearestDist = -1.0;
float curDist = 0.0;
vector nearestPos = <0.0, 0.0, 0.0>;
vector curPos = <0.0, 0.0, 0.0>;
rotation nearestRot = ZERO_ROTATION;
for (i = 0; i < num_detected; i++) {
// Is it the nearest so far?
curPos = llDetectedPos(i);
curDist = llVecDist(curPos, lastMove);
if (nearestDist < 0.0 || curDist < nearestDist) {
nearestDist = curDist;
nearestPos = curPos;
nearestRot = llDetectedRot(i);
}
}

// Did we end up finding a suitable cube nearby?
if (nearestDist > 0.0) {
// Calculate the vector between the sensed object and this one,
// and translate it to local space for the sensed object
// (this lets us figure out which side of it we're on)
vector offset = (lastMove - nearestPos) / nearestRot;
// Figure out which side of it we're on by checking which dimension different is biggest
float xDiff = llFabs(offset.x);
float yDiff = llFabs(offset.y);
float zDiff = llFabs(offset.z);
vector snapPos = <0.0, 0.0, 0.0>;
// Determine the position we ought to be in, relative to the local
// rotation of the object we are snapping to
if (xDiff > yDiff) {
if (xDiff > zDiff) {
if (offset.x < 0.0) snapPos.x = -cubeSize.x;
else snapPos.x = cubeSize.x;
} else {
if (offset.z < 0.0) snapPos.z = -cubeSize.z;
else snapPos.z = cubeSize.z;
}
} else {
if (yDiff > zDiff) {
if (offset.y < 0.0) snapPos.y = -cubeSize.y;
else snapPos.y = cubeSize.y;
} else {
if (offset.z < 0.0) snapPos.z = -cubeSize.z;
else snapPos.z = cubeSize.z;
}
}

// Apply our snap offset according to the detected rotation
snapPos = nearestPos + (snapPos * nearestRot);

llSetPrimitiveParams([PRIM_POSITION, snapPos, PRIM_ROTATION, nearestRot]);
}
}

no_sensor()
{
// Nothing detected
}
}
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
12-01-2008 15:25
Nice contribution Pedro!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
12-01-2008 19:43
I was playing around with your idea tonight and came up with this. But only works for prims that are the same size.

Touch the 1st prim and then the face that you want to move to on the second prim:

EDIT: See my next post down
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Pedro McMillan
SLOODLE Developer
Join date: 28 Jul 2007
Posts: 231
12-02-2008 05:19
I was thinking about something along those lines too at some point... although I'm sure it's one of those ideas I would probably never have gotten round to.

Meanwhile, I've implemented version 1.2 of the Stackable Graph Cubes, which uses touch events instead of moving, so it's a bit more reliable. It's also got physics enabled while you're dragging the cubes, so it's a bit more tactile, and the cubes are less likely to go underground... although it's also very easy for the physics to end up jamming the cubes together immovably, so it's a tradeoff either way.

Rather than post the full script here, I'll just do a link:

http://www.avid-insight.co.uk/dev/stackable_graph_cube_1.2.lsl

(At some point, I'll need to install LSL syntax highlighting on my server... :))


EDIT: almost forgot, I really ought to credit Shamblesguru Voom with the original idea for this!
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
12-04-2008 18:55
I've been playing some more with the idea and came up with this:

https://wiki.secondlife.com/wiki/User:Jesse_Barnett/SandBox_Blox

It is surprising just how damned addicting it is playing with both your's and my versions. A lot of fun and a bit of learning for the new scripters at the same time.

From: Pedro McMillan
(At some point, I'll need to install LSL syntax highlighting on my server... :))


You do know that you can create a wiki page and posts your example scripts to the library? Syntax highlighting is working there.

My page:

https://wiki.secondlife.com/wiki/User:Jesse_Barnett
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Pedro McMillan
SLOODLE Developer
Join date: 28 Jul 2007
Posts: 231
12-05-2008 01:51
I have some kind of addiction to doing everything myself. Just ask my boss, my family, my church, and every lecturer I ever had at uni... :)

Thanks for the tip though... hadn't thought about posting it on the wiki.