Code Intro

From Moviesandbox

(Difference between revisions)
Jump to: navigation, search
Current revision (18:45, 11 April 2011) (edit) (undo)
 
(18 intermediate revisions not shown.)
Line 1: Line 1:
-
This will become bigger and stuff, but for now, we'll use it for random interesting tidbits.
+
If you're looking for the old CodeIntro, that page has moved to [[UT2k4_CodeCentral]].
-
<h2>Custom Input Device integration</h2>
+
<h2>(important) classes </h2>
-
Moviesandbox gives you the possibility to integrate your own input devices and characters by using the udp protocol to communicate between your input device and MSB.
+
* '''Renderer''' - takes care of shadows, FrameBufferObjects, Overlays, textures, etc. Does not do a very good job in sorting, no real scenegraph yet.
-
Once you transformed your Device data to UDP, you can send your data to port ''UDP 31840''+ channel. I'll explain below.
+
-
<h3>Setting up the structure within Moviesandbox</h3>
+
* '''SceneData''' - holds all scene related info, actor- and button-lists, save-directories, scene save/load, etc. Calls setup and update functions. Initialises all known objects for later lookup and type inspection
-
In order to create your own custom interface to control your actors - as the GATech people did for example - you should take a look at the ''MSBCode.MSBPawnInputControl.uc'' file.<br>
+
-
Create your own custom Pawn by subclassing MSBObjects.MSBPawn and create your own MSBPawnInputControl by subclassing MSBPawnInputControl. Ideally you'll have your own package for both your new classes.
+
* '''Input''' - takes care of all Input and callback functions and figures out mouse-pressed/moved, currently selected buttons, etc.
-
Feel free to add functionality to your Pawn, like linking to your special skeleton.<br>
+
-
The Pawn automatically generates a PawnInputControl. All you need to do is to specify which class to use when generating the PawnInputControl. This is done in the Button that will create your pawn.<br>
+
* '''content''' - a convenient way of creating and initialising everything that's supposed to be created on startup.
-
Go ahead and sublass ''MSBMenuButtons.MSBCreatePawn'' and add the following piece of code to your new class:<br>
+
* '''actor''' - base class of all objects (including buttons) saves/loads itself (called from Input, or other places'''.
-
 
+
<br>
-
function LeftBtnFinished(Canvas C)
+
-
{
+
-
local Pawn P;
+
-
+
-
P=Pawn(SpawnActor);
+
-
MSBPawn(P).MSBPawnInputControl=Spawn(class'myPawnInputControl',P,,P.Location);
+
-
super.LeftBtnFinished(C);
+
-
}
+
<br>
<br>
-
whereas myInputControl stands for your InputControl class.
 
-
We're almost through! Now all you need to do is to make your Button appear within Moviesandbox. In order to do this, open the ''MSBButtonConfig.ini'' in your System folder.
+
<h2>Random blurbs that need structure</h2>
-
Find the [MSBCode.MSBMenuButtonStatic] part and add a reference to your button to the end of the list, like this:
+
-
.
+
<h3>Order of Execution</h3>
-
.
+
look at [[Order of Execution]].
-
.
+
-
ButtonList=MSBMenuButtons.MSBCreateMyPawn
+
-
There you go! You're now all set up to program your own Input directives.
+
<h3>How Nodes work in Code</h3>
 +
look at [[Node System]].
-
<h3>How to implement your own functionality</h3>
+
<h3>Particle Systems</h3>
-
The MSBPlayerInputControl has its own UDP socket, set to a port that can be defined within the Moviesandbox environment. After placing your character (using the button we created before), right click on it and set the UDP channel. This will set the UDP socket of this character's PAwnInputControl to port 31840+channel.
+
* transparency right now is binary (transparent pixels get pushed to z=100000 in Pixelshader)
 +
* ParticleScale is being transferred as particleLocation.w to save shader bandwidth
-
The PawnInputControl.Tick(float DeltaTime) function has access to the byte array that is being transferred each frame through udpLink.byteData[]. It also has access to a string conversion of said byte array through udplink.Data.
+
<h3>Actor to Actor References</h3>
-
An example on how you can use your input data can be found within the original MSBPawnInputControl, where the pressing of a gamepadbutton is transformed to a pose and moving the sticks is transformed to head or eye movement, following the data structure:
+
Integer numbers that reference the location of an actor or button in the ''Renderer::actorList'' or ''Renderer::buttonList''.<br>
 +
So far this is used for key-frames and attachments. This way they can be easily serialized to XML when saved. But we need to be careful when we change the actorList!
-
Byte0 -> xAxis
+
* when deleting, always call ''checkReferences'' on Actors!
-
Byte1 -> yAxis
+
* always be mindful of the function ''checkReferences'' when buttons/actors reference something!
-
Byte2 -> uAxis
+
 
-
Byte3 -> vAxis
+
--[[User:Fiezi|Fiezi]] 23:15, 5 June 2008 (MEST)
-
Byte4 -> ButtonNumber
+
[[Category:Coding]]
 +
 
 +
<h3>OSC message control</h3>
 +
 
 +
Did you know Moviesandbox can be remote controlled? <br>
 +
All you need to do is set up a UDP connection, get a Port and then post a valid OSC message.<br>
 +
The idea is to follow this sequence:<br>
 +
* request a new UDP connection on the main UDP channel/port
 +
* receive all relevant object names, setup instructions, etc. /should these be updated regularly through the main UDP channel?)
 +
* keep listening on the MSB broadcast port (this is where all clients are listening)
 +
* setup a connection on the new port
 +
* send a /select message to select an actor you would like to work with
 +
* send a /set message together with the name of the property you would like to set
 +
* send a /get message together with the name of the property you would like to get
 +
* send a /function message to call a function on the object (still have to figure this one out...)
 +
 
 +
<h3>OSC message implementation</h3>
 +
The two classes to watch here are '''UDPInput''' and '''Pilot'''.
 +
The UDPInput is the main class that creates a specified '''Pilot''' class, as a sort of interpreter for different formats depending on the type of Input we are expecting (TUIO or general OSC).
 +
The Pilot class is created as a seperate thread.<br/>
 +
<br/>
 +
Pilot parses the OSC Message and looks for data types. Current supported datatypes:
 +
 
 +
* vector3f
 +
* float
 +
 
 +
The structure of the OSC message is "/pilot/''datatype''/''datatype''/''...'' ''arg'', ''arg'', ''...''
 +
 
 +
Interface-wise, we use the class '''[[UDPInput]]''' and '''[[inputConnectButton]]''' to visualise the incoming data and connect to different parts of the program.
 +
 
 +
UDPInput describes the main UDPInput - you can have many different channels through which you can recieve data. This class then creates small '''[[inputConnectButton]]s''' that visualise the type and amount of data coming in.
 +
 
 +
<h3>OSC message example</h3>
 +
 
 +
The port I am listening to OSC messages on is '''31841'''.
 +
 
 +
OSC messages consist of an adress part and a list of arguments that can be of many different types.
 +
The way I set things up right now, the adress part identifies the type of arguments that are expected. The different types are seperated by a "/". Also, the first part in the adress should always be "pilot", this has been added for extendability reasons (later on, different identifiers could channel the data to different commands).
 +
The arguments contain the values in linear order.
 +
 
 +
For example:
 +
 +
'''adress:''' "/pilot/float/float"
 +
'''arguments:''' 0.2, 0.8
 +
 
 +
The first segment, "pilot" is used to tell the program what to do with the rest of the message.
 +
The second segment, "float" tells me that the first argument will be a float.
 +
The third segment tells me that the second argument will also be a float.
 +
 
 +
Since we're primarily working with rotation, there's another type that I use, called vector3f, which indicates that there's 3 floats that should be interpreted as a vector. For example:
 +
 
 +
'''adress:''' "pilot/vector3f/vector3f/vector3f"
 +
'''arguments:''' 1.0, 0.1, 0.3, 0.4, 0.4, 0.2, 0.1, 0.0, 0.0
 +
 
 +
First segment, again, has to be "pilot".
 +
Second segment says that there are three float arguments that I will interpret as a vector.
 +
Third segment says there are three more float arguments that i will interpret as a vector
 +
And the fourth segment says the same thing.
 +
 
 +
In the processing OSC implementation (oscP5, see oscP5sendReceive example), this would look like this:
 +
 
 +
OscMessage myMessage = new OscMessage("/pilot/vector3f/vector3f/vector3f");
 +
 +
myMessage.add(1.0); /* add a float to the osc message */
 +
myMessage.add(0.1); /* add a float to the osc message */
 +
myMessage.add(0.3); /* add a float to the osc message */
 +
 
 +
myMessage.add(0.4); /* add a float to the osc message */
 +
myMessage.add(0.4); /* add a float to the osc message */
 +
myMessage.add(0.2); /* add a float to the osc message */
 +
 
 +
myMessage.add(0.1); /* add a float to the osc message */
 +
myMessage.add(0.0); /* add a float to the osc message */
 +
myMessage.add(0.0); /* add a float to the osc message */
 +
 
 +
What we will do in the end is transfer all the bone rotations (relative rotations per joint, with two potentiometers per joint) as vector3f s, so you will need to fill in 0s for the missing third and sometimes the missing 2nd value. So for the right arm, we would do something like this:
 +
 
 +
OscMessage myMessage = new OscMessage("/pilot/vector3f/vector3f");
 +
 +
//shoulder
 +
myMessage.add(potiOne);
 +
myMessage.add(potiTwo);
 +
myMessage.add(0.0);
-
<h2>General UDP Port Usage</h2>
+
//elbow
-
These ports are being used by Moviesandbox to communicate with tools or devices:
+
myMessage.add(potiThree);
 +
myMessage.add(0.0);
 +
myMessage.add(0.0);
-
UDP 21840 -> speech with channel IN (from vvvv)
+
whereas potiOne is the 0.0 to 1.0 mapped value of your first shoulder potentiometer, potiTwo the second shoulder potentiometer, and so on.
-
UDP 31840 -> Device with channel IN (from Multi HID Input)
+
-
UDP 41840 -> blocks IN (from Tracer)
+
-
UDP 61840 -> Bone Rotations IN (from MoCap Tool)
+

Current revision

If you're looking for the old CodeIntro, that page has moved to UT2k4_CodeCentral.

Contents

[edit] (important) classes

  • Renderer - takes care of shadows, FrameBufferObjects, Overlays, textures, etc. Does not do a very good job in sorting, no real scenegraph yet.
  • SceneData - holds all scene related info, actor- and button-lists, save-directories, scene save/load, etc. Calls setup and update functions. Initialises all known objects for later lookup and type inspection
  • Input - takes care of all Input and callback functions and figures out mouse-pressed/moved, currently selected buttons, etc.
  • content - a convenient way of creating and initialising everything that's supposed to be created on startup.
  • actor - base class of all objects (including buttons) saves/loads itself (called from Input, or other places.



[edit] Random blurbs that need structure

[edit] Order of Execution

look at Order of Execution.

[edit] How Nodes work in Code

look at Node System.

[edit] Particle Systems

  • transparency right now is binary (transparent pixels get pushed to z=100000 in Pixelshader)
  • ParticleScale is being transferred as particleLocation.w to save shader bandwidth

[edit] Actor to Actor References

Integer numbers that reference the location of an actor or button in the Renderer::actorList or Renderer::buttonList.
So far this is used for key-frames and attachments. This way they can be easily serialized to XML when saved. But we need to be careful when we change the actorList!

  • when deleting, always call checkReferences on Actors!
  • always be mindful of the function checkReferences when buttons/actors reference something!

--Fiezi 23:15, 5 June 2008 (MEST)

[edit] OSC message control

Did you know Moviesandbox can be remote controlled?
All you need to do is set up a UDP connection, get a Port and then post a valid OSC message.
The idea is to follow this sequence:

  • request a new UDP connection on the main UDP channel/port
  • receive all relevant object names, setup instructions, etc. /should these be updated regularly through the main UDP channel?)
  • keep listening on the MSB broadcast port (this is where all clients are listening)
  • setup a connection on the new port
  • send a /select message to select an actor you would like to work with
  • send a /set message together with the name of the property you would like to set
  • send a /get message together with the name of the property you would like to get
  • send a /function message to call a function on the object (still have to figure this one out...)

[edit] OSC message implementation

The two classes to watch here are UDPInput and Pilot. The UDPInput is the main class that creates a specified Pilot class, as a sort of interpreter for different formats depending on the type of Input we are expecting (TUIO or general OSC). The Pilot class is created as a seperate thread.

Pilot parses the OSC Message and looks for data types. Current supported datatypes:

  • vector3f
  • float

The structure of the OSC message is "/pilot/datatype/datatype/... arg, arg, ...

Interface-wise, we use the class UDPInput and inputConnectButton to visualise the incoming data and connect to different parts of the program.

UDPInput describes the main UDPInput - you can have many different channels through which you can recieve data. This class then creates small inputConnectButtons that visualise the type and amount of data coming in.

[edit] OSC message example

The port I am listening to OSC messages on is 31841.

OSC messages consist of an adress part and a list of arguments that can be of many different types. The way I set things up right now, the adress part identifies the type of arguments that are expected. The different types are seperated by a "/". Also, the first part in the adress should always be "pilot", this has been added for extendability reasons (later on, different identifiers could channel the data to different commands). The arguments contain the values in linear order.

For example:

adress: "/pilot/float/float" arguments: 0.2, 0.8

The first segment, "pilot" is used to tell the program what to do with the rest of the message. The second segment, "float" tells me that the first argument will be a float. The third segment tells me that the second argument will also be a float.

Since we're primarily working with rotation, there's another type that I use, called vector3f, which indicates that there's 3 floats that should be interpreted as a vector. For example:

adress: "pilot/vector3f/vector3f/vector3f" arguments: 1.0, 0.1, 0.3, 0.4, 0.4, 0.2, 0.1, 0.0, 0.0

First segment, again, has to be "pilot". Second segment says that there are three float arguments that I will interpret as a vector. Third segment says there are three more float arguments that i will interpret as a vector And the fourth segment says the same thing.

In the processing OSC implementation (oscP5, see oscP5sendReceive example), this would look like this:

OscMessage myMessage = new OscMessage("/pilot/vector3f/vector3f/vector3f");

 myMessage.add(1.0); /* add a float to the osc message */
 myMessage.add(0.1); /* add a float to the osc message */
 myMessage.add(0.3); /* add a float to the osc message */
 myMessage.add(0.4); /* add a float to the osc message */
 myMessage.add(0.4); /* add a float to the osc message */
 myMessage.add(0.2); /* add a float to the osc message */
 myMessage.add(0.1); /* add a float to the osc message */
 myMessage.add(0.0); /* add a float to the osc message */
 myMessage.add(0.0); /* add a float to the osc message */

What we will do in the end is transfer all the bone rotations (relative rotations per joint, with two potentiometers per joint) as vector3f s, so you will need to fill in 0s for the missing third and sometimes the missing 2nd value. So for the right arm, we would do something like this:

OscMessage myMessage = new OscMessage("/pilot/vector3f/vector3f");

//shoulder
 myMessage.add(potiOne);
 myMessage.add(potiTwo);
 myMessage.add(0.0);
//elbow
 myMessage.add(potiThree);
 myMessage.add(0.0);
 myMessage.add(0.0);

whereas potiOne is the 0.0 to 1.0 mapped value of your first shoulder potentiometer, potiTwo the second shoulder potentiometer, and so on.

Personal tools
Moviesandbox for UT2004