protected override Real getValue(MovableObject movableObject, Camera camera) { // Get viewport var viewport = camera.Viewport; // Get viewport area float viewportArea = viewport.ActualWidth * viewport.ActualHeight; // Get area of unprojected circle with object bounding radius float boundingArea = MathHelper.PI * MathHelper.Sqr(movableObject.BoundingRadius); // Base computation on projection type switch (camera.ProjectionType) { case Projection.Perspective: { // Get camera distance var distanceSquared = movableObject.ParentNode.GetSquaredViewDepth(camera); // Check for 0 distance if (distanceSquared <= float.Epsilon) { return(BaseValue); } // Get projection matrix (this is done to avoid computation of tan(fov / 2)) var projectionMatrix = camera.ProjectionMatrix; //estimate pixel count return((boundingArea * viewportArea * projectionMatrix[0, 0] * projectionMatrix[1, 1]) / distanceSquared); } // break; case Projection.Orthographic: { // Compute orthographic area var orthoArea = camera.OrthoWindowHeight * camera.OrthoWindowWidth; // Check for 0 orthographic area if (orthoArea <= float.Epsilon) { return(BaseValue); } // Estimate pixel count return((boundingArea * viewportArea) / orthoArea); } // break; default: { // This case is not covered for obvious reasons throw new NotSupportedException(); } } }
/// <summary> /// Sets the reference view upon which the distances were based. /// </summary> /// <note> /// This automatically enables use of the reference view. /// There is no corresponding get method for these values as /// they are not saved, but used to compute a reference value. /// </note> /// <param name="viewportWidth"></param> /// <param name="viewportHeight"></param> /// <param name="fovY"></param> public virtual void SetReferenceView(float viewportWidth, float viewportHeight, Radian fovY) { // Determine x FOV based on aspect ratio var fovX = fovY * ((Real)viewportWidth / (Real)viewportHeight); // Determine viewport area var viewportArea = viewportHeight * viewportWidth; // Compute reference view value based on viewport area and FOVs this.ReferenceViewValue = viewportArea * MathHelper.Tan(fovX * (Real)0.5f) * MathHelper.Tan(fovY * (Real)0.5f); // Enable use of reference view this._referenceViewEnabled = true; }
protected override Real getValue(MovableObject movableObject, Camera cam) { // Get squared depth taking into account bounding radius // (d - r) ^ 2 = d^2 - 2dr + r^2, but this requires a lot // more computation (including a sqrt) so we approximate // it with d^2 - r^2, which is good enough for determining // lod. Real squaredDepth = movableObject.ParentNode.GetSquaredViewDepth(cam) - MathHelper.Sqr(movableObject.BoundingRadius); // Check if reference view needs to be taken into account if (this._referenceViewEnabled) { // Reference view only applicable to perspective projection System.Diagnostics.Debug.Assert(cam.ProjectionType == Projection.Perspective, "Camera projection type must be perspective!"); // Get camera viewport var viewport = cam.Viewport; // Get viewport area Real viewportArea = viewport.ActualWidth * viewport.ActualHeight; // Get projection matrix (this is done to avoid computation of tan(fov / 2)) var projectionMatrix = cam.ProjectionMatrix; // Compute bias value (note that this is similar to the method used for PixelCountLodStrategy) Real biasValue = viewportArea * projectionMatrix[0, 0] * projectionMatrix[1, 1]; // Scale squared depth appropriately squaredDepth *= (this.ReferenceViewValue / biasValue); } // Squared depth should never be below 0, so clamp squaredDepth = MathHelper.Max(squaredDepth, 0); // Now adjust it by the camera bias and return the computed value return(squaredDepth * cam.InverseLodBias); }
public override Real TransformUserValue(Real userValue) { return(MathHelper.Sqr(userValue)); }