Camera::Camera(H3DRes pipeline) { _relative.x = -4.0; _relative.y = 12.0; _relative.z = -4.0; _target = Utils::Vec3f(0.0, 0.0, 0.0); handle = h3dAddCameraNode(H3DRootNode, nullptr, pipeline); h3dSetNodeParamI(handle, H3DCamera::ViewportXI, 0); h3dSetNodeParamI(handle, H3DCamera::ViewportYI, 0); h3dSetNodeParamI(handle, H3DCamera::ViewportWidthI, AppCtrl::screen_w); h3dSetNodeParamI(handle, H3DCamera::ViewportHeightI, AppCtrl::screen_h); h3dSetupCameraView(handle, _std_fov, AppCtrl::screen_aspect, 0.1, 30.0); float mat[16]; h3dGetCameraProjMat(handle, mat); _proj_mat = Utils::Matrix4f(mat); }
void pickRay( H3DNode cameraNode, float nwx, float nwy, float *ox, float *oy, float *oz, float *dx, float *dy, float *dz ) { // Transform from normalized window [0, 1] // to normalized device coordinates [-1, 1] float cx( 2.0f * nwx - 1.0f ); float cy( 2.0f * nwy - 1.0f ); // Get projection matrix Matrix4f projMat; h3dGetCameraProjMat( cameraNode, projMat.x ); // Get camera view matrix const float *camTrans; h3dGetNodeTransMats( cameraNode, 0x0, &camTrans ); Matrix4f viewMat( camTrans ); viewMat = viewMat.inverted(); // Create inverse view-projection matrix for unprojection Matrix4f invViewProjMat = (projMat * viewMat).inverted(); // Unproject Vec4f p0 = invViewProjMat * Vec4f( cx, cy, -1, 1 ); Vec4f p1 = invViewProjMat * Vec4f( cx, cy, 1, 1 ); p0.x /= p0.w; p0.y /= p0.w; p0.z /= p0.w; p1.x /= p1.w; p1.y /= p1.w; p1.z /= p1.w; if( h3dGetNodeParamI( cameraNode, H3DCamera::OrthoI ) == 1 ) { float frustumWidth = h3dGetNodeParamF( cameraNode, H3DCamera::RightPlaneF, 0 ) - h3dGetNodeParamF( cameraNode, H3DCamera::LeftPlaneF, 0 ); float frustumHeight = h3dGetNodeParamF( cameraNode, H3DCamera::TopPlaneF, 0 ) - h3dGetNodeParamF( cameraNode, H3DCamera::BottomPlaneF, 0 ); Vec4f p2( cx, cy, 0, 1 ); p2.x = cx * frustumWidth * 0.5f; p2.y = cy * frustumHeight * 0.5f; viewMat.x[12] = 0; viewMat.x[13] = 0; viewMat.x[14] = 0; p2 = viewMat.inverted() * p2; *ox = camTrans[12] + p2.x; *oy = camTrans[13] + p2.y; *oz = camTrans[14] + p2.z; } else { *ox = camTrans[12]; *oy = camTrans[13]; *oz = camTrans[14]; } *dx = p1.x - p0.x; *dy = p1.y - p0.y; *dz = p1.z - p0.z; }
void Camera::setView(const Vector2 &size, const float fovDegrees, const Vector2 &clipDistances) { this->viewSize = size; this->fovDegrees = fovDegrees; this->clipDistances = clipDistances; h3dSetNodeParamI(cameraNode, H3DCamera::ViewportXI, 0); h3dSetNodeParamI(cameraNode, H3DCamera::ViewportYI, 0); h3dSetNodeParamI(cameraNode, H3DCamera::ViewportWidthI, size.x); h3dSetNodeParamI(cameraNode, H3DCamera::ViewportHeightI, size.y); h3dSetupCameraView(cameraNode, fovDegrees, viewSize.x / viewSize.y, clipDistances.x, clipDistances.y); h3dResizePipelineBuffers(Modules::renderer().getPipelineHandle(), viewSize.x, viewSize.y); h3dSetNodeTransform(cameraNode, 0, 1.8f, 10.0f, 0 , 0, 0, 1, 1, 1); h3dGetCameraProjMat(cameraNode, projMat.ptr()); projMat = Matrix4::initPerspMat(fovDegrees, size.x / size.y, clipDistances.x, clipDistances.y); }