/* virtual */ void HdSt_TestLightingShader::SetCamera(GfMatrix4d const &worldToViewMatrix, GfMatrix4d const &projectionMatrix) { for (int i = 0; i < 2; ++i) { _lights[i].eyeDir = worldToViewMatrix.TransformDir(_lights[i].dir).GetNormalized(); } }
GfPlane & GfPlane::Transform(const GfMatrix4d &matrix) { // Compute the point on the plane along the normal from the origin. GfVec3d pointOnPlane = _distance * _normal; // Transform the plane normal by the adjoint of the matrix to get // the new normal. The adjoint (inverse transpose) is used to // multiply normals so they are not scaled incorrectly. GfMatrix4d adjoint = matrix.GetInverse().GetTranspose(); _normal = adjoint.TransformDir(_normal).GetNormalized(); // Transform the point on the plane by the matrix. pointOnPlane = matrix.Transform(pointOnPlane); // The new distance is the projected distance of the vector to the // transformed point onto the (unit) transformed normal. This is // just a dot product. _distance = GfDot(pointOnPlane, _normal); return *this; }
void GfFrustum::_CalculateFrustumPlanes() const { if (!_planes.empty()) return; _planes.reserve(6); // These are values we need to construct the planes. const GfVec2d &winMin = _window.GetMin(); const GfVec2d &winMax = _window.GetMax(); double near = _nearFar.GetMin(); double far = _nearFar.GetMax(); GfMatrix4d m = ComputeViewInverse(); // For a perspective frustum, we use the viewpoint and four // corners of the near-plane frustum rectangle to define the 4 // planes forming the left, right, top, and bottom sides of the // frustum. if (_projectionType == GfFrustum::Perspective) { // // Get the eye-space viewpoint (the origin) and the four corners // of the near-plane frustum rectangle using similar triangles. // // This picture may help: // // top of near plane // frustum rectangle // // + -- // / | | // / | | // / | | h // / | | // / | | // vp +-----------+ -- // center of near plane frustum rectangle // |___________| // near // // The height (h) of this triangle is found by the following // equation, based on the definition of the _window member // variable, which is the size of the image rectangle in the // reference plane (a distance of 1 from the viewpoint): // // h _window.GetMax()[1] // ------ = -------------------- // near 1 // // Solving for h gets the height of the triangle. Doing the // similar math for the other 3 sizes of the near-plane // rectangle is left as an exercise for the reader. // // XXX Note: If we ever allow reference plane depth to be other // than 1.0, we'll need to revisit this. GfVec3d vp(0.0, 0.0, 0.0); GfVec3d lb(near * winMin[0], near * winMin[1], -near); GfVec3d rb(near * winMax[0], near * winMin[1], -near); GfVec3d lt(near * winMin[0], near * winMax[1], -near); GfVec3d rt(near * winMax[0], near * winMax[1], -near); // Transform all 5 points into world space by the inverse of the // view matrix (which converts from world space to eye space). vp = m.Transform(vp); lb = m.Transform(lb); rb = m.Transform(rb); lt = m.Transform(lt); rt = m.Transform(rt); // Construct the 6 planes. The three points defining each plane // should obey the right-hand-rule; they should be in counter-clockwise // order on the inside of the frustum. This makes the intersection of // the half-spaces defined by the planes the contents of the frustum. _planes.push_back( GfPlane(vp, lb, lt) ); // Left _planes.push_back( GfPlane(vp, rt, rb) ); // Right _planes.push_back( GfPlane(vp, rb, lb) ); // Bottom _planes.push_back( GfPlane(vp, lt, rt) ); // Top _planes.push_back( GfPlane(rb, lb, lt) ); // Near } // For an orthographic projection, we need only the four corners // of the near-plane frustum rectangle and the view direction to // define the 4 planes forming the left, right, top, and bottom // sides of the frustum. else { // // The math here is much easier than in the perspective case, // because we have parallel lines instead of triangles. Just // use the size of the image rectangle in the reference plane, // which is the same in the near plane. // GfVec3d lb(winMin[0], winMin[1], -near); GfVec3d rb(winMax[0], winMin[1], -near); GfVec3d lt(winMin[0], winMax[1], -near); GfVec3d rt(winMax[0], winMax[1], -near); // Transform the 4 points into world space by the inverse of // the view matrix (which converts from world space to eye // space). lb = m.Transform(lb); rb = m.Transform(rb); lt = m.Transform(lt); rt = m.Transform(rt); // Transform the canonical view direction (-z axis) into world // space. GfVec3d dir = m.TransformDir(-GfVec3d::ZAxis()); // Construct the 5 planes from these 4 points and the // eye-space view direction. _planes.push_back( GfPlane(lt + dir, lt, lb) ); // Left _planes.push_back( GfPlane(rb + dir, rb, rt) ); // Right _planes.push_back( GfPlane(lb + dir, lb, rb) ); // Bottom _planes.push_back( GfPlane(rt + dir, rt, lt) ); // Top _planes.push_back( GfPlane(rb, lb, lt) ); // Near } // The far plane is the opposite to the near plane. To compute the // distance from the origin for the far plane, we take the distance // for the near plane, add the difference between the far and the near // and then negate that. We do the negation since the far plane // faces the opposite direction. A small drawing would help: // // far - near // /---------------------------\ * // // | | | // | | | // | | | // <----|----> | | // fnormal|nnormal | | // | | | // near plane far plane // // \---------/ * // ndistance // // \---------------------------------------/ * // fdistance // // So, fdistance = - (ndistance + (far - near)) _planes.push_back( GfPlane(-_planes[4].GetNormal(), -(_planes[4].GetDistanceFromOrigin() + (far - near))) ); }
GfRGB GfRGB::Transform(const GfMatrix4d &m) const { return GfRGB(m.TransformDir(_rgb)); }