wandPosition Examples: Moving an Array of Cubes

This is a more complex example of moving objects with the wandPosition node. Here, we move an object every time button 1 is pressed; but instead of just one object, we cycle through an array of 12 objects. The first time the button is pressed, cube1 moves to where the wand is. The second time, cube2 moves; the third time, cube3 moves, and so on.

After 12 presses, we return to moving cube1, and continue cycling. Clicking the button rapidly creates an effect sort of like drawing, leaving a trail behind the wand. Adding more cubes, or other objects into this scene creates a longer drawing trail.

There are several tricky things this program does. First, we need to find a way to count the number of presses. This is easy enough to do using a value node and sending it an increment message every time the button is pressed. To make it loop around, the greaterEqual node will check if its value is greater than or equal to 12, and if it is, set it back to 1. Note the use of the reference message - this lets you refer to one value node in multiple places.

Now, how use this information to connect to each of the 12 nodes? In an event handler, you can use variables not just in parameters to messages, but also as part of a node name - so you can address nodes as cube$value. When $value = 1, then it will connect to cube1; when $value = 2, it will connect to cube2, and so on.

We have to have two value nodes - one to hold the wand position, and one to act as a counter. The counter node also has to be an integer node, because otherwise you'll get errors that YG cannot find cube1.000000, when you really wanted cube1.

But how do we combine the two pieces of information together? We have one value node that knows where the wand is, and another that knows which cube we should be moving; but because each node can't access the other's variables, there's no way to combine them into one message.

The solution is to use a custom message, so that we can pass the information between them. In the counter node, we can figure out the name of the cube node that we want to move, and pass it over to currentposition, the node that stores the wand position. We'll make up a name for the event, calling it movecube, and make up a variable called whichcube to pass the name of the cube we want to move.

When currentposition handles the event, it has the cube name in the $whichcube variable, and the wand's x,y, and z position in its own $value, $value1, and $value2 variables.

drawing with cubes

/* 
    cube drawing
    
    this is a moderately complicated example demonstrating the 
    use of the wandPosition node to move objects around, and a 
    counter to cycle through 10 cubes.	
	
*/

#include "User0"

light (position(1 -1 1))

object cube1 (file(cube1.b3d))
object cube2 (file(cube2.b3d))
object cube3 (file(cube3.b3d))
object cube4 (file(cube4.b3d))
object cube5 (file(cube5.b3d))
object cube6 (file(cube6.b3d))
object cube7 (file(cube7.b3d))
object cube8 (file(cube8.b3d))
object cube9 (file(cube9.b3d))
object cube10 (file(cube10.b3d))
object cube11 (file(cube11.b3d))
object cube12 (file(cube12.b3d))
// whenever you click the button,
// store the current position in a value node,
// and increment the counter.

wandPosition(volume(infinite),
	when(button1,
		currentposition.values($xpos $ypos $zpos),
		cubecounter.increment))

/* 	
	this counter goes from 1 to 10.
	whenever it changes, it sends a custom event to the value node
	that holds the wand position, telling it which cube it should move	
*/
value cubecounter (set(1),
	integer,
	maximum(12),
	when(changed,currentposition.event(movecube,whichcube=cube$value)))

// if the counter is greater than or equal to 10, reset it to 1.
greaterEqual (when(changedTrue,cubecounter.set(1)))
{
	value (reference(cubecounter))
	value (set(12))
}
	

/*
	a value node to hold the wand position.
	$whichcube will be cube1,cube2,cube3, etc
	and is sent by the cubecounter node.
*/
		
value currentposition (values(0 0 0),
	when(movecube,$whichcube.position($value $value1 $value2)))


	
	


(c) Ben Chang