// in egocentric camera system the "eye" is moving up/down, which means the scene moves in opposite direction public void SceneRateControlledEgogentricPan(FScene scene, fCamera cam, Vector2f curPos, RateControlInfo rc) { float dt = (FPlatform.RealTime() - rc.lastTime); rc.lastTime = FPlatform.RealTime(); float delta_y = (curPos.y - rc.startPos.y); rc.curSpeedY = rc_update_speed(delta_y, rc.rampUpRadius, rc.deadZoneRadius, rc.maxAccel, rc.maxSpeed, dt, rc.curSpeedY); float delta_x = (curPos.x - rc.startPos.x); rc.curSpeedX = rc_update_speed(delta_x, rc.rampUpRadius, rc.deadZoneRadius, rc.maxAccel, rc.maxSpeed, dt, rc.curSpeedX); Frame3f camFrame = cam.GetWorldFrame(); Vector3f forward = camFrame.Z; Vector3f up = camFrame.Y; if (rc.StayLevel) { forward = new Vector3(forward.x, 0.0f, forward.z); forward.Normalize(); up = Vector3.up; } Vector3f right = Vector3.Cross(up, forward); Vector3f curScenePos = scene.RootGameObject.GetPosition(); Vector3f newScenePos = curScenePos - dt * (rc.curSpeedY * up + rc.curSpeedX * right); scene.RootGameObject.SetPosition(newScenePos); }
public static float DefaultHeightInM = 1.6f; // 1.6m ~= 5.5 feet // straight teleport: // camera points at hit point, we back off and set target at hit point static public void TeleportTowards(fCamera camera, FScene scene, Vector3f targetPoint, float fPullback) { fPullback *= scene.GetSceneScale(); Vector3f vCurCamFW = camera.GetWorldFrame().Z; Vector3f vNewCamPos = targetPoint - fPullback * vCurCamFW; Vector3f vNewTargetPos = vNewCamPos + fPullback * vCurCamFW; camera.Animator().Teleport(vNewCamPos, vNewTargetPos); }
// level teleport: // first we level the scene (ie scene up is y axis), then camera points // at ray hit point, pulled back along cam direction projected into xz plane static public void TeleportTowards_Level(fCamera camera, FScene scene, Vector3f targetPoint, float fPullback) { fPullback *= scene.GetSceneScale(); Vector3f vCurCamFW = camera.GetWorldFrame().Z; Vector3f vCurCamFWXZ = new Vector3f(vCurCamFW[0], 0.0f, vCurCamFW[2]).Normalized; Vector3f vNewCamPos = targetPoint - fPullback * vCurCamFWXZ; Vector3f vNewTargetPos = vNewCamPos + fPullback * vCurCamFWXZ; camera.Animator().Teleport_Level(vNewCamPos, vNewTargetPos); }
public void ScenePan(FScene scene, fCamera cam, float dx, float dy) { float fScale = scene.GetSceneScale(); Frame3f camFrame = cam.GetWorldFrame(); Vector3f right = camFrame.X; Vector3f up = camFrame.Y; Vector3f delta = dx * fScale * right + dy * fScale * up; Vector3f newPos = scene.RootGameObject.GetPosition() + delta; scene.RootGameObject.SetPosition(newPos); }
public void SceneAdaptivePan(FScene scene, fCamera cam, float xStepFraction, float yStepFraction) { float fScale = scene.GetSceneScale(); Vector3f fw = cam.GetTarget() - cam.GetPosition(); float fTargetDist = fw.Length; float dx = fTargetDist * xStepFraction; float dy = fTargetDist * yStepFraction; Frame3f camFrame = cam.GetWorldFrame(); Vector3f right = camFrame.X; Vector3f up = camFrame.Y; Vector3f delta = dx * fScale * right + dy * fScale * up; Vector3f newPos = scene.RootGameObject.GetPosition() + delta; scene.RootGameObject.SetPosition(newPos); }
// we orbit view to be level, then again so that the normal of the hit point points towards // the camera. Then we pull back along that direction. Unless we want to face away, // then we rotate an extra 180 degrees, and set the target out by the pullback distance static public void Teleport_LevelNormalOffset(fCamera camera, FScene scene, Vector3f targetPoint, Vector3f targetNormal, float fPullback, bool bFaceAwayFromSurface = false) { fPullback *= scene.GetSceneScale(); Vector3f vCurCamFW = camera.GetWorldFrame().Z; Vector3f vCurCamFWXZ = new Vector3f(vCurCamFW[0], 0.0f, vCurCamFW[2]).Normalized; Vector3f vHitNormalXZ = new Vector3f(targetNormal[0], 0.0f, targetNormal[2]).Normalized; float fFace = bFaceAwayFromSurface ? -1.0f : 1.0f; float fRotate = Vector3f.AngleD(-vCurCamFWXZ, fFace * vHitNormalXZ); float fSign = Vector3f.Cross(vCurCamFWXZ, fFace * vHitNormalXZ)[1] > 0 ? -1 : 1; fRotate *= fSign; // now we use cam instead of normal here because we rotated normal to face cam! Vector3f vNewCamPos = targetPoint - fFace * fPullback * vCurCamFWXZ; Vector3f vNewTargetPos = (bFaceAwayFromSurface) ? vNewCamPos + fPullback * vCurCamFWXZ : targetPoint; camera.Animator().Teleport_Level(vNewCamPos, vNewTargetPos, targetPoint, fRotate); }
public void ScenePanFocus(FScene scene, fCamera camera, Vector3f focusPoint, bool bAnimated) { CameraAnimator animator = camera.Animator(); if (bAnimated == false || animator == null) { // figure out the pan that we would apply to camera, then apply the delta to the scene Vector3f curPos = camera.GetPosition(); Vector3f curDir = camera.GetWorldFrame().Z; float fDist = Vector3.Dot((focusPoint - curPos), curDir); Vector3f newPos = focusPoint - fDist * curDir; Vector3f delta = curPos - newPos; scene.RootGameObject.Translate(delta, false); camera.SetTarget(focusPoint); } else { animator.PanFocus(focusPoint); } }
// vertical-offset level teleport // assumption is that target point is on ground or ceiling, and we want to offset vertically. // To do that we have to first reset orbit around the hit point. // One small problem here is that the output target pos is really arbitrary. perhaps we should // cast another ray into the scene in the forward direction? static public void Teleport_VerticalNormalOffset(fCamera camera, FScene scene, Vector3f targetPoint, Vector3f targetNormal, float fNewTargetDist) { fNewTargetDist *= scene.GetSceneScale(); Vector3f vCurCamFW = camera.GetWorldFrame().Z; Vector3f vCurCamFWXZ = new Vector3f(vCurCamFW[0], 0.0f, vCurCamFW[2]).Normalized; Vector3f vSceneUp = scene.RootGameObject.GetWorldFrame().Y; // when we are offsetting up we use the DefaultHeightInM value to set eye level, // when offsetting down we use half that distance (arbitrary) float fUp = Vector3f.Dot(targetNormal, vSceneUp) > 0 ? 1.0f : -0.5f; // [RMS] camera height does not work because OVRCameraRig sets eye-level to be origin!! //float fHeight = camera.GetPosition()[1] * scene.GetSceneScale(); //float fHeight = DefaultHeightInM * scene.GetSceneScale(); float fHeight = DefaultHeightInM * (float)Math.Sqrt(scene.GetSceneScale()); // don't scale! otherwise tiny offsets Vector3f vNewCamPos = targetPoint + fUp * fHeight * Vector3f.AxisY; Vector3f vNewTargetPos = vNewCamPos + fNewTargetDist * vCurCamFWXZ; camera.Animator().Teleport_Level(vNewCamPos, vNewTargetPos, targetPoint); }