/// <summary> /// Traverses the specified graph path</summary> /// <param name="graphPath">The graph path</param> /// <param name="action">The render action</param> /// <param name="camera">The camera</param> /// <param name="list">The list</param> /// <returns></returns> public override TraverseState Traverse(Stack<SceneNode> graphPath, IRenderAction action, Camera camera, ICollection<TraverseNode> list) { // Get the "top matrix" before we push a new matrix on to it, just in case we need // it for the bounding box test. Matrix4F parentToWorld = action.TopMatrix; // Push matrix onto the matrix stack even if we're not visible because this class // implements the marker interface ISetsLocalTransform. action.PushMatrix(m_node.Transform, true); // If node is invisible then cull if (!m_node.Visible) return TraverseState.Cull; TraverseState dResult = action.TraverseState; if (dResult == TraverseState.None) { // Test if bounding sphere is contained in frustum if (s_enableVFCull) { // Construct bounding box Box box = new Box(); box.Extend(m_node.BoundingBox); // Transform the bounding box into view space Matrix4F localToView = Matrix4F.Multiply(parentToWorld, camera.ViewMatrix); box.Transform(localToView); if (!camera.Frustum.Contains(box)) dResult = TraverseState.Cull; } } return dResult; }
/// <summary> /// Sets this camera to have the same state as the given camera</summary> /// <param name="source">Source camera, which is not modified. This camera becomes a copy of it.</param> public void Init(Camera source) { ViewTypes perspective; Vec3F eye; Vec3F lookAtPoint; Vec3F upVector; float yFov; float nearZ; float farZ; float focusRadius; source.GetState( out perspective, out eye, out lookAtPoint, out upVector, out yFov, out nearZ, out farZ, out focusRadius); SetState( perspective, eye, lookAtPoint, upVector, yFov, nearZ, farZ, focusRadius); }
/// <summary> /// Traverses the specified graph path.</summary> /// <param name="graphPath">The graph path</param> /// <param name="action">The render action</param> /// <param name="camera">The camera</param> /// <param name="list">The list</param> /// <returns></returns> public override TraverseState Traverse(Stack<SceneNode> graphPath, IRenderAction action, Camera camera, ICollection<TraverseNode> list) { // If invisible then cull if (!m_primitives.Visible) return TraverseState.Cull; return base.Traverse(graphPath, action, camera, list); }
/// <summary> /// Calculates required scale such that when it applied to an /// object. The object maintain a constant size in pixel regardless of /// its distance from camera. /// Used for computing size of 3d manipulators.</summary> /// <param name="camera"></param> /// <param name="objectPosW"></param> /// <param name="sizeInPixels"></param> /// <param name="viewHeight"></param> public static float CalcAxisScale(Camera camera, Vec3F objectPosW, float sizeInPixels, float viewHeight) { float worldHeight; // World height on origin's z value if (camera.Frustum.IsOrtho) { worldHeight = (camera.Frustum.Top - camera.Frustum.Bottom); } else { Matrix4F view = camera.ViewMatrix; Vec3F objPosV; view.Transform(objectPosW, out objPosV); worldHeight = 2.0f * Math.Abs(objPosV.Z) * (float)Math.Tan(camera.Frustum.FovY / 2.0f); } return sizeInPixels * (worldHeight / viewHeight); }
public static void ZoomOnSphere(Camera cam, Sphere3F sphere) { float nearZ = cam.PerspectiveNearZ; // todo refactor cam.ZoomOnSphere() cam.ZoomOnSphere(sphere); cam.PerspectiveNearZ = nearZ; }
/// <summary> /// Synchronizes the camera to the controller's current state</summary> /// <param name="camera">Camera</param> protected override void ControllerToCamera(Camera camera) { Vec3F lookAt = camera.LookAt; Vec3F right = camera.Right; Vec3F up = camera.Up; if (camera.ViewType == ViewTypes.Perspective) { Camera.PerspectiveNearZ = CalculatePerspectiveNearZ(); // override the camera's frame of reference float sinPhi = (float)Math.Sin(m_elevation); float cosPhi = (float)Math.Cos(m_elevation); float sinTheta = (float)Math.Sin(m_azimuth); float cosTheta = (float)Math.Cos(m_azimuth); lookAt = new Vec3F(-cosPhi * sinTheta, -sinPhi, -cosPhi * cosTheta); right = new Vec3F(cosTheta, 0, -sinTheta); up = Vec3F.Cross(right, lookAt); // TODO compute from sin/cos values } float lookAtOffset = 0; if (m_distanceFromLookAt < m_dollyThreshold) // do we need to start dollying? lookAtOffset = m_distanceFromLookAt - m_dollyThreshold; float eyeOffset = m_distanceFromLookAt; Camera.Set( m_lookAtPoint - (eyeOffset * lookAt), // eye point m_lookAtPoint - (lookAtOffset * lookAt), // look-at point up); // up vector base.ControllerToCamera(camera); }
/// <summary> /// Synchronizes the controller to the camera's current state</summary> /// <param name="camera">Camera</param> protected override void CameraToController(Camera camera) { m_lookAtPoint = Camera.LookAtPoint; m_distanceFromLookAt = Camera.DistanceFromLookAt; m_dollyThreshold = Camera.FocusRadius * 0.1f; Vec3F lookAtDir = Camera.LookAt; Vec3F up = Camera.Up; m_elevation = (float)Math.Asin(-lookAtDir.Y); if (up.Y < 0) { if (lookAtDir.Y > 0) m_elevation = -PI - m_elevation; else m_elevation = PI - m_elevation; m_azimuth = (float)Math.Atan2(lookAtDir.X, lookAtDir.Z); } else { m_azimuth = (float)Math.Atan2(-lookAtDir.X, -lookAtDir.Z); } base.CameraToController(camera); }
/// <summary> /// Gets whether this camera can handle the given camera</summary> /// <param name="camera">Camera</param> /// <returns>True iff this camera can handle the given camera</returns> public virtual bool CanHandleCamera(Camera camera) { return true; }
/// <summary> /// Gets a value indicating if this camera can handle the given camera</summary> /// <param name="camera">Camera</param> /// <returns>value indicating if this camera can handle the given camera</returns> public override bool CanHandleCamera(Camera camera) { return camera.ProjectionType != ProjectionType.Orthographic; }
/// <summary> /// Projects the specified x and y, in normalized window coordinates, onto the grid, /// and snaps it to the nearest grid vertex if necessary. /// Normalized window coordinates are in the range [-0.5,0.5] with +x pointing to the /// right and +y pointing up.</summary> /// <param name="x">Window x in normalized window coords</param> /// <param name="y">Window y in normalized window coords</param> /// <param name="camera">Camera</param> /// <returns>Projection of x and y onto the grid, in world space.</returns> public Vec3F Project(float x, float y, Camera camera) { Ray3F ray = camera.CreateRay(x, y); Matrix4F V = new Matrix4F(camera.ViewMatrix); V.Mul(m_invAxisSystem, V); if (camera.Frustum.IsOrtho) { V = new Matrix4F(m_V); V.Translation = camera.ViewMatrix.Translation; } // origin Vec3F delta = new Vec3F(0, Height, 0); V.Transform(delta, out delta); Vec3F o = delta; // Up vec Vec3F axis = V.YAxis; Vec3F projPt = ray.IntersectPlane(axis, -Vec3F.Dot(o, axis)); // Transform back into world space Matrix4F Inv = new Matrix4F(); Inv.Invert(camera.ViewMatrix); Inv.Transform(projPt, out projPt); if (Snap) { projPt = SnapPoint(projPt); } return projPt; }
/// <summary> /// Called after post visiting the SceneNode specified by the graph path</summary> /// <param name="graphPath">The graph path</param> /// <param name="action">The render action</param> /// <param name="camera">The camera</param> /// <param name="list">The traverse list</param> /// <returns></returns> public override TraverseState PostTraverse(Stack<SceneNode> graphPath, IRenderAction action, Camera camera, ICollection<TraverseNode> list) { action.PopMatrix(); return TraverseState.Continue; }
/// <summary> /// Synchronizes the controller to the camera's current state</summary> /// <param name="camera">Camera</param> /// <remarks>Both CameraToController and ControllerToCamera should be /// overridden for controllers that shadow camera state</remarks> protected virtual void CameraToController(Camera camera) { }
/// <summary> /// Performs any camera initialization required by the controller</summary> /// <param name="camera">Camera</param> protected virtual void Setup(Camera camera) { }
/// <summary> /// Synchronizes the controller to the camera's current state</summary> /// <param name="camera">Camera</param> protected override void CameraToController(Camera camera) { m_lookAtPoint = Camera.LookAtPoint; Vec3F lookAtVector = Camera.Eye - m_lookAtPoint; m_distanceFromLookAt = lookAtVector.Length; m_dollyThreshold = Camera.FocusRadius * 0.1f; m_rotation.Set(Camera.ViewMatrix); base.CameraToController(camera); }
/// <summary> /// Renders the specified graph path</summary> /// <param name="graphPath">The graph path</param> /// <param name="renderState">The render state</param> /// <param name="action">The render action</param> /// <param name="camera">The camera</param> protected override void Render(SceneNode[] graphPath, RenderState renderState, IRenderAction action, Camera camera) { // apply xform Gl.glPushMatrix(); Util3D.glMultMatrixf(action.TopMatrix); if (m_displayListId == 0) { RenderStats globalStats = Util3D.RenderStats; RenderStats ourStats = new RenderStats(); Util3D.RenderStats = ourStats; m_displayListId = Gl.glGenLists(1); #if MEMORY_DEBUG lock(s_lock) NumDisplayListIds++; #endif Gl.glNewList(m_displayListId, Gl.GL_COMPILE); Render(action); Gl.glEndList(); m_numPrimitives = ourStats.PrimCount; m_numVertices = ourStats.VertexCount; Util3D.RenderStats = globalStats; } Gl.glCallList(m_displayListId); Gl.glPopMatrix(); Util3D.RenderStats.PrimCount += m_numPrimitives; Util3D.RenderStats.VertexCount += m_numVertices; }
/// <summary> /// Synchronizes the camera to the controller's current state</summary> /// <param name="camera">Camera</param> protected override void ControllerToCamera(Camera camera) { Vec3F lookAt = Camera.LookAt; Vec3F up = Camera.Up; if (camera.ViewType == ViewTypes.Perspective) { QuatF rotation = m_rotation * m_currentRotation; rotation = rotation.Inverse; Matrix4F transform = new Matrix4F(rotation); lookAt = new Vec3F(0, 0, -1); up = new Vec3F(0, 1, 0); transform.Transform(ref lookAt); transform.Transform(ref up); } float eyeOffset = m_distanceFromLookAt; float lookAtOffset = 0; if (m_distanceFromLookAt < m_dollyThreshold) // do we need to start dollying? { eyeOffset = m_distanceFromLookAt; lookAtOffset = m_distanceFromLookAt - m_dollyThreshold; } Camera.Set( m_lookAtPoint - (eyeOffset * lookAt), // eye m_lookAtPoint - (lookAtOffset * lookAt), // lookAt up); // up base.ControllerToCamera(camera); }
/// <summary> /// Custom pick rendering</summary> /// <param name="graphPath">The graph path</param> /// <param name="renderState">The render state</param> /// <param name="action">The render action</param> /// <param name="camera">The camera</param> public void PickDispatch(SceneNode[] graphPath, RenderState renderState, IRenderAction action, Camera camera) { action.RenderStateGuardian.Commit(renderState); // apply xform Gl.glPushMatrix(); Util3D.glMultMatrixf(action.TopMatrix); RenderVertices(action); Gl.glPopMatrix(); }
/// <summary> /// Performs any camera initialization required by the controller</summary> /// <param name="camera">Camera</param> protected override void Setup(Camera camera) { camera.PerspectiveNearZ = 0.01f; }
/// <summary> /// Synchronizes the camera to the controller's current state</summary> /// <param name="camera">Camera</param> /// <remarks>Both CameraToController and ControllerToCamera should be /// overridden for controllers that shadow camera state</remarks> protected virtual void ControllerToCamera(Camera camera) { }