Example #1
0
void DrawContext::updateTransforms(
    const AffineTransform3& head, 
    const AffineTransform3& view, 
    float eyeSeparation,
    float nearZ,
    float farZ)
{
    DisplaySystem* ds = renderer->getDisplaySystem();
    DisplayConfig& dcfg = ds->getDisplayConfig();
    
    Vector3f pa = tile->bottomLeft;
    Vector3f pb = tile->bottomRight;
    Vector3f pc = tile->topLeft;
    
    if(tile->isHMD)
    {
        pa = head * pa;
        pb = head * pb;
        pc = head * pc;
    }

    // half eye separation
    float hes = eyeSeparation / 2;
    Vector3f pe = Vector3f::Zero();
    switch(eye)
    {
    case EyeLeft:
        pe[0] = -hes;
        break;
    case EyeRight:
        pe[0] = hes;
        break;
    }

    // Transform eye with head position / orientation. After this, eye position
    // and tile coordinates are all in the same reference frame.
    if(dcfg.panopticStereoEnabled)
    {
        // CAVE2 SIMPLIFICATION: We are just interested in adjusting the observer yaw
        AffineTransform3 ht = AffineTransform3::Identity();
        ht.translate(head.translation());
        pe = ht.rotate(
            AngleAxis(-tile->yaw * Math::DegToRad, Vector3f::UnitY())) * pe;
    }
    else
    {
        pe = head * pe;
    }

    Vector3f vr = pb - pa;
    Vector3f vu = pc - pa;
    Vector3f vn = vr.cross(vu);

    Vector2f viewSize = viewMax - viewMin;

    // Update tile corners based on local view position and size
    pa = pa + vr * viewMin[0] + vu * viewMin[1];
    pb = pa + vr * viewSize[0];
    pc = pa + vu * viewSize[1];

    vr.normalize();
    vu.normalize();
    vn.normalize();

    // Compute the screen corner vectors.
    Vector3f va = pa - pe;
    Vector3f vb = pb - pe;
    Vector3f vc = pc - pe;

    // Find distance from eye to screen plane.
    //Vector3f tm = pe - pa;
    float d = -(vn.dot(va));

    // Find the extent of the perpendicular projection.
    float l = vr.dot(va) * nearZ / d;
    float r = vr.dot(vb) * nearZ / d;
    float b = vu.dot(va) * nearZ / d;
    float t = vu.dot(vc) * nearZ / d;

    // Compute the projection matrix. 
    Transform3 oax;
    oax.setIdentity();
    oax(0,0) = 2 * nearZ / (r - l);
    oax(0,2) = (r + l) / (r - l);
    oax(1,1) = 2 * nearZ / (t - b);
    oax(1,2) = (t + b) / (t - b);
    oax(2,2) = - (farZ + nearZ) / (farZ - nearZ);
    oax(2,3) = - (2 * farZ * nearZ) / (farZ - nearZ);
    oax(3,2) = - 1;
    oax(3,3) = 0;

    projection = oax; 
    
    // Compute the view matrix. The view matrix has two main components:
    // - the navigational component given by myViewTransform, converts points
    //   from world space to 'camera' space (origin is determined by camera position / orientation)
    // - the screen plane component, given by the current tile orientation and head position.
    //   this component converts points from camera space to screen-oriented eye space 
    //   (that is, origin is at eye position, and orientation is determined by the screen plane,
    //   with positive Y being screen up vector, X being screen right vector and Z being screen normal)
    AffineTransform3 newBasis;
    newBasis.setIdentity();
    newBasis.data()[0] = vr[0];
    newBasis.data()[1] = vu[0];
    newBasis.data()[2] = vn[0];

    newBasis.data()[4] = vr[1];
    newBasis.data()[5] = vu[1];
    newBasis.data()[6] = vn[1];

    newBasis.data()[8] = vr[2];
    newBasis.data()[9] = vu[2];
    newBasis.data()[10] = vn[2];

    newBasis = newBasis.translate(-pe);

    modelview = newBasis * view;
}
Example #2
0
void displayCallback(void) 
{
	static float lt = 0.0f;
	static uint64 frame = 0;

	GlutDisplaySystem* ds = (GlutDisplaySystem*)SystemManager::instance()->getDisplaySystem();
	Engine* as = ds->getApplicationServer();
	Renderer* ac = ds->getApplicationClient();

	// Compute dt.
	float t = (float)((double)clock() / CLOCKS_PER_SEC);
	UpdateContext uc;
	uc.dt = t - lt;
	lt = t;

	as->update(uc);
	//ac->update(uc);

	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	// setup the context viewport.
	DrawContext dc;
	DisplayTileConfig dtc(ds->getDisplayConfig());
	dtc.device = 0;
	//dtc.index = Vector2i::Zero();
	dtc.offset = Vector2i::Zero();
	dtc.pixelSize = ds->getCanvasSize();

	dc.frameNum = frame++;
	dc.tile = &dtc;
	dc.gpuContext = ds->getGpuContext();

	ds->updateProjectionMatrix();

	Camera* cam = Engine::instance()->getDefaultCamera();

	// Push observer matrix.
	glPushMatrix();
	AffineTransform3 mat = cam->getViewTransform();
	glLoadIdentity();
	glLoadMatrixd(mat.data());

	dc.viewport = Rect(0, 0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
	glGetDoublev( GL_MODELVIEW_MATRIX, dc.modelview.data() );
	glGetDoublev( GL_PROJECTION_MATRIX, dc.projection.data() );

	//dc.drawBuffer = ds->getFrameBuffer();

	// Process events.
	ServiceManager* im = SystemManager::instance()->getServiceManager();
	int av = im->getAvailableEvents();
	if(av != 0)
	{
		Event evts[OMICRON_MAX_EVENTS];
		im->getEvents(evts, ServiceManager::MaxEvents);

		// Dispatch events to application server.
		for( int evtNum = 0; evtNum < av; evtNum++)
		{
			as->handleEvent(evts[evtNum]);
		}
	}

	dc.eye = DrawContext::EyeCyclop;
	dc.task = DrawContext::SceneDrawTask;
	ac->draw(dc);
	dc.task = DrawContext::OverlayDrawTask;
	ac->draw(dc);

	glPopMatrix();

	//glFlush();
	glutPostRedisplay();

	// poll the input manager for new events.
	im->poll();

	if(SystemManager::instance()->isExitRequested())
	{
		exit(0);
	}
}