internal static void SetLightSources(GameObject gameObject, Material mat)
        {
            List <LightData> datas = new List <LightData>();
            var objs = GetLightObjects(gameObject);

            //Map object with an index
            //Debug.LogFormat("Objs: {0}", objs.Count());

            foreach (var go in objs)
            {
                LightData lightData = new LightData();

                lightData.position   = go.transform.position;
                lightData.brightness = 1;
                lightData.size       = 1;

                datas.Add(lightData);
            }

            // WIP: Move this to blinker object, where we need to generate the spritelight

            //var obj = SpriteLights.CreateLights(gameObject.name.ToLower() + "-LD", datas.ToArray(), mat);

            //Debug.LogFormat("Obj Count: {0}", obj.Count());

            /*gameObject.transform.MakeChild(obj, (p, o) =>
             * {
             *  // Check the index and them set where is has to be generated
             *  o.transform.position = m_frontLeftLight.transform.position;
             * });*/
        }
Esempio n. 2
0
    //Setup all the touch down zone lights.
    private void SetupTDZLights(ref List <SpriteLights.LightData> lightData, ApproachLightData allApproachLightData, RunwayData runwayData, bool randomBrightness, float brightness, float size)
    {
        for (int side = 0; side < 2; side++)
        {
            if (runwayData.lightingType[side] != LightingType.NONE)
            {
                SvgData[] svgData = allApproachLightData.GetApproachLightData(runwayData.lightingType[side]);

                //Set TDZ lights.
                if (runwayData.TDZ[side])
                {
                    svgData = allApproachLightData.GetApproachLightData(LightingType.TDZ);

                    for (int i = 0; i < svgData.Length; i++)
                    {
                        if (svgData[i].materialString == whiteDirectionalSinglesideCString)
                        {
                            SpriteLights.LightData data = new SpriteLights.LightData();
                            Vector3 position            = (runwayData.rotation[side] * svgData[i].position) + runwayData.thresholdPosition[side];

                            data.frontColor = whiteLight;
                            data.brightness = SetBrightness(randomBrightness, brightness);
                            data.position   = position;

                            //Set the direction and upward rotation of the light.
                            data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);
                            data.size     = size;

                            lightData.Add(data);
                        }
                    }
                }
            }
        }
    }
Esempio n. 3
0
    //Setup all the papi lights.
    private void SetupPapiLights(ref List <SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness)
    {
        for (int side = 0; side < 2; side++)
        {
            if (runwayData.papiType[side] != PapiType.NONE)
            {
                //Calculate the offset direction.
                Vector3 lengthOffsetDir     = Math3d.GetForwardVector(runwayData.rotation[side]);
                Vector3 sideOffsetDir       = Math3d.GetRightVector(runwayData.rotation[side]);
                Vector3 lengthEdgeOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, 337f);

                if ((runwayData.papiType[side] == PapiType.PAPIRIGHT) || (runwayData.papiType[side] == PapiType.PAPIBOTH))
                {
                    Vector3 startOffsetVec  = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + 15f);
                    Vector3 startPosition   = runwayData.thresholdPosition[side] + startOffsetVec;
                    Vector3 currentPosition = startPosition;

                    Vector3 sideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 9f);

                    for (int i = 0; i < 4; i++)
                    {
                        SpriteLights.LightData data = new SpriteLights.LightData();

                        float angle = GetPapiAngle(i);

                        data.position = currentPosition;
                        data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * angle);
                        lightData.Add(data);

                        currentPosition += sideOffsetVec;
                    }
                }

                if ((runwayData.papiType[side] == PapiType.PAPILEFT) || (runwayData.papiType[side] == PapiType.PAPIBOTH))
                {
                    sideOffsetDir *= -1;

                    Vector3 startOffsetVec  = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + 15f);
                    Vector3 startPosition   = runwayData.thresholdPosition[side] + startOffsetVec;
                    Vector3 currentPosition = startPosition;

                    Vector3 sideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 9f);

                    for (int i = 0; i < 4; i++)
                    {
                        SpriteLights.LightData data = new SpriteLights.LightData();

                        float angle = GetPapiAngle(i);

                        data.position = currentPosition;
                        data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * angle);
                        lightData.Add(data);

                        currentPosition += sideOffsetVec;
                    }
                }
            }
        }
    }
    //Generates random lights in the specified area.
    private void GenerateRandomLights(int amount, Vector2 area, Material material)
    {
        SpriteLights.LightData[] lightData = new SpriteLights.LightData[amount];

        for(int i = 0; i < amount; i++){

            lightData[i] = new SpriteLights.LightData();
            lightData[i].position = new Vector3(Random.Range(area.x, area.y), 0, Random.Range(area.x, area.y));
        }

        SpriteLights.CreateLights("RandomLights", lightData, material);
    }
Esempio n. 5
0
    //Generates random lights in the specified area.
    private void GenerateRandomLights(int amount, Vector2 area, Material material)
    {
        SpriteLights.LightData[] lightData = new SpriteLights.LightData[amount];

        for (int i = 0; i < amount; i++)
        {
            lightData[i]          = new SpriteLights.LightData();
            lightData[i].position = new Vector3(Random.Range(area.x, area.y), 0, Random.Range(area.x, area.y));
        }

        SpriteLights.CreateLights("RandomLights", lightData, material);
    }
Esempio n. 6
0
    //Setup all the centerline lights.
    private void SetupCenterlineLights(ref List <SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness, float brightness, float size)
    {
        if (runwayData.centerlineLights)
        {
            //Calculate the amount of lights.
            int lightAmountInRow = (int)Mathf.Floor(runwayData.length / runwayData.centerlineLightsSpacing);

            //Calculate the offset direction.
            Vector3 lengthOffsetDir = Math3d.GetForwardVector(runwayData.rotation[0]);

            //Calculate the start position.
            float rowLength  = (lightAmountInRow - 1) * runwayData.centerlineLightsSpacing;
            float edgeOffset = (runwayData.length - rowLength) * 0.5f;

            Vector3 startOffsetVec  = Math3d.SetVectorLength(lengthOffsetDir, edgeOffset);
            Vector3 startPosition   = runwayData.thresholdPosition[0] + startOffsetVec;
            Vector3 currentPosition = startPosition;

            Vector3 lengthOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, runwayData.centerlineLightsSpacing);

            //Calculate the point where the lights should change color.
            float redA       = 300f + runwayData.centerlineLightsSpacing;
            float redB       = (runwayData.length - (300f + runwayData.centerlineLightsSpacing));
            float alternateA = 900f + runwayData.centerlineLightsSpacing;
            float alternateB = (runwayData.length - (900f + runwayData.centerlineLightsSpacing));

            for (int i = 0; i < lightAmountInRow; i++)
            {
                bool passedRedA       = false;
                bool passedAlternateA = false;
                bool passedRedB       = false;
                bool passedAlternateB = false;

                SpriteLights.LightData data = new SpriteLights.LightData();

                //Is the current light index even or odd?
                bool even = IsEven(i);

                data.position = currentPosition;
                data.rotation = runwayData.rotation[0];

                //Calculate the distance to the threshold.
                float currentDistance = (i * runwayData.centerlineLightsSpacing) + edgeOffset;

                //The last 900 meter of the runway has alternating red and white lights.
                if (currentDistance <= alternateA)
                {
                    passedAlternateA = true;
                }

                //The last 900 meter of the runway has alternating red and white lights.
                if (currentDistance >= alternateB)
                {
                    passedAlternateB = true;
                }

                //The last 300 meter of the runway has red centerline lights.
                if (currentDistance <= redA)
                {
                    data.frontColor = whiteLight;
                    data.brightness = SetBrightness(randomBrightness, brightness);
                    data.backColor  = redLight;

                    passedRedA = true;
                }

                //The last 300 meter of the runway has red centerline lights.
                if (currentDistance >= redB)
                {
                    passedRedB = true;

                    data.frontColor = redLight;
                    data.brightness = SetBrightness(randomBrightness, brightness);
                    data.backColor  = whiteLight;
                }

                //The last 900 meter of the runway has alternating red and white lights.
                if (passedAlternateA && !passedRedA)
                {
                    if (even)
                    {
                        data.frontColor = whiteLight;
                        data.brightness = SetBrightness(randomBrightness, brightness);
                        data.backColor  = redLight;
                    }

                    else
                    {
                        data.frontColor = whiteLight;
                        data.brightness = SetBrightness(randomBrightness, brightness);
                        data.backColor  = whiteLight;
                    }
                }

                //The last 900 meter of the runway has alternating red and white lights.
                if (passedAlternateB && !passedRedB)
                {
                    if (even)
                    {
                        data.frontColor = redLight;
                        data.brightness = SetBrightness(randomBrightness, brightness);
                        data.backColor  = whiteLight;
                    }

                    else
                    {
                        data.frontColor = whiteLight;
                        data.brightness = SetBrightness(randomBrightness, brightness);
                        data.backColor  = whiteLight;
                    }
                }

                //Middle of the runway
                if (!passedRedA && !passedRedB && !passedAlternateA && !passedAlternateB)
                {
                    data.frontColor = whiteLight;
                    data.brightness = SetBrightness(randomBrightness, brightness);
                    data.backColor  = whiteLight;
                }

                data.size = size;

                lightData.Add(data);

                currentPosition += lengthOffsetVec;
            }
        }
    }
Esempio n. 7
0
    //Setup all the threshold lights.
    private void SetupThresholdLights(ref List <SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness, float brightness, float size)
    {
        for (int side = 0; side < 2; side++)
        {
            //Calculate the amount of lights.
            int lightAmountInRow = (int)Mathf.Ceil(runwayData.width / thresholdLightsSpacing);

            //Calculate the width of the threshold light row.
            float rowWidth = (lightAmountInRow - 1) * thresholdLightsSpacing;

            //Set start position.
            Vector3 sideOffsetDir    = Math3d.GetRightVector(runwayData.rotation[side]);
            Vector3 startOffsetAVec  = Math3d.SetVectorLength(sideOffsetDir, rowWidth * 0.5f);
            Vector3 startPosition    = runwayData.thresholdPosition[side] + startOffsetAVec;
            Vector3 thresholdACorner = startPosition;
            Vector3 currentPosition  = startPosition;

            Vector3 sideOffsetVec = Math3d.SetVectorLength(-sideOffsetDir, thresholdLightsSpacing);

            SpriteLights.LightData data;

            //Create lights.
            for (int i = 0; i < lightAmountInRow; i++)
            {
                data = new SpriteLights.LightData();

                data.position   = currentPosition;
                data.rotation   = runwayData.rotation[side];
                data.frontColor = greenLight;
                data.brightness = SetBrightness(randomBrightness, brightness);
                data.backColor  = redLight;
                data.size       = size;

                lightData.Add(data);

                currentPosition += sideOffsetVec;
            }

            //Create wing bars.
            if (runwayData.thresholdWingbar[side] != ThresholdWingbar.NONE)
            {
                int lightAmount = 0;

                if (runwayData.thresholdWingbar[side] == ThresholdWingbar.LARGE)
                {
                    lightAmount = 9;
                }

                if (runwayData.thresholdWingbar[side] == ThresholdWingbar.SMALL)
                {
                    lightAmount = 4;
                }

                Vector3 barSideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 1.5f);

                //Set start position.
                currentPosition = thresholdACorner;

                //Create wing bars.
                for (int i = 0; i < lightAmount * 2; i++)
                {
                    data = new SpriteLights.LightData();

                    //Set the new start position.
                    if (i == lightAmount)
                    {
                        currentPosition   = runwayData.thresholdPosition[side] - startOffsetAVec;
                        barSideOffsetVec *= -1;
                    }

                    currentPosition += barSideOffsetVec;
                    data.position    = currentPosition;
                    data.rotation    = runwayData.rotation[side];
                    data.frontColor  = greenLight;
                    data.brightness  = SetBrightness(randomBrightness, brightness);
                    data.size        = size;

                    lightData.Add(data);
                }
            }
        }
    }
Esempio n. 8
0
    //Setup all the strobe lights.
    private void SetupStrobeLights(ref List <SpriteLights.LightData> lightData, ApproachLightData allApproachLightData, RunwayData runwayData, float strobeTimeStep)
    {
        float groupID = Random.Range(0.0f, 0.99f);

        for (int side = 0; side < 2; side++)
        {
            if (runwayData.lightingType[side] != LightingType.NONE)
            {
                SvgData[] svgData = allApproachLightData.GetApproachLightData(runwayData.lightingType[side]);

                if ((runwayData.strobeType[side] == StrobeType.ODALS) || (runwayData.strobeType[side] == StrobeType.BOTH))
                {
                    for (int i = 0; i < svgData.Length; i++)
                    {
                        SpriteLights.LightData data = new SpriteLights.LightData();
                        Vector3 position            = (runwayData.rotation[side] * svgData[i].position) + runwayData.thresholdPosition[side];

                        if (svgData[i].materialString == strobeCString)
                        {
                            data.position = position;

                            //Set the direction and upward rotation of the light.
                            data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);

                            data.strobeID      = svgData[i].id * strobeTimeStep;
                            data.strobeGroupID = groupID;
                            lightData.Add(data);
                        }
                    }
                }

                if ((runwayData.strobeType[side] == StrobeType.REIL) || (runwayData.strobeType[side] == StrobeType.BOTH))
                {
                    float   distanceOffset = 0;
                    Vector3 sideOffsetDir  = Math3d.GetRightVector(runwayData.rotation[side]);

                    //If threshold wing bars are used, the REIL distance must be bigger, otherwise they overlap.
                    if (runwayData.thresholdWingbar[side] == ThresholdWingbar.LARGE)
                    {
                        distanceOffset = 15.5f;
                    }

                    if ((runwayData.thresholdWingbar[side] == ThresholdWingbar.SMALL) || (runwayData.thresholdWingbar[side] == ThresholdWingbar.NONE))
                    {
                        distanceOffset = 12f;
                    }

                    //Right strobe.
                    Vector3 startOffsetAVec     = Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + distanceOffset);
                    Vector3 position            = runwayData.thresholdPosition[side] + startOffsetAVec;
                    SpriteLights.LightData data = new SpriteLights.LightData();

                    data.position = position;

                    //Set the direction and upward rotation of the light.
                    data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);

                    //The strobe ID is 0, so it will flash at the same time as all other strobes with ID 0.
                    //The group ID is the same as the walking strobe, so it is synchronized with that.
                    data.strobeID      = 0;
                    data.strobeGroupID = groupID;

                    lightData.Add(data);

                    //Left strobe.
                    position = runwayData.thresholdPosition[side] - startOffsetAVec;
                    data     = new SpriteLights.LightData();

                    data.position = position;

                    //Set the direction and upward rotation of the light.
                    data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);

                    data.strobeGroupID = groupID;
                    lightData.Add(data);
                }
            }
        }
    }
Esempio n. 9
0
    //Setup all the edge lights.
    private void SetupEdgeLights(ref List <SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness, float brightness, float size)
    {
        float sideFactor = 0;

        //Calculate the amount of lights.
        int lightAmountInRow = (int)Mathf.Floor(runwayData.length / runwayData.edgeLightsSpacing);

        //Calculate the offset direction.
        Vector3 lengthOffsetDir = Math3d.GetForwardVector(runwayData.rotation[0]);
        Vector3 sideOffsetDir   = Math3d.GetRightVector(runwayData.rotation[0]);

        //Calculate the start position.
        float rowLength         = (lightAmountInRow - 1) * runwayData.edgeLightsSpacing;
        float edgeForwardOffset = (runwayData.length - rowLength) * 0.5f;

        Vector3 lengthEdgeOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, edgeForwardOffset);
        Vector3 startOffsetVec      = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, runwayData.width * 0.5f);
        Vector3 startPosition       = runwayData.thresholdPosition[0] + startOffsetVec;
        Vector3 currentPosition     = startPosition;

        Vector3 lengthOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, runwayData.edgeLightsSpacing);

        //Calculate the point where the lights should change color.
        float amberA = 600f + runwayData.edgeLightsSpacing;
        float amberB = (runwayData.length - (600f + runwayData.edgeLightsSpacing));

        int doubleLightAmountInRow = lightAmountInRow * 2;

        for (int i = 0; i < doubleLightAmountInRow; i++)
        {
            bool passedAmberA = false;
            bool passedAmberB = false;

            SpriteLights.LightData data = new SpriteLights.LightData();

            //Shift the current position for the other side.
            if (i == lightAmountInRow)
            {
                startOffsetVec  = lengthEdgeOffsetVec + Math3d.SetVectorLength(-sideOffsetDir, runwayData.width * 0.5f);
                currentPosition = runwayData.thresholdPosition[0] + startOffsetVec;

                //Reset flags.
                passedAmberA = false;
                passedAmberB = false;
                sideFactor   = lightAmountInRow;
            }

            data.position = currentPosition;
            data.rotation = runwayData.rotation[0];

            //Calculate the distance to the threshold.
            float currentDistance = ((i - sideFactor) * runwayData.edgeLightsSpacing) + edgeForwardOffset;

            //The last 600 meter of the runway has red centerline lights.
            if (currentDistance <= amberA)
            {
                data.frontColor = whiteLight;
                data.brightness = SetBrightness(randomBrightness, brightness);
                data.backColor  = amberLight;

                passedAmberA = true;
            }

            //The last 300 meter of the runway has red centerline lights.
            if (currentDistance >= amberB)
            {
                passedAmberB = true;

                data.frontColor = amberLight;
                data.brightness = SetBrightness(randomBrightness, brightness);
                data.backColor  = whiteLight;
            }

            //Middle of the runway
            if (!passedAmberA && !passedAmberB)
            {
                data.frontColor = whiteLight;
                data.brightness = SetBrightness(randomBrightness, brightness);
                data.backColor  = whiteLight;
            }

            data.size = size;

            lightData.Add(data);

            currentPosition += lengthOffsetVec;
        }
    }
	//Setup all the centerline lights.
	private void SetupCenterlineLights(ref List<SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness, float brightness, float size){

		if(runwayData.centerlineLights){

			//Calculate the amount of lights.
			int lightAmountInRow = (int)Mathf.Floor(runwayData.length / runwayData.centerlineLightsSpacing);

			//Calculate the offset direction.
			Vector3 lengthOffsetDir = Math3d.GetForwardVector(runwayData.rotation[0]);

			//Calculate the start position.
			float rowLength = (lightAmountInRow - 1) * runwayData.centerlineLightsSpacing;
			float edgeOffset = (runwayData.length - rowLength) * 0.5f;

			Vector3 startOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, edgeOffset);
			Vector3 startPosition = runwayData.thresholdPosition[0] + startOffsetVec;
			Vector3 currentPosition = startPosition;

			Vector3 lengthOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, runwayData.centerlineLightsSpacing);

			//Calculate the point where the lights should change color.
			float redA = 300f + runwayData.centerlineLightsSpacing;		
			float redB = (runwayData.length - (300f + runwayData.centerlineLightsSpacing));
			float alternateA = 900f + runwayData.centerlineLightsSpacing;
			float alternateB = (runwayData.length - (900f + runwayData.centerlineLightsSpacing));

			for(int i = 0; i < lightAmountInRow; i++){

				bool passedRedA = false;
				bool passedAlternateA = false;
				bool passedRedB = false;
				bool passedAlternateB = false;

				SpriteLights.LightData data = new SpriteLights.LightData();

				//Is the current light index even or odd?
				bool even = IsEven(i);

				data.position = currentPosition;
				data.rotation = runwayData.rotation[0];

				//Calculate the distance to the threshold.
				float currentDistance = (i * runwayData.centerlineLightsSpacing) + edgeOffset;

				//The last 900 meter of the runway has alternating red and white lights.
				if(currentDistance <= alternateA){

					passedAlternateA = true;
				}

				//The last 900 meter of the runway has alternating red and white lights.
				if(currentDistance >= alternateB){

					passedAlternateB = true;
				}

				//The last 300 meter of the runway has red centerline lights.
				if(currentDistance <= redA){

					data.frontColor = whiteLight;
					data.brightness = SetBrightness(randomBrightness, brightness);
					data.backColor = redLight;

					passedRedA = true;
				}

				//The last 300 meter of the runway has red centerline lights.
				if(currentDistance >= redB){

					passedRedB = true;

					data.frontColor = redLight;
					data.brightness = SetBrightness(randomBrightness, brightness);
					data.backColor = whiteLight;
				}

				//The last 900 meter of the runway has alternating red and white lights.
				if(passedAlternateA && !passedRedA){

					if(even){

						data.frontColor = whiteLight;
						data.brightness = SetBrightness(randomBrightness, brightness);
						data.backColor = redLight;
					}

					else{

						data.frontColor = whiteLight;
						data.brightness = SetBrightness(randomBrightness, brightness);
						data.backColor = whiteLight;
					}
				}

				//The last 900 meter of the runway has alternating red and white lights.
				if(passedAlternateB && !passedRedB){

					if(even){

						data.frontColor = redLight;
						data.brightness = SetBrightness(randomBrightness, brightness);
						data.backColor = whiteLight;
					}

					else{

						data.frontColor = whiteLight;
						data.brightness = SetBrightness(randomBrightness, brightness);
						data.backColor = whiteLight;
					}
				}

				//Middle of the runway
				if(!passedRedA && !passedRedB && !passedAlternateA && !passedAlternateB){

					data.frontColor = whiteLight;
					data.brightness = SetBrightness(randomBrightness, brightness);
					data.backColor = whiteLight;
				}

				data.size = size;

				lightData.Add(data);

				currentPosition += lengthOffsetVec;
			}
		}
	}
	//Setup all the threshold lights.
	private void SetupThresholdLights(ref List<SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness, float brightness, float size){

		for(int side = 0; side < 2; side++){

			//Calculate the amount of lights.
			int lightAmountInRow = (int)Mathf.Ceil(runwayData.width / thresholdLightsSpacing);

			//Calculate the width of the threshold light row.
			float rowWidth = (lightAmountInRow - 1) * thresholdLightsSpacing;

			//Set start position.
			Vector3 sideOffsetDir = Math3d.GetRightVector(runwayData.rotation[side]);		
			Vector3 startOffsetAVec = Math3d.SetVectorLength(sideOffsetDir, rowWidth * 0.5f);
			Vector3 startPosition = runwayData.thresholdPosition[side] + startOffsetAVec;
			Vector3 thresholdACorner = startPosition;
			Vector3 currentPosition = startPosition;

			Vector3 sideOffsetVec = Math3d.SetVectorLength(-sideOffsetDir, thresholdLightsSpacing);

			SpriteLights.LightData data;

			//Create lights.
			for(int i = 0; i < lightAmountInRow; i++){

				data = new SpriteLights.LightData();

				data.position = currentPosition;
				data.rotation = runwayData.rotation[side];
				data.frontColor = greenLight;
				data.brightness = SetBrightness(randomBrightness, brightness);
				data.backColor = redLight;
				data.size = size;

				lightData.Add(data);

				currentPosition += sideOffsetVec;
			}

			//Create wing bars.
			if(runwayData.thresholdWingbar[side] != ThresholdWingbar.NONE){

				int lightAmount = 0;

				if(runwayData.thresholdWingbar[side] == ThresholdWingbar.LARGE){

					lightAmount = 9;
				}

				if(runwayData.thresholdWingbar[side] == ThresholdWingbar.SMALL){

					lightAmount = 4;
				}

				Vector3 barSideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 1.5f);

				//Set start position.	
				currentPosition = thresholdACorner;

				//Create wing bars.
				for(int i = 0; i < lightAmount * 2; i++){

					data = new SpriteLights.LightData();

					//Set the new start position.
					if(i == lightAmount){

						currentPosition = runwayData.thresholdPosition[side] - startOffsetAVec;
						barSideOffsetVec *= -1;
					}

					currentPosition += barSideOffsetVec;
					data.position = currentPosition;
					data.rotation = runwayData.rotation[side];
					data.frontColor = greenLight;
					data.brightness = SetBrightness(randomBrightness, brightness);
					data.size = size;

					lightData.Add(data);
				}
			}
		}
	}
	//Setup all the touch down zone lights.
	private void SetupTDZLights(ref List<SpriteLights.LightData> lightData, ApproachLightData allApproachLightData, RunwayData runwayData, bool randomBrightness, float brightness, float size){

		for(int side = 0; side < 2; side++){

			if(runwayData.lightingType[side] != LightingType.NONE){

				SvgData[] svgData = allApproachLightData.GetApproachLightData(runwayData.lightingType[side]);

				//Set TDZ lights.
				if(runwayData.TDZ[side]){

					svgData = allApproachLightData.GetApproachLightData(LightingType.TDZ);

					for(int i = 0; i < svgData.Length; i++){

						if(svgData[i].materialString == whiteDirectionalSinglesideCString){

							SpriteLights.LightData data = new SpriteLights.LightData();
							Vector3 position = (runwayData.rotation[side] * svgData[i].position) + runwayData.thresholdPosition[side];

							data.frontColor = whiteLight;
							data.brightness = SetBrightness(randomBrightness, brightness);
							data.position = position;

							//Set the direction and upward rotation of the light.
							data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);
							data.size = size;

							lightData.Add(data);
						}
					}
				}
			}
		}
	}
	//Setup all the strobe lights.
	private void SetupStrobeLights(ref List<SpriteLights.LightData> lightData, ApproachLightData allApproachLightData, RunwayData runwayData, float strobeTimeStep){

		float groupID = Random.Range(0.0f, 0.99f); 

		for(int side = 0; side < 2; side++){

			if(runwayData.lightingType[side] != LightingType.NONE){

				SvgData[] svgData = allApproachLightData.GetApproachLightData(runwayData.lightingType[side]);

				if((runwayData.strobeType[side] == StrobeType.ODALS) || (runwayData.strobeType[side] == StrobeType.BOTH)){

					for(int i = 0; i < svgData.Length; i++){

						SpriteLights.LightData data = new SpriteLights.LightData();
						Vector3 position = (runwayData.rotation[side] * svgData[i].position) + runwayData.thresholdPosition[side];

						if(svgData[i].materialString == strobeCString){				

							data.position = position;

							//Set the direction and upward rotation of the light.
							data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);

							data.strobeID = svgData[i].id * strobeTimeStep;
							data.strobeGroupID = groupID;
							lightData.Add(data);
						}			
					}
				}

				if((runwayData.strobeType[side] == StrobeType.REIL) || (runwayData.strobeType[side] == StrobeType.BOTH)){

					float distanceOffset = 0;
					Vector3 sideOffsetDir = Math3d.GetRightVector(runwayData.rotation[side]);	

					//If threshold wing bars are used, the REIL distance must be bigger, otherwise they overlap.
					if(runwayData.thresholdWingbar[side] == ThresholdWingbar.LARGE){

						distanceOffset = 15.5f;
					}

					if((runwayData.thresholdWingbar[side] == ThresholdWingbar.SMALL) || (runwayData.thresholdWingbar[side] == ThresholdWingbar.NONE)){

						distanceOffset = 12f;
					}					

					//Right strobe.
					Vector3 startOffsetAVec = Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + distanceOffset);
					Vector3 position = runwayData.thresholdPosition[side] + startOffsetAVec;
					SpriteLights.LightData data = new SpriteLights.LightData();

					data.position = position;

					//Set the direction and upward rotation of the light.
					data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);

					//The strobe ID is 0, so it will flash at the same time as all other strobes with ID 0.
					//The group ID is the same as the walking strobe, so it is synchronized with that.
					data.strobeID = 0;
					data.strobeGroupID = groupID;

					lightData.Add(data);

					//Left strobe.
					position = runwayData.thresholdPosition[side] - startOffsetAVec;
					data = new SpriteLights.LightData();

					data.position = position;

					//Set the direction and upward rotation of the light.
					data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * runwayData.lightAngle);

					data.strobeGroupID = groupID;
					lightData.Add(data);
				}
			}
		}
	}
	//Setup all the papi lights.
	private void SetupPapiLights(ref List<SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness){

		for(int side = 0; side < 2; side++){

			if(runwayData.papiType[side] != PapiType.NONE){

				//Calculate the offset direction.
				Vector3 lengthOffsetDir = Math3d.GetForwardVector(runwayData.rotation[side]);
				Vector3 sideOffsetDir = Math3d.GetRightVector(runwayData.rotation[side]);
				Vector3 lengthEdgeOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, 337f);

				if((runwayData.papiType[side] == PapiType.PAPIRIGHT) || (runwayData.papiType[side] == PapiType.PAPIBOTH)){
			
					Vector3 startOffsetVec = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + 15f);
					Vector3 startPosition = runwayData.thresholdPosition[side] + startOffsetVec;
					Vector3 currentPosition = startPosition;

					Vector3 sideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 9f);

					for(int i = 0; i < 4; i++){

						SpriteLights.LightData data = new SpriteLights.LightData();

						float angle = GetPapiAngle(i);

						data.position = currentPosition;
						data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * angle);
						lightData.Add(data);

						currentPosition += sideOffsetVec;
					}
				}

				if((runwayData.papiType[side] == PapiType.PAPILEFT) || (runwayData.papiType[side] == PapiType.PAPIBOTH)){

					sideOffsetDir *= -1;

					Vector3 startOffsetVec = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, (runwayData.width * 0.5f) + 15f);
					Vector3 startPosition = runwayData.thresholdPosition[side] + startOffsetVec;
					Vector3 currentPosition = startPosition;

					Vector3 sideOffsetVec = Math3d.SetVectorLength(sideOffsetDir, 9f);

					for(int i = 0; i < 4; i++){

						SpriteLights.LightData data = new SpriteLights.LightData();

						float angle = GetPapiAngle(i);

						data.position = currentPosition;
						data.rotation = runwayData.rotation[side] * Quaternion.Euler(Vector3.right * angle);
						lightData.Add(data);

						currentPosition += sideOffsetVec;
					}
				}
			}
		}
	}
	//Setup all the edge lights.
	private void SetupEdgeLights(ref List<SpriteLights.LightData> lightData, RunwayData runwayData, bool randomBrightness, float brightness, float size){

		float sideFactor = 0;

		//Calculate the amount of lights.
		int lightAmountInRow = (int)Mathf.Floor(runwayData.length / runwayData.edgeLightsSpacing);

		//Calculate the offset direction.
		Vector3 lengthOffsetDir = Math3d.GetForwardVector(runwayData.rotation[0]);
		Vector3 sideOffsetDir = Math3d.GetRightVector(runwayData.rotation[0]);

		//Calculate the start position.
		float rowLength = (lightAmountInRow - 1) * runwayData.edgeLightsSpacing;
		float edgeForwardOffset = (runwayData.length - rowLength) * 0.5f;

		Vector3 lengthEdgeOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, edgeForwardOffset);
		Vector3 startOffsetVec = lengthEdgeOffsetVec + Math3d.SetVectorLength(sideOffsetDir, runwayData.width * 0.5f);
		Vector3 startPosition = runwayData.thresholdPosition[0] + startOffsetVec;
		Vector3 currentPosition = startPosition;

		Vector3 lengthOffsetVec = Math3d.SetVectorLength(lengthOffsetDir, runwayData.edgeLightsSpacing);

		//Calculate the point where the lights should change color.
		float amberA = 600f + runwayData.edgeLightsSpacing;		
		float amberB = (runwayData.length - (600f + runwayData.edgeLightsSpacing));

		int doubleLightAmountInRow = lightAmountInRow * 2;

		for(int i = 0; i < doubleLightAmountInRow; i++){

			bool passedAmberA = false;
			bool passedAmberB = false;

			SpriteLights.LightData data = new SpriteLights.LightData();

			//Shift the current position for the other side.
			if(i == lightAmountInRow){

				startOffsetVec = lengthEdgeOffsetVec + Math3d.SetVectorLength(-sideOffsetDir, runwayData.width * 0.5f);
				currentPosition = runwayData.thresholdPosition[0] + startOffsetVec;

				//Reset flags.
				passedAmberA = false;
				passedAmberB = false;
				sideFactor = lightAmountInRow;
			}

			data.position = currentPosition;
			data.rotation = runwayData.rotation[0];

			//Calculate the distance to the threshold.
			float currentDistance = ((i - sideFactor) * runwayData.edgeLightsSpacing) + edgeForwardOffset;

			//The last 600 meter of the runway has red centerline lights.
			if(currentDistance <= amberA){

				data.frontColor = whiteLight;
				data.brightness = SetBrightness(randomBrightness, brightness);
				data.backColor = amberLight;

				passedAmberA = true;
			}

			//The last 300 meter of the runway has red centerline lights.
			if(currentDistance >= amberB){

				passedAmberB = true;

				data.frontColor = amberLight;
				data.brightness = SetBrightness(randomBrightness, brightness);
				data.backColor = whiteLight;
			}

			//Middle of the runway
			if(!passedAmberA && !passedAmberB){

				data.frontColor = whiteLight;
				data.brightness = SetBrightness(randomBrightness, brightness);
				data.backColor = whiteLight;
			}

			data.size = size;

			lightData.Add(data);

			currentPosition += lengthOffsetVec;
		}
	}