private void ConfigureElements(float screenWidth, float screenHeight)
        {
            // How big is the nav ball, anyway?
            navballRadius = 0.0f;
            MeshFilter meshFilter = navBall.GetComponent<MeshFilter>();
            if (meshFilter != null)
            {
                // NOTE: I assume this really is a nav*ball*, not something
                // weird, and that it's centered on the origin.
                navballRadius = meshFilter.mesh.bounds.size.x * 0.5f;
                if (!(navballRadius > 0.0f))
                {
                    throw new Exception("JSIPrimaryFlightDisplay navball had an invalid size");
                }
            }
            else
            {
                throw new Exception("JSIPrimaryFlightDisplay could not get the navball mesh");
            }

            // Figure out how we have to manipulate the camera to get the
            // navball in the right place, and in the right size.
            float cameraSpan = navballRadius * screenHeight / navBallDiameter;
            float pixelSize = cameraSpan / (screenHeight * 0.5f);

            ballCamera.orthographicSize = cameraSpan;

            float newXPos = navBallCenter.x - screenWidth * 0.5f;
            float newYPos = screenHeight * 0.5f - navBallCenter.y;
            navBallOrigin = navBall.transform.position;
            navBallOrigin.x += newXPos * pixelSize;
            navBallOrigin.y += newYPos * pixelSize;
            navBall.transform.position = navBallOrigin;
            // Because we use this value to offset the markers, we don't
            // want/need depth info.
            navBallOrigin.z = 0.0f;

            float overlayDepth = navBall.transform.position.z - navballRadius - 0.1f;

            Shader displayShader = JUtil.LoadInternalShader("RPM/DisplayShader");

            if (!string.IsNullOrEmpty(staticOverlay))
            {
                Material overlayMaterial = new Material(displayShader);
                overlayMaterial.mainTexture = GameDatabase.Instance.GetTexture(staticOverlay.EnforceSlashes(), false);

                overlay = JUtil.CreateSimplePlane("RPMPFDOverlay" + internalProp.propID, cameraSpan, drawingLayer);
                overlay.layer = drawingLayer;
                overlay.transform.position = new Vector3(0, 0, overlayDepth);
                overlay.GetComponent<Renderer>().material = overlayMaterial;
                overlay.transform.parent = cameraBody.transform;
            }

            if (!string.IsNullOrEmpty(headingBar))
            {
                Material headingMaterial = new Material(displayShader);
                headingMaterial.mainTexture = GameDatabase.Instance.GetTexture(headingBar.EnforceSlashes(), false);

                float hbXPos = headingBarPosition.x - screenWidth * 0.5f;
                float hbYPos = screenHeight * 0.5f - headingBarPosition.y;

                heading = JUtil.CreateSimplePlane("RPMPFDHeading" + internalProp.propID, new Vector2(headingBarPosition.z * pixelSize, headingBarPosition.w * pixelSize), new Rect(0.0f, 0.0f, 1.0f, 1.0f), drawingLayer);
                heading.transform.position = new Vector3(hbXPos * pixelSize, hbYPos * pixelSize, headingAboveOverlay ? (overlayDepth - 0.1f) : (overlayDepth + 0.1f));
                heading.transform.parent = cameraBody.transform;
                Renderer hdgMatl = null;
                heading.GetComponentCached<Renderer>(ref hdgMatl).material = headingMaterial;
                hdgMatl.material.SetTextureScale("_MainTex", new Vector2(headingSpan, 1f));
            }

            Texture2D gizmoTexture = JUtil.GetGizmoTexture();
            markerDepth = navBall.transform.position.z - navballRadius - 0.05f;
            float scaledMarkerSize = markerSize * 0.5f * pixelSize;
            markerPrograde = BuildMarker(0, 2, scaledMarkerSize, gizmoTexture, progradeColorValue, drawingLayer, internalProp.propID, displayShader);
            markerRetrograde = BuildMarker(1, 2, scaledMarkerSize, gizmoTexture, progradeColorValue, drawingLayer, internalProp.propID, displayShader);
            markerManeuver = BuildMarker(2, 0, scaledMarkerSize, gizmoTexture, maneuverColorValue, drawingLayer, internalProp.propID, displayShader);
            markerManeuverMinus = BuildMarker(1, 2, scaledMarkerSize, gizmoTexture, maneuverColorValue, drawingLayer, internalProp.propID, displayShader);
            markerTarget = BuildMarker(2, 1, scaledMarkerSize, gizmoTexture, targetColorValue, drawingLayer, internalProp.propID, displayShader);
            markerTargetMinus = BuildMarker(2, 2, scaledMarkerSize, gizmoTexture, targetColorValue, drawingLayer, internalProp.propID, displayShader);
            markerNormal = BuildMarker(0, 0, scaledMarkerSize, gizmoTexture, normalColorValue, drawingLayer, internalProp.propID, displayShader);
            markerNormalMinus = BuildMarker(1, 0, scaledMarkerSize, gizmoTexture, normalColorValue, drawingLayer, internalProp.propID, displayShader);
            markerRadial = BuildMarker(1, 1, scaledMarkerSize, gizmoTexture, radialColorValue, drawingLayer, internalProp.propID, displayShader);
            markerRadialMinus = BuildMarker(0, 1, scaledMarkerSize, gizmoTexture, radialColorValue, drawingLayer, internalProp.propID, displayShader);

            markerDockingAlignment = BuildMarker(0, 2, scaledMarkerSize, gizmoTexture, dockingColorValue, drawingLayer, internalProp.propID, displayShader);
            markerNavWaypoint = BuildMarker(0, 2, scaledMarkerSize, gizmoTexture, waypointColorValue, drawingLayer, internalProp.propID, displayShader);
        }
 private void MoveMarker(GameObject marker, Vector3 position, Quaternion voodooGymbal)
 {
     Vector3 newPosition = ((voodooGymbal * position) * navballRadius) + navBallOrigin;
     Renderer r = markerRenderer[marker];
     marker.GetComponentCached<Renderer>(ref r);
     markerRenderer[marker] = r;
     r.material.SetFloat(opacityIndex, Mathf.Clamp01(newPosition.z + 0.5f));
     marker.transform.position = new Vector3(newPosition.x, newPosition.y, markerDepth);
 }
        /// <summary>
        /// Create a selection model for a specific kerbal.
        /// </summary>
        /// <param name="eva"></param>
        private void CreateLine(EvaContainer container)
        {
            if (selectionLines.ContainsKey(container.flightID))
            {
                return;
            }

            LineRenderer lineRenderer = new GameObject().AddComponent<LineRenderer>();

            lineRenderer.useWorldSpace = false;
            lineRenderer.material = new Material(Shader.Find("Particles/Additive"));
            lineRenderer.SetWidth(0.05f, 0.05f);
            lineRenderer.SetColors(Color.green, Color.red);

			Renderer _renderer = null;
			lineRenderer.GetComponentCached<Renderer> (ref _renderer);

			if (_renderer != null) {
				_renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
				_renderer.receiveShadows = false;
			}

            int segments = 32;

            lineRenderer.SetVertexCount(segments);

            CreateCircle(lineRenderer, segments, 0.25);

            //set properties
            SetSelectionLineProperties(container.EVA, lineRenderer);

            selectionLines.Add(container.flightID, lineRenderer);

        }