private void SelectNextCamera() { if (cameras.Count < 2) { return; } ++currentCamera; if (currentCamera == cameras.Count) { currentCamera = 0; } bool gotCamera = cameraObject.PointCamera(cameras[currentCamera].cameraTransform, cameras[currentCamera].currentFoV); if (!skipMissingCameras) { if (rpmComp != null) { rpmComp.SetPropVar(cameraInfoVarName + "_ID", internalProp.propID, currentCamera + 1); } return; } int camerasTested = 1; while (!gotCamera && camerasTested < cameras.Count) { ++camerasTested; ++currentCamera; if (currentCamera == cameras.Count) { currentCamera = 0; } gotCamera = cameraObject.PointCamera(cameras[currentCamera].cameraTransform, cameras[currentCamera].currentFoV); } if (rpmComp != null) { rpmComp.SetPropVar(cameraInfoVarName + "_ID", internalProp.propID, currentCamera + 1); } }
public void Active(bool state) { if (state) { cameraObject.PointCamera(camera, ComputeFOV()); } if (pageHandlerS.activate != null) { pageHandlerS.activate(state, pageNumber); } if (backgroundHandlerS.activate != null && backgroundHandlerS.activate != pageHandlerS.activate) { backgroundHandlerS.activate(state, pageNumber); } if (cameraFlickerChance > 0) { cameraObject.SetFlicker(cameraFlickerChance, cameraFlickerRange); } else { cameraObject.SetFlicker(0, 0); } }
/// <summary> /// Initialize the renderable game objects for the HUD. /// </summary> /// <param name="screenWidth"></param> /// <param name="screenHeight"></param> void InitializeRenderables(RenderTexture screen) { float screenWidth = (float)screen.width; float screenHeight = (float)screen.height; Shader displayShader = JUtil.LoadInternalShader("RPM-DisplayShader"); if (!string.IsNullOrEmpty(cameraTransform)) { cameraObject = new FlyingCamera(part, screen, hudCamera.aspect); cameraObject.PointCamera(cameraTransform, hudFov); } if (!string.IsNullOrEmpty(staticOverlay)) { Material overlayMaterial = new Material(displayShader); overlayMaterial.color = Color.white; Texture overlayTexture = GameDatabase.Instance.GetTexture(staticOverlay.EnforceSlashes(), false); overlayMaterial.mainTexture = overlayTexture; overlayMesh = JUtil.CreateSimplePlane("JSIHeadsUpDisplayOverlay" + hudCamera.GetInstanceID(), screenWidth * 0.5f, drawingLayer); overlayMesh.transform.position = new Vector3(0, 0, 1.0f); overlayMesh.renderer.material = overlayMaterial; overlayMesh.transform.parent = cameraBody.transform; JUtil.ShowHide(false, overlayMesh); } if (!string.IsNullOrEmpty(horizonTexture)) { Shader ladderShader = JUtil.LoadInternalShader("RPM-CroppedDisplayShader"); Material ladderMaterial = new Material(ladderShader); // _CropBound is in device normalized coordinates (-1 - +1) Vector4 cropBound = new Vector4(-horizonSize.x / screenWidth, -horizonSize.y / screenHeight, horizonSize.x / screenWidth, horizonSize.y / screenHeight); ladderMaterial.SetVector("_CropBound", cropBound); ladderMaterial.color = Color.white; ladderMaterial.mainTexture = GameDatabase.Instance.GetTexture(horizonTexture.EnforceSlashes(), false); if (ladderMaterial.mainTexture != null) { horizonTextureSize.x = 0.5f * (horizonTextureSize.x / ladderMaterial.mainTexture.width); horizonTextureSize.y = 0.5f * (horizonTextureSize.y / ladderMaterial.mainTexture.height); ladderMaterial.mainTexture.wrapMode = TextureWrapMode.Clamp; ladderMesh = JUtil.CreateSimplePlane("JSIHeadsUpDisplayLadder" + hudCamera.GetInstanceID(), new Vector2(horizonSize.x * 0.5f, horizonSize.y * 0.5f), new Rect(0.0f, 0.0f, 1.0f, 1.0f), drawingLayer); ladderMesh.transform.position = new Vector3(0, 0, 1.4f); ladderMesh.renderer.material = ladderMaterial; ladderMesh.transform.parent = cameraBody.transform; JUtil.ShowHide(false, ladderMesh); if (progradeColorValue.a > 0.0f && showLadderPrograde) { Material progradeIconMaterial = new Material(displayShader); progradeIconMaterial.color = Color.white; Rect texCoord; if (string.IsNullOrEmpty(ladderProgradeTexture)) { progradeIconMaterial.mainTexture = JUtil.GetGizmoTexture(); texCoord = GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE); } else { Texture2D progradeTexture = GameDatabase.Instance.GetTexture(ladderProgradeTexture.EnforceSlashes(), false); if (progradeTexture == null) { JUtil.LogErrorMessage(this, "Failed to find ladder prograde texture \"{0}\".", ladderProgradeTexture); } progradeIconMaterial.mainTexture = progradeTexture; texCoord = new Rect(0.0f, 0.0f, 1.0f, 1.0f); } progradeIconMaterial.SetVector("_Color", progradeColorValue); progradeLadderIcon = JUtil.CreateSimplePlane("JSIHeadsUpDisplayLadderProgradeIcon" + hudCamera.GetInstanceID(), new Vector2(iconPixelSize * 0.5f, iconPixelSize * 0.5f), texCoord, drawingLayer); progradeLadderIcon.transform.position = new Vector3(0.0f, 0.0f, 1.35f); progradeLadderIcon.renderer.material = progradeIconMaterial; progradeLadderIcon.transform.parent = cameraBody.transform; } } } if (!string.IsNullOrEmpty(headingBar)) { Material headingMaterial = new Material(displayShader); headingMaterial.color = Color.white; headingMaterial.mainTexture = GameDatabase.Instance.GetTexture(headingBar.EnforceSlashes(), false); if (headingMaterial.mainTexture != null) { headingBarTextureWidth = 0.5f * (headingBarWidth / (float)headingMaterial.mainTexture.width); headingMaterial.mainTexture.wrapMode = TextureWrapMode.Repeat; headingMesh = JUtil.CreateSimplePlane("JSIHeadsUpDisplayHeading" + hudCamera.GetInstanceID(), new Vector2(headingBarPosition.z * 0.5f, headingBarPosition.w * 0.5f), new Rect(0.0f, 0.0f, 1.0f, 1.0f), drawingLayer); headingMesh.transform.position = new Vector3(headingBarPosition.x + 0.5f * (headingBarPosition.z - screenWidth), 0.5f * (screenHeight - headingBarPosition.w) - headingBarPosition.y, 1.4f); headingMesh.renderer.material = headingMaterial; headingMesh.transform.parent = cameraBody.transform; JUtil.ShowHide(false, headingMesh); if (progradeColorValue.a > 0.0f && showHeadingBarPrograde) { Material progradeIconMaterial = new Material(displayShader); progradeIconMaterial.color = Color.white; Rect texCoord; if (string.IsNullOrEmpty(headingBarProgradeTexture)) { progradeIconMaterial.mainTexture = JUtil.GetGizmoTexture(); texCoord = GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE); } else { Texture2D progradeTexture = GameDatabase.Instance.GetTexture(headingBarProgradeTexture.EnforceSlashes(), false); if (progradeTexture == null) { JUtil.LogErrorMessage(this, "Failed to find heading bar prograde texture \"{0}\".", headingBarProgradeTexture); } progradeIconMaterial.mainTexture = progradeTexture; texCoord = new Rect(0.0f, 0.0f, 1.0f, 1.0f); } progradeIconMaterial.SetVector("_Color", progradeColorValue); progradeHeadingIconOrigin = headingBarPosition.x + 0.5f * (headingBarPosition.z - screenWidth); progradeHeadingIcon = JUtil.CreateSimplePlane("JSIHeadsUpDisplayHeadingProgradeIcon" + hudCamera.GetInstanceID(), new Vector2(iconPixelSize * 0.5f, iconPixelSize * 0.5f), texCoord, drawingLayer); progradeHeadingIcon.transform.position = new Vector3(progradeHeadingIconOrigin, 0.5f * (screenHeight - headingBarPosition.w) - headingBarPosition.y, 1.35f); progradeHeadingIcon.renderer.material = progradeIconMaterial; progradeHeadingIcon.transform.parent = headingMesh.transform; } } } if (!string.IsNullOrEmpty(verticalBar)) { ConfigNode[] nodes = GameDatabase.Instance.GetConfigNodes("JSIHUD_VERTICAL_BAR"); string[] vBars = verticalBar.Split(';'); for (int i = 0; i < vBars.Length; ++i) { for (int j = 0; j < nodes.Length; ++j) { if (nodes[j].HasValue("name") && vBars[i].Trim() == nodes[j].GetValue("name")) { try { VerticalBar vb = new VerticalBar(nodes[j], screenWidth, screenHeight, drawingLayer, displayShader, cameraBody); verticalBars.Add(vb); } catch (Exception e) { JUtil.LogErrorMessage(this, "Error parsing JSIHUD_VERTICAL_BAR: {0}", e); } break; } } } } }
public void ClickProcessor(int buttonID) { if (cameraObject == null) { return; } if (cameras.Count < 1) { return; } if (buttonID == zoomIn) { zoomDirection = -1.0f; yawDirection = 0.0f; pitchDirection = 0.0f; } else if (buttonID == zoomOut) { zoomDirection = 1.0f; yawDirection = 0.0f; pitchDirection = 0.0f; } else if (buttonID == yawLeft) { zoomDirection = 0.0f; yawDirection = -1.0f; pitchDirection = 0.0f; cameras[currentCamera].seekHome = false; } else if (buttonID == yawRight) { zoomDirection = 0.0f; yawDirection = 1.0f; pitchDirection = 0.0f; cameras[currentCamera].seekHome = false; } else if (buttonID == pitchUp) { zoomDirection = 0.0f; yawDirection = 0.0f; pitchDirection = 1.0f; cameras[currentCamera].seekHome = false; } else if (buttonID == pitchDown) { zoomDirection = 0.0f; yawDirection = 0.0f; pitchDirection = -1.0f; cameras[currentCamera].seekHome = false; } else if (buttonID == toggleTargetIcon) { showTargetIcon = !showTargetIcon; } else if (buttonID == nextCamera) { // Stop current camera motion, since we're not going to update it. cameras[currentCamera].seekHome = false; ++currentCamera; if (currentCamera == cameras.Count) { currentCamera = 0; } cameraObject.PointCamera(cameras[currentCamera].cameraTransform, cameras[currentCamera].currentFoV); } else if (buttonID == prevCamera) { // Stop current camera motion, since we're not going to update it. cameras[currentCamera].seekHome = false; if (currentCamera == 0) { currentCamera = cameras.Count - 1; } else { --currentCamera; } cameraObject.PointCamera(cameras[currentCamera].cameraTransform, cameras[currentCamera].currentFoV); } else if (buttonID == seekHome) { cameras[currentCamera].seekHome = true; } // Always reset the lastUpdateTime on a button click, in case it // has been a while since the last click. lastUpdateTime = Planetarium.GetUniversalTime(); }
public bool RenderCamera(RenderTexture screen, float cameraAspect) { // Just in case. if (!HighLogic.LoadedSceneIsFlight) { return(false); } if (cameras.Count < 1) { return(false); } var activeCamera = cameras[currentCamera]; if (string.IsNullOrEmpty(activeCamera.cameraTransform)) { return(false); } if (cameraObject == null) { cameraObject = new FlyingCamera(part, screen, cameraAspect); cameraObject.PointCamera(activeCamera.cameraTransform, activeCamera.currentFoV); } cameraObject.FOV = activeCamera.currentFoV; // Negate pitch - the camera object treats a negative pitch as "up" if (cameraObject.Render(activeCamera.currentYaw, -activeCamera.currentPitch)) { ITargetable target = FlightGlobals.fetch.VesselTarget; bool drawSomething = ((gizmoTexture != null && target != null && showTargetIcon) || homeCrosshairMaterial.color.a > 0); if (drawSomething) { GL.PushMatrix(); GL.LoadPixelMatrix(0, screen.width, screen.height, 0); } if (gizmoTexture != null && target != null && showTargetIcon) { // Figure out which direction the target is. Vector3 targetDisplacement = target.GetTransform().position - cameraObject.GetTransform().position; targetDisplacement.Normalize(); // Transform it using the active camera's rotation. var targetDisp = GetNormalizedScreenPosition(activeCamera, targetDisplacement, cameraAspect); var iconCenter = new Vector2(screen.width * targetDisp.x, screen.height * targetDisp.y); // Apply some clamping values to force the icon to stay on screen iconCenter.x = Math.Max(iconPixelSize * 0.5f, iconCenter.x); iconCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, iconCenter.x); iconCenter.y = Math.Max(iconPixelSize * 0.5f, iconCenter.y); iconCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, iconCenter.y); var position = new Rect(iconCenter.x - iconPixelSize * 0.5f, iconCenter.y - iconPixelSize * 0.5f, iconPixelSize, iconPixelSize); Graphics.DrawTexture(position, gizmoTexture, GizmoIcons.GetIconLocation(GizmoIcons.IconType.TARGETPLUS), 0, 0, 0, 0, iconMaterial); } if (homeCrosshairMaterial.color.a > 0) { // Mihara: Reference point cameras are different enough to warrant it. var cameraForward = cameraObject.GetTransformForward(); var crossHairCenter = GetNormalizedScreenPosition(activeCamera, cameraForward, cameraAspect); crossHairCenter.x *= screen.width; crossHairCenter.y *= screen.height; crossHairCenter.x = Math.Max(iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.y = Math.Max(iconPixelSize * 0.5f, crossHairCenter.y); crossHairCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, crossHairCenter.y); float zoomAdjustedIconSize = iconPixelSize * Mathf.Tan(Mathf.Deg2Rad * activeCamera.fovLimits.y * 0.5f) / Mathf.Tan(Mathf.Deg2Rad * activeCamera.currentFoV * 0.5f); homeCrosshairMaterial.SetPass(0); GL.Begin(GL.LINES); GL.Vertex3(crossHairCenter.x - zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x + zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y - zoomAdjustedIconSize * 0.5f, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y + zoomAdjustedIconSize * 0.5f, 0.0f); GL.End(); } if (drawSomething) { GL.PopMatrix(); } return(true); } return(false); }
public bool RenderCamera(RenderTexture screen, float cameraAspect) { // Just in case. if (HighLogic.LoadedSceneIsEditor) { return false; } if(cameras.Count < 1) { return false; } var activeCamera = cameras[currentCamera]; if (string.IsNullOrEmpty(activeCamera.cameraTransform)) { return false; } if (cameraObject == null) { cameraObject = new FlyingCamera(part, screen, cameraAspect); cameraObject.PointCamera(activeCamera.cameraTransform, activeCamera.currentFoV); } cameraObject.FOV = activeCamera.currentFoV; // Negate pitch - the camera object treats a negative pitch as "up" if (cameraObject.Render(activeCamera.currentYaw, -activeCamera.currentPitch)) { ITargetable target = FlightGlobals.fetch.VesselTarget; bool drawSomething = ((gizmoTexture != null && target != null && showTargetIcon) || homeCrosshairMaterial.color.a > 0); if (drawSomething) { GL.PushMatrix(); GL.LoadPixelMatrix(0, screen.width, screen.height, 0); } if (gizmoTexture != null && target != null && showTargetIcon) { // Figure out which direction the target is. Vector3 targetDisplacement = target.GetTransform().position - cameraObject.GetTransform().position; targetDisplacement.Normalize(); // Transform it using the active camera's rotation. var targetDisp = GetNormalizedScreenPosition(activeCamera, targetDisplacement, cameraAspect); var iconCenter = new Vector2(screen.width * targetDisp.x, screen.height * targetDisp.y); // Apply some clamping values to force the icon to stay on screen iconCenter.x = Math.Max(iconPixelSize * 0.5f, iconCenter.x); iconCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, iconCenter.x); iconCenter.y = Math.Max(iconPixelSize * 0.5f, iconCenter.y); iconCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, iconCenter.y); var position = new Rect(iconCenter.x - iconPixelSize * 0.5f, iconCenter.y - iconPixelSize * 0.5f, iconPixelSize, iconPixelSize); Graphics.DrawTexture(position, gizmoTexture, GizmoIcons.GetIconLocation(GizmoIcons.IconType.TARGETPLUS), 0, 0, 0, 0, iconMaterial); } if (homeCrosshairMaterial.color.a > 0) { // Mihara: Reference point cameras are different enough to warrant it. var cameraForward = cameraObject.GetTransformForward(); var crossHairCenter = GetNormalizedScreenPosition(activeCamera, cameraForward, cameraAspect); crossHairCenter.x *= screen.width; crossHairCenter.y *= screen.height; crossHairCenter.x = Math.Max(iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.y = Math.Max(iconPixelSize * 0.5f, crossHairCenter.y); crossHairCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, crossHairCenter.y); float zoomAdjustedIconSize = iconPixelSize * Mathf.Tan(Mathf.Deg2Rad * activeCamera.fovLimits.y * 0.5f) / Mathf.Tan(Mathf.Deg2Rad * activeCamera.currentFoV * 0.5f); homeCrosshairMaterial.SetPass(0); GL.Begin(GL.LINES); GL.Vertex3(crossHairCenter.x - zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x + zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y - zoomAdjustedIconSize * 0.5f, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y + zoomAdjustedIconSize * 0.5f, 0.0f); GL.End(); } if (drawSomething) { GL.PopMatrix(); } return true; } return false; }
public bool RenderHUD(RenderTexture screen, float cameraAspect) { if (screen == null || !startupComplete || HighLogic.LoadedSceneIsEditor) return false; // Clear the background, if configured. GL.Clear(true, true, backgroundColorValue); // Configure the camera, if configured. // MOARdV: Might be worthwhile to refactor the flying camera so // it is created in Start (like new FlyingCamera(part, cameraTransform)), // and pass the screen, FoV, and aspect ratio (or just screen and // FoV) as Render parameters, so there's no need to test if the // camera's been created every render call. if (cameraObject == null && !string.IsNullOrEmpty(cameraTransform)) { cameraObject = new FlyingCamera(part, screen, cameraAspect); cameraObject.PointCamera(cameraTransform, hudFov); } // Draw the camera's view, if configured. if (cameraObject != null) { cameraObject.Render(); } // Configure the matrix so that the origin is the center of the screen. GL.PushMatrix(); // Draw the HUD ladder // MOARdV note, 2014/03/19: swapping the y values, to invert the // coordinates so the prograde icon is right-side up. GL.LoadPixelMatrix(-horizonSize.x * 0.5f, horizonSize.x * 0.5f, horizonSize.y * 0.5f, -horizonSize.y * 0.5f); GL.Viewport(new Rect((screen.width - horizonSize.x) * 0.5f, (screen.height - horizonSize.y) * 0.5f, horizonSize.x, horizonSize.y)); Vector3 coM = vessel.findWorldCenterOfMass(); Vector3 up = (coM - vessel.mainBody.position).normalized; Vector3 forward = vessel.GetTransform().up; Vector3 right = vessel.GetTransform().right; Vector3 top = Vector3.Cross(right, forward); Vector3 north = Vector3.Exclude(up, (vessel.mainBody.position + (Vector3d)vessel.mainBody.transform.up * vessel.mainBody.Radius) - coM).normalized; Vector3d velocityVesselSurface = vessel.orbit.GetVel() - vessel.mainBody.getRFrmVel(coM); Vector3 velocityVesselSurfaceUnit = velocityVesselSurface.normalized; if (ladderMaterial) { // Figure out the texture coordinate scaling for the ladder. float ladderTextureOffset = horizonTextureSize.y / ladderMaterial.mainTexture.height; float cosUp = Vector3.Dot(forward, up); float cosRoll = Vector3.Dot(top, up); float sinRoll = Vector3.Dot(right, up); var normalizedRoll = new Vector2(cosRoll, sinRoll); normalizedRoll.Normalize(); if (normalizedRoll.magnitude < 0.99f) { // If we're hitting +/- 90 nearly perfectly, the sin and cos will // be too far out of whack to normalize. Arbitrarily pick // a roll of 0.0. normalizedRoll.x = 1.0f; normalizedRoll.y = 0.0f; } cosRoll = normalizedRoll.x; sinRoll = normalizedRoll.y; // Mihara: I'm pretty sure this was negative of what it should actually be, at least according to my mockup. float pitch = -(Mathf.Asin(cosUp) * Mathf.Rad2Deg); float ladderMidpointCoord; if (use360horizon) { // Straight up is texture coord 0.75; // Straight down is TC 0.25; ladderMidpointCoord = JUtil.DualLerp(0.25f, 0.75f, -90f, 90f, pitch); } else { // Straight up is texture coord 1.0; // Straight down is TC 0.0; ladderMidpointCoord = JUtil.DualLerp(0.0f, 1.0f, -90f, 90f, pitch); } ladderMaterial.SetPass(0); GL.Begin(GL.QUADS); // transform -x -y GL.TexCoord2(0.5f + horizonTextureSize.x, ladderMidpointCoord - ladderTextureOffset); GL.Vertex3(cosRoll * horizonSize.x + sinRoll * horizonSize.y, -sinRoll * horizonSize.x + cosRoll * horizonSize.y, 0.0f); // transform +x -y GL.TexCoord2(0.5f - horizonTextureSize.x, ladderMidpointCoord - ladderTextureOffset); GL.Vertex3(-cosRoll * horizonSize.x + sinRoll * horizonSize.y, sinRoll * horizonSize.x + cosRoll * horizonSize.y, 0.0f); // transform +x +y GL.TexCoord2(0.5f - horizonTextureSize.x, ladderMidpointCoord + ladderTextureOffset); GL.Vertex3(-cosRoll * horizonSize.x - sinRoll * horizonSize.y, sinRoll * horizonSize.x - cosRoll * horizonSize.y, 0.0f); // transform -x +y GL.TexCoord2(0.5f + horizonTextureSize.x, ladderMidpointCoord + ladderTextureOffset); GL.Vertex3(cosRoll * horizonSize.x - sinRoll * horizonSize.y, -sinRoll * horizonSize.x - cosRoll * horizonSize.y, 0.0f); GL.End(); float AoA = velocityVesselSurfaceUnit.AngleInPlane(right, forward); float AoATC; if (use360horizon) { // Straight up is texture coord 0.75; // Straight down is TC 0.25; AoATC = JUtil.DualLerp(0.25f, 0.75f, -90f, 90f, pitch + AoA); } else { // Straight up is texture coord 1.0; // Straight down is TC 0.0; AoATC = JUtil.DualLerp(0.0f, 1.0f, -90f, 90f, pitch + AoA); } float Ypos = JUtil.DualLerp( -horizonSize.y, horizonSize.y, ladderMidpointCoord - ladderTextureOffset, ladderMidpointCoord + ladderTextureOffset, AoATC); // Placing the icon on the (0, Ypos) location, so simplify the transform. DrawIcon(-sinRoll * Ypos, -cosRoll * Ypos, GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE), progradeColorValue); } // Draw the rest of the HUD stuff (0,0) is the top left corner of the screen. GL.LoadPixelMatrix(0, screen.width, screen.height, 0); GL.Viewport(new Rect(0, 0, screen.width, screen.height)); if (headingMaterial != null) { Quaternion rotationSurface = Quaternion.LookRotation(north, up); Quaternion rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface); float headingTexture = JUtil.DualLerp(0f, 1f, 0f, 360f, rotationVesselSurface.eulerAngles.y); float headingTextureOffset = (headingBarWidth / headingMaterial.mainTexture.width) / 2; headingMaterial.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(headingTexture - headingTextureOffset, 1.0f); GL.Vertex3(headingBarPosition.x, headingBarPosition.y, 0.0f); GL.TexCoord2(headingTexture + headingTextureOffset, 1.0f); GL.Vertex3(headingBarPosition.x + headingBarPosition.z, headingBarPosition.y, 0.0f); GL.TexCoord2(headingTexture + headingTextureOffset, 0.0f); GL.Vertex3(headingBarPosition.x + headingBarPosition.z, headingBarPosition.y + headingBarPosition.w, 0.0f); GL.TexCoord2(headingTexture - headingTextureOffset, 0.0f); GL.Vertex3(headingBarPosition.x, headingBarPosition.y + headingBarPosition.w, 0.0f); GL.End(); if (showHeadingBarPrograde) { float slipAngle = velocityVesselSurfaceUnit.AngleInPlane(up, forward); float slipTC = JUtil.DualLerp(0f, 1f, 0f, 360f, rotationVesselSurface.eulerAngles.y + slipAngle); float slipIconX = JUtil.DualLerp(headingBarPosition.x, headingBarPosition.x + headingBarPosition.z, headingTexture - headingTextureOffset, headingTexture + headingTextureOffset, slipTC); DrawIcon(slipIconX, headingBarPosition.y + headingBarPosition.w * 0.5f, GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE), progradeColorValue); } } if (vertBar1Material != null) { float value = comp.ProcessVariable(vertBar1Variable).MassageToFloat(); if (float.IsNaN(value)) { value = 0.0f; } if (vertBar1UseLog10) { value = JUtil.PseudoLog10(value); } float vertBar1TexCoord = JUtil.DualLerp(vertBar1TextureLimit.x, vertBar1TextureLimit.y, vertBar1Limit.x, vertBar1Limit.y, value); vertBar1Material.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, vertBar1TexCoord + vertBar1TextureSize); GL.Vertex3(vertBar1Position.x, vertBar1Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar1TexCoord + vertBar1TextureSize); GL.Vertex3(vertBar1Position.x + vertBar1Position.z, vertBar1Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar1TexCoord - vertBar1TextureSize); GL.Vertex3(vertBar1Position.x + vertBar1Position.z, vertBar1Position.y + vertBar1Position.w, 0.0f); GL.TexCoord2(0.0f, vertBar1TexCoord - vertBar1TextureSize); GL.Vertex3(vertBar1Position.x, vertBar1Position.y + vertBar1Position.w, 0.0f); GL.End(); } if (vertBar2Material != null) { float value = comp.ProcessVariable(vertBar2Variable).MassageToFloat(); if (float.IsNaN(value)) { value = 0.0f; } if (vertBar2UseLog10) { value = JUtil.PseudoLog10(value); } float vertBar2TexCoord = JUtil.DualLerp(vertBar2TextureLimit.x, vertBar2TextureLimit.y, vertBar2Limit.x, vertBar2Limit.y, value); vertBar2Material.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, vertBar2TexCoord + vertBar2TextureSize); GL.Vertex3(vertBar2Position.x, vertBar2Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar2TexCoord + vertBar2TextureSize); GL.Vertex3(vertBar2Position.x + vertBar2Position.z, vertBar2Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar2TexCoord - vertBar2TextureSize); GL.Vertex3(vertBar2Position.x + vertBar2Position.z, vertBar2Position.y + vertBar2Position.w, 0.0f); GL.TexCoord2(0.0f, vertBar2TexCoord - vertBar2TextureSize); GL.Vertex3(vertBar2Position.x, vertBar2Position.y + vertBar2Position.w, 0.0f); GL.End(); } if (overlayMaterial != null) { overlayMaterial.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 0.0f, 0.0f); GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(screen.width, 0.0f, 0.0f); GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(screen.width, screen.height, 0.0f); GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, screen.height, 0.0f); GL.End(); } GL.PopMatrix(); return true; }
/// <summary> /// Initialize the renderable game objects for the HUD. /// </summary> /// <param name="screenWidth"></param> /// <param name="screenHeight"></param> void InitializeRenderables(RenderTexture screen) { float screenWidth = (float)screen.width; float screenHeight = (float)screen.height; Shader displayShader = JUtil.LoadInternalShader("RPM-DisplayShader"); if (!string.IsNullOrEmpty(cameraTransform)) { cameraObject = new FlyingCamera(part, screen, hudCamera.aspect); cameraObject.PointCamera(cameraTransform, hudFov); } if (!string.IsNullOrEmpty(staticOverlay)) { Material overlayMaterial = new Material(displayShader); overlayMaterial.color = Color.white; Texture overlayTexture = GameDatabase.Instance.GetTexture(staticOverlay.EnforceSlashes(), false); overlayMaterial.mainTexture = overlayTexture; overlayMesh = JUtil.CreateSimplePlane("JSIHeadsUpDisplayOverlay" + hudCamera.GetInstanceID(), screenWidth * 0.5f, drawingLayer); overlayMesh.transform.position = new Vector3(0, 0, 1.0f); overlayMesh.GetComponent <Renderer>().material = overlayMaterial; overlayMesh.transform.parent = cameraBody.transform; JUtil.ShowHide(false, overlayMesh); } if (!string.IsNullOrEmpty(horizonTexture)) { Shader ladderShader = JUtil.LoadInternalShader("RPM-CroppedDisplayShader"); Material ladderMaterial = new Material(ladderShader); // _CropBound is in device normalized coordinates (-1 - +1) Vector4 cropBound = new Vector4(-horizonSize.x / screenWidth, -horizonSize.y / screenHeight, horizonSize.x / screenWidth, horizonSize.y / screenHeight); ladderMaterial.SetVector("_CropBound", cropBound); ladderMaterial.color = Color.white; ladderMaterial.mainTexture = GameDatabase.Instance.GetTexture(horizonTexture.EnforceSlashes(), false); if (ladderMaterial.mainTexture != null) { float diagonal = horizonSize.magnitude / Mathf.Min(horizonSize.x, horizonSize.y) * 0.5f; Vector2 horizonDrawSize = diagonal * horizonSize; horizonTextureSize.x = 0.5f * (horizonTextureSize.x / ladderMaterial.mainTexture.width); horizonTextureSize.y = 0.5f * (horizonTextureSize.y / ladderMaterial.mainTexture.height); ladderMaterial.mainTexture.wrapMode = TextureWrapMode.Clamp; ladderMesh = JUtil.CreateSimplePlane("JSIHeadsUpDisplayLadder" + hudCamera.GetInstanceID(), horizonDrawSize, new Rect(0.0f, 0.0f, 1.0f, 1.0f), drawingLayer); ladderMesh.transform.position = new Vector3(0, 0, 1.45f); ladderMesh.GetComponent <Renderer>().material = ladderMaterial; ladderMesh.transform.parent = cameraBody.transform; JUtil.ShowHide(false, ladderMesh); if (progradeColorValue.a > 0.0f && showLadderPrograde) { Material progradeIconMaterial = new Material(displayShader); progradeIconMaterial.color = Color.white; Rect texCoord; if (string.IsNullOrEmpty(ladderProgradeTexture)) { progradeIconMaterial.mainTexture = JUtil.GetGizmoTexture(); texCoord = GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE); } else { Texture2D progradeTexture = GameDatabase.Instance.GetTexture(ladderProgradeTexture.EnforceSlashes(), false); if (progradeTexture == null) { JUtil.LogErrorMessage(this, "Failed to find ladder prograde texture \"{0}\".", ladderProgradeTexture); } progradeIconMaterial.mainTexture = progradeTexture; texCoord = new Rect(0.0f, 0.0f, 1.0f, 1.0f); } progradeIconMaterial.SetVector("_Color", progradeColorValue); progradeLadderIcon = JUtil.CreateSimplePlane("JSIHeadsUpDisplayLadderProgradeIcon" + hudCamera.GetInstanceID(), new Vector2(iconPixelSize * 0.5f, iconPixelSize * 0.5f), texCoord, drawingLayer); progradeLadderIcon.transform.position = new Vector3(0.0f, 0.0f, 1.41f); progradeLadderIcon.GetComponent <Renderer>().material = progradeIconMaterial; progradeLadderIcon.transform.parent = cameraBody.transform; } } } if (!string.IsNullOrEmpty(headingBar)) { Material headingMaterial = new Material(displayShader); headingMaterial.color = Color.white; headingMaterial.mainTexture = GameDatabase.Instance.GetTexture(headingBar.EnforceSlashes(), false); if (headingMaterial.mainTexture != null) { headingBarTextureWidth = 0.5f * (headingBarWidth / (float)headingMaterial.mainTexture.width); headingMaterial.mainTexture.wrapMode = TextureWrapMode.Repeat; headingMesh = JUtil.CreateSimplePlane("JSIHeadsUpDisplayHeading" + hudCamera.GetInstanceID(), new Vector2(headingBarPosition.z * 0.5f, headingBarPosition.w * 0.5f), new Rect(0.0f, 0.0f, 1.0f, 1.0f), drawingLayer); headingMesh.transform.position = new Vector3(headingBarPosition.x + 0.5f * (headingBarPosition.z - screenWidth), 0.5f * (screenHeight - headingBarPosition.w) - headingBarPosition.y, 1.4f); headingMesh.GetComponent <Renderer>().material = headingMaterial; headingMesh.transform.parent = cameraBody.transform; JUtil.ShowHide(false, headingMesh); if (progradeColorValue.a > 0.0f && showHeadingBarPrograde) { Material progradeIconMaterial = new Material(displayShader); progradeIconMaterial.color = Color.white; Rect texCoord; if (string.IsNullOrEmpty(headingBarProgradeTexture)) { progradeIconMaterial.mainTexture = JUtil.GetGizmoTexture(); texCoord = GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE); } else { Texture2D progradeTexture = GameDatabase.Instance.GetTexture(headingBarProgradeTexture.EnforceSlashes(), false); if (progradeTexture == null) { JUtil.LogErrorMessage(this, "Failed to find heading bar prograde texture \"{0}\".", headingBarProgradeTexture); } progradeIconMaterial.mainTexture = progradeTexture; texCoord = new Rect(0.0f, 0.0f, 1.0f, 1.0f); } progradeIconMaterial.SetVector("_Color", progradeColorValue); progradeHeadingIconOrigin = headingBarPosition.x + 0.5f * (headingBarPosition.z - screenWidth); progradeHeadingIcon = JUtil.CreateSimplePlane("JSIHeadsUpDisplayHeadingProgradeIcon" + hudCamera.GetInstanceID(), new Vector2(iconPixelSize * 0.5f, iconPixelSize * 0.5f), texCoord, drawingLayer); progradeHeadingIcon.transform.position = new Vector3(progradeHeadingIconOrigin, 0.5f * (screenHeight - headingBarPosition.w) - headingBarPosition.y, 1.35f); progradeHeadingIcon.GetComponent <Renderer>().material = progradeIconMaterial; progradeHeadingIcon.transform.parent = headingMesh.transform; } } } if (!string.IsNullOrEmpty(verticalBar)) { ConfigNode[] nodes = GameDatabase.Instance.GetConfigNodes("JSIHUD_VERTICAL_BAR"); string[] vBars = verticalBar.Split(';'); for (int i = 0; i < vBars.Length; ++i) { for (int j = 0; j < nodes.Length; ++j) { if (nodes[j].HasValue("name") && vBars[i].Trim() == nodes[j].GetValue("name")) { try { VerticalBar vb = new VerticalBar(nodes[j], screenWidth, screenHeight, drawingLayer, displayShader, cameraBody); verticalBars.Add(vb); } catch (Exception e) { JUtil.LogErrorMessage(this, "Error parsing JSIHUD_VERTICAL_BAR: {0}", e); } break; } } } } if (!string.IsNullOrEmpty(horizontalBar)) { ConfigNode[] nodes = GameDatabase.Instance.GetConfigNodes("JSIHUD_HORIZONTAL_BAR"); string[] hBars = horizontalBar.Split(';'); for (int i = 0; i < hBars.Length; ++i) { for (int j = 0; j < nodes.Length; ++j) { if (nodes[j].HasValue("name") && hBars[i].Trim() == nodes[j].GetValue("name")) { try { HorizontalBar hb = new HorizontalBar(nodes[j], screenWidth, screenHeight, drawingLayer, displayShader, cameraBody); horizontalBars.Add(hb); } catch (Exception e) { JUtil.LogErrorMessage(this, "Error parsing JSIHUD_HORIZONTAL_BAR: {0}", e); } break; } } } } }
public bool RenderCamera(RenderTexture screen, float cameraAspect) { // Just in case. if (HighLogic.LoadedSceneIsEditor) { return(false); } if (cameras.Count < 1) { return(false); } var activeCamera = cameras[currentCamera]; if (string.IsNullOrEmpty(activeCamera.cameraTransform)) { return(false); } if (cameraObject == null) { cameraObject = new FlyingCamera(part, cameraAspect); cameraObject.PointCamera(activeCamera.cameraTransform, activeCamera.currentFoV); } cameraObject.FOV = activeCamera.currentFoV; if (rentexWidth == 0) { rentexWidth = screen.width; rentexHeight = screen.height; // Note to self: when rentex dims != screen dims, the FOV seems to be wrong (like FOV is smaller). } if (renderTex == null) { renderTex = new RenderTexture(rentexWidth, rentexHeight, screen.depth); renderTex.Create(); } // Negate pitch - the camera object treats a negative pitch as "up" if (cameraObject.Render(renderTex, activeCamera.currentYaw, -activeCamera.currentPitch)) { if (cameraEffectMaterial != null) { cameraEffectMaterial.SetVector("_ImageDims", new Vector4((float)renderTex.width, (float)renderTex.height, 1.0f / (float)renderTex.width, 1.0f / (float)renderTex.height)); for (int i = 0; i < ceVariables.Count; ++i) { float value = ceVariables[i].value.AsFloat(); cameraEffectMaterial.SetFloat(ceVariables[i].variable, value); } Graphics.Blit(renderTex, screen, cameraEffectMaterial); } else { Graphics.Blit(renderTex, screen); } renderTex.DiscardContents(); ITargetable target = FlightGlobals.fetch.VesselTarget; bool drawSomething = ((gizmoTexture != null && target != null && showTargetIcon) || homeCrosshairMaterial.color.a > 0); if (drawSomething) { GL.PushMatrix(); GL.LoadPixelMatrix(0, screen.width, screen.height, 0); } if (gizmoTexture != null && target != null && showTargetIcon) { // Figure out which direction the target is. Vector3 targetDisplacement = target.GetTransform().position - cameraObject.GetTransform().position; targetDisplacement.Normalize(); // Transform it using the active camera's rotation. var targetDisp = GetNormalizedScreenPosition(activeCamera, targetDisplacement, cameraAspect); var iconCenter = new Vector2(screen.width * targetDisp.x, screen.height * targetDisp.y); // Apply some clamping values to force the icon to stay on screen iconCenter.x = Math.Max(iconPixelSize * 0.5f, iconCenter.x); iconCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, iconCenter.x); iconCenter.y = Math.Max(iconPixelSize * 0.5f, iconCenter.y); iconCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, iconCenter.y); var position = new Rect(iconCenter.x - iconPixelSize * 0.5f, iconCenter.y - iconPixelSize * 0.5f, iconPixelSize, iconPixelSize); Graphics.DrawTexture(position, gizmoTexture, GizmoIcons.GetIconLocation(GizmoIcons.IconType.TARGETPLUS), 0, 0, 0, 0, iconMaterial); } if (homeCrosshairMaterial.color.a > 0) { // Mihara: Reference point cameras are different enough to warrant it. var cameraForward = cameraObject.GetTransformForward(); var crossHairCenter = GetNormalizedScreenPosition(activeCamera, cameraForward, cameraAspect); crossHairCenter.x *= screen.width; crossHairCenter.y *= screen.height; crossHairCenter.x = Math.Max(iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.y = Math.Max(iconPixelSize * 0.5f, crossHairCenter.y); crossHairCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, crossHairCenter.y); float zoomAdjustedIconSize = iconPixelSize * Mathf.Tan(Mathf.Deg2Rad * activeCamera.fovLimits.y * 0.5f) / Mathf.Tan(Mathf.Deg2Rad * activeCamera.currentFoV * 0.5f); homeCrosshairMaterial.SetPass(0); GL.Begin(GL.LINES); GL.Vertex3(crossHairCenter.x - zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x + zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y - zoomAdjustedIconSize * 0.5f, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y + zoomAdjustedIconSize * 0.5f, 0.0f); GL.End(); } if (drawSomething) { GL.PopMatrix(); } return(true); } else if (skipMissingCameras) { // This will handle cameras getting ejected while in use. SelectNextCamera(); } return(false); }
public bool RenderHUD(RenderTexture screen, float cameraAspect) { if (screen == null || !startupComplete || HighLogic.LoadedSceneIsEditor) { return(false); } // Clear the background, if configured. GL.Clear(true, true, backgroundColorValue); // Configure the camera, if configured. // MOARdV: Might be worthwhile to refactor the flying camera so // it is created in Start (like new FlyingCamera(part, cameraTransform)), // and pass the screen, FoV, and aspect ratio (or just screen and // FoV) as Render parameters, so there's no need to test if the // camera's been created every render call. if (cameraObject == null && !string.IsNullOrEmpty(cameraTransform)) { cameraObject = new FlyingCamera(part, screen, cameraAspect); cameraObject.PointCamera(cameraTransform, hudFov); } // Draw the camera's view, if configured. if (cameraObject != null) { cameraObject.Render(); } // Configure the matrix so that the origin is the center of the screen. GL.PushMatrix(); // Draw the HUD ladder // MOARdV note, 2014/03/19: swapping the y values, to invert the // coordinates so the prograde icon is right-side up. GL.LoadPixelMatrix(-horizonSize.x * 0.5f, horizonSize.x * 0.5f, horizonSize.y * 0.5f, -horizonSize.y * 0.5f); GL.Viewport(new Rect((screen.width - horizonSize.x) * 0.5f, (screen.height - horizonSize.y) * 0.5f, horizonSize.x, horizonSize.y)); Vector3 coM = vessel.findWorldCenterOfMass(); Vector3 up = (coM - vessel.mainBody.position).normalized; Vector3 forward = vessel.GetTransform().up; Vector3 right = vessel.GetTransform().right; Vector3 top = Vector3.Cross(right, forward); Vector3 north = Vector3.Exclude(up, (vessel.mainBody.position + (Vector3d)vessel.mainBody.transform.up * vessel.mainBody.Radius) - coM).normalized; Vector3d velocityVesselSurface = vessel.orbit.GetVel() - vessel.mainBody.getRFrmVel(coM); Vector3 velocityVesselSurfaceUnit = velocityVesselSurface.normalized; if (ladderMaterial) { // Figure out the texture coordinate scaling for the ladder. float ladderTextureOffset = horizonTextureSize.y / ladderMaterial.mainTexture.height; float cosUp = Vector3.Dot(forward, up); float cosRoll = Vector3.Dot(top, up); float sinRoll = Vector3.Dot(right, up); var normalizedRoll = new Vector2(cosRoll, sinRoll); normalizedRoll.Normalize(); if (normalizedRoll.magnitude < 0.99f) { // If we're hitting +/- 90 nearly perfectly, the sin and cos will // be too far out of whack to normalize. Arbitrarily pick // a roll of 0.0. normalizedRoll.x = 1.0f; normalizedRoll.y = 0.0f; } cosRoll = normalizedRoll.x; sinRoll = normalizedRoll.y; // Mihara: I'm pretty sure this was negative of what it should actually be, at least according to my mockup. float pitch = -(Mathf.Asin(cosUp) * Mathf.Rad2Deg); float ladderMidpointCoord; if (use360horizon) { // Straight up is texture coord 0.75; // Straight down is TC 0.25; ladderMidpointCoord = JUtil.DualLerp(0.25f, 0.75f, -90f, 90f, pitch); } else { // Straight up is texture coord 1.0; // Straight down is TC 0.0; ladderMidpointCoord = JUtil.DualLerp(0.0f, 1.0f, -90f, 90f, pitch); } ladderMaterial.SetPass(0); GL.Begin(GL.QUADS); // transform -x -y GL.TexCoord2(0.5f + horizonTextureSize.x, ladderMidpointCoord - ladderTextureOffset); GL.Vertex3(cosRoll * horizonSize.x + sinRoll * horizonSize.y, -sinRoll * horizonSize.x + cosRoll * horizonSize.y, 0.0f); // transform +x -y GL.TexCoord2(0.5f - horizonTextureSize.x, ladderMidpointCoord - ladderTextureOffset); GL.Vertex3(-cosRoll * horizonSize.x + sinRoll * horizonSize.y, sinRoll * horizonSize.x + cosRoll * horizonSize.y, 0.0f); // transform +x +y GL.TexCoord2(0.5f - horizonTextureSize.x, ladderMidpointCoord + ladderTextureOffset); GL.Vertex3(-cosRoll * horizonSize.x - sinRoll * horizonSize.y, sinRoll * horizonSize.x - cosRoll * horizonSize.y, 0.0f); // transform -x +y GL.TexCoord2(0.5f + horizonTextureSize.x, ladderMidpointCoord + ladderTextureOffset); GL.Vertex3(cosRoll * horizonSize.x - sinRoll * horizonSize.y, -sinRoll * horizonSize.x - cosRoll * horizonSize.y, 0.0f); GL.End(); float AoA = velocityVesselSurfaceUnit.AngleInPlane(right, forward); float AoATC; if (use360horizon) { // Straight up is texture coord 0.75; // Straight down is TC 0.25; AoATC = JUtil.DualLerp(0.25f, 0.75f, -90f, 90f, pitch + AoA); } else { // Straight up is texture coord 1.0; // Straight down is TC 0.0; AoATC = JUtil.DualLerp(0.0f, 1.0f, -90f, 90f, pitch + AoA); } float Ypos = JUtil.DualLerp( -horizonSize.y, horizonSize.y, ladderMidpointCoord - ladderTextureOffset, ladderMidpointCoord + ladderTextureOffset, AoATC); // Placing the icon on the (0, Ypos) location, so simplify the transform. DrawIcon(-sinRoll * Ypos, -cosRoll * Ypos, GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE), progradeColorValue); } // Draw the rest of the HUD stuff (0,0) is the top left corner of the screen. GL.LoadPixelMatrix(0, screen.width, screen.height, 0); GL.Viewport(new Rect(0, 0, screen.width, screen.height)); if (headingMaterial != null) { Quaternion rotationSurface = Quaternion.LookRotation(north, up); Quaternion rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface); float headingTexture = JUtil.DualLerp(0f, 1f, 0f, 360f, rotationVesselSurface.eulerAngles.y); float headingTextureOffset = (headingBarWidth / headingMaterial.mainTexture.width) / 2; headingMaterial.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(headingTexture - headingTextureOffset, 1.0f); GL.Vertex3(headingBarPosition.x, headingBarPosition.y, 0.0f); GL.TexCoord2(headingTexture + headingTextureOffset, 1.0f); GL.Vertex3(headingBarPosition.x + headingBarPosition.z, headingBarPosition.y, 0.0f); GL.TexCoord2(headingTexture + headingTextureOffset, 0.0f); GL.Vertex3(headingBarPosition.x + headingBarPosition.z, headingBarPosition.y + headingBarPosition.w, 0.0f); GL.TexCoord2(headingTexture - headingTextureOffset, 0.0f); GL.Vertex3(headingBarPosition.x, headingBarPosition.y + headingBarPosition.w, 0.0f); GL.End(); if (showHeadingBarPrograde) { float slipAngle = velocityVesselSurfaceUnit.AngleInPlane(up, forward); float slipTC = JUtil.DualLerp(0f, 1f, 0f, 360f, rotationVesselSurface.eulerAngles.y + slipAngle); float slipIconX = JUtil.DualLerp(headingBarPosition.x, headingBarPosition.x + headingBarPosition.z, headingTexture - headingTextureOffset, headingTexture + headingTextureOffset, slipTC); DrawIcon(slipIconX, headingBarPosition.y + headingBarPosition.w * 0.5f, GizmoIcons.GetIconLocation(GizmoIcons.IconType.PROGRADE), progradeColorValue); } } if (vertBar1Material != null) { float value = comp.ProcessVariable(vertBar1Variable).MassageToFloat(); if (float.IsNaN(value)) { value = 0.0f; } if (vertBar1UseLog10) { value = JUtil.PseudoLog10(value); } float vertBar1TexCoord = JUtil.DualLerp(vertBar1TextureLimit.x, vertBar1TextureLimit.y, vertBar1Limit.x, vertBar1Limit.y, value); vertBar1Material.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, vertBar1TexCoord + vertBar1TextureSize); GL.Vertex3(vertBar1Position.x, vertBar1Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar1TexCoord + vertBar1TextureSize); GL.Vertex3(vertBar1Position.x + vertBar1Position.z, vertBar1Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar1TexCoord - vertBar1TextureSize); GL.Vertex3(vertBar1Position.x + vertBar1Position.z, vertBar1Position.y + vertBar1Position.w, 0.0f); GL.TexCoord2(0.0f, vertBar1TexCoord - vertBar1TextureSize); GL.Vertex3(vertBar1Position.x, vertBar1Position.y + vertBar1Position.w, 0.0f); GL.End(); } if (vertBar2Material != null) { float value = comp.ProcessVariable(vertBar2Variable).MassageToFloat(); if (float.IsNaN(value)) { value = 0.0f; } if (vertBar2UseLog10) { value = JUtil.PseudoLog10(value); } float vertBar2TexCoord = JUtil.DualLerp(vertBar2TextureLimit.x, vertBar2TextureLimit.y, vertBar2Limit.x, vertBar2Limit.y, value); vertBar2Material.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, vertBar2TexCoord + vertBar2TextureSize); GL.Vertex3(vertBar2Position.x, vertBar2Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar2TexCoord + vertBar2TextureSize); GL.Vertex3(vertBar2Position.x + vertBar2Position.z, vertBar2Position.y, 0.0f); GL.TexCoord2(1.0f, vertBar2TexCoord - vertBar2TextureSize); GL.Vertex3(vertBar2Position.x + vertBar2Position.z, vertBar2Position.y + vertBar2Position.w, 0.0f); GL.TexCoord2(0.0f, vertBar2TexCoord - vertBar2TextureSize); GL.Vertex3(vertBar2Position.x, vertBar2Position.y + vertBar2Position.w, 0.0f); GL.End(); } if (overlayMaterial != null) { overlayMaterial.SetPass(0); GL.Begin(GL.QUADS); GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 0.0f, 0.0f); GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(screen.width, 0.0f, 0.0f); GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(screen.width, screen.height, 0.0f); GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, screen.height, 0.0f); GL.End(); } GL.PopMatrix(); return(true); }
public bool RenderCamera(RenderTexture screen, float cameraAspect) { // Just in case. if (HighLogic.LoadedSceneIsEditor) { return false; } if (cameras.Count < 1) { return false; } var activeCamera = cameras[currentCamera]; if (string.IsNullOrEmpty(activeCamera.cameraTransform)) { return false; } if (cameraObject == null) { cameraObject = new FlyingCamera(part, cameraAspect); cameraObject.PointCamera(activeCamera.cameraTransform, activeCamera.currentFoV); } cameraObject.FOV = activeCamera.currentFoV; if (rentexWidth == 0) { rentexWidth = screen.width; rentexHeight = screen.height; // Note to self: when rentex dims != screen dims, the FOV seems to be wrong (like FOV is smaller). } if (renderTex == null) { renderTex = new RenderTexture(rentexWidth, rentexHeight, screen.depth); renderTex.Create(); } // Negate pitch - the camera object treats a negative pitch as "up" if (cameraObject.Render(renderTex, activeCamera.currentYaw, -activeCamera.currentPitch)) { if (cameraEffectMaterial != null) { cameraEffectMaterial.SetVector("_ImageDims", new Vector4((float)renderTex.width, (float)renderTex.height, 1.0f / (float)renderTex.width, 1.0f / (float)renderTex.height)); for (int i = 0; i < ceVariables.Count; ++i) { float value = ceVariables[i].value.AsFloat(); cameraEffectMaterial.SetFloat(ceVariables[i].variable, value); } Graphics.Blit(renderTex, screen, cameraEffectMaterial); } else { Graphics.Blit(renderTex, screen); } renderTex.DiscardContents(); ITargetable target = FlightGlobals.fetch.VesselTarget; bool drawSomething = ((gizmoTexture != null && target != null && showTargetIcon) || homeCrosshairMaterial.color.a > 0); if (drawSomething) { GL.PushMatrix(); GL.LoadPixelMatrix(0, screen.width, screen.height, 0); } if (gizmoTexture != null && target != null && showTargetIcon) { // Figure out which direction the target is. Vector3 targetDisplacement = target.GetTransform().position - cameraObject.GetTransform().position; targetDisplacement.Normalize(); // Transform it using the active camera's rotation. var targetDisp = GetNormalizedScreenPosition(activeCamera, targetDisplacement, cameraAspect); var iconCenter = new Vector2(screen.width * targetDisp.x, screen.height * targetDisp.y); // Apply some clamping values to force the icon to stay on screen iconCenter.x = Math.Max(iconPixelSize * 0.5f, iconCenter.x); iconCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, iconCenter.x); iconCenter.y = Math.Max(iconPixelSize * 0.5f, iconCenter.y); iconCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, iconCenter.y); var position = new Rect(iconCenter.x - iconPixelSize * 0.5f, iconCenter.y - iconPixelSize * 0.5f, iconPixelSize, iconPixelSize); Graphics.DrawTexture(position, gizmoTexture, GizmoIcons.GetIconLocation(GizmoIcons.IconType.TARGETPLUS), 0, 0, 0, 0, iconMaterial); } if (homeCrosshairMaterial.color.a > 0) { // Mihara: Reference point cameras are different enough to warrant it. var cameraForward = cameraObject.GetTransformForward(); var crossHairCenter = GetNormalizedScreenPosition(activeCamera, cameraForward, cameraAspect); crossHairCenter.x *= screen.width; crossHairCenter.y *= screen.height; crossHairCenter.x = Math.Max(iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.x = Math.Min(screen.width - iconPixelSize * 0.5f, crossHairCenter.x); crossHairCenter.y = Math.Max(iconPixelSize * 0.5f, crossHairCenter.y); crossHairCenter.y = Math.Min(screen.height - iconPixelSize * 0.5f, crossHairCenter.y); float zoomAdjustedIconSize = iconPixelSize * Mathf.Tan(Mathf.Deg2Rad * activeCamera.fovLimits.y * 0.5f) / Mathf.Tan(Mathf.Deg2Rad * activeCamera.currentFoV * 0.5f); homeCrosshairMaterial.SetPass(0); GL.Begin(GL.LINES); GL.Vertex3(crossHairCenter.x - zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x + zoomAdjustedIconSize * 0.5f, crossHairCenter.y, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y - zoomAdjustedIconSize * 0.5f, 0.0f); GL.Vertex3(crossHairCenter.x, crossHairCenter.y + zoomAdjustedIconSize * 0.5f, 0.0f); GL.End(); } if (drawSomething) { GL.PopMatrix(); } return true; } else if (skipMissingCameras) { // This will handle cameras getting ejected while in use. SelectNextCamera(); } return false; }