User Centric Projection
- Running the Example
- glutCyberleSrv
- SensorSimSrv
This example is again a small distibuted application. In this example for rendering the glutCyberleSrv component from the project section is used. If you compiled the whole OAW project the executable should be in the bin folder of the project root. So does the OAWMaster component. So if you put the bin folder in your system path you should be able to run the demo of this tutorial by typing on three different consols:
console1>glutCyberleSrv -inifile gsrv.ini
console2>SensorSimSrv
console3>OAWMaster master.ini
The glutCyberleSrv component is a render component, that can be fully parameterized through commandline parameters. In the following section it will be explained the basic different to the myGSrv from the simple_pds tutorial. The whole paramters of the glutCyberleSrv component you can see in the Binaries - Tools section.
Main thing to do for user centric projection is to integrate a headtracker into the render server. The view classes are already suitable for the integration of a headtracker. But the headtracker sensor is not integrated into the view class directly, but through a user object. The relation can be seen in the following diagramm.
The reason for this is that OAW implements billboards in a way that they rotate to the projection point rather than to the viewpoint alone. The billboards rotate towards a user moving around the table of a workbench. In OAW the viewpoint is always interpreted as the position of the display in the virtual world. So if the user moves its head in respect to the immersive display the viepoint doesn't change. But to control the billboard appropriatly, the user has to be aquiant to the world object. The user object calculates from the headtracker data the positions of each eye. The code integrating the headtracker into the render component is therefore like follows:
OAW::CybUserC user;
OAW::CybSixDOFSensorC headtracker;
user.SetHeadtracker(&headtracker);
pEB->AssignInterface("default_headtracker",&headtracker);
headtracker.SetPosition(params.headPos);
//Enable user centric features like billboards
if(params.bUser){
world.SetUser(&user);
}
..
..
pView->SetUser(&user);
Rendering passive stereo means, that two projectors are needed equiped with filters polarizing the light in two orthognal states (horizontal - vertical or lefthand, righthand circular polarization). The user is wearing eyeglasses where each eyeglass is only transparent for the light of one projector. So if the image for the right and the left eye is rendered on one of the projectors each, the user will percive a stereoscopic spacial image. The CybMonoProjectionViewC class is implemented to be used for parallel passive stereo rendering. It takes an option that indicates which eye should be rendered.
//Create a view for a mono projection screen
pView = new OAW::CybMonoProjectionViewC(params.viewSizeX,params.viewSizeY);
//Set the OpenGL channel for rendering
((OAW::CybMonoProjectionViewC*)pView)->SetGraphicChannel(pChan1);
//seteye to render
if(params.eyeStr=="left"){
((OAW::CybMonoProjectionViewC*)pView)->SetEyetype(OAW::CybMonoProjectionViewC::LEFT);
}
if(params.eyeStr=="right"){
((OAW::CybMonoProjectionViewC*)pView)->SetEyetype(OAW::CybMonoProjectionViewC::RIGHT);
}
Again, also the single view is only monoscopic in a cluster it may be the monoscopic view of a steroscopic image.
In actiev stereo mode there are simply two channel objects instanciated an a stereo view class parameterizes them both appropriatly. In the display function both channels are rendered into the appropriate gl buffer.
To demostrate the headtracking, this tutorial contains a small OAW component simulating a headtracker and 3DMouse sensor (sensorsimsrv.cpp). You may rewrite it to a small server to integrate your own tracking devices. A pure sensor component need no world model. Therefore this component only instancitates one event broker and two objects from the SixDOFSensorC and CybSixDOFMouseSensorC class. These classes are inherited from the InterfaceC class and are therefore appropriate to distribute their data in the cluster. In the simulation loop tracking data is simply written into the corresponding interfaces.
The three stages of the distributed loop - exchange interface data - update model and views - swap, and there callbacks are ordered like shown in the following image.
Because the exchange interface data is the first thing done, after the eventProcessed function of the event broker is called, there will be no delay in the sensor data if you write the data to the interfaces in the
while(eb.ProcessEvents()){
..
pHeadTracker->SetOrientation(q);
pHeadTracker->SetPosition(pos);
..
}
loop. It will be used for the rendering in the current frame.