Code Intro
From Moviesandbox
(22 intermediate revisions not shown.) | |||
Line 1: | Line 1: | ||
- | + | If you're looking for the old CodeIntro, that page has moved to [[UT2k4_CodeCentral]]. | |
- | <h2> | + | <h2>(important) classes </h2> |
- | + | * '''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'''. | |
- | + | <br> | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
<br> | <br> | ||
- | whereas myInputControl stands for your InputControl class. | ||
- | + | <h2>Random blurbs that need structure</h2> | |
- | + | ||
- | + | <h3>Order of Execution</h3> | |
- | + | look at [[Order of Execution]]. | |
- | + | ||
- | + | ||
- | + | <h3>How Nodes work in Code</h3> | |
+ | look at [[Node System]]. | ||
- | <h3> | + | <h3>Particle Systems</h3> |
- | + | * 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 | ||
- | + | <h3>Actor to Actor References</h3> | |
- | + | 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! | ||
- | + | * when deleting, always call ''checkReferences'' on Actors! | |
- | + | * always be mindful of the function ''checkReferences'' when buttons/actors reference something! | |
- | + | ||
- | + | --[[User:Fiezi|Fiezi]] 23:15, 5 June 2008 (MEST) | |
- | + | [[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); | ||
- | + | //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. | |
- | + | ||
- | + | ||
- | + |
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.