void Channel::_calcMVandITMV( eq::Matrix4f& modelviewM, eq::Matrix3f& modelviewITM ) const { const FrameData& frameData = _getFrameData(); const Pipe* pipe = static_cast< const Pipe* >( getPipe( )); const Renderer* renderer = pipe->getRenderer(); if( renderer ) { const VolumeScaling& volScaling = renderer->getVolumeScaling(); eq::Matrix4f scale( eq::Matrix4f::ZERO ); scale.at(0,0) = volScaling.W; scale.at(1,1) = volScaling.H; scale.at(2,2) = volScaling.D; scale.at(3,3) = 1.f; modelviewM = scale * frameData.getRotation(); } modelviewM.set_translation( frameData.getTranslation( )); modelviewM = getHeadTransform() * modelviewM; //calculate inverse transposed matrix eq::Matrix4f modelviewIM; modelviewM.inverse( modelviewIM ); eq::Matrix3f( modelviewIM ).transpose_to( modelviewITM ); }
glm::vec3 CameraRig::getLookAt() const { glm::mat4 model_matrix = getHeadTransform()->getModelMatrix(); float x0 = model_matrix[3][0]; float y0 = model_matrix[3][1]; float z0 = model_matrix[3][2]; float reciprocalW0 = 1 / model_matrix[3][3]; x0 *= reciprocalW0; y0 *= reciprocalW0; z0 *= reciprocalW0; float x1 = model_matrix[2][0] * -1.0f + model_matrix[3][0]; float y1 = model_matrix[2][1] * -1.0f + model_matrix[3][1]; float z1 = model_matrix[2][2] * -1.0f + model_matrix[3][2]; float reciprocalW1 = 1.0f / (model_matrix[2][3] * -1.0f + model_matrix[3][3]); x1 *= reciprocalW1; y1 *= reciprocalW1; z1 *= reciprocalW1; float lookAtX = x1 - x0; float lookAtY = y1 - y0; float lookAtZ = z1 - z0; float reciprocalLength = 1.0f / sqrtf(lookAtX * lookAtX + lookAtY * lookAtY + lookAtZ * lookAtZ); lookAtX *= reciprocalLength; lookAtY *= reciprocalLength; lookAtZ *= reciprocalLength; return glm::vec3(lookAtX, lookAtY, lookAtZ); }
void CameraRig::setRotation(const glm::quat& transform_rotation) { // Get head transform (a child of camera rig object) Transform* transform = getHeadTransform(); if (camera_rig_type_ == FREE) { transform->set_rotation(transform_rotation); } else if (camera_rig_type_ == YAW_ONLY) { glm::vec3 look_at = glm::rotate(transform_rotation, glm::vec3(0.0f, 0.0f, -1.0f)); float yaw = atan2f(-look_at.x, -look_at.z) * 180.0f / M_PI; transform->set_rotation( glm::angleAxis(yaw, glm::vec3(0.0f, 1.0f, 0.0f))); } else if (camera_rig_type_ == ROLL_FREEZE) { glm::vec3 look_at = glm::rotate(transform_rotation, glm::vec3(0.0f, 0.0f, -1.0f)); float pitch = atan2f(look_at.y, sqrtf(look_at.x * look_at.x + look_at.z * look_at.z)) * 180.0f / M_PI; float yaw = atan2f(-look_at.x, -look_at.z) * 180.0f / M_PI; transform->set_rotation( glm::angleAxis(pitch, glm::vec3(1.0f, 0.0f, 0.0f))); transform->rotateByAxis(yaw, 0.0f, 1.0f, 0.0f); } else if (camera_rig_type_ == FREEZE) { transform->set_rotation(glm::quat()); } else if (camera_rig_type_ == ORBIT_PIVOT) { glm::vec3 pivot(getVec3("pivot")); transform->set_position(pivot.x, pivot.y, pivot.z + getFloat("distance")); transform->set_rotation(glm::quat()); transform->rotateWithPivot(transform_rotation.w, transform_rotation.x, transform_rotation.y, transform_rotation.z, pivot.x, pivot.y, pivot.z); } }
void Channel::_drawModel( const Model* scene ) { Window* window = static_cast< Window* >( getWindow( )); VertexBufferState& state = window->getState(); const FrameData& frameData = _getFrameData(); if( frameData.getColorMode() == COLOR_MODEL && scene->hasColors( )) state.setColors( true ); else state.setColors( false ); state.setChannel( this ); // Compute cull matrix const eq::Matrix4f& rotation = frameData.getCameraRotation(); const eq::Matrix4f& modelRotation = frameData.getModelRotation(); eq::Matrix4f position = eq::Matrix4f::IDENTITY; position.set_translation( frameData.getCameraPosition()); const eq::Frustumf& frustum = getFrustum(); const eq::Matrix4f projection = useOrtho() ? frustum.compute_ortho_matrix(): frustum.compute_matrix(); const eq::Matrix4f& view = getHeadTransform(); const eq::Matrix4f model = rotation * position * modelRotation; state.setProjectionModelViewMatrix( projection * view * model ); state.setRange( &getRange().start); const eq::Pipe* pipe = getPipe(); const GLuint program = state.getProgram( pipe ); if( program != VertexBufferState::INVALID ) glUseProgram( program ); scene->cullDraw( state ); state.setChannel( 0 ); if( program != VertexBufferState::INVALID ) glUseProgram( 0 ); const InitData& initData = static_cast<Config*>( getConfig( ))->getInitData(); if( initData.useROI( )) // declare empty region in case nothing is in frustum declareRegion( eq::PixelViewport( )); else declareRegion( getPixelViewport( )); #ifndef NDEBUG outlineViewport(); #endif }
void Channel::_updateNearFar( const mesh::BoundingSphere& boundingSphere ) { // compute dynamic near/far plane of whole model const FrameData& frameData = _getFrameData(); const eq::Matrix4f& rotation = frameData.getCameraRotation(); const eq::Matrix4f headTransform = getHeadTransform() * rotation; eq::Matrix4f modelInv; compute_inverse( headTransform, modelInv ); const eq::Vector3f zero = modelInv * eq::Vector3f::ZERO; eq::Vector3f front = modelInv * eq::Vector3f( 0.0f, 0.0f, -1.0f ); front -= zero; front.normalize(); front *= boundingSphere.w(); const eq::Vector3f center = frameData.getCameraPosition().get_sub_vector< 3 >() - boundingSphere.get_sub_vector< 3 >(); const eq::Vector3f nearPoint = headTransform * ( center - front ); const eq::Vector3f farPoint = headTransform * ( center + front ); if( useOrtho( )) { LBASSERTINFO( fabs( farPoint.z() - nearPoint.z() ) > std::numeric_limits< float >::epsilon(), nearPoint << " == " << farPoint ); setNearFar( -nearPoint.z(), -farPoint.z() ); } else { // estimate minimal value of near plane based on frustum size const eq::Frustumf& frustum = getFrustum(); const float width = fabs( frustum.right() - frustum.left() ); const float height = fabs( frustum.top() - frustum.bottom() ); const float size = LB_MIN( width, height ); const float minNear = frustum.near_plane() / size * .001f; const float zNear = LB_MAX( minNear, -nearPoint.z() ); const float zFar = LB_MAX( zNear * 2.f, -farPoint.z() ); setNearFar( zNear, zFar ); } }
eq::Matrix4f Channel::_computeModelView() const { const FrameData& frameData = _getFrameData(); const Pipe* pipe = static_cast< const Pipe* >( getPipe( )); const Renderer* renderer = pipe->getRenderer(); eq::Matrix4f modelView; if( renderer ) { const VolumeScaling& volScaling = renderer->getVolumeScaling(); eq::Matrix4f scale; scale(0,0) = volScaling.W; scale(1,1) = volScaling.H; scale(2,2) = volScaling.D; modelView = scale * frameData.getRotation(); } modelView.setTranslation( frameData.getTranslation( )); return getHeadTransform() * modelView; }
void Channel::frameDraw(const eq::uint128_t &frame_id) { // Setup OpenGL state (view frustum etc.) eq::Channel::frameDraw(frame_id); // Get data const Config *config = static_cast<Config *>(getConfig()); const Node *node = static_cast<Node *>(getNode()); const InitData &init_data = node->getInitData(); const Pipe *pipe = static_cast<Pipe *>(getPipe()); const FrameData &frame_data = pipe->getFrameData(); Window *window = static_cast<Window *>(getWindow()); Ogre::Camera *cam = pipe->_ogre->getCamera(); // Set the projection matrix const eq::Frustumf & frustum = getFrustum(); cam->setCustomProjectionMatrix(true, toOgreMatrix(frustum.compute_matrix())); const eq::Matrix4f eqViewMatrix = getHeadTransform(); // Adjust the view matrix according to equalizer's view matrix Ogre::Matrix4 ogreViewMatrix = toOgreMatrix(eqViewMatrix); cam->setCustomViewMatrix(true, ogreViewMatrix); cam->setNearClipDistance(frustum.near_plane()); cam->setFarClipDistance(frustum.far_plane()); // Set the viewport eq::PixelViewport winPvp = window->getPixelViewport(); eq::PixelViewport pvp = getPixelViewport(); window->setViewport((float)pvp.x/(float)winPvp.w, 1.0f - (float)(pvp.h + pvp.y)/(float)winPvp.h, (float)pvp.w/(float)winPvp.w, (float)pvp.h/(float)winPvp.h); // Render window->render(); }
void Channel::_drawModel( const Model* scene ) { Window* window = static_cast< Window* >( getWindow( )); VertexBufferState& state = window->getState(); const FrameData& frameData = _getFrameData(); if( frameData.getColorMode() == COLOR_MODEL && scene->hasColors( )) state.setColors( true ); else state.setColors( false ); state.setChannel( this ); // Compute cull matrix const eq::Matrix4f& rotation = frameData.getCameraRotation(); const eq::Matrix4f& modelRotation = frameData.getModelRotation(); eq::Matrix4f position = eq::Matrix4f::IDENTITY; position.set_translation( frameData.getCameraPosition()); const eq::Frustumf& frustum = getFrustum(); const eq::Matrix4f projection = useOrtho() ? frustum.compute_ortho_matrix(): frustum.compute_matrix(); const eq::Matrix4f& view = getHeadTransform(); const eq::Matrix4f model = rotation * position * modelRotation; state.setProjectionModelViewMatrix( projection * view * model ); state.setRange( &getRange().start); const eq::Pipe* pipe = getPipe(); const GLuint program = state.getProgram( pipe ); if( program != VertexBufferState::INVALID ) glUseProgram( program ); scene->cullDraw( state ); state.setChannel( 0 ); if( program != VertexBufferState::INVALID ) glUseProgram( 0 ); const InitData& initData = static_cast<Config*>( getConfig( ))->getInitData(); if( !initData.useROI( )) { declareRegion( getPixelViewport( )); return; } #ifndef NDEBUG // region border const eq::PixelViewport& pvp = getPixelViewport(); const eq::PixelViewport& region = getRegion(); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( 0.f, pvp.w, 0.f, pvp.h, -1.f, 1.f ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); const eq::View* currentView = getView(); if( currentView && frameData.getCurrentViewID() == currentView->getID( )) glColor3f( 0.f, 0.f, 0.f ); else glColor3f( 1.f, 1.f, 1.f ); glNormal3f( 0.f, 0.f, 1.f ); const eq::Vector4f rect( float( region.x ) + .5f, float( region.y ) + .5f, float( region.getXEnd( )) - .5f, float( region.getYEnd( )) - .5f ); glBegin( GL_LINE_LOOP ); { glVertex3f( rect[0], rect[1], -.99f ); glVertex3f( rect[2], rect[1], -.99f ); glVertex3f( rect[2], rect[3], -.99f ); glVertex3f( rect[0], rect[3], -.99f ); } glEnd(); #endif }