Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

The Walking Dead VR

Discussion in 'Scripting' started by Michaelm9945, Mar 11, 2015.

  1. Michaelm9945

    Michaelm9945

    Joined:
    Feb 20, 2015
    Posts:
    27
    I've attached a photo of my Walking Dead game I made for the Oculus Rift. I recreated the Prison


    I have a problem with building the player. I keep getting errors in the scripts. I've managed to fix about 10 different errors, but more keep coming (It's really frustrating)

    I can't build my player, because there's compiling errors stopping me from doing that.

    Can somebody help me, so I can upload this game on the internet. Its better if I talk to somebody through E-mail, so we can keep in constant contact until this problem is fixed. I will also, send you the game through E-mail.
     

    Attached Files:

  2. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,384
    You need to post some errors before anyone can attempt to suggest how you are to fix them.
     
  3. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,510
    Good lord, that sounds horrible! The boards are the perfect place to resolve your issue. No need to acquire a dedicated support person.

    As LaneFox said, you'll have to let people know what the actual errors are before anyone can help you. If the errors point to a line in one of your scripts, it's a good idea to post those scripts as well so people can see what might be going on. Otherwise, all they'll be able to do is tell you what the error already is: here's what's failing and here's the place it's happening.
     
  4. Michaelm9945

    Michaelm9945

    Joined:
    Feb 20, 2015
    Posts:
    27
    These are all the errors that I am receiving

    HDR RenderTexture format is not supported on this platform. This
    camera will render without HDR buffers.

    Assets/Lux/Lux Scripts/Lux Cubemapper/Scripts/LuxCubeProcessor.cs(1040,8):
    error CS8025: Parsing error


    Assets/OVR/Scripts/Util/OVRMainMenu.cs(98,33): warning CS0414:
    The private field `OVRMainMenu.VRVarsSX' is assigned but its value is never used


    Assets/OVR/Scripts/Util/OVRMainMenu.cs(99,33): warning CS0414:
    The private field `OVRMainMenu.VRVarsSY' is assigned but its value is never used



    Assets/OVR/Scripts/Util/OVRMainMenu.cs(100,33): warning CS0414:
    The private field `OVRMainMenu.VRVarsWidthX' is assigned but its value is never used


    Assets/OVR/Scripts/Util/OVRMainMenu.cs(101,33): warning CS0414:
    The private field `OVRMainMenu.VRVarsWidthY' is assigned but its value is never used


    Assets/OVR/Scripts/Util/OVRMainMenu.cs(145,24): warning CS0414:
    The private field `OVRMainMenu.AlphaFadeValue' is assigned but its value is never used



    Assets/OVR/Scripts/Util/OVRUGUI.cs(94,24): warning CS0414:
    The private field `OVRUGUI.numOfGUI' is assigned but its value is never used


    Assets/Lux/Lux Scripts/Editor/LuxMaterialInspector.cs(55,33):
    warning CS0618: `UnityEditor.MaterialEditor.TextureProperty(string, string,
    UnityEditor.ShaderUtil.ShaderPropertyTexDim)' is obsolete: `Use TextureProperty
    with MaterialProperty instead.'


    Assets/Lux/Lux Scripts/Lux Cubemapper/Editor/LuxEnvProbeEditor.cs(208,21):
    warning CS0219: The variable `spec' is assigned but its value is never used


    Assets/Lux/Lux Scripts/Lux Cubemapper/Editor/LuxEnvProbeEditor.cs(207,21):
    warning CS0219: The variable `diff' is assigned but its value is never used


    Assets/RoadTool/Editor/RoadTool.cs(240,22): warning CS0618:
    `UnityEditor.Undo.RegisterUndo(UnityEngine.Object[], string)'
    is obsolete: `Use Undo.RecordObjects instead'


    Assets/RoadTool/Editor/RoadTool.cs(253,22): warning CS0618:
    `UnityEditor.Undo.RegisterUndo(UnityEngine.Object[], string)'
    is obsolete: `Use Undo.RecordObjects instead'


    Assets/EasyRoads3D Free/Editor/RoadObjectEditorScript.js(730,74):
    BCW0028: WARNING: Implicit downcast from 'System.Object' to 'int'.


    Assets/EasyRoads3D Free/Editor/RoadObjectEditorScript.js(813,17):
    BCW0023: WARNING: This method could return default value implicitly.





    This is the script for Luxcubeprocessor.cs




    Code (CSharp):
    1. //    ////////////////////
    2. //    Lux LuxCubeProcessor
    3.  
    4. //    http://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
    5.  
    6.  
    7. using UnityEngine;
    8. #if UNITY_EDITOR
    9. using UnityEditor;
    10. #endif
    11. public enum ConvoModes
    12. {
    13.     Diffuse = 0,
    14.     Specular = 1
    15. }
    16.  
    17. //public class LuxCubeProcessor : ScriptableWizard {
    18. public class LuxCubeProcessor {
    19.  
    20.     public Cubemap cubeMap;
    21.     public bool TakeNewProbe;
    22.     public GameObject probe;
    23.  
    24.     public ConvoModes ConvolutionMode;
    25.     public bool HighestMipIsReflection = true;
    26.     public bool PullHDR;
    27.  
    28.     private Color[] CubeMapColors;
    29.  
    30.     public float SpecularPower = 2048; // Matches Lux SpecPower
    31.  
    32.  
    33. #if UNITY_EDITOR
    34. //--------------------------------------------------------------------------------------
    35. //    parameter, vars and arrays needed by the script
    36.  
    37.     private float[] solidAngles;
    38.     private static float CP_PI = 3.14159265358979323846f;
    39.  
    40.     // matrices that map cube map indexing vectors in 3d (after face selection and divide through by the _ABSOLUTE VALUE_ of the max coord) into NVC space
    41.     // Note this currently assumes the D3D cube face ordering and orientation
    42.     private Vector3[ , ] sgFace2DMapping = new Vector3[ , ] {
    43.         //XPOS face 0
    44.         { new Vector3( 0,  0, -1),       //u towards negative Z
    45.           new Vector3( 0, -1,  0),       //v towards negative Y
    46.           new Vector3( 1,  0,  0)},      //pos X axis
    47.         //XNEG face 1
    48.         { new Vector3( 0,  0,  1),       //u towards positive Z
    49.           new Vector3( 0, -1,  0),       //v towards negative Y
    50.           new Vector3( -1,  0,  0)},     //neg X axis    
    51.         //YPOS face 2
    52.         { new Vector3(1, 0, 0),            //u towards positive X
    53.           new Vector3(0, 0, 1),            //v towards positive Z
    54.           new Vector3(0, 1 , 0)},        //pos Y axis
    55.         //YNEG face 3
    56.         { new Vector3(1, 0, 0),            //u towards positive X
    57.           new Vector3(0, 0 , -1),        //v towards negative Z
    58.           new Vector3(0, -1 , 0)},        //neg Y axis
    59.         //ZPOS face 4
    60.         { new Vector3(1, 0, 0),            //u towards positive X
    61.           new Vector3(0, -1, 0),        //v towards negative Y
    62.           new Vector3(0, 0,  1)},        //pos Z axis
    63.         //ZNEG face 5
    64.         { new Vector3(-1, 0, 0),        //u towards negative X
    65.           new Vector3(0, -1, 0),        //v towards negative Y
    66.           new Vector3(0, 0, -1)}        //neg Z axis
    67.     };
    68.  
    69.  
    70.     //The 12 edges of the cubemap
    71.     // this table is used to average over the edges.
    72.     private int[ , ] sg_CubeEdgeList = new int[ , ] {
    73.     // face1, face2
    74.         {0,2},                // X_POS Y_POS
    75.         {0,3},                // X_POS Y_NEG
    76.         {0,4},                // X_POS Z_POS
    77.         {0,5},                // X_POS Z_NEG
    78.  
    79.         {1,2},                // X_NEG Y_POS
    80.         {1,3},                // X_NEG Y_NEG
    81.         {1,4},                // X_NEG Z_POS
    82.         {1,5},                // X_NEG Z_NEG
    83.  
    84.         {2,4},                // Y_POS Z_POS
    85.         {2,5},                // Y_POS Z_NEG
    86.         {3,4},                // Y_NEG Z_POS
    87.         {3,5}                // Y_NEG Z_NEG
    88.     };
    89.  
    90.     private int[ , ] sg_CubeCornerList = new int[ , ] {
    91.     // face1, face2, face3
    92.         {0,2,4},            // X_POS Y_POS Z_POS
    93.         {0,2,5},            // X_POS Y_POS Z_NEG
    94.         {0,3,4},            // X_POS Y_NEG Z_POS
    95.         {0,3,5},            // X_POS Y_NEG Z_NEG
    96.  
    97.         {1,2,4},            // X_NEG Y_POS Z_POS
    98.         {1,2,5},            // X_NEG Y_POS Z_NEG
    99.         {1,3,4},            // X_NEG Y_NEG Z_POS
    100.         {1,3,5},            // X_NEG Y_NEG Z_NEG
    101.  
    102.     };
    103.  
    104.  
    105. //--------------------------------------------------------------------------------------
    106.  
    107.     // Helper for Cubemapper Probe
    108.     public void ProcessCubemap(Cubemap cube, bool diff, bool hdr)
    109.     {
    110.         if (diff)
    111.         {
    112.             ConvolveIrradianceEnvironmentMap(cube);
    113.             if (hdr) FakeHDR(cube, false);
    114.             Debug.Log("Diff Cube Processed");
    115.         }
    116.         else
    117.         {
    118.             ConvolveRadianceEnvironmentMap(cube);
    119.             FixupCubeEdges(cube);
    120.             if (hdr) FakeHDR(cube, true);
    121.             cube.filterMode = FilterMode.Trilinear;
    122.             cube.mipMapBias = 0.5f;
    123.             Debug.Log("Spec Cube Processed");
    124.         }
    125.     }
    126.  
    127.     //[MenuItem ("Lux Cubemapper/Cubemapper")]
    128.     //static void CreateWizard () {
    129.     //    ScriptableWizard.DisplayWizard<LuxCubeMapper>("Convolve cubemap", "Go");
    130.     //}
    131.  
    132.     //void OnWizardCreate () {
    133.     //    if (TakeNewProbe) RenderToCubeMap(cubeMap,probe);
    134.  
    135.  
    136.     //    //    diffuse
    137.     //    if (ConvolutionMode == ConvoModes.Diffuse) {
    138.     //        ConvolveIrradianceEnvironmentMap (cubeMap);
    139.     //        if (PullHDR) FakeHDR(cubeMap, false);
    140.     //    }
    141.  
    142.     //    if (ConvolutionMode == ConvoModes.Specular) {
    143.     //        ConvolveRadianceEnvironmentMap (cubeMap);
    144.     //        FixupCubeEdges(cubeMap);
    145.     //        if (PullHDR) FakeHDR(cubeMap, true);
    146.     //        cubeMap.filterMode = FilterMode.Trilinear;
    147.     //        cubeMap.mipMapBias = 0.5f;
    148.     //    }
    149.     //}
    150.  
    151.  
    152.     //void OnWizardUpdate () {
    153.     //}
    154.  
    155.     //void RenderToCubeMap(Cubemap dest, GameObject probe) {
    156.     //    var cubeCamera = new GameObject( "CubemapCamera", typeof(Camera) ) as GameObject;
    157.     ////    cubeCamera.hideFlags = HideFlags.HideInHierarchy;
    158.     //    var cubeCam = cubeCamera.GetComponent("Camera") as Camera;
    159.     //    cubeCam.nearClipPlane = 0.001f;
    160.     //    cubeCam.farClipPlane = 1000.0f;
    161.     //    cubeCam.aspect = 1.0f;
    162.     ////    cubeCam.hdr = true;
    163.     //    cubeCam.cullingMask = 1 << 0;    
    164.     //    cubeCamera.transform.position = probe.transform.position;
    165.     //    cubeCam.RenderToCubemap(dest);
    166.     //    GameObject.DestroyImmediate(cubeCamera);
    167.     //}
    168.  
    169.  
    170.  
    171. //--------------------------------------------------------------------------------------
    172. // ConvolveRadianceEnvironmentMap
    173.  
    174.     void ConvolveRadianceEnvironmentMap (Cubemap RadianceCube) {
    175.         int a_Size = RadianceCube.width;
    176.         int n_Size = a_Size;
    177.         int startMipLevel = 0;
    178.         float specularPower;
    179.         float[] specPowr = new float [] {
    180.             SpecularPower, SpecularPower/2.0f, SpecularPower/4.0f, SpecularPower/8.0f, SpecularPower/16.0f, SpecularPower/32.0f, SpecularPower/64.0f, SpecularPower/128.0f, SpecularPower/256.0f, SpecularPower/512.0f
    181.         };
    182.  
    183.         // Calculate maxmiplevels
    184.         int maxMipLevels = (int)Mathf.Log(a_Size, 2) + 1;
    185.     //
    186.         float mytime = Time.realtimeSinceStartup;
    187.  
    188.         // if HighestMipIsReflection == true then skip processing of the highest mip level
    189.         if (HighestMipIsReflection) {
    190.             startMipLevel = 1;
    191.             n_Size = n_Size >> 1;    
    192.         }
    193.  
    194.         for (int mipLevel = startMipLevel; mipLevel < maxMipLevels; mipLevel++)
    195.         {
    196.             Vector4[] m_NormCubeMapArray = new Vector4[n_Size*n_Size*6];
    197.             BuildNormalizerSolidAngleArray(n_Size, ref m_NormCubeMapArray);
    198.  
    199.             specularPower = specPowr[mipLevel];
    200.             float Angle;
    201.             // If we use SpecularPower, automatically calculate the a_BaseFilterAngle required, this will speed the process
    202.             Angle = GetBaseFilterAngle(specularPower);
    203.             // Go for it:
    204.             FilterCubefaces(RadianceCube, m_NormCubeMapArray, mipLevel, Angle, specularPower);
    205.     //        FilterCubefacesBF(RadianceCube, mipLevel, Angle, specularPower);
    206.             n_Size = n_Size >> 1;
    207.         }
    208.     //
    209.         Debug.Log(Time.realtimeSinceStartup - mytime);
    210.  
    211.         RadianceCube.Apply(false);
    212.  
    213.     }
    214.  
    215.  
    216.     void FilterCubefaces (Cubemap RadianceCubeMap, Vector4[] m_NormCubeMapArray, int mipLevel, float a_FilterConeAngle, float a_SpecularPower)
    217.     {
    218.         // Read the first CubeFace
    219.         Color[] InputCubeFacePixels = RadianceCubeMap.GetPixels(CubemapFace.PositiveX, mipLevel);
    220.         // Get its dimensions
    221.         int faceLength = InputCubeFacePixels.Length;
    222.         int a_Size = (int)Mathf.Sqrt(faceLength);
    223.         // Create new array for all Faces
    224.         Color[] PixelsOfAllFaces = new Color[faceLength * 6];
    225.         // Copy first face
    226.         InputCubeFacePixels.CopyTo(PixelsOfAllFaces, 0);
    227.         // Copy all other Faces
    228.         for (int readFace = 1; readFace < 6; readFace++ ) {
    229.             InputCubeFacePixels = RadianceCubeMap.GetPixels((CubemapFace)readFace, mipLevel);
    230.             InputCubeFacePixels.CopyTo(PixelsOfAllFaces, faceLength * readFace);
    231.         }
    232.         InputCubeFacePixels = null;
    233.         // Declare jagged output array and init its child arrays
    234.         Color[][] OutputCubeFacePixels = new Color[6][];
    235.         OutputCubeFacePixels[0] = new Color[faceLength];
    236.         OutputCubeFacePixels[1] = new Color[faceLength];
    237.         OutputCubeFacePixels[2] = new Color[faceLength];
    238.         OutputCubeFacePixels[3] = new Color[faceLength];
    239.         OutputCubeFacePixels[4] = new Color[faceLength];
    240.         OutputCubeFacePixels[5] = new Color[faceLength];
    241.  
    242.         // FilterCubeSurfaces
    243.         float srcTexelAngle;
    244.         float dotProdThresh;
    245.         int filterSize;
    246.         // Angle about center tap to define filter cone
    247.         float filterAngle;
    248.         // Min angle a src texel can cover (in degrees)
    249.         srcTexelAngle = (180.0f / CP_PI) * Mathf.Atan2(1.0f, (float)a_Size);
    250.         // Filter angle is 1/2 the cone angle
    251.         filterAngle = a_FilterConeAngle / 2.0f;
    252.         // Ensure filter angle is larger than a texel
    253.         if(filterAngle < srcTexelAngle)
    254.         {
    255.             filterAngle = srcTexelAngle;
    256.         }
    257.         // Ensure filter cone is always smaller than the hemisphere
    258.         if(filterAngle > 90.0f)
    259.         {
    260.             filterAngle = 90.0f;
    261.         }
    262.         // The maximum number of texels in 1D the filter cone angle will cover
    263.         // Used to determine bounding box size for filter extents
    264.         filterSize = (int)Mathf.Ceil(filterAngle / srcTexelAngle);
    265.         // Ensure conservative region always covers at least one texel
    266.         if(filterSize < 1)
    267.         {
    268.             filterSize = 1;
    269.         }
    270.         // dotProdThresh threshold based on cone angle to determine whether or not taps
    271.         // Reside within the cone angle
    272.         dotProdThresh = Mathf.Cos( (CP_PI / 180.0f) * filterAngle );
    273.  
    274.         // Process required faces
    275.         for (int a_FaceIdx = 0; a_FaceIdx < 6; a_FaceIdx++)
    276.         {
    277.             // Iterate over dst cube map face texel
    278.             for (int a_V  = 0; a_V < a_Size; a_V++)
    279.             {
    280.                 for (int a_U = 0; a_U < a_Size; a_U++)
    281.                 {
    282.                     Vector4 Sample = new Vector4();
    283.                     Color tempCol = new Color();
    284.                     // Get center tap direction
    285.                     Vector3 centerTapDir = TexelToVect(a_FaceIdx, (float)a_U, (float)a_V, a_Size);
    286.                     //--------------------------------------------------------------------------------------
    287.                     // ProcessFilterExtents
    288.                     float weightAccum = 0.0f;
    289.                     int startFacePtr = 0;
    290.                     // Iterate over cubefaces
    291.                     for(int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++ )
    292.                     {
    293.                         // Pointer to the start of the given face
    294.                         startFacePtr = a_Size*a_Size*iFaceIdx;
    295.                         for(int v = 0; v < a_Size; v++)
    296.                         {
    297.                             for(int u = 0; u < a_Size; u++)
    298.                             {
    299.                                 // CP_FILTER_TYPE_COSINE_POWER
    300.  
    301.                                 // Read normalCube single "pixel"
    302.                                 Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + a_Size*v + u];
    303.                                 // Pointer to direction in cube map associated with texel
    304.                                 // Vector3 texelVect = TexelToVect(iFaceIdx, (float)u, (float)v, a_Size);
    305.                                 Vector3 texelVect;
    306.                                 // Optimized version
    307.                                 texelVect.x = m_NormCubeMap_pixel[0];// * 2.0f - 1.0f;
    308.                                 texelVect.y = m_NormCubeMap_pixel[1];// * 2.0f - 1.0f;
    309.                                 texelVect.z = m_NormCubeMap_pixel[2];// * 2.0f - 1.0f;
    310.                                 // Check dot product to see if texel is within cone
    311.                                 float tapDotProd = Vector3.Dot(texelVect, centerTapDir);
    312.                                 float weight = 0.0f;
    313.                                 if( tapDotProd >= dotProdThresh && tapDotProd > 0.0f )
    314.                                 {
    315.                                     // Weight should be proportional to the solid angle of the tap
    316.                                      // weight = TexelCoordSolidAngle(iFaceIdx, (float)u, (float)v, a_Size);
    317.                                     weight = m_NormCubeMap_pixel[3];
    318.                                     // Here we decide if we use a Phong/Blinn or a Phong/Blinn BRDF.
    319.                                     // Phong/Blinn BRDF is just the Phong/Blinn model multiply by the cosine of the lambert law
    320.                                     // so just adding one to specularpower do the trick.                    
    321.                                     // weight *= pow(tapDotProd, (a_SpecularPower + (float32)IsPhongBRDF));
    322.                                 // CP_FILTER_TYPE_COSINE_POWER
    323.                                     weight *= Mathf.Pow(tapDotProd, a_SpecularPower);
    324.                                 // CP_FILTER_TYPE_COSINE
    325.                                     //weight *= tapDotProd;
    326.                              
    327.                                 }
    328.                                 // Accumulate weight
    329.                                 weightAccum += weight;
    330.                                 // Get pixel from the input cubeMap array
    331.                                 tempCol = PixelsOfAllFaces[a_Size*a_Size*iFaceIdx + a_Size*v + u];
    332.                                 Sample += new Vector4(tempCol.r * weight, tempCol.g * weight, tempCol.b * weight, 1.0f);
    333.                             }
    334.                         }
    335.                     }
    336.                     // one pixel processed
    337.                     // Lux needs alpha!
    338.                     OutputCubeFacePixels[a_FaceIdx][a_V*a_Size + a_U] = new Color(Sample.x/ weightAccum, Sample.y/ weightAccum, Sample.z/ weightAccum, 1.0f);
    339.                 // end inner loops
    340.                 }
    341.             }
    342.         }
    343.         // Write Pixel from the jagged array back to the cubemap faces
    344.         for (int writeFace = 0; writeFace < 6; writeFace++ ) {
    345.             Color[] tempColors = OutputCubeFacePixels[writeFace];
    346.             RadianceCubeMap.SetPixels(tempColors, (CubemapFace)writeFace, mipLevel);
    347.         }
    348.     }
    349.  
    350.  
    351.  
    352.  
    353. // brute force: no look up table used
    354.  
    355.     void FilterCubefacesBF (Cubemap RadianceCubeMap, int mipLevel, float a_FilterConeAngle, float a_SpecularPower)
    356.     {
    357.         // Read the first CubeFace
    358.         Color[] InputCubeFacePixels = RadianceCubeMap.GetPixels(CubemapFace.PositiveX, mipLevel);
    359.         // Get its dimensions
    360.         int faceLength = InputCubeFacePixels.Length;
    361.         int a_Size = (int)Mathf.Sqrt(faceLength);
    362.         // Create new array for all Faces
    363.         Color[] PixelsOfAllFaces = new Color[faceLength * 6];
    364.         // Copy first face
    365.         InputCubeFacePixels.CopyTo(PixelsOfAllFaces, 0);
    366.         // Copy all other Faces
    367.         for (int readFace = 1; readFace < 6; readFace++ ) {
    368.             InputCubeFacePixels = RadianceCubeMap.GetPixels((CubemapFace)readFace, mipLevel);
    369.             InputCubeFacePixels.CopyTo(PixelsOfAllFaces, faceLength * readFace);
    370.         }
    371.         InputCubeFacePixels = null;
    372.  
    373.         // declare jagged output array and init its child arrays
    374.         Color[][] OutputCubeFacePixels = new Color[6][];
    375.         OutputCubeFacePixels[0] = new Color[faceLength];
    376.         OutputCubeFacePixels[1] = new Color[faceLength];
    377.         OutputCubeFacePixels[2] = new Color[faceLength];
    378.         OutputCubeFacePixels[3] = new Color[faceLength];
    379.         OutputCubeFacePixels[4] = new Color[faceLength];
    380.         OutputCubeFacePixels[5] = new Color[faceLength];
    381.  
    382.  
    383.         // FilterCubeSurfaces
    384.         float srcTexelAngle;
    385.         float dotProdThresh;
    386.         int filterSize;
    387.         //angle about center tap to define filter cone
    388.         float filterAngle;
    389.         //min angle a src texel can cover (in degrees)
    390.         srcTexelAngle = (180.0f / CP_PI) * Mathf.Atan2(1.0f, (float)a_Size);
    391.         //filter angle is 1/2 the cone angle
    392.         filterAngle = a_FilterConeAngle / 2.0f;
    393.         //ensure filter angle is larger than a texel
    394.         if(filterAngle < srcTexelAngle)
    395.         {
    396.             filterAngle = srcTexelAngle;
    397.         }
    398.         //ensure filter cone is always smaller than the hemisphere
    399.         if(filterAngle > 90.0f)
    400.         {
    401.             filterAngle = 90.0f;
    402.         }
    403.  
    404.         // The maximum number of texels in 1D the filter cone angle will cover
    405.         // Used to determine bounding box size for filter extents
    406.         filterSize = (int)Mathf.Ceil(filterAngle / srcTexelAngle);
    407.         // Ensure conservative region always covers at least one texel
    408.         if(filterSize < 1)
    409.         {
    410.             filterSize = 1;
    411.         }
    412.  
    413.         // dotProdThresh threshold based on cone angle to determine whether or not taps
    414.         // Reside within the cone angle
    415.         dotProdThresh = Mathf.Cos( (CP_PI / 180.0f) * filterAngle );
    416.  
    417.         // Process required faces
    418.         for (int a_FaceIdx = 0; a_FaceIdx < 6; a_FaceIdx++)
    419.         {
    420.             // Iterate over dst cube map face texel
    421.             for (int a_V  = 0; a_V < a_Size; a_V++)
    422.             {
    423.                 for (int a_U = 0; a_U < a_Size; a_U++)
    424.                 {
    425.                     Vector4 Sample = new Vector4();
    426.                     Color tempCol = new Color();
    427.              
    428.                     // get center tap direction
    429.                     Vector3 centerTapDir = TexelToVect(a_FaceIdx, (float)a_U, (float)a_V, a_Size);
    430.  
    431.                     //--------------------------------------------------------------------------------------
    432.                     //    ProcessFilterExtents
    433.  
    434.                     float weightAccum = 0.0f;
    435.  
    436.                     // Iterate over cubefaces
    437.                     for(int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++ )
    438.                     {
    439.                         for(int v = 0; v < a_Size; v++)
    440.                         {
    441.                             for(int u = 0; u < a_Size; u++)
    442.                             {
    443.                                 // CP_FILTER_TYPE_COSINE_POWER
    444.                                 // Pointer to direction in cube map associated with texel
    445.                                 Vector3 texelVect = TexelToVect(iFaceIdx, (float)u, (float)v, a_Size);
    446.                                 // Check dot product to see if texel is within cone
    447.                                 float tapDotProd = Vector3.Dot(texelVect, centerTapDir);
    448.  
    449.  
    450.                                 float weight = 0.0f;
    451.                                 if( tapDotProd >= dotProdThresh && tapDotProd > 0.0f )
    452.                                 {
    453.                              
    454.                                     // Weight should be proportional to the solid angle of the tap
    455.                                      weight = TexelCoordSolidAngle(iFaceIdx, (float)u, (float)v, a_Size);
    456.                                     // Here we decide if we use a Phong/Blinn or a Phong/Blinn BRDF.
    457.                                     // Phong/Blinn BRDF is just the Phong/Blinn model multiply by the cosine of the lambert law
    458.                                     // so just adding one to specularpower do the trick.                    
    459.                                     // weight *= pow(tapDotProd, (a_SpecularPower + (float32)IsPhongBRDF));
    460.                                 // CP_FILTER_TYPE_COSINE_POWER
    461.                                     weight *= Mathf.Pow(tapDotProd, a_SpecularPower);
    462.                                 // CP_FILTER_TYPE_COSINE
    463.                                     //weight *= tapDotProd;
    464.                                 }
    465.                                 // Accumulate weight
    466.                                 weightAccum += weight;
    467.  
    468.                                 // Get pixel from the input cubeMap array
    469.                                 tempCol = PixelsOfAllFaces[a_Size*a_Size*iFaceIdx + a_Size*v + u];
    470.                                 Sample += new Vector4(tempCol.r * weight, tempCol.g * weight, tempCol.b * weight, 1.0f);
    471.                             }
    472.                         }
    473.                     }
    474.                     // one pixel processed
    475.                     // Lux needs alpha!
    476.                     OutputCubeFacePixels[a_FaceIdx][a_V*a_Size + a_U] = new Color(Sample.x/ weightAccum, Sample.y/ weightAccum, Sample.z/ weightAccum, 1.0f);
    477.                 // end inner loops
    478.                 }
    479.             }
    480.         }
    481.         // Write Pixel from the jagged array back to the cubemap faces
    482.         for (int writeFace = 0; writeFace < 6; writeFace++ ) {
    483.             Color[] tempColors = OutputCubeFacePixels[writeFace];
    484.             RadianceCubeMap.SetPixels(tempColors, (CubemapFace)writeFace, mipLevel);
    485.         }
    486.     }
    487.  
    488.     //--------------------------------------------------------------------------------------
    489.     // Irridiance Convolution based on SH
    490.  
    491.     void ConvolveIrradianceEnvironmentMap(Cubemap irrCubeMap)
    492.     {
    493.         int a_Size = irrCubeMap.width;
    494.  
    495.         Vector4[] m_NormCubeMapArray = new Vector4[a_Size*a_Size*6];
    496.         BuildNormalizerSolidAngleArray(a_Size, ref m_NormCubeMapArray);
    497.  
    498.         //This is a custom implementation of D3DXSHProjectCubeMap to avoid to deal with LPDIRECT3DSURFACE9 pointer
    499.         //Use Sh order 2 for a total of 9 coefficient as describe in http://www.cs.berkeley.edu/~ravir/papers/envmap/
    500.         //accumulators are 64-bit floats in order to have the precision needed
    501.         //over a summation of a large number of pixels
    502.         double[] SHr = new double[25]; // NUM_SH_COEFFICIENT
    503.         double[] SHg = new double[25];
    504.         double[] SHb = new double[25];
    505.         double[] SHdir = new double[25];
    506.  
    507.         double weightAccum = 0.0;
    508.         double weight = 0.0;
    509.  
    510.         int startFacePtr = 0;
    511.  
    512.         for (int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++) {
    513.  
    514.             // read pixels of m_NormCubeMap
    515.             //var m_NormCubeMap_pixels  = new Color[m_NormCubeMap.width*m_NormCubeMap.height];
    516.             //m_NormCubeMap_pixels = m_NormCubeMap.GetPixels((CubemapFace)iFaceIdx);
    517.  
    518.             // Pointer to the start of the given face in m_NormCubeMapArray
    519.             startFacePtr = a_Size*a_Size*iFaceIdx;
    520.  
    521.             // read all pixels of irrCubeMap
    522.             var cubeMap_pixels = new Color[irrCubeMap.width * irrCubeMap.height];
    523.             cubeMap_pixels = irrCubeMap.GetPixels((CubemapFace)iFaceIdx);
    524.  
    525.  
    526.                 for (int y = 0; y < a_Size; y++) {
    527.                     for (int x = 0; x < a_Size; x++) {
    528.  
    529.                         // read normalCube single pixel
    530.                         Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + y*a_Size + x];
    531.  
    532.                         // read originalCube single pixel
    533.                         Color cubeMap_pixel = cubeMap_pixels[y*a_Size + x];
    534.  
    535.                         // solid angle stored in 4th channel of normalizer/solid angle cube map
    536.                         weight = m_NormCubeMap_pixel[3];
    537.                         //weight = TexelCoordSolidAngle(iFaceIdx, (float)x, (float)y, a_Size);
    538.  
    539.                         // pointer to direction and solid angle in cube map associated with texel
    540.                         Vector3 texelVect;
    541.                         texelVect.x = m_NormCubeMap_pixel[0];
    542.                         texelVect.y = m_NormCubeMap_pixel[1];
    543.                         texelVect.z = m_NormCubeMap_pixel[2];
    544.                         //texelVect = TexelToVect(iFaceIdx, (float)x, (float)y, a_Size);
    545.  
    546.                         EvalSHBasis(texelVect, ref SHdir);
    547.  
    548.                         // read original colors and convert to float64
    549.                         double R = cubeMap_pixel[0];
    550.                         double G = cubeMap_pixel[1];
    551.                         double B = cubeMap_pixel[2];
    552.  
    553.                         for (int i = 0; i < 25; i++)
    554.                         {
    555.                             SHr[i] += R * SHdir[i] * weight;
    556.                             SHg[i] += G * SHdir[i] * weight;
    557.                             SHb[i] += B * SHdir[i] * weight;
    558.                         }
    559.                         weightAccum += weight;
    560.                 }
    561.             }
    562.         }
    563.         // Normalization - The sum of solid angle should be equal to the solid angle of the sphere (4 PI), so
    564.         // Normalize in order our weightAccum exactly match 4 PI.
    565.         for (int i = 0; i < 25; ++i)
    566.         {
    567.             SHr[i] *= 4.0 * CP_PI / weightAccum;
    568.             SHg[i] *= 4.0 * CP_PI / weightAccum;
    569.             SHb[i] *= 4.0 * CP_PI / weightAccum;
    570.         }
    571.  
    572.         // Second step - Generate cubemap from SH coefficient
    573.  
    574.         // Normalized vectors per cubeface and per-texel solid angle
    575.         // Why do we do it a 2nd time????
    576.         BuildNormalizerSolidAngleArray(a_Size, ref m_NormCubeMapArray);
    577.  
    578.         for (int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++) {
    579.  
    580.             // Pointer to the start of the given face in m_NormCubeMapArray
    581.             startFacePtr = a_Size*a_Size*iFaceIdx;
    582.  
    583.             for (int y = 0; y < a_Size; y++) {
    584.                 for (int x = 0; x < a_Size; x++) {
    585.                     // read normalCube pixel
    586.                     Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + y*a_Size + x];
    587.  
    588.                     // read normalvector and pass it to EvalSHBasis to get SHdir
    589.                     Vector3 texelVect;
    590.                     texelVect.x = m_NormCubeMap_pixel[0];
    591.                     texelVect.y = m_NormCubeMap_pixel[1];
    592.                     texelVect.z = m_NormCubeMap_pixel[2];
    593.                     //texelVect = TexelToVect(iFaceIdx, (float)x, (float)y, a_Size);
    594.  
    595.                     EvalSHBasis( texelVect, ref SHdir);
    596.  
    597.                     // set color values
    598.                     double R = 0.0;
    599.                     double G = 0.0;
    600.                     double B = 0.0;
    601.              
    602.                     for (int i = 0; i < 25; ++i)
    603.                     {
    604.                         R += (SHr[i] * SHdir[i] * SHBandFactor[i]);
    605.                         G += (SHg[i] * SHdir[i] * SHBandFactor[i]);
    606.                         B += (SHb[i] * SHdir[i] * SHBandFactor[i]);
    607.                     }
    608.                     // Lux needs alpha!
    609.                     irrCubeMap.SetPixel((CubemapFace)iFaceIdx, x, y, new Color((float)R,(float)G,(float)B, 1.0f ));
    610.                 }
    611.             }
    612.         }
    613.         irrCubeMap.Apply();
    614.     }
    615.  
    616.     //--------------------------------------------------------------------------------------
    617.     // This function return the BaseFilterAngle require by cubemapgen to its FilterExtends
    618.     // It allow to optimize the texel to access base on the specular power.
    619.     static float GetBaseFilterAngle(float cosinePower)
    620.     {
    621.         // We want to find the alpha such that:
    622.         // cos(alpha)^cosinePower = epsilon
    623.         // That's: acos(epsilon^(1/cosinePower))
    624.         const float threshold = 0.000001f;  // Empirical threshold (Work perfectly, didn't check for a more big number, may get some performance and still god approximation)
    625.         float Angle = 180.0f;
    626.         if (Angle != 0.0f)
    627.         {
    628.             Angle = Mathf.Acos(Mathf.Pow(threshold, 1.0f / cosinePower));
    629.             Angle *= 180.0f / CP_PI; // Convert to degree
    630.             Angle *= 2.0f; // * 2.0f because cubemapgen divide by 2 later
    631.         }
    632.  
    633.         return Angle;
    634.     }
    635.  
    636.     //--------------------------------------------------------------------------------------
    637.     // Convert cubemap face texel coordinates and face idx to 3D vector
    638.  
    639.     Vector3 TexelToVect(int a_FaceIdx, float a_U, float a_V, int a_Size) {
    640.         float nvcU, nvcV;
    641.  
    642.         nvcU = (2.0f * ((float)a_U + 0.5f) / (float)a_Size ) - 1.0f;
    643.         nvcV = (2.0f * ((float)a_V + 0.5f) / (float)a_Size ) - 1.0f;
    644.         // U contribution
    645.         Vector3 Dir = sgFace2DMapping[a_FaceIdx, 0] * nvcU;
    646.         // V contribution
    647.         Vector3 tempVec = sgFace2DMapping[a_FaceIdx, 1] * nvcV;
    648.         Dir += tempVec;
    649.         // Add face axis
    650.         Dir += sgFace2DMapping[a_FaceIdx, 2];
    651.         // Normalize vector
    652.         Dir = Vector3.Normalize(Dir);
    653.         return(Dir);
    654.     }
    655.  
    656.     //--------------------------------------------------------------------------------------
    657.     // Convert 3D vector to cubemap face texel coordinates and face idx
    658.  
    659.     private Vector3 VectToTexelCoord(Vector3 a_XYZ, int a_Size) {
    660.         float nvcU, nvcV;
    661.         float maxCoord;
    662.         Vector3 onFaceXYZ;
    663.         int faceIdx;
    664.         float u, v;
    665.             // Get Absolute value
    666.         Vector3 absXYZ = new Vector3(Mathf.Abs(a_XYZ.x), Mathf.Abs(a_XYZ.y), Mathf.Abs(a_XYZ.z));
    667.  
    668.         if( (absXYZ[0] >= absXYZ[1]) && (absXYZ[0] >= absXYZ[2]) )
    669.         {
    670.             maxCoord = absXYZ[0];
    671.             if(a_XYZ[0] >= 0) faceIdx = 0; // face = XPOS -> FACE_X_POS
    672.             else faceIdx = 1; // FACE_X_NEG;                
    673.         }
    674.         else if ( (absXYZ[1] >= absXYZ[0]) && (absXYZ[1] >= absXYZ[2]) )
    675.         {
    676.             maxCoord = absXYZ[1];
    677.             if(a_XYZ[1] >= 0) faceIdx = 2; // face = XPOS -> FACE_Y_POS
    678.             else faceIdx = 3; // FACE_Y_NEG;                
    679.         }
    680.         else
    681.         {
    682.             maxCoord = absXYZ[2];
    683.             if(a_XYZ[2] >= 0) faceIdx = 4;  // face = XPOS -> FACE_Z_POS
    684.             else faceIdx = 5; // FACE_Z_NEG;                
    685.         }
    686.         // Divide through by max coord so face vector lies on cube face
    687.         onFaceXYZ = a_XYZ * 1.0f/maxCoord;
    688.         nvcU = Vector3.Dot(sgFace2DMapping[faceIdx, 0] , onFaceXYZ ); // U-Direction
    689.         nvcV = Vector3.Dot(sgFace2DMapping[faceIdx, 1] , onFaceXYZ ); // V-Direction
    690.         // Modify original AMD code to return value from 0 to Size - 1
    691.     //    As we will sample multiple pixels we skip (int)Mathf.Floor here
    692.         u = (a_Size - 1) * 0.5f * (nvcU + 1.0f);
    693.         v = (a_Size - 1) * 0.5f * (nvcV + 1.0f);
    694.         a_XYZ.x = faceIdx;
    695.         a_XYZ.y = u;
    696.         a_XYZ.z = v;
    697.         return a_XYZ;
    698.     }
    699.  
    700.     //--------------------------------------------------------------------------------------
    701.     //    Compute solid angle of given texel in cubemap face for weighting taps in the
    702.     //    kernel by the area they project to on the unit sphere.
    703.  
    704.     //    Original code from Ignacio Castaño
    705.  
    706.     float TexelCoordSolidAngle(int a_FaceIdx, float a_U, float a_V, int faceSize)
    707.     {
    708.         // Scale up to [-1, 1] range (inclusive), offset by 0.5 to point to texel center.
    709.             float U = (2.0f * ((float)a_U + 0.5f) / (float)faceSize ) - 1.0f;
    710.             float V = (2.0f * ((float)a_V + 0.5f) / (float)faceSize ) - 1.0f;
    711.  
    712.             float InvResolution = 1.0f / faceSize;
    713.             // U and V are the -1..1 texture coordinate on the current face.
    714.         // Get projected area for this texel
    715.         float x0 = U - InvResolution;
    716.         float y0 = V - InvResolution;
    717.         float x1 = U + InvResolution;
    718.         float y1 = V + InvResolution;
    719.         float SolidAngle = AreaElement(x0, y0) - AreaElement(x0, y1) - AreaElement(x1, y0) + AreaElement(x1, y1);
    720.     //    Returns values between 0.001 and 0.009
    721.     //    So lets multiply it by 100.0f
    722.         return SolidAngle * 100.0f;
    723.     }
    724.     static float AreaElement( float x, float y )
    725.     {
    726.         return Mathf.Atan2(x * y, Mathf.Sqrt(x * x + y * y + 1));
    727.     }
    728.  
    729.     //--------------------------------------------------------------------------------------
    730.     // Fixup cube edges
    731.  
    732.     void FixupCubeEdges (Cubemap CubeMap)
    733.     {
    734.         int maxMipLevels = (int)(Mathf.Log((float)CubeMap.width, 2.0f)) + 1;
    735.         int base_Size = CubeMap.width;
    736.  
    737.         // Do not perform any edge fixed for mip level 0
    738.         for (int mipLevel = 1; mipLevel < maxMipLevels; mipLevel++)
    739.         {
    740.             // declare jagged array for all faces and init its child arrays
    741.             Color[][] PixelsOfAllFaces = new Color[6][];
    742.             PixelsOfAllFaces[0] = CubeMap.GetPixels(CubemapFace.PositiveX, mipLevel);
    743.             PixelsOfAllFaces[1] = CubeMap.GetPixels(CubemapFace.NegativeX, mipLevel);
    744.             PixelsOfAllFaces[2] = CubeMap.GetPixels(CubemapFace.PositiveY, mipLevel);
    745.             PixelsOfAllFaces[3] = CubeMap.GetPixels(CubemapFace.NegativeY, mipLevel);
    746.             PixelsOfAllFaces[4] = CubeMap.GetPixels(CubemapFace.PositiveZ, mipLevel);
    747.             PixelsOfAllFaces[5] = CubeMap.GetPixels(CubemapFace.NegativeZ, mipLevel);
    748.  
    749.             int a_Size = base_Size >> mipLevel;
    750.             // As we use a_Size as pointer in our arrays we have to lower it by 1
    751.             a_Size -= 1;
    752.  
    753.  
    754.             int a_FixupWidth = 3;
    755.             int fixupDist = (int)Mathf.Min( a_FixupWidth, a_Size / 2);
    756.  
    757.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[0,0]], PixelsOfAllFaces[sg_CubeCornerList[0,1]], PixelsOfAllFaces[sg_CubeCornerList[0,2]], 0, 0, a_Size, a_Size, a_Size, 0);
    758.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[1,0]], PixelsOfAllFaces[sg_CubeCornerList[1,1]], PixelsOfAllFaces[sg_CubeCornerList[1,2]], a_Size, 0, a_Size, 0, 0, 0);
    759.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[2,0]], PixelsOfAllFaces[sg_CubeCornerList[2,1]], PixelsOfAllFaces[sg_CubeCornerList[2,2]], 0, a_Size, a_Size, 0, a_Size, a_Size);
    760.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[3,0]], PixelsOfAllFaces[sg_CubeCornerList[3,1]], PixelsOfAllFaces[sg_CubeCornerList[3,2]], a_Size, a_Size, a_Size, a_Size, 0, a_Size);
    761.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[4,0]], PixelsOfAllFaces[sg_CubeCornerList[4,1]], PixelsOfAllFaces[sg_CubeCornerList[4,2]], a_Size, 0, 0, a_Size, 0, 0);
    762.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[5,0]], PixelsOfAllFaces[sg_CubeCornerList[5,1]], PixelsOfAllFaces[sg_CubeCornerList[5,2]], 0, 0, 0, 0, a_Size, 0);
    763.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[6,0]], PixelsOfAllFaces[sg_CubeCornerList[6,1]], PixelsOfAllFaces[sg_CubeCornerList[6,2]], a_Size, a_Size, 0, 0, 0, a_Size);
    764.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[7,0]], PixelsOfAllFaces[sg_CubeCornerList[7,1]], PixelsOfAllFaces[sg_CubeCornerList[7,2]], 0, a_Size, 0, a_Size, a_Size, a_Size);
    765.  
    766.             // Perform 2nd iteration in reverse order
    767.  
    768.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[7,0]], PixelsOfAllFaces[sg_CubeCornerList[7,1]], PixelsOfAllFaces[sg_CubeCornerList[7,2]], 0, a_Size, 0, a_Size, a_Size, a_Size);
    769.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[6,0]], PixelsOfAllFaces[sg_CubeCornerList[6,1]], PixelsOfAllFaces[sg_CubeCornerList[6,2]], a_Size, a_Size, 0, 0, 0, a_Size);
    770.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[5,0]], PixelsOfAllFaces[sg_CubeCornerList[5,1]], PixelsOfAllFaces[sg_CubeCornerList[5,2]], 0, 0, 0, 0, a_Size, 0);
    771.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[4,0]], PixelsOfAllFaces[sg_CubeCornerList[4,1]], PixelsOfAllFaces[sg_CubeCornerList[4,2]], a_Size, 0, 0, a_Size, 0, 0);
    772.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[3,0]], PixelsOfAllFaces[sg_CubeCornerList[3,1]], PixelsOfAllFaces[sg_CubeCornerList[3,2]], a_Size, a_Size, a_Size, a_Size, 0, a_Size);
    773.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[2,0]], PixelsOfAllFaces[sg_CubeCornerList[2,1]], PixelsOfAllFaces[sg_CubeCornerList[2,2]], 0, a_Size, a_Size, 0, a_Size, a_Size);
    774.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[1,0]], PixelsOfAllFaces[sg_CubeCornerList[1,1]], PixelsOfAllFaces[sg_CubeCornerList[1,2]], a_Size, 0, a_Size, 0, 0, 0);
    775.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[0,0]], PixelsOfAllFaces[sg_CubeCornerList[0,1]], PixelsOfAllFaces[sg_CubeCornerList[0,2]], 0, 0, a_Size, a_Size, a_Size, 0);
    776.  
    777.  
    778.  
    779.             // Average Edges
    780.             // Note that this loop does not process the corner texels, since they have already been averaged
    781.             for (int i = 1; i < (a_Size - 1); i++)
    782.             {
    783.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[0,0]], PixelsOfAllFaces[sg_CubeEdgeList[0,1]], i, 0, a_Size, a_Size - i, fixupDist, new Vector4(0, 1, -1, 0) );
    784.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[1,0]], PixelsOfAllFaces[sg_CubeEdgeList[1,1]], i, a_Size, a_Size, i, fixupDist, new Vector4(0, -1, -1, 0) );
    785.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[2,0]], PixelsOfAllFaces[sg_CubeEdgeList[2,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    786.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[3,0]], PixelsOfAllFaces[sg_CubeEdgeList[3,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    787.          
    788.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[4,0]], PixelsOfAllFaces[sg_CubeEdgeList[4,1]], i, 0, 0, i, fixupDist, new Vector4(0, 1, 1, 0) );
    789.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[5,0]], PixelsOfAllFaces[sg_CubeEdgeList[5,1]], i, a_Size, 0, a_Size - i, fixupDist, new Vector4(0, -1, 1, 0) );
    790.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[6,0]], PixelsOfAllFaces[sg_CubeEdgeList[6,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    791.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[7,0]], PixelsOfAllFaces[sg_CubeEdgeList[7,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    792.          
    793.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[8,0]], PixelsOfAllFaces[sg_CubeEdgeList[8,1]], i, a_Size, i, 0, fixupDist, new Vector4(0, -1, 0, 1) );
    794.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[9,0]], PixelsOfAllFaces[sg_CubeEdgeList[9,1]], i, 0, a_Size - i, 0, fixupDist, new Vector4(0, 1, 0, 1) );
    795.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[10,0]], PixelsOfAllFaces[sg_CubeEdgeList[10,1]], i, 0, i, a_Size, fixupDist, new Vector4(0, 1, 0, -1) );
    796.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[11,0]], PixelsOfAllFaces[sg_CubeEdgeList[11,1]], i, a_Size, a_Size - i, a_Size, fixupDist, new Vector4(0, -1, 0, -1) );
    797.      
    798.             }
    799.             // Perform 2nd iteration in reverse order
    800.         /*    for (int i = 0; i < (a_Size); i++)
    801.             {
    802.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[11,0]], PixelsOfAllFaces[sg_CubeEdgeList[11,1]], i, a_Size, a_Size - i, a_Size, fixupDist, new Vector4(0, -1, 0, -1) );
    803.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[10,0]], PixelsOfAllFaces[sg_CubeEdgeList[10,1]], i, 0, i, a_Size, fixupDist, new Vector4(0, 1, 0, -1) );
    804.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[9,0]], PixelsOfAllFaces[sg_CubeEdgeList[9,1]], i, 0, a_Size - i, 0, fixupDist, new Vector4(0, 1, 0, 1) );
    805.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[8,0]], PixelsOfAllFaces[sg_CubeEdgeList[8,1]], i, a_Size, i, 0, fixupDist, new Vector4(0, -1, 0, 1) );
    806.          
    807.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[7,0]], PixelsOfAllFaces[sg_CubeEdgeList[7,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    808.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[6,0]], PixelsOfAllFaces[sg_CubeEdgeList[6,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    809.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[5,0]], PixelsOfAllFaces[sg_CubeEdgeList[5,1]], i, a_Size, 0, a_Size - i, fixupDist, new Vector4(0, -1, 1, 0) );
    810.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[4,0]], PixelsOfAllFaces[sg_CubeEdgeList[4,1]], i, 0, 0, i, fixupDist, new Vector4(0, 1, 1, 0) );
    811.          
    812.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[3,0]], PixelsOfAllFaces[sg_CubeEdgeList[3,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    813.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[2,0]], PixelsOfAllFaces[sg_CubeEdgeList[2,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    814.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[1,0]], PixelsOfAllFaces[sg_CubeEdgeList[1,1]], i, a_Size, a_Size, i, fixupDist, new Vector4(0, -1, -1, 0) );
    815.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[0,0]], PixelsOfAllFaces[sg_CubeEdgeList[0,1]], i, 0, a_Size, a_Size - i, fixupDist, new Vector4(0, 1, -1, 0) );
    816.             } */
    817.  
    818.      
    819.  
    820.             // Write Pixel from the jagged array back to the cubemap faces
    821.             for (int writeFace = 0; writeFace < 6; writeFace++ ) {
    822.                 Color[] tempColors = PixelsOfAllFaces[writeFace];
    823.                 CubeMap.SetPixels(tempColors, (CubemapFace)writeFace, mipLevel);
    824.             }
    825.         }
    826.         CubeMap.Apply(false);
    827.     }
    828.  
    829.  
    830.     private void AverageEdge(int a_Size, Color[] face_A, Color[] face_B, int x_A, int y_A, int x_B, int y_B, int fixupDist, Vector4 dir)
    831.     {
    832.         // As a_Size is used as factor we have to increase it by 1
    833.         a_Size += 1;
    834.         Color AverageEdgeColor = face_A[a_Size * y_A + x_A] * 0.5f + face_B[+ a_Size * y_B + x_B] * 0.5f;
    835.         face_A[a_Size * y_A + x_A] = AverageEdgeColor;
    836.         face_B[a_Size * y_B + x_B] = AverageEdgeColor;
    837.     /*    for (int iFixup = 0; iFixup < fixupDist; iFixup++)
    838.         {
    839.             float fixupFrac = (float)(fixupDist - iFixup) / (float)fixupDist;
    840.             Color AverageEdgeColor_A = face_A[a_Size * y_A + a_Size * (int)dir.y * iFixup + x_A + (int)dir.x * iFixup];
    841.             Color AverageEdgeColor_B = face_B[a_Size * y_B + a_Size * (int)dir.w * iFixup + x_B + (int)dir.z * iFixup];
    842.             // CP_FIXUP_PULL_HERMITE
    843.             float fixupWeight = ((-2.0f * fixupFrac + 3.0f) * fixupFrac * fixupFrac);
    844.      
    845.         //    face_A[a_Size* y_A + a_Size * (int)dir.y * iFixup + x_A + (int)dir.x * iFixup ] = Color.red * (fixupWeight);
    846.         //    face_B[a_Size * y_B + a_Size * (int)dir.w * iFixup + x_B + (int)dir.z * iFixup ] = Color.blue * (fixupWeight);
    847.  
    848.             face_A[a_Size* y_A + a_Size * (int)dir.y * iFixup + x_A + (int)dir.x * iFixup ] = AverageEdgeColor * fixupWeight + AverageEdgeColor_A * (1.0f-fixupWeight) ;
    849.             face_B[a_Size * y_B + a_Size * (int)dir.w * iFixup + x_B + (int)dir.z * iFixup ] = AverageEdgeColor * fixupWeight + AverageEdgeColor_B * (1.0f-fixupWeight) ;
    850.  
    851.  
    852.         } */
    853.     }
    854.  
    855.     private void AverageCorner (int a_Size, Color[] face_A , Color[] face_B, Color [] face_C, int x_A, int y_A, int x_B, int y_B, int x_C, int y_C)
    856.     {
    857.         // As a_Size is used as factor we have to increase it by 1
    858.         a_Size += 1;
    859.         Color AverageCornerColor = face_A[a_Size * y_A + x_A]/3.0f + face_B[a_Size * y_B + x_B]/3.0f + face_C[a_Size * y_C + x_C]/3.0f;
    860.         face_A[ a_Size * y_A + x_A] = AverageCornerColor;
    861.         face_B[a_Size * y_B + x_B] = AverageCornerColor;
    862.         face_C[a_Size * y_C + x_C] = AverageCornerColor;
    863.     }
    864.  
    865.  
    866.     //--------------------------------------------------------------------------------------
    867.     // Builds a normalizer cubemap, with the texels solid angle stored in the fourth component
    868.  
    869.     void BuildNormalizerSolidAngleCubemap(int a_Size, Cubemap a_Surface)
    870.     {
    871.         //a_Size = a_Surface.width;
    872.         int iCubeFace, u, v;
    873.         Vector3 a_XYZ = new Vector3(0,0,0);
    874.         Color[] i_CubeMapColors = new Color[a_Size*a_Size];
    875.         //
    876.         float weight = 0.0f;
    877.         //iterate over cube faces
    878.         for(iCubeFace=0; iCubeFace<6; iCubeFace++)
    879.         {
    880.             for(v=0; v< a_Size; v++)
    881.             {
    882.                 for(u=0; u < a_Size; u++)
    883.                 {
    884.                     // calc TexelToVect in a_XYZ
    885.                     a_XYZ = TexelToVect(iCubeFace, (float)u, (float)v, a_Size);
    886.                     // calc weight
    887.                     weight = TexelCoordSolidAngle(iCubeFace, (float)u, (float)v, a_Size);
    888.                     // Compress a_XYZ to fit into Color
    889.                     i_CubeMapColors[v * a_Size + u] = new Color ((a_XYZ[0]+1.0f)/2.0f, (a_XYZ[1]+1.0f)/2.0f, (a_XYZ[2]+1.0f)/2.0f, weight);
    890.                 }      
    891.             }
    892.             // set CubemapFace
    893.             a_Surface.SetPixels(i_CubeMapColors, (CubemapFace)iCubeFace);
    894.         }
    895.         // set cubeMap
    896.         a_Surface.Apply(true);
    897.         // Debug.Log ("BuildNormalizerSolidAngleCubemap finished");
    898.     }
    899.  
    900.     //--------------------------------------------------------------------------------------
    901.     // Builds a normalizer array, with the texels solid angle stored in the fourth component
    902.  
    903.     void BuildNormalizerSolidAngleArray (int a_Size, ref Vector4[] normSolid)
    904.     {
    905.         int iCubeFace, u, v;
    906.         Vector3 a_XYZ = new Vector3(0,0,0);
    907.         //
    908.         float weight = 0.0f;
    909.         //iterate over cube faces
    910.         for(iCubeFace=0; iCubeFace<6; iCubeFace++)
    911.         {
    912.             for(v=0; v< a_Size; v++)
    913.             {
    914.                 for(u=0; u < a_Size; u++)
    915.                 {
    916.                     // calc TexelToVect in a_XYZ
    917.                     a_XYZ = TexelToVect(iCubeFace, (float)u, (float)v, a_Size);
    918.                     // calc weight
    919.                     weight = TexelCoordSolidAngle(iCubeFace, (float)u, (float)v, a_Size);
    920.                     //
    921.                     normSolid[iCubeFace * a_Size* a_Size + v * a_Size + u] = new Vector4(a_XYZ[0], a_XYZ[1], a_XYZ[2], weight);
    922.                 }      
    923.             }
    924.         }
    925.         // Debug.Log ("BuildNormalizerSolidAngleArray finished");
    926.     }
    927.  
    928.     ///////////////////////////////////////////////
    929.     // SH order use for approximation of irradiance cubemap is 5, mean 5*5 equals 25 coefficients
    930.     // #define MAX_SH_ORDER 5
    931.     // #define NUM_SH_COEFFICIENT (MAX_SH_ORDER * MAX_SH_ORDER)
    932.  
    933.     void EvalSHBasis(Vector3 dir, ref double[] res )
    934.     {
    935.         double SqrtPi = (double)Mathf.Sqrt(CP_PI);
    936.  
    937.         double xx = dir[0];
    938.         double yy = dir[1];
    939.         double zz = dir[2];
    940.  
    941.         // x[i] == pow(x, i), etc.
    942.         // float64 x[MAX_SH_ORDER+1], y[MAX_SH_ORDER+1], z[MAX_SH_ORDER+1];
    943.         double[] x = new double[26];
    944.         double[] y = new double[26];
    945.         double[] z = new double[26];
    946.         x[0] = 1.0;
    947.         y[0] = 1.0;
    948.         z[0] = 1.0;
    949.         for (int i = 1; i < 25+1; ++i)
    950.         {
    951.             x[i] = xx * x[i-1];
    952.             y[i] = yy * y[i-1];
    953.             z[i] = zz * z[i-1];
    954.         }
    955.  
    956.         res[0]  = (1/(2.0*SqrtPi));
    957.  
    958.         res[1]  = -(Mathf.Sqrt(3/CP_PI)*yy)/2.0;
    959.         res[2]  = (Mathf.Sqrt(3/CP_PI)*zz)/2.0;
    960.         res[3]  = -(Mathf.Sqrt(3/CP_PI)*xx)/2.0;
    961.  
    962.         res[4]  = (Mathf.Sqrt(15/CP_PI)*xx*yy)/2.0;
    963.         res[5]  = -(Mathf.Sqrt(15/CP_PI)*yy*zz)/2.0;
    964.         res[6]  = (Mathf.Sqrt(5/CP_PI)*(-1 + 3*z[2]))/4.0;
    965.         res[7]  = -(Mathf.Sqrt(15/CP_PI)*xx*zz)/2.0;
    966.         res[8]  = Mathf.Sqrt(15/CP_PI)*(x[2] - y[2])/4.0;
    967.  
    968.         res[9]  = (Mathf.Sqrt(35/(2.0f*CP_PI))*(-3*x[2]*yy + y[3]))/4.0;
    969.         res[10] = (Mathf.Sqrt(105/CP_PI)*xx*yy*zz)/2.0;
    970.         res[11] = -(Mathf.Sqrt(21/(2.0f*CP_PI))*yy*(-1 + 5*z[2]))/4.0;
    971.         res[12] = (Mathf.Sqrt(7/CP_PI)*zz*(-3 + 5*z[2]))/4.0;
    972.         res[13] = -(Mathf.Sqrt(21/(2.0f*CP_PI))*xx*(-1 + 5*z[2]))/4.0;
    973.         res[14] = (Mathf.Sqrt(105/CP_PI)*(x[2] - y[2])*zz)/4.0;
    974.         res[15] = -(Mathf.Sqrt(35/(2.0f*CP_PI))*(x[3] - 3*xx*y[2]))/4.0;
    975.  
    976.         res[16] = (3*Mathf.Sqrt(35/CP_PI)*xx*yy*(x[2] - y[2]))/4.0;
    977.         res[17] = (-3*Mathf.Sqrt(35/(2.0f*CP_PI))*(3*x[2]*yy - y[3])*zz)/4.0;
    978.         res[18] = (3*Mathf.Sqrt(5/CP_PI)*xx*yy*(-1 + 7*z[2]))/4.0f;
    979.         res[19] = (-3*Mathf.Sqrt(5/(2.0f*CP_PI))*yy*zz*(-3 + 7*z[2]))/4.0;
    980.         res[20] = (3*(3 - 30*z[2] + 35*z[4]))/(16.0*SqrtPi);
    981.         res[21] = (-3*Mathf.Sqrt(5/(2.0f*CP_PI))*xx*zz*(-3+ 7*z[2]))/4.0;
    982.         res[22] = (3*Mathf.Sqrt(5/CP_PI)*(x[2] - y[2])*(-1 + 7*z[2]))/8.0;
    983.         res[23] = (-3*Mathf.Sqrt(35/(2.0f*CP_PI))*(x[3] - 3*xx*y[2])*zz)/4.0;
    984.         res[24] = (3*Mathf.Sqrt(35/CP_PI)*(x[4] - 6*x[2]*y[2] + y[4]))/16.0;
    985.     }
    986.  
    987.     // See Peter-Pike Sloan paper for these coefficients
    988.     static double[] SHBandFactor = {
    989.         1.0,
    990.         2.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0,
    991.         1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0,
    992.         0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // The 4 band will be zeroed
    993.         - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0
    994.     };
    995.  
    996.     void FakeHDR (Cubemap CubeMap, bool hasmipLevels) {
    997.         int maxMipLevels = 1;
    998.         if (hasmipLevels) {
    999.             maxMipLevels = (int)(Mathf.Log((float)CubeMap.width, 2.0f)) + 1;
    1000.         }
    1001.         int base_Size = CubeMap.width;
    1002.         Vector4 rgbmColor = new Vector4();
    1003.  
    1004.         for (int mipLevel = 0; mipLevel < maxMipLevels; mipLevel++)
    1005.         {
    1006.             int a_Size = base_Size >> mipLevel;
    1007.             // As we use a_Size as pointer in our arrays we have to lower it by 1
    1008.             //a_Size -= 1;
    1009.  
    1010.  
    1011.             for (int a_FaceIdx = 0; a_FaceIdx < 6; a_FaceIdx++)
    1012.             {
    1013.                 // Get all pixels of the given face
    1014.                 Color[] FaceColors = CubeMap.GetPixels((CubemapFace)a_FaceIdx, mipLevel);
    1015.                 // Iterate over dst cube map face texel
    1016.                 for (int a_V  = 0; a_V < a_Size; a_V++)
    1017.                 {
    1018.                     for (int a_U = 0; a_U < a_Size; a_U++)
    1019.                     {
    1020.                         rgbmColor.x = FaceColors[a_V * a_Size + a_U].r;
    1021.                         rgbmColor.y = FaceColors[a_V * a_Size + a_U].g;
    1022.                         rgbmColor.z = FaceColors[a_V * a_Size + a_U].b;
    1023.                         rgbmColor *= 1.0f/6.0f;
    1024.                         rgbmColor.w = Mathf.Clamp01(Mathf.Max(Mathf.Max(rgbmColor.x, rgbmColor.y), rgbmColor.z));
    1025.                         rgbmColor.w = Mathf.Ceil(rgbmColor.w*255.0f) / 255.0f;
    1026.                         rgbmColor.x = rgbmColor.x / rgbmColor.w;
    1027.                         rgbmColor.y = rgbmColor.y / rgbmColor.w;
    1028.                         rgbmColor.z = rgbmColor.z / rgbmColor.w;
    1029.                         FaceColors[a_V * a_Size + a_U] = rgbmColor;
    1030.                     }
    1031.                 }
    1032.                 CubeMap.SetPixels(FaceColors,(CubemapFace)a_FaceIdx, mipLevel);
    1033.             }
    1034.         }
    1035.         CubeMap.Apply(false);
    1036.     }
    1037.  
    1038.  
    1039. }
    1040. #endif





    This is the script for OVRMainMenu.cs



    Code (CSharp):
    1. /************************************************************************************
    2.  
    3. Copyright   :   Copyright 2014 Oculus VR, LLC. All Rights reserved.
    4.  
    5. Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
    6. you may not use the Oculus VR Rift SDK except in compliance with the License,
    7. which is provided at the time of installation or download, or which
    8. otherwise accompanies this software in either electronic or hard copy form.
    9.  
    10. You may obtain a copy of the License at
    11.  
    12. http://www.oculusvr.com/licenses/LICENSE-3.2
    13.  
    14. Unless required by applicable law or agreed to in writing, the Oculus VR SDK
    15. distributed under the License is distributed on an "AS IS" BASIS,
    16. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    17. See the License for the specific language governing permissions and
    18. limitations under the License.
    19.  
    20. ************************************************************************************/
    21.  
    22. // #define SHOW_DK2_VARIABLES
    23.  
    24. // Use the Unity new GUI with Unity 4.6 or above.
    25. #if UNITY_4_6 || UNITY_5_0
    26. #define USE_NEW_GUI
    27. #endif
    28.  
    29. using System;
    30. using System.Collections;
    31. using UnityEngine;
    32. #if USE_NEW_GUI
    33. using UnityEngine.UI;
    34. # endif
    35.  
    36. //-------------------------------------------------------------------------------------
    37. // ***** OVRMainMenu
    38. //
    39. /// <summary>
    40. /// OVRMainMenu is used to control the loading of different scenes. It also renders out
    41. /// a menu that allows a user to modify various Rift settings, and allow for storing
    42. /// these settings for recall later.
    43. ///
    44. /// A user of this component can add as many scenes that they would like to be able to
    45. /// have access to.
    46. ///
    47. /// OVRMainMenu is currently attached to the OVRPlayerController prefab for convenience,
    48. /// but can safely removed from it and added to another GameObject that is used for general
    49. /// Unity logic.
    50. ///
    51. /// </summary>
    52. public class OVRMainMenu : MonoBehaviour
    53. {
    54.     /// <summary>
    55.     /// The amount of time in seconds that it takes for the menu to fade in.
    56.     /// </summary>
    57.     public float     FadeInTime        = 2.0f;
    58.  
    59.     /// <summary>
    60.     /// An optional texture that appears before the menu fades in.
    61.     /// </summary>
    62.     public UnityEngine.Texture     FadeInTexture     = null;
    63.  
    64.     /// <summary>
    65.     /// An optional font that replaces Unity's default Arial.
    66.     /// </summary>
    67.     public Font     FontReplace        = null;
    68.  
    69.     /// <summary>
    70.     /// The key that toggles the menu.
    71.     /// </summary>
    72.     public KeyCode    MenuKey            = KeyCode.Space;
    73.  
    74.     /// <summary>
    75.     /// The key that quits the application.
    76.     /// </summary>
    77.     public KeyCode    QuitKey            = KeyCode.Escape;
    78.  
    79.     /// <summary>
    80.     /// Scene names to show on-screen for each of the scenes in Scenes.
    81.     /// </summary>
    82.     public string [] SceneNames;
    83.  
    84.     /// <summary>
    85.     /// The set of scenes that the user can jump to.
    86.     /// </summary>
    87.     public string [] Scenes;
    88.  
    89.     private bool ScenesVisible       = false;
    90.  
    91.     // Spacing for scenes menu
    92.     private int        StartX            = 490;
    93.     private int        StartY            = 250;
    94.     private int        WidthX            = 300;
    95.     private int        WidthY            = 23;
    96.  
    97.     // Spacing for variables that users can change
    98.     private int        VRVarsSX        = 553;
    99.     private int        VRVarsSY        = 250;
    100.     private int        VRVarsWidthX     = 175;
    101.     private int        VRVarsWidthY     = 23;
    102.  
    103.     private int        StepY            = 25;
    104.  
    105.     // Handle to OVRCameraRig
    106.     private OVRCameraRig CameraController = null;
    107.  
    108.     // Handle to OVRPlayerController
    109.     private OVRPlayerController PlayerController = null;
    110.  
    111.     // Controller buttons
    112.     private bool  PrevStartDown;
    113.     private bool  PrevHatDown;
    114.     private bool  PrevHatUp;
    115.  
    116.     private bool  ShowVRVars;
    117.  
    118.     private bool  OldSpaceHit;
    119.  
    120.     // FPS
    121.     private float  UpdateInterval     = 0.5f;
    122.     private float  Accum               = 0;  
    123.     private int    Frames              = 0;  
    124.     private float  TimeLeft            = 0;              
    125.     private string strFPS            = "FPS: 0";
    126.  
    127.     private string strIPD             = "IPD: 0.000";  
    128.  
    129.     /// <summary>
    130.     /// Prediction (in ms)
    131.     /// </summary>
    132.     public float   PredictionIncrement = 0.001f; // 1 ms
    133.     private string strPrediction       = "Pred: OFF";  
    134.  
    135.     private string strFOV             = "FOV: 0.0f";
    136.     private string strHeight          = "Height: 0.0f";
    137.  
    138.     /// <summary>
    139.     /// Controls how quickly the player's speed and rotation change based on input.
    140.     /// </summary>
    141.     public float   SpeedRotationIncrement       = 0.05f;
    142.     private string strSpeedRotationMultipler    = "Spd. X: 0.0f Rot. X: 0.0f";
    143.  
    144.     private bool   LoadingLevel     = false;      
    145.     private float  AlphaFadeValue    = 1.0f;
    146.     private int    CurrentLevel        = 0;
    147.  
    148.     // Rift detection
    149.     private bool   HMDPresent           = false;
    150.     private float  RiftPresentTimeout   = 0.0f;
    151.     private string strRiftPresent        = "";
    152.  
    153.     // Replace the GUI with our own texture and 3D plane that
    154.     // is attached to the rendder camera for true 3D placement
    155.     private OVRGUI          GuiHelper          = new OVRGUI();
    156.     private GameObject      GUIRenderObject  = null;
    157.     private RenderTexture    GUIRenderTexture = null;
    158.  
    159.     // We want to use new Unity GUI built in 4.6 for OVRMainMenu GUI
    160.     // Enable the UsingNewGUI option in the editor,
    161.     // if you want to use new GUI and Unity version is higher than 4.6  
    162. #if USE_NEW_GUI
    163.     private GameObject NewGUIObject                 = null;
    164.     private GameObject RiftPresentGUIObject         = null;
    165. #endif
    166.  
    167.     /// <summary>
    168.     /// We can set the layer to be anything we want to, this allows
    169.     /// a specific camera to render it.
    170.     /// </summary>
    171.     public string             LayerName          = "Default";
    172.  
    173.     /// <summary>
    174.     /// Crosshair rendered onto 3D plane.
    175.     /// </summary>
    176.     public UnityEngine.Texture  CrosshairImage             = null;
    177.     private OVRCrosshair Crosshair            = new OVRCrosshair();
    178.  
    179.     // Resolution Eye Texture
    180.     private string strResolutionEyeTexture = "Resolution: 0 x 0";
    181.  
    182.     // Latency values
    183.     private string strLatencies = "Ren: 0.0f TWrp: 0.0f PostPresent: 0.0f";
    184.  
    185.     // Vision mode on/off
    186.     private bool VisionMode = true;
    187. #if    SHOW_DK2_VARIABLES
    188.     private string strVisionMode = "Vision Enabled: ON";
    189. #endif
    190.  
    191.     // We want to hold onto GridCube, for potential sharing
    192.     // of the menu RenderTarget
    193.     OVRGridCube GridCube = null;
    194.  
    195.     // We want to hold onto the VisionGuide so we can share
    196.     // the menu RenderTarget
    197.     OVRVisionGuide VisionGuide = null;
    198.  
    199.     #region MonoBehaviour Message Handlers
    200.     /// <summary>
    201.     /// Awake this instance.
    202.     /// </summary>
    203.     void Awake()
    204.     {  
    205.         // Find camera controller
    206.         OVRCameraRig[] CameraControllers;
    207.         CameraControllers = gameObject.GetComponentsInChildren<OVRCameraRig>();
    208.      
    209.         if(CameraControllers.Length == 0)
    210.             Debug.LogWarning("OVRMainMenu: No OVRCameraRig attached.");
    211.         else if (CameraControllers.Length > 1)
    212.             Debug.LogWarning("OVRMainMenu: More then 1 OVRCameraRig attached.");
    213.         else{
    214.             CameraController = CameraControllers[0];
    215. #if USE_NEW_GUI
    216.             OVRUGUI.CameraController = CameraController;
    217. #endif
    218.         }
    219.  
    220.         // Find player controller
    221.         OVRPlayerController[] PlayerControllers;
    222.         PlayerControllers = gameObject.GetComponentsInChildren<OVRPlayerController>();
    223.      
    224.         if(PlayerControllers.Length == 0)
    225.             Debug.LogWarning("OVRMainMenu: No OVRPlayerController attached.");
    226.         else if (PlayerControllers.Length > 1)
    227.             Debug.LogWarning("OVRMainMenu: More then 1 OVRPlayerController attached.");
    228.         else{
    229.             PlayerController = PlayerControllers[0];
    230. #if USE_NEW_GUI
    231.             OVRUGUI.PlayerController = PlayerController;
    232. #endif
    233.         }
    234.  
    235. #if USE_NEW_GUI
    236.             // Create canvas for using new GUI
    237.             NewGUIObject = new GameObject();
    238.             NewGUIObject.name = "OVRGUIMain";
    239.             NewGUIObject.transform.parent = GameObject.Find("LeftEyeAnchor").transform;
    240.             RectTransform r = NewGUIObject.AddComponent<RectTransform>();
    241.             r.sizeDelta = new Vector2(100f, 100f);
    242.             r.localScale = new Vector3(0.001f, 0.001f, 0.001f);
    243.             r.localPosition = new Vector3(0.01f, 0.17f, 0.53f);
    244.             r.localEulerAngles = Vector3.zero;
    245.  
    246.             Canvas c = NewGUIObject.AddComponent<Canvas>();
    247. #if (UNITY_5_0)
    248.             // TODO: Unity 5.0b11 has an older version of the new GUI being developed in Unity 4.6.
    249.             // Remove this once Unity 5 has a more recent merge of Unity 4.6.
    250.             c.renderMode = RenderMode.World;
    251. #else
    252.             c.renderMode = RenderMode.WorldSpace;
    253. #endif
    254.             c.pixelPerfect = false;
    255. #endif
    256.     }
    257.  
    258.     /// <summary>
    259.     /// Start this instance.
    260.     /// </summary>
    261.     void Start()
    262.     {      
    263.         AlphaFadeValue = 1.0f;
    264.         CurrentLevel   = 0;
    265.         PrevStartDown  = false;
    266.         PrevHatDown    = false;
    267.         PrevHatUp      = false;
    268.         ShowVRVars       = false;
    269.         OldSpaceHit    = false;
    270.         strFPS         = "FPS: 0";
    271.         LoadingLevel   = false;  
    272.         ScenesVisible  = false;
    273.    
    274.         // Set the GUI target
    275.         GUIRenderObject = GameObject.Instantiate(Resources.Load("OVRGUIObjectMain")) as GameObject;
    276.  
    277.         if(GUIRenderObject != null)
    278.         {
    279.             // Chnge the layer
    280.             GUIRenderObject.layer = LayerMask.NameToLayer(LayerName);
    281.  
    282.             if(GUIRenderTexture == null)
    283.             {
    284.                 int w = Screen.width;
    285.                 int h = Screen.height;
    286.  
    287.                 // We don't need a depth buffer on this texture
    288.                 GUIRenderTexture = new RenderTexture(w, h, 0);  
    289.                 GuiHelper.SetPixelResolution(w, h);
    290.                 // NOTE: All GUI elements are being written with pixel values based
    291.                 // from DK1 (1280x800). These should change to normalized locations so
    292.                 // that we can scale more cleanly with varying resolutions
    293.                 GuiHelper.SetDisplayResolution(1280.0f, 800.0f);
    294.             }
    295.         }
    296.      
    297.         // Attach GUI texture to GUI object and GUI object to Camera
    298.         if(GUIRenderTexture != null && GUIRenderObject != null)
    299.         {
    300.             GUIRenderObject.GetComponent<Renderer>().material.mainTexture = GUIRenderTexture;
    301.          
    302.             if(CameraController != null)
    303.             {
    304.                 // Grab transform of GUI object
    305.                 Vector3 ls = GUIRenderObject.transform.localScale;
    306.                 Vector3 lp = GUIRenderObject.transform.localPosition;
    307.                 Quaternion lr = GUIRenderObject.transform.localRotation;
    308.  
    309.                 // Attach the GUI object to the camera
    310.                 GUIRenderObject.transform.parent = CameraController.centerEyeAnchor;
    311.                 // Reset the transform values (we will be maintaining state of the GUI object
    312.                 // in local state)
    313.  
    314.                 GUIRenderObject.transform.localScale = ls;
    315.                 GUIRenderObject.transform.localPosition = lp;
    316.                 GUIRenderObject.transform.localRotation = lr;
    317.  
    318.                 // Deactivate object until we have completed the fade-in
    319.                 // Also, we may want to deactive the render object if there is nothing being rendered
    320.                 // into the UI
    321.                 GUIRenderObject.SetActive(false);
    322.             }
    323.         }
    324.      
    325.         // Make sure to hide cursor
    326.         if(Application.isEditor == false)
    327.         {
    328. #if UNITY_5_0
    329.             Cursor.visible = false;
    330.             Cursor.lockState = CursorLockMode.Locked;
    331. #else
    332.             Screen.showCursor = false;
    333.             Screen.lockCursor = true;
    334. #endif
    335.         }
    336.      
    337.         // CameraController updates
    338.         if(CameraController != null)
    339.         {
    340.             // Add a GridCube component to this object
    341.             GridCube = gameObject.AddComponent<OVRGridCube>();
    342.             GridCube.SetOVRCameraController(ref CameraController);
    343.  
    344.             // Add a VisionGuide component to this object
    345.             VisionGuide = gameObject.AddComponent<OVRVisionGuide>();
    346.             VisionGuide.SetOVRCameraController(ref CameraController);
    347.             VisionGuide.SetFadeTexture(ref FadeInTexture);
    348.             VisionGuide.SetVisionGuideLayer(ref LayerName);
    349.         }
    350.      
    351.         // Crosshair functionality
    352.         Crosshair.Init();
    353.         Crosshair.SetCrosshairTexture(ref CrosshairImage);
    354.         Crosshair.SetOVRCameraController (ref CameraController);
    355.         Crosshair.SetOVRPlayerController(ref PlayerController);
    356.      
    357.         // Check for HMD and sensor
    358.         CheckIfRiftPresent();
    359.  
    360. #if USE_NEW_GUI
    361.         if (!string.IsNullOrEmpty(strRiftPresent)){
    362.             ShowRiftPresentGUI();
    363.         }
    364. #endif
    365.     }
    366.  
    367.     /// <summary>
    368.     /// Update this instance.
    369.     /// </summary>
    370.     void Update()
    371.     {      
    372.         if(LoadingLevel == true)
    373.             return;
    374.  
    375.         // Main update
    376.         UpdateFPS();
    377.      
    378.         // CameraController updates
    379.         if(CameraController != null)
    380.         {
    381.             UpdateIPD();
    382.          
    383.             UpdateRecenterPose();
    384.             UpdateVisionMode();
    385.             UpdateFOV();
    386.             UpdateEyeHeightOffset();
    387.             UpdateResolutionEyeTexture();
    388.             UpdateLatencyValues();
    389.         }
    390.      
    391.         // PlayerController updates
    392.         if(PlayerController != null)
    393.         {
    394.             UpdateSpeedAndRotationScaleMultiplier();
    395.             UpdatePlayerControllerMovement();
    396.         }
    397.      
    398.         // MainMenu updates
    399.         UpdateSelectCurrentLevel();
    400.      
    401.         // Device updates
    402.         UpdateDeviceDetection();
    403.      
    404.         // Crosshair functionality
    405.         Crosshair.UpdateCrosshair();
    406.  
    407. #if USE_NEW_GUI
    408.         if (ShowVRVars && RiftPresentTimeout <= 0.0f)
    409.         {
    410.             NewGUIObject.SetActive(true);
    411.             UpdateNewGUIVars();
    412.             OVRUGUI.UpdateGUI();
    413.         }
    414.         else
    415.         {
    416.             NewGUIObject.SetActive(false);
    417.         }
    418. #endif
    419.    
    420.         // Toggle Fullscreen
    421.         if(Input.GetKeyDown(KeyCode.F11))
    422.             Screen.fullScreen = !Screen.fullScreen;
    423.  
    424.         if (Input.GetKeyDown(KeyCode.M))
    425.             OVRManager.display.mirrorMode = !OVRManager.display.mirrorMode;
    426.      
    427.         // Escape Application
    428.         if (Input.GetKeyDown(QuitKey))
    429.             Application.Quit();
    430.     }
    431.  
    432.     /// <summary>
    433.     /// Updates Variables for new GUI.
    434.     /// </summary>
    435. #if USE_NEW_GUI
    436.     void UpdateNewGUIVars()
    437.     {
    438. #if    SHOW_DK2_VARIABLES      
    439.         // Print out Vision Mode
    440.         OVRUGUI.strVisionMode = strVisionMode;      
    441. #endif
    442.         // Print out FPS
    443.         OVRUGUI.strFPS = strFPS;
    444.  
    445.         // Don't draw these vars if CameraController is not present
    446.         if (CameraController != null)
    447.         {
    448.             OVRUGUI.strPrediction = strPrediction;
    449.             OVRUGUI.strIPD = strIPD;
    450.             OVRUGUI.strFOV = strFOV;
    451.             OVRUGUI.strResolutionEyeTexture = strResolutionEyeTexture;
    452.             OVRUGUI.strLatencies = strLatencies;
    453.         }
    454.  
    455.         // Don't draw these vars if PlayerController is not present
    456.         if (PlayerController != null)
    457.         {
    458.             OVRUGUI.strHeight = strHeight;
    459.             OVRUGUI.strSpeedRotationMultipler = strSpeedRotationMultipler;
    460.         }
    461.  
    462.         OVRUGUI.strRiftPresent = strRiftPresent;
    463.     }
    464. #endif
    465.  
    466.     void OnGUI()
    467.     {  
    468.         // Important to keep from skipping render events
    469.         if (Event.current.type != EventType.Repaint)
    470.             return;
    471.  
    472. #if !USE_NEW_GUI      
    473.         // Fade in screen
    474.         if(AlphaFadeValue > 0.0f)
    475.         {
    476.             AlphaFadeValue -= Mathf.Clamp01(Time.deltaTime / FadeInTime);
    477.             if(AlphaFadeValue < 0.0f)
    478.             {
    479.                 AlphaFadeValue = 0.0f;  
    480.             }
    481.             else
    482.             {
    483.                 GUI.color = new Color(0, 0, 0, AlphaFadeValue);
    484.                 GUI.DrawTexture( new Rect(0, 0, Screen.width, Screen.height ), FadeInTexture );
    485.                 return;
    486.             }
    487.         }
    488. #endif
    489.         // We can turn on the render object so we can render the on-screen menu
    490.         if(GUIRenderObject != null)
    491.         {
    492.             if (ScenesVisible ||
    493.                 ShowVRVars ||
    494.                 Crosshair.IsCrosshairVisible() ||
    495.                 RiftPresentTimeout > 0.0f ||
    496.                 VisionGuide.GetFadeAlphaValue() > 0.0f)
    497.             {
    498.                 GUIRenderObject.SetActive(true);
    499.             }
    500.             else
    501.             {
    502.                 GUIRenderObject.SetActive(false);
    503.             }
    504.         }
    505.      
    506.         //***
    507.         // Set the GUI matrix to deal with portrait mode
    508.         Vector3 scale = Vector3.one;
    509.         Matrix4x4 svMat = GUI.matrix; // save current matrix
    510.         // substitute matrix - only scale is altered from standard
    511.         GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, scale);
    512.      
    513.         // Cache current active render texture
    514.         RenderTexture previousActive = RenderTexture.active;
    515.      
    516.         // if set, we will render to this texture
    517.         if(GUIRenderTexture != null && GUIRenderObject.activeSelf)
    518.         {
    519.             RenderTexture.active = GUIRenderTexture;
    520.             GL.Clear (false, true, new Color (0.0f, 0.0f, 0.0f, 0.0f));
    521.         }
    522.      
    523.         // Update OVRGUI functions (will be deprecated eventually when 2D renderingc
    524.         // is removed from GUI)
    525.         GuiHelper.SetFontReplace(FontReplace);
    526.  
    527.         // If true, we are displaying information about the Rift not being detected
    528.         // So do not show anything else
    529.         if(GUIShowRiftDetected() != true)
    530.         {  
    531.             GUIShowLevels();
    532.             GUIShowVRVariables();          
    533.         }
    534.      
    535.         // The cross-hair may need to go away at some point, unless someone finds it
    536.         // useful
    537.         Crosshair.OnGUICrosshair();
    538.      
    539.         // Since we want to draw into the main GUI that is shared within the MainMenu,
    540.         // we call the OVRVisionGuide GUI function here
    541.         VisionGuide.OnGUIVisionGuide();
    542.      
    543.         // Restore active render texture
    544.         if (GUIRenderObject.activeSelf)
    545.         {
    546.             RenderTexture.active = previousActive;
    547.         }
    548.      
    549.         // ***
    550.         // Restore previous GUI matrix
    551.         GUI.matrix = svMat;
    552.     }
    553.     #endregion
    554.  
    555.     #region Internal State Management Functions
    556.     /// <summary>
    557.     /// Updates the FPS.
    558.     /// </summary>
    559.     void UpdateFPS()
    560.     {
    561.         TimeLeft -= Time.deltaTime;
    562.         Accum += Time.timeScale/Time.deltaTime;
    563.         ++Frames;
    564.         // Interval ended - update GUI text and start new interval
    565.         if( TimeLeft <= 0.0 )
    566.         {
    567.             // display two fractional digits (f2 format)
    568.             float fps = Accum / Frames;
    569.          
    570.             if(ShowVRVars == true)// limit gc
    571.                 strFPS = System.String.Format("FPS: {0:F2}",fps);
    572.  
    573.                TimeLeft += UpdateInterval;
    574.             Accum  = 0.0f;
    575.             Frames = 0;
    576.         }
    577.     }
    578.  
    579.     /// <summary>
    580.     /// Updates the IPD.
    581.     /// </summary>
    582.     void UpdateIPD()
    583.     {
    584.         if(ShowVRVars == true) // limit gc
    585.         {  
    586.             strIPD = System.String.Format("IPD (mm): {0:F4}", OVRManager.profile.ipd * 1000.0f);
    587.         }
    588.     }
    589.  
    590.     void UpdateRecenterPose()
    591.     {
    592.         if(Input.GetKeyDown(KeyCode.R))
    593.         {
    594.             OVRManager.display.RecenterPose();
    595.         }
    596.     }
    597.  
    598.     /// <summary>
    599.     /// Updates the vision mode.
    600.     /// </summary>
    601.     void UpdateVisionMode()
    602.     {
    603.         if (Input.GetKeyDown(KeyCode.F2))
    604.         {
    605.             VisionMode = !VisionMode;
    606.             OVRManager.tracker.isEnabled = VisionMode;
    607.  
    608. #if SHOW_DK2_VARIABLES
    609.             strVisionMode = VisionMode ? "Vision Enabled: ON" : "Vision Enabled: OFF";
    610. #endif
    611.         }
    612.     }
    613.  
    614.     /// <summary>
    615.     /// Updates the FOV.
    616.     /// </summary>
    617.     void UpdateFOV()
    618.     {
    619.         if(ShowVRVars == true)// limit gc
    620.         {
    621.             OVRDisplay.EyeRenderDesc eyeDesc = OVRManager.display.GetEyeRenderDesc(OVREye.Left);
    622.  
    623.             strFOV = System.String.Format ("FOV (deg): {0:F3}", eyeDesc.fov.y);
    624.         }
    625.     }
    626.  
    627.     /// <summary>
    628.     /// Updates resolution of eye texture
    629.     /// </summary>
    630.     void UpdateResolutionEyeTexture()
    631.     {
    632.         if (ShowVRVars == true) // limit gc
    633.         {
    634.             OVRDisplay.EyeRenderDesc leftEyeDesc = OVRManager.display.GetEyeRenderDesc(OVREye.Left);
    635.             OVRDisplay.EyeRenderDesc rightEyeDesc = OVRManager.display.GetEyeRenderDesc(OVREye.Right);
    636.  
    637.             float scale = OVRManager.instance.nativeTextureScale * OVRManager.instance.virtualTextureScale;
    638.             float w = (int)(scale * (float)(leftEyeDesc.resolution.x + rightEyeDesc.resolution.x));
    639.             float h = (int)(scale * (float)Mathf.Max(leftEyeDesc.resolution.y, rightEyeDesc.resolution.y));
    640.  
    641.             strResolutionEyeTexture = System.String.Format("Resolution : {0} x {1}", w, h);
    642.         }
    643.     }
    644.  
    645.     /// <summary>
    646.     /// Updates latency values
    647.     /// </summary>
    648.     void UpdateLatencyValues()
    649.     {
    650. #if !UNITY_ANDROID || UNITY_EDITOR
    651.         if (ShowVRVars == true) // limit gc
    652.         {
    653.             OVRDisplay.LatencyData latency = OVRManager.display.latency;
    654.             if (latency.render < 0.000001f && latency.timeWarp < 0.000001f && latency.postPresent < 0.000001f)
    655.                 strLatencies = System.String.Format("Ren : N/A TWrp: N/A PostPresent: N/A");
    656.             else
    657.                 strLatencies = System.String.Format("Ren : {0:F3} TWrp: {1:F3} PostPresent: {2:F3}",
    658.                     latency.render,
    659.                     latency.timeWarp,
    660.                     latency.postPresent);
    661.         }
    662. #endif
    663.     }
    664.      
    665.     /// <summary>
    666.     /// Updates the eye height offset.
    667.     /// </summary>
    668.     void UpdateEyeHeightOffset()
    669.     {
    670.         if(ShowVRVars == true)// limit gc
    671.         {
    672.             float eyeHeight = OVRManager.profile.eyeHeight;
    673.          
    674.             strHeight = System.String.Format ("Eye Height (m): {0:F3}", eyeHeight);
    675.         }
    676.     }
    677.  
    678.     /// <summary>
    679.     /// Updates the speed and rotation scale multiplier.
    680.     /// </summary>
    681.     void UpdateSpeedAndRotationScaleMultiplier()
    682.     {
    683.         float moveScaleMultiplier = 0.0f;
    684.         PlayerController.GetMoveScaleMultiplier(ref moveScaleMultiplier);
    685.         if(Input.GetKeyDown(KeyCode.Alpha7))
    686.             moveScaleMultiplier -= SpeedRotationIncrement;
    687.         else if (Input.GetKeyDown(KeyCode.Alpha8))
    688.             moveScaleMultiplier += SpeedRotationIncrement;      
    689.         PlayerController.SetMoveScaleMultiplier(moveScaleMultiplier);
    690.      
    691.         float rotationScaleMultiplier = 0.0f;
    692.         PlayerController.GetRotationScaleMultiplier(ref rotationScaleMultiplier);
    693.         if(Input.GetKeyDown(KeyCode.Alpha9))
    694.             rotationScaleMultiplier -= SpeedRotationIncrement;
    695.         else if (Input.GetKeyDown(KeyCode.Alpha0))
    696.             rotationScaleMultiplier += SpeedRotationIncrement;  
    697.         PlayerController.SetRotationScaleMultiplier(rotationScaleMultiplier);
    698.      
    699.         if(ShowVRVars == true)// limit gc
    700.             strSpeedRotationMultipler = System.String.Format ("Spd.X: {0:F2} Rot.X: {1:F2}",
    701.                                     moveScaleMultiplier,
    702.                                     rotationScaleMultiplier);
    703.     }
    704.  
    705.     /// <summary>
    706.     /// Updates the player controller movement.
    707.     /// </summary>
    708.     void UpdatePlayerControllerMovement()
    709.     {
    710.         if(PlayerController != null)
    711.             PlayerController.SetHaltUpdateMovement(ScenesVisible);
    712.     }
    713.  
    714.     /// <summary>
    715.     /// Updates the select current level.
    716.     /// </summary>
    717.     void UpdateSelectCurrentLevel()
    718.     {
    719.         ShowLevels();
    720.              
    721.         if (!ScenesVisible)
    722.             return;
    723.          
    724.         CurrentLevel = GetCurrentLevel();
    725.      
    726.         if (Scenes.Length != 0
    727.             && (OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.A)
    728.                 || Input.GetKeyDown(KeyCode.Return)))
    729.         {
    730.             LoadingLevel = true;
    731.             Application.LoadLevelAsync(Scenes[CurrentLevel]);
    732.         }
    733.     }
    734.  
    735.     /// <summary>
    736.     /// Shows the levels.
    737.     /// </summary>
    738.     /// <returns><c>true</c>, if levels was shown, <c>false</c> otherwise.</returns>
    739.     bool ShowLevels()
    740.     {
    741.         if (Scenes.Length == 0)
    742.         {
    743.             ScenesVisible = false;
    744.             return ScenesVisible;
    745.         }
    746.      
    747.         bool curStartDown = OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.Start);
    748.         bool startPressed = (curStartDown && !PrevStartDown) || Input.GetKeyDown(KeyCode.RightShift);
    749.         PrevStartDown = curStartDown;
    750.      
    751.         if (startPressed)
    752.         {
    753.             ScenesVisible = !ScenesVisible;
    754.         }
    755.      
    756.         return ScenesVisible;
    757.     }
    758.  
    759.     /// <summary>
    760.     /// Gets the current level.
    761.     /// </summary>
    762.     /// <returns>The current level.</returns>
    763.     int GetCurrentLevel()
    764.     {
    765.         bool curHatDown = false;
    766.         if(OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.Down) == true)
    767.             curHatDown = true;
    768.      
    769.         bool curHatUp = false;
    770.         if(OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.Down) == true)
    771.             curHatUp = true;
    772.      
    773.         if((PrevHatDown == false) && (curHatDown == true) ||
    774.             Input.GetKeyDown(KeyCode.DownArrow))
    775.         {
    776.             CurrentLevel = (CurrentLevel + 1) % SceneNames.Length;  
    777.         }
    778.         else if((PrevHatUp == false) && (curHatUp == true) ||
    779.             Input.GetKeyDown(KeyCode.UpArrow))
    780.         {
    781.             CurrentLevel--;  
    782.             if(CurrentLevel < 0)
    783.                 CurrentLevel = SceneNames.Length - 1;
    784.         }
    785.                  
    786.         PrevHatDown = curHatDown;
    787.         PrevHatUp = curHatUp;
    788.      
    789.         return CurrentLevel;
    790.     }
    791.  
    792.     #endregion
    793.  
    794.     #region Internal GUI Functions
    795.  
    796.     /// <summary>
    797.     /// Show the GUI levels.
    798.     /// </summary>
    799.     void GUIShowLevels()
    800.     {
    801.         if(ScenesVisible == true)
    802.         {
    803.             // Darken the background by rendering fade texture
    804.             GUI.color = new Color(0, 0, 0, 0.5f);
    805.               GUI.DrawTexture( new Rect(0, 0, Screen.width, Screen.height ), FadeInTexture );
    806.              GUI.color = Color.white;
    807.      
    808.             if(LoadingLevel == true)
    809.             {
    810.                 string loading = "LOADING...";
    811.                 GuiHelper.StereoBox (StartX, StartY, WidthX, WidthY, ref loading, Color.yellow);
    812.                 return;
    813.             }
    814.          
    815.             for (int i = 0; i < SceneNames.Length; i++)
    816.             {
    817.                 Color c;
    818.                 if(i == CurrentLevel)
    819.                     c = Color.yellow;
    820.                 else
    821.                     c = Color.black;
    822.              
    823.                 int y   = StartY + (i * StepY);
    824.              
    825.                 GuiHelper.StereoBox (StartX, y, WidthX, WidthY, ref SceneNames[i], c);
    826.             }
    827.         }              
    828.     }
    829.  
    830.     /// <summary>
    831.     /// Show the VR variables.
    832.     /// </summary>
    833.     void GUIShowVRVariables()
    834.     {
    835.         bool SpaceHit = Input.GetKey(MenuKey);
    836.         if ((OldSpaceHit == false) && (SpaceHit == true))
    837.         {
    838.             if (ShowVRVars == true)
    839.             {
    840.                 ShowVRVars = false;
    841.             }
    842.             else
    843.             {
    844.                 ShowVRVars = true;
    845. #if USE_NEW_GUI
    846.                 OVRUGUI.InitUIComponent = ShowVRVars;
    847. #endif
    848.             }
    849.         }
    850.  
    851.         OldSpaceHit = SpaceHit;
    852.  
    853.         // Do not render if we are not showing
    854.         if (ShowVRVars == false)
    855.             return;
    856.  
    857.      
    858.  
    859. #if !USE_NEW_GUI
    860.         int y = VRVarsSY;
    861. #if    SHOW_DK2_VARIABLES
    862.         // Print out Vision Mode
    863.         GuiHelper.StereoBox (VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    864.                              ref strVisionMode, Color.green);
    865. #endif
    866.  
    867.         // Draw FPS
    868.         GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    869.                              ref strFPS, Color.green);
    870.  
    871.         // Don't draw these vars if CameraController is not present
    872.         if (CameraController != null)
    873.         {
    874.             GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    875.                              ref strPrediction, Color.white);
    876.             GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    877.                              ref strIPD, Color.yellow);
    878.             GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    879.                              ref strFOV, Color.white);
    880.             GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    881.                              ref strResolutionEyeTexture, Color.white);
    882.             GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    883.                              ref strLatencies, Color.white);
    884.         }
    885.  
    886.         // Don't draw these vars if PlayerController is not present
    887.         if (PlayerController != null)
    888.         {
    889.             GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    890.                                  ref strHeight, Color.yellow);
    891.             GuiHelper.StereoBox(VRVarsSX, y += StepY, VRVarsWidthX, VRVarsWidthY,
    892.                                  ref strSpeedRotationMultipler, Color.white);
    893.         }
    894. #endif
    895.     }
    896.  
    897.     // RIFT DETECTION
    898.  
    899.     /// <summary>
    900.     /// Checks to see if HMD and / or sensor is available, and displays a
    901.     /// message if it is not.
    902.     /// </summary>
    903.     void CheckIfRiftPresent()
    904.     {
    905.         HMDPresent = OVRManager.display.isPresent;
    906.      
    907.         if (!HMDPresent)
    908.         {
    909.             RiftPresentTimeout = 15.0f;
    910.          
    911.             if (!HMDPresent)
    912.                 strRiftPresent = "NO HMD DETECTED";
    913. #if USE_NEW_GUI
    914.             OVRUGUI.strRiftPresent = strRiftPresent;
    915. #endif
    916.         }
    917.     }
    918.  
    919.     /// <summary>
    920.     /// Show if Rift is detected.
    921.     /// </summary>
    922.     /// <returns><c>true</c>, if show rift detected was GUIed, <c>false</c> otherwise.</returns>
    923.     bool GUIShowRiftDetected()
    924.     {
    925. #if !USE_NEW_GUI
    926.         if(RiftPresentTimeout > 0.0f)
    927.         {
    928.             GuiHelper.StereoBox (StartX, StartY, WidthX, WidthY,
    929.                                  ref strRiftPresent, Color.white);
    930.      
    931.             return true;
    932.         }
    933. #else
    934.          if(RiftPresentTimeout < 0.0f)
    935.             DestroyImmediate(RiftPresentGUIObject);
    936. #endif
    937.         return false;
    938.     }
    939.  
    940.     /// <summary>
    941.     /// Updates the device detection.
    942.     /// </summary>
    943.     void UpdateDeviceDetection()
    944.     {
    945.         if(RiftPresentTimeout > 0.0f)
    946.             RiftPresentTimeout -= Time.deltaTime;
    947.     }
    948.  
    949.     /// <summary>
    950.     /// Show rift present GUI with new GUI
    951.     /// </summary>
    952.     void ShowRiftPresentGUI()
    953.     {
    954. #if USE_NEW_GUI
    955.         RiftPresentGUIObject = new GameObject();
    956.         RiftPresentGUIObject.name = "RiftPresentGUIMain";
    957.         RiftPresentGUIObject.transform.parent = GameObject.Find("LeftEyeAnchor").transform;
    958.  
    959.         RectTransform r = RiftPresentGUIObject.AddComponent<RectTransform>();
    960.         r.sizeDelta = new Vector2(100f, 100f);
    961.         r.localPosition = new Vector3(0.01f, 0.17f, 0.53f);
    962.         r.localEulerAngles = Vector3.zero;
    963.         r.localScale = new Vector3(0.001f, 0.001f, 0.001f);
    964.         Canvas c = RiftPresentGUIObject.AddComponent<Canvas>();
    965. #if UNITY_5_0
    966.         // TODO: Unity 5.0b11 has an older version of the new GUI being developed in Unity 4.6.
    967.            // Remove this once Unity 5 has a more recent merge of Unity 4.6.
    968.         c.renderMode = RenderMode.World;
    969. #else
    970.         c.renderMode = RenderMode.WorldSpace;
    971. #endif
    972.         c.pixelPerfect = false;
    973.         OVRUGUI.RiftPresentGUI(RiftPresentGUIObject);
    974. #endif
    975.     }
    976.     #endregion
    977. }



    This is the script for OVRUGUI.cs



    /************************************************************************************

    Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved.

    Licensed under the Oculus VR Rift SDK License Version

    3.2 (the "License");
    you may not use the Oculus VR Rift SDK except in compliance with the License,
    which is provided at the time of installation or download, or which
    otherwise accompanies this software in either electronic or hard copy form.

    You may obtain a copy of the License at

    http://www.oculusvr.com/licenses/LICENSE-3.2

    Unless required by applicable law or agreed to in writing, the Oculus VR SDK
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

    ************************************************************************************/

    // Use the Unity new GUI with Unity 4.6 or above.
    #if UNITY_4_6 || UNITY_5_0
    #define USE_NEW_GUI
    #endif

    using UnityEngine;
    #if USE_NEW_GUI
    using UnityEngine.UI;
    #endif
    using System.Collections;

    //-------------------------------------------------------------------------------------
    /// <summary>
    /// Class for Unity new GUI built in 4.6
    /// </summary>
    public class OVRUGUI
    {
    #if USE_NEW_GUI

    #region UIGameObject
    private static GameObject NewGUIManager;
    private static GameObject RiftPresent;
    private static GameObject LowPersistence;
    private static GameObject VisionMode;
    private static GameObject FPS;
    private static GameObject Prediction;
    private static GameObject IPD;
    private static GameObject FOV;
    private static GameObject Height;
    private static GameObject SpeedRotationMutipler;
    private static GameObject DeviceDetection;
    private static GameObject ResolutionEyeTexture;
    private static GameObject Latencies;
    #endregion

    #region VRVariables
    [HideInInspector]
    public static string strRiftPresent = null;
    [HideInInspector]
    public static string strLPM = null; //"LowPersistenceMode: ON";
    [HideInInspector]
    public static string strVisionMode = null;//"Vision Enabled: ON";
    [HideInInspector]
    public static string strFPS = null;//"FPS: 0";
    [HideInInspector]
    public static string strIPD = null;//"IPD: 0.000";
    [HideInInspector]
    public static string strPrediction = null;//"Pred: OFF";
    [HideInInspector]
    public static string strFOV = null;//"FOV: 0.0f";
    [HideInInspector]
    public static string strHeight = null;//"Height: 0.0f";
    [HideInInspector]
    public static string strSpeedRotationMultipler = null;//"Spd. X: 0.0f Rot. X: 0.0f";
    [HideInInspector]
    public static OVRPlayerController PlayerController = null;
    [HideInInspector]
    public static OVRCameraRig CameraController = null;
    //[HideInInspector]
    //public static string strDeviceDetection = null;// Device attach / detach
    [HideInInspector]
    public static string strResolutionEyeTexture = null;// "Resolution : {0} x {1}"
    [HideInInspector]
    public static string strLatencies = null;// Device attach / detach
    #endregion

    [HideInInspector]
    public static bool InitUIComponent = false;
    private static float offsetY = 55.0f;
    private static bool isInited = false;
    private static int numOfGUI = 0;
    private static GameObject text;

    /// <summary>
    /// It's for rift present GUI
    /// </summary>
    public static void RiftPresentGUI(GameObject GUIMainOBj)
    {
    RiftPresent = ComponentComposition(RiftPresent);
    RiftPresent.transform.parent = GUIMainOBj.transform;
    RiftPresent.name = "RiftPresent";
    RectTransform r = RiftPresent.GetComponent<RectTransform>();
    r.localPosition = new Vector3(0.0f, 0.0f, 0.0f);
    r.localScale = new Vector3(1.0f, 1.0f, 1.0f);
    r.localEulerAngles = Vector3.zero;

    Text t = RiftPresent.GetComponentInChildren<Text>();
    t.text = strRiftPresent;
    t.fontSize = 20;
    }

    /// <summary>
    /// It's for rift present GUI
    /// </summary>
    public static void UpdateGUI()
    {
    if (InitUIComponent && !isInited)
    {
    InitUIComponents();
    }

    UpdateVariable();
    }


    /// <summary>
    /// Update VR Variables
    /// </summary>
    static void UpdateVariable()
    {
    NewGUIManager.transform.localPosition = new Vector3(0.0f, 100.0f, 0.0f);

    if (!string.IsNullOrEmpty(strLPM))
    LowPersistence.GetComponentInChildren<Text>().text = strLPM;
    if (!string.IsNullOrEmpty(strVisionMode))
    VisionMode.GetComponentInChildren<Text>().text = strVisionMode;
    if (!string.IsNullOrEmpty(strFPS))
    FPS.GetComponentInChildren<Text>().text = strFPS;
    if (!string.IsNullOrEmpty(strPrediction))
    Prediction.GetComponentInChildren<Text>().text = strPrediction;
    if (!string.IsNullOrEmpty(strIPD))
    IPD.GetComponentInChildren<Text>().text = strIPD;
    if (!string.IsNullOrEmpty(strFOV))
    FOV.GetComponentInChildren<Text>().text = strFOV;
    if (!string.IsNullOrEmpty(strResolutionEyeTexture))
    ResolutionEyeTexture.GetComponentInChildren<Text>().text = strResolutionEyeTexture;
    if (!string.IsNullOrEmpty(strLatencies))
    Latencies.GetComponentInChildren<Text>().text = strLatencies;

    if (PlayerController != null)
    {
    if (!string.IsNullOrEmpty(strHeight))
    Height.GetComponentInChildren<Text>().text = strHeight;
    if (!string.IsNullOrEmpty(strSpeedRotationMultipler))
    SpeedRotationMutipler.GetComponentInChildren<Text>().text = strSpeedRotationMultipler;
    }
    }

    /// <summary>
    /// Initialize UI GameObjects
    /// </summary>
    static void InitUIComponents()
    {
    float posY = 0.0f;
    int fontSize = 20;

    NewGUIManager = new GameObject();
    NewGUIManager.name = "GUIManager";
    NewGUIManager.transform.parent = GameObject.Find("OVRGUIMain").transform;
    NewGUIManager.transform.localPosition = Vector3.zero;
    NewGUIManager.transform.localEulerAngles = Vector3.zero;
    NewGUIManager.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);

    // Print out for Low Persistence Mode
    if (!string.IsNullOrEmpty(strLPM))
    {
    LowPersistence = UIObjectManager(LowPersistence, "LowPersistence", posY -= offsetY, strLPM, fontSize);
    }

    // Print out for VisionMode
    if (!string.IsNullOrEmpty(strVisionMode))
    {
    VisionMode = UIObjectManager(VisionMode, "VisionMode", posY -= offsetY, strVisionMode, fontSize);
    }

    // Print out for FPS
    if (!string.IsNullOrEmpty(strFPS))
    {
    FPS = UIObjectManager(FPS, "FPS", posY -= offsetY, strFPS, fontSize);
    }

    // Print out for Prediction
    if (!string.IsNullOrEmpty(strPrediction))
    {
    Prediction = UIObjectManager(Prediction, "Prediction", posY -= offsetY, strPrediction, fontSize);
    }

    // Print out for IPD
    if (!string.IsNullOrEmpty(strIPD))
    {
    IPD = UIObjectManager(IPD, "IPD", posY -= offsetY, strIPD, fontSize);
    }

    // Print out for FOV
    if (!string.IsNullOrEmpty(strFOV))
    {
    FOV = UIObjectManager(FOV, "FOV", posY -= offsetY, strFOV, fontSize);
    }

    if (PlayerController != null)
    {
    // Print out for Height
    if (!string.IsNullOrEmpty(strHeight))
    {
    Height = UIObjectManager(Height, "Height", posY -= offsetY, strHeight, fontSize);
    }

    // Print out for Speed Rotation Multiplier
    if (!string.IsNullOrEmpty(strSpeedRotationMultipler))
    {
    SpeedRotationMutipler = UIObjectManager(SpeedRotationMutipler, "SpeedRotationMutipler", posY -= offsetY, strSpeedRotationMultipler, fontSize);
    }
    }

    // Print out for Resoulution of Eye Texture
    if (!string.IsNullOrEmpty(strResolutionEyeTexture))
    {
    ResolutionEyeTexture = UIObjectManager(ResolutionEyeTexture, "Resolution", posY -= offsetY, strResolutionEyeTexture, fontSize);
    }

    // Print out for Latency
    if (!string.IsNullOrEmpty(strLatencies))
    {
    Latencies = UIObjectManager(Latencies, "Latency", posY -= offsetY, strLatencies, 17);
    posY = 0.0f;
    }

    InitUIComponent = false;
    isInited = true;

    }

    static GameObject UIObjectManager(GameObject gameObject, string name, float posY, string text, int fontSize)
    {
    gameObject = ComponentComposition(gameObject);
    gameObject.name = name;
    gameObject.transform.parent = NewGUIManager.transform;

    RectTransform r = gameObject.GetComponent<RectTransform>();
    r.localPosition = new Vector3(0.0f, posY -= offsetY, 0.0f);

    Text t = gameObject.GetComponentInChildren<Text>();
    t.text = text;
    t.fontSize = fontSize;
    gameObject.transform.localEulerAngles = Vector3.zero;

    r.localScale = new Vector3(1.0f, 1.0f, 1.0f);

    return gameObject;

    }

    /// <summary>
    /// Component composition
    /// </summary>
    /// <returns> Composed game object. </returns>
    static GameObject ComponentComposition(GameObject GO)
    {
    GO = new GameObject ();
    GO.AddComponent<RectTransform> ();
    GO.AddComponent<CanvasRenderer> ();
    GO.AddComponent<Image> ();
    GO.GetComponent<RectTransform> ().sizeDelta = new Vector2 (350f, 50f);
    GO.GetComponent<Image> ().color = new Color (7f / 255f, 45f / 255f, 71f / 255f, 200f / 255f);

    text = new GameObject ();
    text.AddComponent<RectTransform> ();
    text.AddComponent<CanvasRenderer> ();
    text.AddComponent<Text> ();
    text.GetComponent<RectTransform> ().sizeDelta = new Vector2 (350f, 50f);
    text.GetComponent<Text> ().font = (Font)Resources.Load ("DINPro-Bold");
    text.transform.parent = GO.transform;
    text.name = "TextBox";

    return GO;
    }

    #endif
    }





    This is the script for LuxMaterialInspector.cs




    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Linq;
    5.  
    6. public class LuxMaterialInspector : MaterialEditor {
    7.  
    8.     public bool diffuseOnly;
    9.  
    10.     public override void OnInspectorGUI ()
    11.     {
    12.         // render the default inspector
    13.         base.OnInspectorGUI ();
    14.      
    15.         // if we are not visible... return
    16.         if (!isVisible)
    17.             return;
    18.  
    19.         // get the current keywords from the material
    20.         Material targetMat = target as Material;
    21.         string[] keyWords = targetMat.shaderKeywords;
    22.  
    23.         //if (targetMat.shader.name.Contains("Diffuse") || targetMat.shader.name.Contains("diffuse")) {
    24.         //    diffuseOnly = true;
    25.         //}
    26.  
    27.         // IBL settings
    28.         bool diffCube = keyWords.Contains ("DIFFCUBE_OFF");
    29.         bool specCube = keyWords.Contains ("SPECCUBE_OFF");
    30.         bool ambientOcclusion = keyWords.Contains ("LUX_AO_ON");
    31.  
    32.         GUILayout.BeginVertical("box");
    33.         GUILayout.Label("Customize Material");
    34.  
    35.         EditorGUI.BeginChangeCheck();
    36.         EditorGUILayout.BeginHorizontal();
    37.         // DiffCube
    38.         diffCube = EditorGUILayout.Toggle ("", diffCube, GUILayout.Width(14));
    39.         EditorGUILayout.LabelField("Disable diffuse Cube IBL");
    40.         EditorGUILayout.EndHorizontal();
    41.         // SpecCube
    42.         if (targetMat.HasProperty("_SpecCubeIBL")) {
    43.             EditorGUILayout.BeginHorizontal();
    44.             specCube = EditorGUILayout.Toggle ("", specCube, GUILayout.Width(14));
    45.             EditorGUILayout.LabelField("Disable specular Cube IBL");
    46.             EditorGUILayout.EndHorizontal();
    47.         }
    48.         // AO
    49.         if (targetMat.HasProperty("_AO") ) {
    50.             EditorGUILayout.BeginHorizontal();
    51.             ambientOcclusion = EditorGUILayout.Toggle ("", ambientOcclusion, GUILayout.Width(14));
    52.             EditorGUILayout.LabelField("Enable Ambient Occlusion");
    53.             EditorGUILayout.EndHorizontal();
    54.             if (ambientOcclusion) {
    55.                 TextureProperty("_AO", "Ambient Occlusion (Alpha)", ShaderUtil.ShaderPropertyTexDim.TexDim2D );
    56.             }
    57.         }
    58.         if (EditorGUI.EndChangeCheck())
    59.         {
    60.             // if the checkbox is changed, reset the shader keywords
    61.             var keywords = new List<string> { diffCube ? "DIFFCUBE_OFF" : "DIFFCUBE_ON"};
    62.             if (specCube) {
    63.                 keywords.Add("SPECCUBE_OFF");
    64.             }
    65.             else if (!diffuseOnly) {
    66.                 keywords.Add("SPECCUBE_ON");
    67.             }
    68.             if (ambientOcclusion) {
    69.                 keywords.Add("LUX_AO_ON");
    70.             }
    71.             else {
    72.                 keywords.Add("LUX_AO_OFF");
    73.             }
    74.  
    75.             //keywords.Add("_BumpMap");
    76.             //keywords.Add({ specCube ? "SPECCUBE_OFF" : "SPECCUBE_ON"});
    77.             targetMat.shaderKeywords = keywords.ToArray ();
    78.             EditorUtility.SetDirty (targetMat);
    79.         }
    80.         GUILayout.EndVertical();
    81.     }
    82. }




    This is the script for LuxEnvProbeEditor.cs




    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6. using System.IO;
    7. //using System.
    8.  
    9. [CustomEditor(typeof(LuxEnvProbe))]
    10. public class LuxEnvProbeEditor : Editor
    11. {
    12.     private SerializedObject LuxProbe;
    13.     LuxEnvProbe Target;
    14.     LuxCubeProcessor ConvolutedCubemap = new LuxCubeProcessor();
    15.     private SerializedProperty Culling;
    16.     private SerializedProperty DiffSize;
    17.     private SerializedProperty SpecSize;
    18.     private SerializedProperty UseHDR;
    19.     private SerializedProperty Smooth;
    20.     private SerializedProperty SmoothWidth;
    21.     private SerializedProperty linear;
    22.     private SerializedProperty UseRTC;
    23.  
    24.  
    25.     private SerializedProperty Mode;
    26.     private SerializedProperty BoxSize;
    27.     private SerializedProperty AssignedMeshes;
    28.     private GameObject newAssignedMesh;
    29.  
    30.  
    31.     //private SerializedProperty init;
    32.  
    33.     private Object diffcubeObj;
    34.     private Object speccubeObj;
    35.  
    36.     //if you want to show debug msg box
    37.     //just change the value
    38.     //bool ShowDebugMsg = true;
    39.  
    40.     void OnEnable()
    41.     {
    42.         Target = (LuxEnvProbe)target;
    43.         LuxProbe = new SerializedObject(target);
    44.  
    45.         DiffSize = LuxProbe.FindProperty("DiffSize");
    46.         SpecSize = LuxProbe.FindProperty("SpecSize");
    47.         Culling = LuxProbe.FindProperty("CullingMask");
    48.         UseHDR = LuxProbe.FindProperty("HDR");
    49.         Smooth = LuxProbe.FindProperty("SmoothEdges");
    50.         SmoothWidth = LuxProbe.FindProperty("SmoothEdgePixel");
    51.         linear = LuxProbe.FindProperty("Linear");
    52.         UseRTC = LuxProbe.FindProperty("UseRTC");
    53.         // BoxProjection
    54.         Mode = LuxProbe.FindProperty("Mode");
    55.         BoxSize = LuxProbe.FindProperty("BoxSize");
    56.         // AssignedMeshes = LuxProbe.FindProperty("AssignedMeshes");
    57.         //init = LuxProbe.FindProperty("init");
    58.     }
    59.     public override void OnInspectorGUI()
    60.     {
    61.         //  Debug
    62.         //  DrawDefaultInspector();
    63.  
    64.         // Update assigned Materials in BoxProjection Mode
    65.         if (Mode.enumValueIndex == 1) {
    66.             Target.SyncAssignedGameobjects();
    67.         }
    68.  
    69.         /* Debugging only better leave it as it is
    70.         EditorGUILayout.BeginVertical();
    71.         GUILayout.Label("Cubemaps will be saved as"+Target.cubeName.ToString());
    72.         EditorGUILayout.EndVertical();
    73.         */
    74.         //DrawDefaultInspector();
    75.  
    76.         // Let's give it some styles \m/
    77.         GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
    78.         buttonStyle.margin = new RectOffset(4,4,10,10);
    79.         buttonStyle.padding = new RectOffset(10, 10, 10, 10);
    80.         GUIStyle smallbuttonStyle = new GUIStyle(GUI.skin.button);
    81.         smallbuttonStyle.margin = new RectOffset(4,4,0,0);
    82.  
    83.         EditorGUILayout.BeginVertical("Box");
    84.         GUILayout.Space(5);
    85.      
    86.         //Cubemap Settings
    87.         GUILayout.Label("Probe Settings", "BoldLabel");
    88.         //FaceSizes
    89.         EditorGUILayout.BeginHorizontal();
    90.         EditorGUILayout.BeginVertical();
    91.         EditorGUILayout.PropertyField(DiffSize, new GUIContent("Diffuse Size"));
    92.         EditorGUILayout.PropertyField(SpecSize, new GUIContent("Specular Size"));
    93.         EditorGUILayout.EndVertical();
    94.         EditorGUILayout.EndHorizontal();
    95.  
    96.         // Baking Options
    97.         GUILayout.Space(5);
    98.         EditorGUILayout.BeginHorizontal();
    99.         EditorGUILayout.BeginHorizontal(GUILayout.MinWidth(114));
    100.         EditorGUILayout.PropertyField(UseHDR, new GUIContent(""), GUILayout.Width(14));
    101.         GUILayout.Label("Pull to HDR", GUILayout.MinWidth(96));
    102.         EditorGUILayout.EndHorizontal();
    103.         EditorGUILayout.BeginHorizontal();
    104.         EditorGUILayout.PropertyField(linear, new GUIContent(""), GUILayout.Width(14));
    105.         GUILayout.Label("Set to Linear Space");
    106.         EditorGUILayout.EndHorizontal();
    107.         EditorGUILayout.EndHorizontal();
    108.  
    109.         EditorGUILayout.BeginHorizontal();
    110.         EditorGUILayout.BeginHorizontal(GUILayout.MinWidth(114));
    111.         EditorGUILayout.PropertyField(Smooth, new GUIContent(""), GUILayout.Width(14));
    112.         GUILayout.Label("Smooth Edges", GUILayout.MinWidth(96));
    113.         EditorGUILayout.EndHorizontal();
    114.         EditorGUILayout.BeginHorizontal();
    115.         if (Smooth.boolValue) {
    116.             EditorGUILayout.PropertyField(SmoothWidth, new GUIContent(""), GUILayout.Width(14));
    117.             GUILayout.Label("Edge Width");
    118.         }
    119.         EditorGUILayout.EndHorizontal();
    120.         EditorGUILayout.EndHorizontal();
    121.  
    122.         EditorGUILayout.BeginVertical("Box");
    123.         GUILayout.Space(4);
    124.         EditorGUILayout.PropertyField(Mode, new GUIContent("Cube Mode"));
    125.         if (Mode.enumValueIndex == 1) {
    126.             GUILayout.Space(4);
    127.             Target.ShowAssignedMeshes = EditorGUILayout.Foldout(Target.ShowAssignedMeshes,"Manage associated GameObjects");
    128.             if (Target.ShowAssignedMeshes) {
    129.                 GUILayout.Space(4);
    130.                 for (int i = 0; i < Target.AssignedMeshes.Count; i++)
    131.                 {
    132.                     EditorGUILayout.BeginHorizontal();
    133.                     GUILayout.Space(4);
    134.     //          TODO: Make it work with SerializedProperty
    135.                     Target.AssignedMeshes[i] = (GameObject)EditorGUILayout.ObjectField("", Target.AssignedMeshes[i], typeof(GameObject), true);
    136.                     if (GUILayout.Button("Remove", EditorStyles.miniButton, GUILayout.Width(50)) ) {
    137.                         Target.AssignedMeshes.RemoveAt(i);
    138.                     }
    139.                     EditorGUILayout.EndHorizontal();
    140.                     GUILayout.Space(2);
    141.                 }
    142.  
    143.                 GUILayout.Space(5);
    144.                 EditorGUILayout.BeginHorizontal();
    145.                 GUILayout.Space(4);
    146.                 newAssignedMesh = (GameObject)EditorGUILayout.ObjectField("", newAssignedMesh, typeof(GameObject), true);
    147.                 if (GUILayout.Button("Add", EditorStyles.miniButton, GUILayout.Width(50)) ) {
    148.                     if (newAssignedMesh) {
    149.                         Target.AssignedMeshes.Add(newAssignedMesh);
    150.                         newAssignedMesh = null;
    151.                     }
    152.                 }
    153.                 EditorGUILayout.EndHorizontal();
    154.             }
    155.             GUILayout.Space(5);
    156.         }
    157.         EditorGUILayout.EndVertical();
    158.      
    159.         //Camera Settings
    160.         GUILayout.Space(5);
    161.         GUILayout.Label("Probe Camera Settings", "BoldLabel");
    162.         EditorGUILayout.EnumPopup("Clear Flags", Target.ClearFlags);
    163.         EditorGUILayout.ColorField("Clear Color", Target.ClearColor);
    164.         EditorGUILayout.PropertyField(Culling, new GUIContent("Culling Mask"));
    165.         EditorGUILayout.FloatField("Near Clip Plane", Target.Near);
    166.         EditorGUILayout.FloatField("Far Clip Plane", Target.Far);
    167.         EditorGUILayout.PropertyField(UseRTC, new GUIContent("RenderToCubemap"));
    168.  
    169.         if (GUILayout.Button("Bake Probe", buttonStyle))
    170.         {
    171.             if(UseRTC.boolValue) {
    172.                 Target.RenderToCubeMap();
    173.             }
    174.             else {
    175.               Target.PreSetup();
    176.               Target.InitRenderCube();
    177.             }
    178.         }
    179.         EditorGUILayout.EndVertical();
    180.  
    181.         EditorGUILayout.BeginVertical("Box");
    182.         GUILayout.Space(5);
    183.         GUILayout.Label("Process Cubemaps", "BoldLabel");
    184.  
    185.         EditorGUILayout.BeginHorizontal();
    186.         EditorGUILayout.BeginVertical();
    187.         GUILayout.Label("Diffuse Cubemap");
    188.         // use object in order to enable manual assignment
    189.         diffcubeObj = EditorGUILayout.ObjectField(Target.DIFFCube, typeof(Cubemap), false, GUILayout.MinHeight(64), GUILayout.MinWidth(64), GUILayout.MaxWidth(64));
    190.         Target.DIFFCube = (Cubemap)diffcubeObj;
    191.  
    192.         EditorGUILayout.EndVertical();
    193.         EditorGUILayout.BeginVertical();
    194.         GUILayout.Label("Specular Cubemap");
    195.         // use object in order to enable manual assignment
    196.         speccubeObj = EditorGUILayout.ObjectField(Target.SPECCube, typeof(Cubemap), false, GUILayout.MinHeight(64), GUILayout.MinWidth(64), GUILayout.MaxWidth(64));
    197.         Target.SPECCube = (Cubemap)speccubeObj;
    198.  
    199.         EditorGUILayout.EndVertical();
    200.         EditorGUILayout.EndHorizontal();
    201.  
    202.         if (GUILayout.Button("Get Generated Cubemaps", buttonStyle))
    203.         {
    204.             Target.init = false;
    205.             Target.CleanUp();
    206.             Target.RetriveCubemap();
    207.             Cubemap diff = Target.DIFFCube;
    208.             Cubemap spec = Target.SPECCube;
    209.         }
    210.  
    211.         if (GUILayout.Button("Convolve Cubemaps", buttonStyle))
    212.         {
    213.             Target.init = false;
    214.             Target.CleanUp();
    215.             Cubemap diff = null;
    216.             Cubemap spec = null;
    217.             if (!EditorApplication.isPlaying && Target.DIFFCube != null && Target.SPECCube != null)
    218.             {
    219.                 diff = Target.DIFFCube;
    220.                 spec = Target.SPECCube;
    221.             }
    222.             bool hdr = Target.HDR;
    223.             if (diff == null || spec == null)
    224.             {
    225.                 if (UnityEditor.EditorUtility.DisplayDialog("No Cubemaps found", "Please generate or assign cubemaps to the probe.", "OK"))
    226.                 {
    227.                     return;
    228.                 }
    229.             }
    230.             if (UnityEditor.EditorUtility.DisplayDialog("Convolve Cubemaps", "Proceed to cubemap convolution?\nThis could take a while.", "Proceed", "Cancel"))
    231.             {
    232.                 ConvolutedCubemap.ProcessCubemap(diff, true, hdr);
    233.                 ConvolutedCubemap.ProcessCubemap(spec, false, hdr);
    234.             }
    235.  
    236.         }
    237.         EditorGUILayout.EndVertical();
    238.  
    239.  
    240.         if(GUI.changed){
    241.   //       EditorUtility.SetDirty(Target);
    242.          //EditorUtility.SetDirty(myTrackData);
    243.         }
    244.  
    245.  
    246.         LuxProbe.ApplyModifiedProperties();
    247.  
    248.         //Debugging only better leave it as it is
    249.         /*
    250.         if (ShowDebugMsg)
    251.         {
    252.             EditorGUILayout.BeginVertical("Box");
    253.             EditorGUILayout.ToggleLeft("Init",Target.init);
    254.             GUILayout.Label("Cubemaps will be saved as:");
    255.             if (Target.DiffPath != null && Target.SpecPath != null)
    256.             {
    257.                 GUILayout.Label(Target.DiffPath.ToString(), EditorStyles.wordWrappedLabel);
    258.                 GUILayout.Label(Target.SpecPath.ToString(), EditorStyles.wordWrappedLabel);
    259.             }
    260.             EditorGUILayout.EndVertical();
    261.         }*/
    262.     }
    263.  
    264.  
    265.     // Draw BoxSize Handles
    266.     void OnSceneGUI () {
    267.         if (Mode.enumValueIndex == 1) {
    268.             BoxSize.vector3Value = Handles.ScaleHandle (BoxSize.vector3Value, Target.transform.position, Target.transform.rotation, 3.5f);
    269.         }
    270.     }
    271.  
    272. }
    273. #endif
    274.  




    This is the script for RoadTool.cs




    Code (CSharp):
    1. // @khenkel
    2. // parabox llc
    3.  
    4. using UnityEngine;
    5. using UnityEditor;
    6. using System.Collections;
    7. using System.Collections.Generic;
    8. using System.Text;
    9.  
    10. [CustomEditor(typeof(Road))]
    11. public class RoadTool : Editor
    12. {
    13. #region Private
    14.  
    15.     Road road;
    16. #endregion
    17.  
    18. #region Constant
    19.  
    20.     const float MIN_ROAD_WIDTH = .3f;
    21.     const float MAX_ROAD_WIDTH = 50f;
    22.  
    23.     const float MIN_GROUND_OFFSET = .001f;
    24.     const float MAX_GROUND_OFFSET = 1f;
    25. #endregion
    26.  
    27. #region Shortcut
    28.  
    29.     // big list of things that cause onscenegui to loop endlessly if mixed with our code.
    30.     public bool earlyOut
    31.     {
    32.         get
    33.         {
    34.             return (
    35.                 Event.current.alt ||
    36.                 Tools.current == Tool.View ||
    37.                 GUIUtility.hotControl > 0 ||
    38.                 (Event.current.isMouse ? Event.current.button > 1 : false) ||
    39.                 Tools.viewTool == ViewTool.FPS ||
    40.                 Tools.viewTool == ViewTool.Orbit);
    41.         }
    42.     }
    43. #endregion
    44.  
    45. #region Initalization / Destruction
    46.  
    47.     [MenuItem("GameObject/Create Other/Road %#r")]
    48.     public static void init()
    49.     {
    50.         GameObject go = new GameObject();
    51.         Road r = go.AddComponent<Road>();
    52.         r.acceptInput = true;
    53.         r.mat = (Material)Resources.LoadAssetAtPath("Assets/RoadTool/Example/Texture/Materials/Road.mat", typeof(Material));
    54.         go.name = "Road " + go.GetInstanceID();
    55.         go.AddComponent<MeshRenderer>();
    56.         Selection.activeObject = go;
    57.     }
    58.  
    59.     public void OnEnable()
    60.     {
    61.         road = (Road)target;
    62.     }
    63. #endregion
    64.  
    65. #region Window Lifecycle
    66.  
    67.     bool showUVOptions = false;
    68.     public override void OnInspectorGUI()
    69.     {
    70.         GUI.changed = false;
    71.         road.roadWidth = EditorGUILayout.Slider("Road Width", road.roadWidth, MIN_ROAD_WIDTH, MAX_ROAD_WIDTH);
    72.         road.groundOffset = EditorGUILayout.Slider("Ground Offset", road.groundOffset, MIN_GROUND_OFFSET, MAX_GROUND_OFFSET);
    73.  
    74.         EditorGUILayout.HelpBox("A negative value inserts new points at the end of the line.", MessageType.Info);
    75.         road.insertPoint = EditorGUILayout.IntField("Insert At Point", road.insertPoint);
    76.  
    77.         road.connectEnds = EditorGUILayout.Toggle("Connect Ends", road.connectEnds);
    78.  
    79.         showUVOptions = EditorGUILayout.Foldout(showUVOptions, "UV Options");
    80.         if(showUVOptions)
    81.         {
    82.             road.swapUV = EditorGUILayout.Toggle("Swap UV", road.swapUV);
    83.             road.flipU = EditorGUILayout.Toggle("Flip U", road.flipU);
    84.             road.flipV = EditorGUILayout.Toggle("Flip V", road.flipV);
    85.  
    86.             road.uvScale = EditorGUILayout.Vector2Field("Scale", road.uvScale);
    87.             road.uvOffset = EditorGUILayout.Vector2Field("Offset", road.uvOffset);
    88.         }
    89.  
    90.         road.mat = (Material)EditorGUILayout.ObjectField("Material", road.mat, typeof(Material), true);
    91.  
    92.         if(road.acceptInput)
    93.         {
    94.             GUI.backgroundColor = Color.red;
    95.             if(GUILayout.Button("Lock"))
    96.             {
    97.                 road.acceptInput = false;
    98.                 SceneView.RepaintAll();
    99.             }
    100.         }
    101.         else
    102.         {
    103.             GUI.backgroundColor = Color.green;
    104.             if(GUILayout.Button("Modify"))
    105.             {
    106.                 road.acceptInput = true;              
    107.                 SceneView.RepaintAll();
    108.             }
    109.         }
    110.  
    111.      
    112.         GUI.backgroundColor = Color.white;
    113.         if(GUI.changed)
    114.         {
    115.             EditorUtility.SetDirty(road);
    116.             road.Refresh();
    117.             SceneView.RepaintAll();
    118.         }
    119.     }
    120. #endregion
    121.  
    122. #region Scene
    123.  
    124.     Vector3 groundPoint = Vector3.zero;
    125.     Vector3 tp;
    126.     public void OnSceneGUI()
    127.     {
    128.         if(road.acceptInput == false)
    129.             return;
    130.  
    131.         Event e = Event.current;
    132.  
    133.         if(e.type == EventType.ValidateCommand)
    134.         {
    135.             road.Refresh();
    136.             SceneView.RepaintAll();
    137.         }
    138.  
    139.         if(e.isKey && (e.keyCode == KeyCode.Escape || e.keyCode == KeyCode.Return))
    140.         {
    141.             road.acceptInput = false;
    142.             SceneView.RepaintAll();
    143.         }
    144.  
    145.         // Existing point handles
    146.         DrawHandleGUI(road.points);
    147.  
    148.         // TODO -- figure out why Handles.PositionHandle is sooo slow when panning
    149.  
    150.         if(!e.alt)
    151.         for(int i = 0; i < road.points.Count; i++)
    152.         {
    153.             tp = road.points[i];
    154.             road.points[i] = Handles.PositionHandle(road.points[i], Quaternion.identity);
    155.          
    156.             if(tp != road.points[i])
    157.             {
    158.                 Vector3 p = road.points[i];
    159.                 p.y = road.GroundHeight(road.points[i]);
    160.                 road.points[i] = p;
    161.                 road.Refresh();
    162.             }
    163.         }
    164.  
    165.         if(earlyOut)
    166.             return;
    167.  
    168.         // New point placement from here down
    169.  
    170.         int controlID = GUIUtility.GetControlID(FocusType.Passive);
    171.         HandleUtility.AddDefaultControl(controlID);
    172.  
    173.         if(e.modifiers != 0 || Tools.current != Tool.Move)
    174.         {
    175.             if(e.type == EventType.mouseUp && e.button == 0 && Tools.current != Tool.Move && e.modifiers == 0)
    176.             {
    177.                 FindSceneView().ShowNotification(new GUIContent("Tool must be set to 'Move' to place points!", ""));
    178.                 SceneView.RepaintAll();
    179.             }
    180.             return;      
    181.         }
    182.  
    183.         if( (e.type == EventType.mouseDown || e.type == EventType.mouseDrag) && e.button == 0)
    184.         {
    185.             Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition);
    186.             RaycastHit ground = new RaycastHit();
    187.  
    188.             if( Physics.Raycast(ray.origin, ray.direction, out ground) )
    189.                 groundPoint = ground.point;
    190.         }
    191.          
    192.         // Listen for mouse input
    193.         if(e.type == EventType.mouseUp && e.button == 0)
    194.         {
    195.             Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition);
    196.             RaycastHit ground = new RaycastHit();
    197.  
    198.             if( Physics.Raycast(ray.origin, ray.direction, out ground) )
    199.             {
    200.                 groundPoint = ground.point;
    201.                 AddPoint(groundPoint);
    202.             }
    203.         }
    204.     }
    205.  
    206.     public static SceneView FindSceneView()
    207.     {
    208.         return SceneView.lastActiveSceneView == null ? EditorWindow.GetWindow<SceneView>() : SceneView.lastActiveSceneView;
    209.     }
    210. #endregion
    211.  
    212. #region Handles
    213.  
    214.     public void DrawHandleGUI(List<Vector3> points)
    215.     {
    216.         if(points == null || points.Count < 1)
    217.             return;
    218.  
    219.         Handles.BeginGUI();
    220.         GUI.backgroundColor = Color.red;
    221.         for(int i = 0; i < points.Count; i++)
    222.         {
    223.  
    224.             Vector2 p = HandleUtility.WorldToGUIPoint(points[i]);
    225.  
    226.             if(GUI.Button(new Rect(p.x+10, p.y-50, 25, 25), "x"))
    227.                 DeletePoint(i);
    228.  
    229.             GUI.Label(new Rect(p.x+45, p.y-50, 200, 25), "Point: " + i.ToString());  
    230.         }
    231.         GUI.backgroundColor = Color.white;
    232.         Handles.EndGUI();
    233.     }
    234. #endregion
    235.  
    236. #region Point Management
    237.  
    238.     public void AddPoint(Vector3 v)
    239.     {
    240.         Undo.RegisterUndo(new Object[1]{target as Object}, "Set Point");
    241.  
    242.         if(road.insertPoint < 0 || road.insertPoint > road.points.Count)
    243.             road.points.Add(v);
    244.         else
    245.             road.points.Insert(road.insertPoint, v);
    246.  
    247.         road.Refresh();
    248.         SceneView.RepaintAll();
    249.     }
    250.  
    251.     public void DeletePoint(int index)
    252.     {
    253.         Undo.RegisterUndo(new Object[]{target}, "Delete Point");
    254.  
    255.         road.points.RemoveAt(index);
    256.         road.Refresh();
    257.         SceneView.RepaintAll();
    258.     }
    259. #endregion
    260. }



    And this is the script for RoadObjectEditorScript.js



    import System.Collections.Generic;
    import System.IO;
    import EasyRoads3D;
    import EasyRoads3DEditor;
    @CustomEditor(RoadObjectScript)
    class RoadObjectEditorScript extends Editor
    {
    var counter : int;
    var pe : float;
    var tv : boolean;
    var tvDone : boolean;
    var debugDone : boolean;
    var res : boolean;
    var col : Collider;

    function OnEnable(){

    target.backupLocation = EditorPrefs.GetInt("ER3DbckLocation", 0);

    if(target.OQCODQCQOC == null){
    ODCDDDDDDQ();
    target.OCOOCQODQD(null, null, null);
    }

    target.ODODQOQO = target.OQCODQCQOC.ODDDCOQDCC();
    target.ODODQOQOInt = target.OQCODQCQOC.OCDDCDCCQD();
    if(target.splatmapLayer >= target.ODODQOQO.Length)target.splatmapLayer = 4;
    if(target.customMesh != null){
    if(target.customMesh.GetComponent(typeof(Collider))){
    col = target.customMesh.GetComponent(typeof(Collider));
    }else if(OQCDOODQQQ.terrain != null){
    col = OQCDOODQQQ.terrain.GetComponent(typeof(TerrainCollider));
    }
    }else if(OQCDOODQQQ.terrain != null){
    col = OQCDOODQQQ.terrain.GetComponent(typeof(TerrainCollider));
    }

    if(ODCDDDDDDQ()){
    OQCDOODQQQ.OQOOCOCDDQ();
    }
    target.ODQDODOODQs = new GameObject[0];




    }
    function OnInspectorGUI(){

    EasyRoadsGUIMenu(true, true, target);
    }
    function OnSceneGUI() {
    if(target.OQCODQCQOC == null){
    ODCDDDDDDQ();
    target.OCOOCQODQD(null, null, null);
    if(target.OCDQCCOCOC != EditorApplication.currentScene && target.OQCODQCQOC == null){
    OCQCDCCDOC.terrainList.Clear();
    target.OCDQCCOCOC = EditorApplication.currentScene;
    }

    }

    OnScene();

    }
    function EasyRoadsGUIMenu(flag : boolean, senderIsMain : boolean, nRoadScript : RoadObjectScript) : int {





    if(target.OQDDCQCCDQ == null || target.OODQCQCDQO == null || target.ODOOCQDQCD == null || target.OQDDCQCCDQ.Length == 0 ){
    target.OQDDCQCCDQ = new boolean[5];
    target.OODQCQCDQO = new boolean[5];
    target.ODOOCQDQCD = nRoadScript;

    target.ODODQCCDOC = target.OQCODQCQOC.OQQCCOQDQO();
    target.ODODQOQO = target.OQCODQCQOC.ODDDCOQDCC();
    target.ODODQOQOInt = target.OQCODQCQOC.OCDDCDCCQD();
    }
    origAnchor = GUI.skin.box.alignment;
    if(target.OODCOCOOCC == null){
    target.OODCOCOOCC = Resources.Load("ER3DSkin", GUISkin);
    target.OQQOCCQOOC = Resources.Load("ER3DLogo", Texture2D);
    }
    if(!flag) target.OODODDQDOQ();
    if(target.ODDDQCOOQD == -1) target.ODQDODOODQ = null;
    var origSkin : GUISkin = GUI.skin;
    GUI.skin = target.OODCOCOOCC;
    EditorGUILayout.Space();

    EditorGUILayout.BeginHorizontal ();
    GUILayout.FlexibleSpace();
    target.OQDDCQCCDQ[0] = GUILayout.Toggle(target.OQDDCQCCDQ[0] ,new GUIContent("", " Add road markers. "),"AddMarkers",GUILayout.Width(40), GUILayout.Height(22));
    if(target.OQDDCQCCDQ[0] == true && target.OODQCQCDQO[0] == false) {
    target.OODODDQDOQ();
    target.OQDDCQCCDQ[0] = true; target.OODQCQCDQO[0] = true;
    }
    target.OQDDCQCCDQ[1] = GUILayout.Toggle(target.OQDDCQCCDQ[1] ,new GUIContent("", " Insert road markers. "),"insertMarkers",GUILayout.Width(40),GUILayout.Height(22));
    if(target.OQDDCQCCDQ[1] == true && target.OODQCQCDQO[1] == false) {
    target.OODODDQDOQ();
    target.OQDDCQCCDQ[1] = true; target.OODQCQCDQO[1] = true;
    }
    target.OQDDCQCCDQ[2] = GUILayout.Toggle(target.OQDDCQCCDQ[2] ,new GUIContent("", " Process the terrain and create road geometry. "),"terrain",GUILayout.Width(40),GUILayout.Height(22));

    if(target.OQDDCQCCDQ[2] == true && (target.OODQCQCDQO[2] == false || target.doTerrain)) {

    if(target.markers <= 2){
    EditorUtility.DisplayDialog("Alert", "A minimum of 2 road markers is required before the terrain can be leveled!", "Close");
    target.OQDDCQCCDQ[2] = false;
    }else{
    if(target.disableFreeAlerts)EditorUtility.DisplayDialog("Alert", "Switching back to 'Edit Mode' is not supported in the free version.\n\nClick Close to generate the road mesh and deform the terrain. This process can take some time depending on the terrains heightmap resolution and the optional vegetation removal, please be patient!\n\nYou can always restore the terrain using the EasyRoads3D terrain restore option in the main menu.\n\nNote: you can disable displaying this message in General Settings.", "Close");
    if(!flag){
    EditorUtility.DisplayDialog("Alert", "The Unity Terrain Object does not accept height values < 0. The river floor will be equal or higher then the water level. Position all markers higher above the terrain!", "Close");
    target.OQDDCQCCDQ[2] = false;
    }else{
    tvDone = false;
    target.OODODDQDOQ();
    target.OQDDCQCCDQ[2] = true; target.OODQCQCDQO[2] = true;
    target.OOCQCCQOQQ = true;
    target.doTerrain = false;
    target.markerDisplayStr = "Show Markers";
    if(target.objectType < 2){




    #if UNITY_4_6
    #elif UNITY_4_5
    #elif UNITY_4_3
    #else
    Undo.RegisterUndo(OQCDOODQQQ.terrain.terrainData, "EasyRoads3D Terrain leveling");
    #endif




    if(!target.displayRoad){
    target.displayRoad = true;
    target.OQCODQCQOC.OQOCOCCQOC(true, target.OCCQOQDDDO);
    }
    OCQCDCCDOC.ODQODCODOD = false;

    OOQCOOQQDO(target);
    if(target.OOQDOOQQ)target.OQCCOODCDO();



    }else{

    target.OQCODQCQOC.OCCODDODOO(target.transform, false);
    }
    }
    if(target.disableFreeAlerts)EditorUtility.DisplayDialog("Finished!", "The terrain data has been updated.\n\nIf you want to keep these changes and add more road objects it is recommended to update the terrain backup data using the EasyRoads3D terrain backup options in the main menu. By doing this you will not loose the current terrain changes if later in the development process you want to restore the terrain back to the current status.\n\nYou can also duplicate the terrain object in the project panel and keep that as the terrain backup.\n\nNote: you can disable displaying this message in General Settings.", "Close");
    }
    }

    target.OQDDCQCCDQ[3] = GUILayout.Toggle(target.OQDDCQCCDQ[3] ,new GUIContent("", " General settings. "),"settings",GUILayout.Width(40),GUILayout.Height(22));
    if(target.OQDDCQCCDQ[3] == true && target.OODQCQCDQO[3] == false) {
    target.OODODDQDOQ();
    target.OQDDCQCCDQ[3] = true; target.OODQCQCDQO[3] = true;
    }
    target.OQDDCQCCDQ[4] = GUILayout.Toggle(target.OQDDCQCCDQ[4] ,new GUIContent("", "Version and Purchase Info"),"info",GUILayout.Width(40),GUILayout.Height(22));
    if(target.OQDDCQCCDQ[4] == true && target.OODQCQCDQO[4] == false) {
    target.OODODDQDOQ();
    target.OQDDCQCCDQ[4] = true; target.OODQCQCDQO[4] = true;
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    GUI.skin = null;
    GUI.skin = origSkin;
    target.ODDDQCOOQD = -1;
    for(var i : int = 0; i < 5; i++){
    if(target.OQDDCQCCDQ){
    target.ODDDQCOOQD = i;
    target.OODQCOQQQQ = i;
    }
    }
    if(target.ODDDQCOOQD == -1) target.OODODDQDOQ();
    var markerMenuDisplay : int = 1;
    if(target.ODDDQCOOQD == 0 || target.ODDDQCOOQD == 1) markerMenuDisplay = 0;
    else if(target.ODDDQCOOQD == 2 || target.ODDDQCOOQD == 3 || target.ODDDQCOOQD == 4) markerMenuDisplay = 0;

    if(target.OOCQCCQOQQ && !target.OQDDCQCCDQ[2] && Application.isPlaying){
    EditorPrefs.SetBool("ERv2isPlaying", true);

    }







    if(target.OOCQCCQOQQ && !target.OQDDCQCCDQ[2]){
    target.OQDDCQCCDQ[2] = true;
    target.OODQCQCDQO[2] = true;
    if(target.disableFreeAlerts)EditorUtility.DisplayDialog("Alert", "Switching back to 'Edit Mode' to add markers or change other settings is not supported in the free version.\n\nDrag the road mesh to the root of the hierarchy and delete the EasyRoads3D editor object once the road is ready!\n\nYou can use Undo to restore the terrain.", "Close");
    }
    GUI.skin.box.alignment = TextAnchor.UpperLeft;
    if(target.ODDDQCOOQD >= 0 && target.ODDDQCOOQD != 4){
    if(target.ODODQCCDOC == null || target.ODODQCCDOC.Length == 0){

    target.ODODQCCDOC = target.OQCODQCQOC.OQQCCOQDQO();
    target.ODODQOQO = target.OQCODQCQOC.ODDDCOQDCC();
    target.ODODQOQOInt = target.OQCODQCQOC.OCDDCDCCQD();
    }
    EditorGUILayout.BeginHorizontal();
    GUILayout.Box(target.ODODQCCDOC[target.ODDDQCOOQD], GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(50));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    }
    if(target.ODDDQCOOQD == -1 && target.ODQDODOODQ != null) Selection.activeGameObject = target.ODQDODOODQ.gameObject;
    GUI.skin.box.alignment = origAnchor;

    if(target.erInit == "" || (OCQCDCCDOC.debugFlag && !debugDone)){
    debugDone = true;

    target.erInit = OCDQQCOQOD.OQOCQOQCOO(target.version);
    target.OQCODQCQOC.erInit = target.erInit;



    this.Repaint();

    }
    if(target.erInit != "" && res){

    target.OQDODQOODQ(target.geoResolution, false, false);
    res = false;
    }
    if(target.erInit.Length == 0){
    }else if(target.ODDDQCOOQD == 0 || target.ODDDQCOOQD == 1){
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Refresh Surfaces", GUILayout.Width(200))){
    target.ODDCCCQCOC();
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    }else if(target.ODDDQCOOQD == 3){

    GUI.skin.box.alignment = TextAnchor.MiddleLeft;
    GUILayout.Box(" General Settings", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));
    if(target.objectType != 2){
    GUILayout.Space(10);
    var oldDisplay : boolean = target.displayRoad;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Display object", "This will activate/deactivate the road object transforms"), GUILayout.Width(125) );
    target.displayRoad = EditorGUILayout.Toggle (target.displayRoad);
    EditorGUILayout.EndHorizontal();
    if(oldDisplay != target.displayRoad){
    target.OQCODQCQOC.OQOCOCCQOC(target.displayRoad, target.OCCQOQDDDO);
    }
    }
    if(target.materialStrings == null){target.materialStrings = new String[2]; target.materialStrings[0] = "Diffuse Shader"; target.materialStrings[1] = "Transparent Shader"; }
    if(target.materialStrings.Length == 0){target.materialStrings = new String[2]; target.materialStrings[0] = "Diffuse Shader"; target.materialStrings[1] = "Transparent Shader"; }
    var cm : int = target.materialType;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Surface Material", "The material type used for the road surfaces."), GUILayout.Width(125) );
    target.materialType = EditorGUILayout.Popup (target.materialType, target.materialStrings, GUILayout.Width(115));
    EditorGUILayout.EndHorizontal();
    if(cm != target.materialType) target.OQCODQCQOC.ODODDDCCOQ(target.materialType);
    if(target.materialType == 1){
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Surface Opacity", "This controls the transparacy level of the surface objects."), GUILayout.Width(125) );
    var so : float = target.surfaceOpacity;
    target.surfaceOpacity = EditorGUILayout.Slider(target.surfaceOpacity, 0, 1, GUILayout.Width(150));
    EditorGUILayout.EndHorizontal();
    if(so != target.surfaceOpacity) target.OQCODQCQOC.OOCQQCCCDO(target.surfaceOpacity);
    }
    EditorGUILayout.Space();
    if(target.objectType < 2){
    var od: boolean = target.multipleTerrains;
    }
    GUI.enabled = true;
    GUI.enabled = false;
    var cl = target.backupLocation;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Backup Location", "Use outside Assets folder unless you are using the asset server."), GUILayout.Width(125) );
    target.backupLocation = EditorGUILayout.Popup (target.backupLocation, target.backupStrings, GUILayout.Width(115));
    EditorGUILayout.EndHorizontal();
    if(target.backupLocation != cl){
    if(target.backupLocation == 1){
    if(EditorUtility.DisplayDialog("Backup Location", "Changing the backup location to inside the assets folder is only recommended when you want to synchronize EasyRoads3D backup files with the assetserver.\n\nWould you like to continue?", "Yes", "No")){
    EditorPrefs.SetInt("ER3DbckLocation", target.backupLocation);
    OOQDDDCQDD.SwapFiles(target.backupLocation);
    EditorUtility.DisplayDialog("Confirmation", "The backup location has been updated, all backup folders and files have been copied to the new location.\n\nUse CTRL+R to update the assets folder!", "Close");
    }else target.backupLocation = 0;
    }else{
    if(EditorUtility.DisplayDialog("Backup Location", "The backup location will be changed to outside the assets folder.\n\nWould you like to continue?", "Yes", "No")){
    EditorPrefs.SetInt("ER3DbckLocation", target.backupLocation);
    OOQDDDCQDD.SwapFiles(target.backupLocation);
    EditorUtility.DisplayDialog("Confirmation", "The backup location has been updated, all backup folders and files have been copied to the new location.\n\nUse CTRL+R to update the assets folder!", "Close");
    }else target.backupLocation = 1;
    }
    }
    GUI.enabled = true;
    od = OCQCDCCDOC.debugFlag;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Enable Debugging", "This will enable debugging."), GUILayout.Width(125) );;
    OCQCDCCDOC.debugFlag = EditorGUILayout.Toggle (OCQCDCCDOC.debugFlag);
    EditorGUILayout.EndHorizontal();
    if(od != OCQCDCCDOC.debugFlag && OCQCDCCDOC.debugFlag) debugDone = false;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Free version alerts", "Uncheck to disable free version alerts."), GUILayout.Width(125) );;
    target.disableFreeAlerts = EditorGUILayout.Toggle (target.disableFreeAlerts);
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    GUILayout.Box(" Object Settings", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));
    EditorGUILayout.BeginHorizontal();
    var wd : float = target.roadWidth;
    if(target.objectType == 0)GUILayout.Label(new GUIContent(" Road width", "The width of the road") , GUILayout.Width(125));
    else GUILayout.Label(new GUIContent(" River Width", "The width of the river") , GUILayout.Width(125));
    target.roadWidth = EditorGUILayout.FloatField(target.roadWidth, GUILayout.Width(40) );
    EditorGUILayout.EndHorizontal();
    if(wd != target.roadWidth) target.OQDODQOODQ(target.geoResolution, false, false);
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Default Indent", "The distance from the left and right side of the road to the part of the terrain levelled at the same height as the road"), GUILayout.Width(125));
    target.indent = EditorGUILayout.FloatField(target.indent, GUILayout.Width(40));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Raise Markers", "This will raise the position of the markers (m)."), GUILayout.Width(125) );;
    target.raiseMarkers = EditorGUILayout.FloatField (target.raiseMarkers, GUILayout.Width(40));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Force Y Position", "When toggled on, ne road markers will inherit the y position of the previous marker."), GUILayout.Width(125) );;
    target.forceY = EditorGUILayout.Toggle (target.forceY);
    EditorGUILayout.EndHorizontal();
    if(target.forceY){
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Y Change", "The marker will be raised / lowered according this amount for every 100 meters."), GUILayout.Width(125) );;
    target.yChange = EditorGUILayout.FloatField (target.yChange, GUILayout.Width(40));
    EditorGUILayout.EndHorizontal();
    }
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Surrounding", "This represents the distance over which the terrain will be gradually leveled to the original terrain height"), GUILayout.Width(125));
    target.surrounding = EditorGUILayout.FloatField(target.surrounding, GUILayout.Width(40));
    EditorGUILayout.EndHorizontal();
    var OldClosedTrack : boolean = target.OOQDOOQQ;
    EditorGUILayout.BeginHorizontal();
    if(target.objectType == 0)GUILayout.Label(new GUIContent(" Closed Track", "This will connect the 'start' and 'end' of the road"), GUILayout.Width(125) );
    else if(target.objectType == 1)GUILayout.Label(new GUIContent(" Closed River", "This will connect the 'start' and 'end' of the river"), GUILayout.Width(125) );
    else GUILayout.Label(new GUIContent(" Closed Object", "This will connect the 'start' and 'end' of the object"), GUILayout.Width(125) );
    target.OOQDOOQQ = EditorGUILayout.Toggle (target.OOQDOOQQ);
    EditorGUILayout.EndHorizontal();
    if(OldClosedTrack != target.OOQDOOQQ){
    target.ODDCCCQCOC();
    }
    EditorGUILayout.BeginHorizontal();
    GUI.enabled = false;
    GUILayout.Label(new GUIContent(" iOS Platform", "This will prepare the road mesh for the iOS Platform"), GUILayout.Width(125) );
    target.iOS = EditorGUILayout.Toggle (target.iOS);
    EditorGUILayout.EndHorizontal();
    if(OldClosedTrack != target.iOS){
    }
    GUI.enabled = true;

    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Geometry Resolution", "The polycount of the generated surfaces. It is recommended to use a low resolution while creating the road. Use the maximum resolution when processing the final terrain."), GUILayout.Width(125) );
    var gr : float = target.geoResolution;
    target.geoResolution = EditorGUILayout.Slider(target.geoResolution, 0.5, 5, GUILayout.Width(150));
    EditorGUILayout.EndHorizontal();
    if(gr != target.geoResolution) target.OQDODQOODQ(target.geoResolution, false, false);
    EditorGUILayout.BeginHorizontal();
    OldClosedTrack = target.iOS;
    GUI.enabled = false;
    GUILayout.Label(new GUIContent(" Tangents", "This will automatically calculate mesh tangents data required for bump mapping. Note that this will take a little bit more preocessing time."), GUILayout.Width(125) );
    target.applyTangents = EditorGUILayout.Toggle (target.applyTangents);
    EditorGUILayout.EndHorizontal();
    GUI.enabled = true;
    EditorGUILayout.Space();
    GUILayout.Box(" Render Settings", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));
    GUI.enabled = false;
    if(OQCDOODQQQ.selectedTerrain == null)OQCDOODQQQ.OQOOCOCDDQ();
    var st : int = OQCDOODQQQ.selectedTerrain;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Active Terrain", "The terrain that will be updated"), GUILayout.Width(125) );
    OQCDOODQQQ.selectedTerrain = EditorGUILayout.Popup (OQCDOODQQQ.selectedTerrain, OQCDOODQQQ.terrainStrings, GUILayout.Width(115));
    EditorGUILayout.EndHorizontal();
    if(st != OQCDOODQQQ.selectedTerrain)OQCDOODQQQ.OOODOQCOOQ();
    GUI.enabled = true;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Update Vegetation", "When toggled on tree and detail objects near the road will be removed when rendering the terrain."), GUILayout.Width(125) );;
    target.handleVegetation = EditorGUILayout.Toggle (target.handleVegetation);
    EditorGUILayout.EndHorizontal();
    if(target.handleVegetation){
    GUI.enabled = false;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Tree Distance (m)", "The distance from the left and the right of the road up to which terrain trees should be removed."), GUILayout.Width(125) );
    var tr : float = target.OCOCODCCDD;
    target.OCOCODCCDD = EditorGUILayout.Slider(target.OCOCODCCDD, 0, 25, GUILayout.Width(150));
    EditorGUILayout.EndHorizontal();
    if(tr != target.OCOCODCCDD) target.OQCODQCQOC.OCOCODCCDD = target.OCOCODCCDD;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Detail Distance (m)", "The distance from the left and the right of the road up to which terrain detail opbjects should be removed."), GUILayout.Width(125) );
    tr = target.ODDQODQCOO;
    target.ODDQODQCOO = EditorGUILayout.Slider(target.ODDQODQCOO, 0, 25, GUILayout.Width(150));
    EditorGUILayout.EndHorizontal();
    if(tr != target.ODDQODQCOO) target.OQCODQCQOC.ODDQODQCOO = target.ODDQODQCOO;
    GUI.enabled = true;
    }
    EditorGUILayout.Space();


    }else if(target.ODDDQCOOQD == 2){

    EditorGUILayout.Space();
    if(target.objectType == 0)GUILayout.Box(" Road Settings:", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));
    else GUILayout.Box(" River Settings:", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));
    GUILayout.Space(10);
    var oldRoad : boolean = target.renderRoad;
    var oldRoadResolution : float = target.roadResolution;
    var oldRoadUV : float = target.tuw;
    var oldRaise : float = target.raise;
    var oldSegments : int = target.OdQODQOD;
    var oldOOQQQDOD : float = target.OOQQQDOD;
    var oldOOQQQDODOffset : float = target.OOQQQDODOffset;
    var oldOOQQQDODLength : float = target.OOQQQDODLength;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Render"," When active, terrain matching road geometry will be created."), GUILayout.Width(105) );
    target.renderRoad = EditorGUILayout.Toggle (target.renderRoad);
    EditorGUILayout.EndHorizontal();
    if(target.renderRoad){
    if(target.objectType == 0){
    if(target.roadTexture == null){
    mat = Resources.Load("roadMaterial", typeof(Material));
    target.roadTexture = mat.mainTexture;
    }
    GUI.enabled = false;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Material"," The road texture."), GUILayout.Width(105) );
    if(GUILayout.Button (target.roadTexture, GUILayout.Width(75), GUILayout.Height(75))){
    }
    EditorGUILayout.EndHorizontal();
    GUI.enabled = true;
    }
    EditorGUILayout.BeginHorizontal();
    GUI.enabled = false;
    GUILayout.Label(new GUIContent(" Road Segments"," The number of segments over the width of the road."), GUILayout.Width(105) );
    target.OdQODQOD = EditorGUILayout.IntSlider(target.OdQODQOD, 1, 10, GUILayout.Width(175));
    GUI.enabled = true;
    EditorGUILayout.EndHorizontal();
    if(target.OdQODQOD > 1){
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Bumpyness"," The bumypness of the surface of the road."), GUILayout.Width(95) );
    target.OOQQQDOD = EditorGUILayout.Slider(target.OOQQQDOD, 0, 1, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Bumpyness Offset"," The bumypness variation of the road."), GUILayout.Width(95) );
    target.OOQQQDODOffset = EditorGUILayout.Slider(target.OOQQQDODOffset, 0, 1, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Bumpyness Density"," The bumypness density on the road."), GUILayout.Width(95) );
    target.OOQQQDODLength = EditorGUILayout.Slider(target.OOQQQDODLength, 0.01, 1, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    }
    GUI.enabled = false;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Resolution"," The resolution level of the road geometry."), GUILayout.Width(95) );
    target.roadResolution = EditorGUILayout.IntSlider(target.roadResolution, 1, 10, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    GUI.enabled = true;
    if(target.objectType == 0){
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" UV Mapping"," Use the slider to control texture uv mapping of the road geometry."), GUILayout.Width(95) );
    target.tuw = EditorGUILayout.Slider(target.tuw, 1, 30, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Raise (cm)","Optionally increase this setting when parts of the terrain stick through the road geometry. It is recommended to adjust these areas using the terrain tools!"), GUILayout.Width(95) );
    target.raise = EditorGUILayout.Slider(target.raise, 0, 100, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    }else{
    }
    GUILayout.Space(5);
    GUI.enabled = false;
    if(target.applyTangents)GUI.enabled = false;
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Calculate Tangents", GUILayout.Width(175))){
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    GUI.enabled = true;
    GUI.enabled = true;
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Save Geometry", GUILayout.Width(175))){
    target.ODCDDDOCDO();
    Debug.Log("Road object geometry saved");
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Finalize Object", GUILayout.Width(175))){
    var bflag = false;
    for(i=0;i<target.ODODQQOD.Length;i++){
    if(target.ODODQQOD){
    bflag = true;
    break;
    }
    }
    if(target.autoODODDQQO || target.sosBuild == true)bflag = false;
    if(EditorUtility.DisplayDialog("Important!", "This will unlink the road from the EasyRoads3D editor object and the EasyRoads3D object will be destroyed!\n\nWould you like to continue?", "Yes", "No")){
    if(bflag){
    if(EditorUtility.DisplayDialog("Important!", "This object includes activated side objects that have not yet been build!\n\nAre you sure you would you like to continue?", "Yes", "No")){
    bflag = false;
    }
    }
    if(!bflag){
    target.OQCODQCQOC.FinalizeObject(target.gameObject);
    DestroyImmediate(target.gameObject);
    }
    }
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    GUI.enabled = true;
    }
    EditorGUILayout.Space();
    if(oldRoad != target.renderRoad || oldRoadResolution != target.roadResolution || oldRoadUV != target.tuw || oldRaise != target.raise || oldSegments != target.OdQODQOD || target.OOQQQDOD != oldOOQQQDOD || target.OOQQQDODOffset != oldOOQQQDODOffset || target.OOQQQDODLength != oldOOQQQDODLength){

    target.OQQOCOQQOC();

    }
    GUILayout.Box(" Terrain Settings:", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));
    GUILayout.Space(5);
    var oldApplySplatmap : boolean = target.applySplatmap;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Apply Splatmap"," When active, the road will be added to the terrain splatmap. The quality highly depends on the terrain Control Texture Resolution size."), GUILayout.Width(125) );
    target.applySplatmap = EditorGUILayout.Toggle (target.applySplatmap);
    EditorGUILayout.EndHorizontal();
    if(target.applySplatmap){
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Terrain texture", "This represents the terrain texture which will be used for the road spatmap."), GUILayout.Width(125) );
    target.splatmapLayer = EditorGUILayout.IntPopup (target.splatmapLayer, target.ODODQOQO, target.ODODQOQOInt, GUILayout.Width(120));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Expand"," Use this setting to increase the size of the splatmap."), GUILayout.Width(125) );
    target.expand = EditorGUILayout.IntSlider(target.expand,0, 3, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Smooth Level"," Use this setting to blur the road splatmap for smoother results."), GUILayout.Width(125) );
    target.splatmapSmoothLevel = EditorGUILayout.IntSlider (target.splatmapSmoothLevel, 0, 3, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Offset x"," Moves the road splatmap in the x direction."), GUILayout.Width(125) );
    target.offsetX = EditorGUILayout.IntField (target.offsetX, GUILayout.Width(50));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Offset y"," Moves the road splatmap in the y direction."), GUILayout.Width(125) );
    target.offsetY= EditorGUILayout.IntField (target.offsetY, GUILayout.Width(50));
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Opacity","Use this setting to blend the road splatmap with the terrain splatmap."), GUILayout.Width(125) );
    target.opacity = EditorGUILayout.Slider (target.opacity, 0, 1, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    GUILayout.Space(5);
    GUI.enabled = target.OCDCOQDCDQ;
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Apply Changes", GUILayout.Width(175))){
    target.OQCCOODCDO();

    if(target.OOQDOOQQ)target.OQCCOODCDO();
    target.OCDCOQDCDQ = false;
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    }
    GUILayout.Space(5);
    if(oldApplySplatmap != target.applySplatmap){
    target.OQCCOODCDO();

    if(target.OOQDOOQQ)target.OQCCOODCDO();
    }
    GUI.enabled = true;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Terrain Smoothing:", "This will smoothen the terrain near the surface edges according the below distance."), GUILayout.Width(175) );
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Edges (m)","This represents the smoothen distance."), GUILayout.Width(125) );
    target.smoothDistance = EditorGUILayout.Slider (target.smoothDistance, 0, 5, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    GUILayout.Space(5);
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Update Edges", GUILayout.Width(175))){

    #if UNITY_4_6
    #elif UNITY_4_5
    #elif UNITY_4_3
    #else
    Undo.RegisterUndo(OQCDOODQQQ.terrain.terrainData, "EasyRoads3D Terrain smooth");
    #endif
    target.OQCODQCQOC.OQQDCDQQDC(target.smoothDistance, 0);
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Surrounding (m)","This represents the smoothen distance."), GUILayout.Width(125) );
    target.smoothSurDistance = EditorGUILayout.Slider (target.smoothSurDistance, 0, 15, GUILayout.Width(175));
    EditorGUILayout.EndHorizontal();
    GUILayout.Space(5);
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Update Surrounding", GUILayout.Width(175))){

    #if UNITY_4_6
    #elif UNITY_4_5
    #elif UNITY_4_3
    #else
    Undo.RegisterUndo(OQCDOODQQQ.terrain.terrainData, "EasyRoads3D Terrain smooth");
    #endif
    target.OQCODQCQOC.OQQDCDQQDC(target.smoothSurDistance, 1);
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();

    GUILayout.Box(" Cam Fly Over", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));
    GUI.enabled = false;
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Position", ""), GUILayout.Width(75) );
    var sp : float = target.splinePos;
    target.splinePos = EditorGUILayout.Slider(target.splinePos, 0, 0.9999);
    EditorGUILayout.EndHorizontal();
    if(sp != target.splinePos){
    }
    EditorGUILayout.BeginHorizontal();
    GUILayout.Label(new GUIContent(" Height", ""), GUILayout.Width(75) );
    sp = target.camHeight;
    target.camHeight = EditorGUILayout.Slider(target.camHeight, 1, 10);
    EditorGUILayout.EndHorizontal();
    if(sp != target.camHeight){
    }
    GUI.enabled = true;
    EditorGUILayout.Space();
    }else if(target.ODDDQCOOQD == 4){
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();

    GUILayout.Label(target.OQQOCCQOOC);
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    GUILayout.Label(" EasyRoads3D v"+target.version);
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();

    GUILayout.Label(" Version Type: Free Version", GUILayout.Height(22));
    if(GUILayout.Button ("i", GUILayout.Width(22))){
    Application.OpenURL ("http://www.unityterraintools.com");
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Help", GUILayout.Width(225))){
    Application.OpenURL ("http://www.unityterraintools.com/manual.php");
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    GUI.skin = origSkin;
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    GUILayout.Box("Check out the full version if you had like to take advantage of all the features including the built-in paramatric modeling tool", GUILayout.Width(250));
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Get the Full Version", GUILayout.Width(225))){
    // AssetStore.Open("http://u3d.as/content/anda-soft/easy-roads3d-pro/1Ch");
    Application.OpenURL ("https://www.assetstore.unity3d.com/#/content/469");
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    GUILayout.Label(new GUIContent(" Newsletter Sign Up:",""), GUILayout.Width(155) );
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    GUILayout.Label(new GUIContent(" Name", ""), GUILayout.Width(75) );
    target.uname = GUILayout.TextField(target.uname, GUILayout.Width(150));
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    GUILayout.Label(new GUIContent(" Email", ""), GUILayout.Width(75) );
    target.email = GUILayout.TextField(target.email, GUILayout.Width(150));
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    EditorGUILayout.Space();
    EditorGUILayout.BeginHorizontal();
    GUILayout.FlexibleSpace();
    if(GUILayout.Button ("Submit", GUILayout.Width(225))){
    EditorUtility.DisplayDialog("Newsletter Signup", OCDDOQCCDD0.NewsletterSignUp(target.uname, target.email), "Ok");
    }
    GUILayout.FlexibleSpace();
    EditorGUILayout.EndHorizontal();
    }else{
    if(target.markers != target.OCCQOQDDDO.childCount){
    target.ODDCCCQCOC();
    }
    EditorGUILayout.Space();
    GUILayout.Box(" General Info", GUILayout.MinWidth(253), GUILayout.MaxWidth(1500), GUILayout.Height(20));

    if(RoadObjectScript.objectStrings == null){
    RoadObjectScript.objectStrings = new String[3];
    RoadObjectScript.objectStrings[0] = "Road Object"; RoadObjectScript.objectStrings[1]="River Object";RoadObjectScript.objectStrings[2]="Procedural Mesh Object";
    }
    if(target.distance == "-1"){
    var ar : String[] = target.OQCODQCQOC.ODQQQDDDCQ(-1);
    target.distance = ar[0];
    }
    EditorGUILayout.Space();
    GUILayout.Label(" Object Type: " + RoadObjectScript.objectStrings[target.objectType]);
    if(target.objectType == 0) GUILayout.Label(" Total Road Distance: " + target.distance.ToString() + " km");
    }
    EditorGUILayout.Space();
    if (GUI.tooltip != "") GUI.Label(new Rect(Input.mousePosition.x, Screen.height - Input.mousePosition.y, 200, 40), GUI.tooltip);
    if (GUI.changed)
    {
    target.OCDCOQDCDQ = true;
    }
    return markerMenuDisplay;
    }
    function OOCDDQQOOD(fwd: Vector3, targetDir: Vector3, up: Vector3) : float {
    var perp: Vector3 = Vector3.Cross(fwd, targetDir);
    var dir: float = Vector3.Dot(perp, up);
    if (dir > 0.0) {
    return 1.0;
    } else if (dir < 0.0) {
    return -1.0;
    } else {
    return 0.0;
    }
    }
    function OnScene(){
    var cEvent : Event = Event.current;
    if(target.OODQCOQQQQ != -1 && Event.current.shift) target.OQDDCQCCDQ[target.OODQCOQQQQ] = true;
    if(target.OQDDCQCCDQ == null || target.OQDDCQCCDQ.Length == 0){
    target.OQDDCQCCDQ = new boolean[5];
    target.OODQCQCDQO = new boolean[5];
    }
    if((cEvent.shift && cEvent.type == EventType.mouseDown) || target.OQDDCQCCDQ[1])
    {
    var hit : RaycastHit;
    var mPos : Vector2 = cEvent.mousePosition;
    mPos.y = Screen.height - mPos.y - 40;
    var ray : Ray = Camera.current.ScreenPointToRay(mPos);

    if (Physics.Raycast (Camera.current.transform.position, ray.direction, hit, 3000))

    {
    if(target.OQDDCQCCDQ[0]){
    go = target.OOOCOOQCOD(hit.point);
    }
    else if(target.OQDDCQCCDQ[1] && cEvent.type == EventType.mouseDown && cEvent.shift){

    target.ODDCCQDCQC(hit.point, true);
    }
    else if(target.OQDDCQCCDQ[1] && cEvent.shift) target.ODDCCQDCQC(hit.point, false);
    else if(target.handleInsertFlag) target.handleInsertFlag = target.OQCODQCQOC.OOOCDCQDOC();
    Selection.activeGameObject = target.obj.gameObject;
    }
    }
    if(cEvent.control && cEvent.alt && cEvent.type == EventType.mouseDown){
    mPos = cEvent.mousePosition;
    mPos.y = Screen.height - mPos.y - 40;
    ray = Camera.current.ScreenPointToRay(mPos);
    if (Physics.Raycast (Camera.current.transform.position, ray.direction, hit, 3000))
    {
    if(hit.collider.gameObject.GetComponent(typeof(Terrain)) != null){

    var t : Terrain = hit.collider.gameObject.GetComponent(typeof(Terrain));
    for(i = 0; i < OQCDOODQQQ.terrains.Length; i++){

    if(t == OQCDOODQQQ.terrains){
    if(OQCDOODQQQ.terrains.Length > 1)OQCDOODQQQ.selectedTerrain = i + 1;
    else OQCDOODQQQ.selectedTerrain = i;
    OQCDOODQQQ.OOODOQCOOQ();
    EditorUtility.SetDirty (target);
    }
    }
    }
    }
    }
    if(target.OQCQDODCQQ != target.obj || target.obj.name != target.OQQODDQQOO){
    target.OQCODQCQOC.OCQOQQOCCO();
    target.OQCQDODCQQ = target.obj;
    target.OQQODDQQOO = target.obj.name;
    }
    if(target.ODQDODOODQ != null){
    target.OQCODQCQOC.OOOCDCQDOC();

    }
    if(target.transform.position != Vector3.zero) target.transform.position = Vector3.zero;
    }
    static function ODCDDDDDDQ() : boolean{

    var flag : boolean = false;
    var terrains : Terrain[] = MonoBehaviour.FindObjectsOfType(typeof(Terrain));
    for(terrain in terrains) {
    if(!terrain.gameObject.GetComponent(EasyRoads3DTerrainID)){
    var terrainscript : EasyRoads3DTerrainID = terrain.gameObject.AddComponent("EasyRoads3DTerrainID");
    var id : String = UnityEngine.Random.Range(100000000,999999999).ToString();
    terrainscript.terrainid = id;
    flag = true;

    path = Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + id;
    if( !Directory.Exists(path)){
    try{
    Directory.CreateDirectory( path);
    }
    catch(e:System.Exception)
    {
    Debug.Log("Could not create directory: " + path + " " + e);
    }
    }
    if(Directory.Exists(path)){


    }
    }
    }
    }
    static function OOQCOOQQDO(target){
    EditorUtility.DisplayProgressBar("Build EasyRoads3D Object","Initializing", 0);

    scripts = FindObjectsOfType(typeof(RoadObjectScript));
    var rObj : List.<Transform> = new List.<Transform>();
    for(script in scripts) {
    if(script.transform != target.transform) rObj.Add(script.transform);
    }
    if(target.ODODQOQO == null){
    target.ODODQOQO = target.OQCODQCQOC.ODDDCOQDCC();
    target.ODODQOQOInt = target.OQCODQCQOC.OCDDCDCCQD();
    }
    target.OQDODQOODQ(0.5f, true, false);


    if(OQCDOODQQQ.selectedTerrain == null || target.OQCODQCQOC.terrain == null)OQCDOODQQQ.OQOOCOCDDQ();
    target.OQCODQCQOC.OCDCCOCOQO();

    OQCDOODQQQ.OOCCDDOCCO(target.OQCODQCQOC.terrain, Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder + "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain) + "/"+target.OQCODQCQOC.OQQODDQQOO+"_splatMap");


    OOQDDDCQDD.ODQODDOOCC(target.OQCODQCQOC.terrain, Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain) + "/"+target.OQCODQCQOC.OQQODDQQOO+"_heightmap.backup");
    var hitOCOCCDOQQD : List.<tPoint> = target.OQCODQCQOC.OQCCCOQCOO(Vector3.zero, target.raise, target.obj, target.OOQDOOQQ, rObj, target.handleVegetation);
    var changeArr : List.<Vector3> = new List.<Vector3>();
    var stepsf : float = Mathf.Floor(hitOCOCCDOQQD.Count / 10);
    var steps : int = Mathf.RoundToInt(stepsf);


    for(i = 0; i < 10;i++){
    changeArr = target.OQCODQCQOC.OOCDDDQQQD(hitOCOCCDOQQD, i * steps, steps, changeArr);
    EditorUtility.DisplayProgressBar("Build EasyRoads3D Object","Updating Terrain", i * 10);
    }

    changeArr = target.OQCODQCQOC.OOCDDDQQQD(hitOCOCCDOQQD, 10 * steps, hitOCOCCDOQQD.Count - (10 * steps), changeArr);
    target.OQCODQCQOC.OQCQCCCOOQ(changeArr, rObj);
    if(target.OQCODQCQOC.handleVegetation){
    target.OQCODQCQOC.OCCDDQCOCO();

    path = Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain) + "/"+target.OQCODQCQOC.OCDCQCDDDO.OQQODDQQOO;
    OOCDCOQDQC.OQDDODQOOQ(Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder);
    OOCDCOQDQC.OQDDODQOOQ(Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain));
    OOQDDDCQDD.ODCDDCDCQD(target.OQCODQCQOC.OQQDCCOCCO.ToArray(), target.OQCODQCQOC.ODQDDQQOQQ, path);
    }

    target.OQCCOODCDO();

    target.OQCODQCQOC.ODODDCCCQC(target.transform, true);
    target.OQCODQCQOC.OOCCQQODQO();
    EditorUtility.ClearProgressBar();

    }
    function OCOCCCDDDO(target){
    EditorUtility.DisplayProgressBar("Restore EasyRoads3D Object","Restoring terrain data", 0f);
    target.OQDODQOODQ(target.geoResolution, false, false);

    if(target.OQCODQCQOC.OQQQOODDCC != null && target.OQCODQCQOC != null){
    if(target.OQCODQCQOC.editRestore && File.Exists(Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain) + "/"+target.OQCODQCQOC.OQQODDQQOO+"_heightmap.backup")){
    OOQDDDCQDD.OCDDQCDODO(target.OQCODQCQOC.terrain, Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain) + "/"+target.OQCODQCQOC.OQQODDQQOO+"_heightmap.backup");
    }else if(target.OQCODQCQOC.editRestore){
    Debug.LogWarning("The original terrain heightmap data file was not found. If necessary you may restore the terrain data by using Undo or, if the terrain backup is up to date, through the EasyRoads3D Menu");
    }
    }

    if(target.OQCODQCQOC != null){
    target.OQCODQCQOC.OQCODQODOQ();
    if(target.OQCODQCQOC.handleVegetation && target.OQCODQCQOC.editRestore){
    if(target.OQCODQCQOC.OQQDCCOCCO != null){
    if(target.OQCODQCQOC.OQQDCCOCCO.Count == 0){
    // get treeData from file
    path = Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain) + "/"+target.OQCODQCQOC.OQQODDQQOO;
    target.OQCODQCQOC.OQQDCCOCCO = OOQDDDCQDD.ODCCCCQQCQ(path);
    }
    if(target.OQCODQCQOC.OQQDCCOCCO != null) target.OQCODQCQOC.OCCOCQQDOO();

    if(target.OQCODQCQOC.ODQDDQQOQQ.Count == 0){
    // get detailData from file

    path = Directory.GetCurrentDirectory() + OOCDCOQDQC.backupFolder+ "/" + OQCDOODQQQ.OCCQOOCOCQ(target.OQCODQCQOC.terrain) + "/"+target.OQCODQCQOC.OQQODDQQOO;
    target.OQCODQCQOC.ODQDDQQOQQ = OOQDDDCQDD.ODQQDOCODQ(path);

    }
    if(target.OQCODQCQOC.ODQDDQQOQQ != null) target.OQCODQCQOC.OQCDDCCCOD();
    }
    }
    }
    target.ODODDDOO = false;

    EditorUtility.ClearProgressBar();
    }
    }







    I don't know anything about script. I just want to build my player, so I can publish my game Online for people to play
     
    Last edited by a moderator: Mar 11, 2015
  5. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,384
    There actually aren't any errors there, those are warnings. Have you actually read them?

    Please, calm down and form a coherent post. Use code tags when posting code.

    If builds fail, post the errors that the build failure returns.
     
  6. Michaelm9945

    Michaelm9945

    Joined:
    Feb 20, 2015
    Posts:
    27
    The build failure returns this warning

    Assets/Lux/Lux Scripts/Lux Cubemapper/Scripts/LuxCubeProcessor.cs(1040,8): error CS8025: Parsing error


    And this is the script


    Code (CSharp):
    1. //    ////////////////////
    2. //    Lux LuxCubeProcessor
    3.  
    4. //    http://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
    5.  
    6.  
    7. using UnityEngine;
    8. #if UNITY_EDITOR
    9. using UnityEditor;
    10. #endif
    11. public enum ConvoModes
    12. {
    13.     Diffuse = 0,
    14.     Specular = 1
    15. }
    16.  
    17. //public class LuxCubeProcessor : ScriptableWizard {
    18. public class LuxCubeProcessor {
    19.  
    20.     public Cubemap cubeMap;
    21.     public bool TakeNewProbe;
    22.     public GameObject probe;
    23.  
    24.     public ConvoModes ConvolutionMode;
    25.     public bool HighestMipIsReflection = true;
    26.     public bool PullHDR;
    27.  
    28.     private Color[] CubeMapColors;
    29.    
    30.     public float SpecularPower = 2048; // Matches Lux SpecPower
    31.  
    32.  
    33. #if UNITY_EDITOR
    34. //--------------------------------------------------------------------------------------
    35. //    parameter, vars and arrays needed by the script
    36.  
    37.     private float[] solidAngles;
    38.     private static float CP_PI = 3.14159265358979323846f;
    39.  
    40.     // matrices that map cube map indexing vectors in 3d (after face selection and divide through by the _ABSOLUTE VALUE_ of the max coord) into NVC space
    41.     // Note this currently assumes the D3D cube face ordering and orientation
    42.     private Vector3[ , ] sgFace2DMapping = new Vector3[ , ] {
    43.         //XPOS face 0
    44.         { new Vector3( 0,  0, -1),       //u towards negative Z
    45.           new Vector3( 0, -1,  0),       //v towards negative Y
    46.           new Vector3( 1,  0,  0)},      //pos X axis
    47.         //XNEG face 1
    48.         { new Vector3( 0,  0,  1),       //u towards positive Z
    49.           new Vector3( 0, -1,  0),       //v towards negative Y
    50.           new Vector3( -1,  0,  0)},     //neg X axis      
    51.         //YPOS face 2
    52.         { new Vector3(1, 0, 0),            //u towards positive X
    53.           new Vector3(0, 0, 1),            //v towards positive Z
    54.           new Vector3(0, 1 , 0)},        //pos Y axis
    55.         //YNEG face 3
    56.         { new Vector3(1, 0, 0),            //u towards positive X
    57.           new Vector3(0, 0 , -1),        //v towards negative Z
    58.           new Vector3(0, -1 , 0)},        //neg Y axis
    59.         //ZPOS face 4
    60.         { new Vector3(1, 0, 0),            //u towards positive X
    61.           new Vector3(0, -1, 0),        //v towards negative Y
    62.           new Vector3(0, 0,  1)},        //pos Z axis
    63.         //ZNEG face 5
    64.         { new Vector3(-1, 0, 0),        //u towards negative X
    65.           new Vector3(0, -1, 0),        //v towards negative Y
    66.           new Vector3(0, 0, -1)}        //neg Z axis
    67.     };
    68.  
    69.    
    70.     //The 12 edges of the cubemap
    71.     // this table is used to average over the edges.
    72.     private int[ , ] sg_CubeEdgeList = new int[ , ] {
    73.     // face1, face2
    74.         {0,2},                // X_POS Y_POS
    75.         {0,3},                // X_POS Y_NEG
    76.         {0,4},                // X_POS Z_POS
    77.         {0,5},                // X_POS Z_NEG
    78.  
    79.         {1,2},                // X_NEG Y_POS
    80.         {1,3},                // X_NEG Y_NEG
    81.         {1,4},                // X_NEG Z_POS
    82.         {1,5},                // X_NEG Z_NEG
    83.  
    84.         {2,4},                // Y_POS Z_POS
    85.         {2,5},                // Y_POS Z_NEG
    86.         {3,4},                // Y_NEG Z_POS
    87.         {3,5}                // Y_NEG Z_NEG
    88.     };
    89.  
    90.     private int[ , ] sg_CubeCornerList = new int[ , ] {
    91.     // face1, face2, face3
    92.         {0,2,4},            // X_POS Y_POS Z_POS
    93.         {0,2,5},            // X_POS Y_POS Z_NEG
    94.         {0,3,4},            // X_POS Y_NEG Z_POS
    95.         {0,3,5},            // X_POS Y_NEG Z_NEG
    96.  
    97.         {1,2,4},            // X_NEG Y_POS Z_POS
    98.         {1,2,5},            // X_NEG Y_POS Z_NEG
    99.         {1,3,4},            // X_NEG Y_NEG Z_POS
    100.         {1,3,5},            // X_NEG Y_NEG Z_NEG
    101.  
    102.     };
    103.  
    104.  
    105. //--------------------------------------------------------------------------------------
    106.  
    107.     // Helper for Cubemapper Probe
    108.     public void ProcessCubemap(Cubemap cube, bool diff, bool hdr)
    109.     {
    110.         if (diff)
    111.         {
    112.             ConvolveIrradianceEnvironmentMap(cube);
    113.             if (hdr) FakeHDR(cube, false);
    114.             Debug.Log("Diff Cube Processed");
    115.         }
    116.         else
    117.         {
    118.             ConvolveRadianceEnvironmentMap(cube);
    119.             FixupCubeEdges(cube);
    120.             if (hdr) FakeHDR(cube, true);
    121.             cube.filterMode = FilterMode.Trilinear;
    122.             cube.mipMapBias = 0.5f;
    123.             Debug.Log("Spec Cube Processed");
    124.         }
    125.     }
    126.  
    127.     //[MenuItem ("Lux Cubemapper/Cubemapper")]
    128.     //static void CreateWizard () {
    129.     //    ScriptableWizard.DisplayWizard<LuxCubeMapper>("Convolve cubemap", "Go");
    130.     //}
    131.  
    132.     //void OnWizardCreate () {
    133.     //    if (TakeNewProbe) RenderToCubeMap(cubeMap,probe);
    134.  
    135.  
    136.     //    //    diffuse  
    137.     //    if (ConvolutionMode == ConvoModes.Diffuse) {
    138.     //        ConvolveIrradianceEnvironmentMap (cubeMap);
    139.     //        if (PullHDR) FakeHDR(cubeMap, false);
    140.     //    }
    141.  
    142.     //    if (ConvolutionMode == ConvoModes.Specular) {
    143.     //        ConvolveRadianceEnvironmentMap (cubeMap);
    144.     //        FixupCubeEdges(cubeMap);
    145.     //        if (PullHDR) FakeHDR(cubeMap, true);
    146.     //        cubeMap.filterMode = FilterMode.Trilinear;
    147.     //        cubeMap.mipMapBias = 0.5f;
    148.     //    }
    149.     //}
    150.  
    151.  
    152.     //void OnWizardUpdate () {
    153.     //}  
    154.  
    155.     //void RenderToCubeMap(Cubemap dest, GameObject probe) {
    156.     //    var cubeCamera = new GameObject( "CubemapCamera", typeof(Camera) ) as GameObject;
    157.     ////    cubeCamera.hideFlags = HideFlags.HideInHierarchy;
    158.     //    var cubeCam = cubeCamera.GetComponent("Camera") as Camera;
    159.     //    cubeCam.nearClipPlane = 0.001f;
    160.     //    cubeCam.farClipPlane = 1000.0f;
    161.     //    cubeCam.aspect = 1.0f;
    162.     ////    cubeCam.hdr = true;
    163.     //    cubeCam.cullingMask = 1 << 0;      
    164.     //    cubeCamera.transform.position = probe.transform.position;
    165.     //    cubeCam.RenderToCubemap(dest);
    166.     //    GameObject.DestroyImmediate(cubeCamera);
    167.     //}
    168.  
    169.  
    170.  
    171. //--------------------------------------------------------------------------------------
    172. // ConvolveRadianceEnvironmentMap
    173.  
    174.     void ConvolveRadianceEnvironmentMap (Cubemap RadianceCube) {
    175.         int a_Size = RadianceCube.width;
    176.         int n_Size = a_Size;
    177.         int startMipLevel = 0;
    178.         float specularPower;
    179.         float[] specPowr = new float [] {
    180.             SpecularPower, SpecularPower/2.0f, SpecularPower/4.0f, SpecularPower/8.0f, SpecularPower/16.0f, SpecularPower/32.0f, SpecularPower/64.0f, SpecularPower/128.0f, SpecularPower/256.0f, SpecularPower/512.0f
    181.         };
    182.  
    183.         // Calculate maxmiplevels
    184.         int maxMipLevels = (int)Mathf.Log(a_Size, 2) + 1;
    185.     //
    186.         float mytime = Time.realtimeSinceStartup;
    187.    
    188.         // if HighestMipIsReflection == true then skip processing of the highest mip level
    189.         if (HighestMipIsReflection) {
    190.             startMipLevel = 1;
    191.             n_Size = n_Size >> 1;      
    192.         }
    193.  
    194.         for (int mipLevel = startMipLevel; mipLevel < maxMipLevels; mipLevel++)
    195.         {
    196.             Vector4[] m_NormCubeMapArray = new Vector4[n_Size*n_Size*6];
    197.             BuildNormalizerSolidAngleArray(n_Size, ref m_NormCubeMapArray);
    198.  
    199.             specularPower = specPowr[mipLevel];
    200.             float Angle;
    201.             // If we use SpecularPower, automatically calculate the a_BaseFilterAngle required, this will speed the process
    202.             Angle = GetBaseFilterAngle(specularPower);
    203.             // Go for it:
    204.             FilterCubefaces(RadianceCube, m_NormCubeMapArray, mipLevel, Angle, specularPower);
    205.     //        FilterCubefacesBF(RadianceCube, mipLevel, Angle, specularPower);
    206.             n_Size = n_Size >> 1;
    207.         }
    208.     //
    209.         Debug.Log(Time.realtimeSinceStartup - mytime);
    210.  
    211.         RadianceCube.Apply(false);
    212.    
    213.     }
    214.  
    215.  
    216.     void FilterCubefaces (Cubemap RadianceCubeMap, Vector4[] m_NormCubeMapArray, int mipLevel, float a_FilterConeAngle, float a_SpecularPower)
    217.     {
    218.         // Read the first CubeFace
    219.         Color[] InputCubeFacePixels = RadianceCubeMap.GetPixels(CubemapFace.PositiveX, mipLevel);
    220.         // Get its dimensions
    221.         int faceLength = InputCubeFacePixels.Length;
    222.         int a_Size = (int)Mathf.Sqrt(faceLength);
    223.         // Create new array for all Faces
    224.         Color[] PixelsOfAllFaces = new Color[faceLength * 6];
    225.         // Copy first face
    226.         InputCubeFacePixels.CopyTo(PixelsOfAllFaces, 0);
    227.         // Copy all other Faces
    228.         for (int readFace = 1; readFace < 6; readFace++ ) {
    229.             InputCubeFacePixels = RadianceCubeMap.GetPixels((CubemapFace)readFace, mipLevel);
    230.             InputCubeFacePixels.CopyTo(PixelsOfAllFaces, faceLength * readFace);
    231.         }
    232.         InputCubeFacePixels = null;
    233.         // Declare jagged output array and init its child arrays
    234.         Color[][] OutputCubeFacePixels = new Color[6][];
    235.         OutputCubeFacePixels[0] = new Color[faceLength];
    236.         OutputCubeFacePixels[1] = new Color[faceLength];
    237.         OutputCubeFacePixels[2] = new Color[faceLength];
    238.         OutputCubeFacePixels[3] = new Color[faceLength];
    239.         OutputCubeFacePixels[4] = new Color[faceLength];
    240.         OutputCubeFacePixels[5] = new Color[faceLength];
    241.  
    242.         // FilterCubeSurfaces
    243.         float srcTexelAngle;
    244.         float dotProdThresh;
    245.         int filterSize;
    246.         // Angle about center tap to define filter cone
    247.         float filterAngle;
    248.         // Min angle a src texel can cover (in degrees)
    249.         srcTexelAngle = (180.0f / CP_PI) * Mathf.Atan2(1.0f, (float)a_Size);
    250.         // Filter angle is 1/2 the cone angle
    251.         filterAngle = a_FilterConeAngle / 2.0f;
    252.         // Ensure filter angle is larger than a texel
    253.         if(filterAngle < srcTexelAngle)
    254.         {
    255.             filterAngle = srcTexelAngle;  
    256.         }
    257.         // Ensure filter cone is always smaller than the hemisphere
    258.         if(filterAngle > 90.0f)
    259.         {
    260.             filterAngle = 90.0f;
    261.         }
    262.         // The maximum number of texels in 1D the filter cone angle will cover
    263.         // Used to determine bounding box size for filter extents
    264.         filterSize = (int)Mathf.Ceil(filterAngle / srcTexelAngle);
    265.         // Ensure conservative region always covers at least one texel
    266.         if(filterSize < 1)
    267.         {
    268.             filterSize = 1;
    269.         }
    270.         // dotProdThresh threshold based on cone angle to determine whether or not taps
    271.         // Reside within the cone angle
    272.         dotProdThresh = Mathf.Cos( (CP_PI / 180.0f) * filterAngle );
    273.  
    274.         // Process required faces
    275.         for (int a_FaceIdx = 0; a_FaceIdx < 6; a_FaceIdx++)
    276.         {
    277.             // Iterate over dst cube map face texel
    278.             for (int a_V  = 0; a_V < a_Size; a_V++)
    279.             {
    280.                 for (int a_U = 0; a_U < a_Size; a_U++)
    281.                 {
    282.                     Vector4 Sample = new Vector4();
    283.                     Color tempCol = new Color();
    284.                     // Get center tap direction
    285.                     Vector3 centerTapDir = TexelToVect(a_FaceIdx, (float)a_U, (float)a_V, a_Size);
    286.                     //--------------------------------------------------------------------------------------
    287.                     // ProcessFilterExtents
    288.                     float weightAccum = 0.0f;
    289.                     int startFacePtr = 0;
    290.                     // Iterate over cubefaces
    291.                     for(int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++ )
    292.                     {
    293.                         // Pointer to the start of the given face
    294.                         startFacePtr = a_Size*a_Size*iFaceIdx;
    295.                         for(int v = 0; v < a_Size; v++)
    296.                         {
    297.                             for(int u = 0; u < a_Size; u++)
    298.                             {
    299.                                 // CP_FILTER_TYPE_COSINE_POWER
    300.  
    301.                                 // Read normalCube single "pixel"
    302.                                 Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + a_Size*v + u];
    303.                                 // Pointer to direction in cube map associated with texel
    304.                                 // Vector3 texelVect = TexelToVect(iFaceIdx, (float)u, (float)v, a_Size);
    305.                                 Vector3 texelVect;
    306.                                 // Optimized version
    307.                                 texelVect.x = m_NormCubeMap_pixel[0];// * 2.0f - 1.0f;
    308.                                 texelVect.y = m_NormCubeMap_pixel[1];// * 2.0f - 1.0f;
    309.                                 texelVect.z = m_NormCubeMap_pixel[2];// * 2.0f - 1.0f;
    310.                                 // Check dot product to see if texel is within cone
    311.                                 float tapDotProd = Vector3.Dot(texelVect, centerTapDir);
    312.                                 float weight = 0.0f;
    313.                                 if( tapDotProd >= dotProdThresh && tapDotProd > 0.0f )
    314.                                 {
    315.                                     // Weight should be proportional to the solid angle of the tap
    316.                                      // weight = TexelCoordSolidAngle(iFaceIdx, (float)u, (float)v, a_Size);
    317.                                     weight = m_NormCubeMap_pixel[3];
    318.                                     // Here we decide if we use a Phong/Blinn or a Phong/Blinn BRDF.
    319.                                     // Phong/Blinn BRDF is just the Phong/Blinn model multiply by the cosine of the lambert law
    320.                                     // so just adding one to specularpower do the trick.                      
    321.                                     // weight *= pow(tapDotProd, (a_SpecularPower + (float32)IsPhongBRDF));
    322.                                 // CP_FILTER_TYPE_COSINE_POWER
    323.                                     weight *= Mathf.Pow(tapDotProd, a_SpecularPower);
    324.                                 // CP_FILTER_TYPE_COSINE
    325.                                     //weight *= tapDotProd;
    326.                                
    327.                                 }
    328.                                 // Accumulate weight
    329.                                 weightAccum += weight;
    330.                                 // Get pixel from the input cubeMap array
    331.                                 tempCol = PixelsOfAllFaces[a_Size*a_Size*iFaceIdx + a_Size*v + u];
    332.                                 Sample += new Vector4(tempCol.r * weight, tempCol.g * weight, tempCol.b * weight, 1.0f);
    333.                             }
    334.                         }
    335.                     }
    336.                     // one pixel processed
    337.                     // Lux needs alpha!
    338.                     OutputCubeFacePixels[a_FaceIdx][a_V*a_Size + a_U] = new Color(Sample.x/ weightAccum, Sample.y/ weightAccum, Sample.z/ weightAccum, 1.0f);
    339.                 // end inner loops
    340.                 }
    341.             }
    342.         }
    343.         // Write Pixel from the jagged array back to the cubemap faces
    344.         for (int writeFace = 0; writeFace < 6; writeFace++ ) {
    345.             Color[] tempColors = OutputCubeFacePixels[writeFace];
    346.             RadianceCubeMap.SetPixels(tempColors, (CubemapFace)writeFace, mipLevel);
    347.         }
    348.     }
    349.  
    350.  
    351.  
    352.  
    353. // brute force: no look up table used
    354.  
    355.     void FilterCubefacesBF (Cubemap RadianceCubeMap, int mipLevel, float a_FilterConeAngle, float a_SpecularPower)
    356.     {
    357.         // Read the first CubeFace
    358.         Color[] InputCubeFacePixels = RadianceCubeMap.GetPixels(CubemapFace.PositiveX, mipLevel);
    359.         // Get its dimensions
    360.         int faceLength = InputCubeFacePixels.Length;
    361.         int a_Size = (int)Mathf.Sqrt(faceLength);
    362.         // Create new array for all Faces
    363.         Color[] PixelsOfAllFaces = new Color[faceLength * 6];
    364.         // Copy first face
    365.         InputCubeFacePixels.CopyTo(PixelsOfAllFaces, 0);
    366.         // Copy all other Faces
    367.         for (int readFace = 1; readFace < 6; readFace++ ) {
    368.             InputCubeFacePixels = RadianceCubeMap.GetPixels((CubemapFace)readFace, mipLevel);
    369.             InputCubeFacePixels.CopyTo(PixelsOfAllFaces, faceLength * readFace);
    370.         }
    371.         InputCubeFacePixels = null;
    372.  
    373.         // declare jagged output array and init its child arrays
    374.         Color[][] OutputCubeFacePixels = new Color[6][];
    375.         OutputCubeFacePixels[0] = new Color[faceLength];
    376.         OutputCubeFacePixels[1] = new Color[faceLength];
    377.         OutputCubeFacePixels[2] = new Color[faceLength];
    378.         OutputCubeFacePixels[3] = new Color[faceLength];
    379.         OutputCubeFacePixels[4] = new Color[faceLength];
    380.         OutputCubeFacePixels[5] = new Color[faceLength];
    381.  
    382.  
    383.         // FilterCubeSurfaces
    384.         float srcTexelAngle;
    385.         float dotProdThresh;
    386.         int filterSize;
    387.         //angle about center tap to define filter cone
    388.         float filterAngle;
    389.         //min angle a src texel can cover (in degrees)
    390.         srcTexelAngle = (180.0f / CP_PI) * Mathf.Atan2(1.0f, (float)a_Size);
    391.         //filter angle is 1/2 the cone angle
    392.         filterAngle = a_FilterConeAngle / 2.0f;
    393.         //ensure filter angle is larger than a texel
    394.         if(filterAngle < srcTexelAngle)
    395.         {
    396.             filterAngle = srcTexelAngle;  
    397.         }
    398.         //ensure filter cone is always smaller than the hemisphere
    399.         if(filterAngle > 90.0f)
    400.         {
    401.             filterAngle = 90.0f;
    402.         }
    403.  
    404.         // The maximum number of texels in 1D the filter cone angle will cover
    405.         // Used to determine bounding box size for filter extents
    406.         filterSize = (int)Mathf.Ceil(filterAngle / srcTexelAngle);
    407.         // Ensure conservative region always covers at least one texel
    408.         if(filterSize < 1)
    409.         {
    410.             filterSize = 1;
    411.         }
    412.  
    413.         // dotProdThresh threshold based on cone angle to determine whether or not taps
    414.         // Reside within the cone angle
    415.         dotProdThresh = Mathf.Cos( (CP_PI / 180.0f) * filterAngle );
    416.  
    417.         // Process required faces
    418.         for (int a_FaceIdx = 0; a_FaceIdx < 6; a_FaceIdx++)
    419.         {
    420.             // Iterate over dst cube map face texel
    421.             for (int a_V  = 0; a_V < a_Size; a_V++)
    422.             {
    423.                 for (int a_U = 0; a_U < a_Size; a_U++)
    424.                 {
    425.                     Vector4 Sample = new Vector4();
    426.                     Color tempCol = new Color();
    427.                
    428.                     // get center tap direction
    429.                     Vector3 centerTapDir = TexelToVect(a_FaceIdx, (float)a_U, (float)a_V, a_Size);
    430.  
    431.                     //--------------------------------------------------------------------------------------
    432.                     //    ProcessFilterExtents
    433.  
    434.                     float weightAccum = 0.0f;
    435.  
    436.                     // Iterate over cubefaces
    437.                     for(int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++ )
    438.                     {
    439.                         for(int v = 0; v < a_Size; v++)
    440.                         {
    441.                             for(int u = 0; u < a_Size; u++)
    442.                             {
    443.                                 // CP_FILTER_TYPE_COSINE_POWER
    444.                                 // Pointer to direction in cube map associated with texel
    445.                                 Vector3 texelVect = TexelToVect(iFaceIdx, (float)u, (float)v, a_Size);
    446.                                 // Check dot product to see if texel is within cone
    447.                                 float tapDotProd = Vector3.Dot(texelVect, centerTapDir);
    448.  
    449.  
    450.                                 float weight = 0.0f;
    451.                                 if( tapDotProd >= dotProdThresh && tapDotProd > 0.0f )
    452.                                 {
    453.                                
    454.                                     // Weight should be proportional to the solid angle of the tap
    455.                                      weight = TexelCoordSolidAngle(iFaceIdx, (float)u, (float)v, a_Size);
    456.                                     // Here we decide if we use a Phong/Blinn or a Phong/Blinn BRDF.
    457.                                     // Phong/Blinn BRDF is just the Phong/Blinn model multiply by the cosine of the lambert law
    458.                                     // so just adding one to specularpower do the trick.                      
    459.                                     // weight *= pow(tapDotProd, (a_SpecularPower + (float32)IsPhongBRDF));
    460.                                 // CP_FILTER_TYPE_COSINE_POWER
    461.                                     weight *= Mathf.Pow(tapDotProd, a_SpecularPower);
    462.                                 // CP_FILTER_TYPE_COSINE
    463.                                     //weight *= tapDotProd;
    464.                                 }
    465.                                 // Accumulate weight
    466.                                 weightAccum += weight;
    467.  
    468.                                 // Get pixel from the input cubeMap array
    469.                                 tempCol = PixelsOfAllFaces[a_Size*a_Size*iFaceIdx + a_Size*v + u];
    470.                                 Sample += new Vector4(tempCol.r * weight, tempCol.g * weight, tempCol.b * weight, 1.0f);
    471.                             }
    472.                         }
    473.                     }
    474.                     // one pixel processed
    475.                     // Lux needs alpha!
    476.                     OutputCubeFacePixels[a_FaceIdx][a_V*a_Size + a_U] = new Color(Sample.x/ weightAccum, Sample.y/ weightAccum, Sample.z/ weightAccum, 1.0f);
    477.                 // end inner loops
    478.                 }
    479.             }
    480.         }
    481.         // Write Pixel from the jagged array back to the cubemap faces
    482.         for (int writeFace = 0; writeFace < 6; writeFace++ ) {
    483.             Color[] tempColors = OutputCubeFacePixels[writeFace];
    484.             RadianceCubeMap.SetPixels(tempColors, (CubemapFace)writeFace, mipLevel);
    485.         }
    486.     }
    487.  
    488.     //--------------------------------------------------------------------------------------
    489.     // Irridiance Convolution based on SH
    490.  
    491.     void ConvolveIrradianceEnvironmentMap(Cubemap irrCubeMap)
    492.     {
    493.         int a_Size = irrCubeMap.width;
    494.  
    495.         Vector4[] m_NormCubeMapArray = new Vector4[a_Size*a_Size*6];
    496.         BuildNormalizerSolidAngleArray(a_Size, ref m_NormCubeMapArray);
    497.  
    498.         //This is a custom implementation of D3DXSHProjectCubeMap to avoid to deal with LPDIRECT3DSURFACE9 pointer
    499.         //Use Sh order 2 for a total of 9 coefficient as describe in http://www.cs.berkeley.edu/~ravir/papers/envmap/
    500.         //accumulators are 64-bit floats in order to have the precision needed
    501.         //over a summation of a large number of pixels
    502.         double[] SHr = new double[25]; // NUM_SH_COEFFICIENT
    503.         double[] SHg = new double[25];
    504.         double[] SHb = new double[25];
    505.         double[] SHdir = new double[25];
    506.  
    507.         double weightAccum = 0.0;
    508.         double weight = 0.0;
    509.  
    510.         int startFacePtr = 0;
    511.  
    512.         for (int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++) {
    513.  
    514.             // read pixels of m_NormCubeMap
    515.             //var m_NormCubeMap_pixels  = new Color[m_NormCubeMap.width*m_NormCubeMap.height];
    516.             //m_NormCubeMap_pixels = m_NormCubeMap.GetPixels((CubemapFace)iFaceIdx);
    517.  
    518.             // Pointer to the start of the given face in m_NormCubeMapArray
    519.             startFacePtr = a_Size*a_Size*iFaceIdx;
    520.  
    521.             // read all pixels of irrCubeMap
    522.             var cubeMap_pixels = new Color[irrCubeMap.width * irrCubeMap.height];
    523.             cubeMap_pixels = irrCubeMap.GetPixels((CubemapFace)iFaceIdx);
    524.  
    525.  
    526.                 for (int y = 0; y < a_Size; y++) {
    527.                     for (int x = 0; x < a_Size; x++) {
    528.  
    529.                         // read normalCube single pixel
    530.                         Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + y*a_Size + x];
    531.  
    532.                         // read originalCube single pixel
    533.                         Color cubeMap_pixel = cubeMap_pixels[y*a_Size + x];
    534.  
    535.                         // solid angle stored in 4th channel of normalizer/solid angle cube map
    536.                         weight = m_NormCubeMap_pixel[3];
    537.                         //weight = TexelCoordSolidAngle(iFaceIdx, (float)x, (float)y, a_Size);
    538.  
    539.                         // pointer to direction and solid angle in cube map associated with texel
    540.                         Vector3 texelVect;
    541.                         texelVect.x = m_NormCubeMap_pixel[0];
    542.                         texelVect.y = m_NormCubeMap_pixel[1];
    543.                         texelVect.z = m_NormCubeMap_pixel[2];
    544.                         //texelVect = TexelToVect(iFaceIdx, (float)x, (float)y, a_Size);
    545.    
    546.                         EvalSHBasis(texelVect, ref SHdir);
    547.  
    548.                         // read original colors and convert to float64
    549.                         double R = cubeMap_pixel[0];
    550.                         double G = cubeMap_pixel[1];
    551.                         double B = cubeMap_pixel[2];
    552.  
    553.                         for (int i = 0; i < 25; i++)
    554.                         {
    555.                             SHr[i] += R * SHdir[i] * weight;
    556.                             SHg[i] += G * SHdir[i] * weight;
    557.                             SHb[i] += B * SHdir[i] * weight;
    558.                         }
    559.                         weightAccum += weight;
    560.                 }
    561.             }
    562.         }
    563.         // Normalization - The sum of solid angle should be equal to the solid angle of the sphere (4 PI), so
    564.         // Normalize in order our weightAccum exactly match 4 PI.
    565.         for (int i = 0; i < 25; ++i)
    566.         {
    567.             SHr[i] *= 4.0 * CP_PI / weightAccum;
    568.             SHg[i] *= 4.0 * CP_PI / weightAccum;
    569.             SHb[i] *= 4.0 * CP_PI / weightAccum;
    570.         }
    571.  
    572.         // Second step - Generate cubemap from SH coefficient
    573.  
    574.         // Normalized vectors per cubeface and per-texel solid angle
    575.         // Why do we do it a 2nd time????
    576.         BuildNormalizerSolidAngleArray(a_Size, ref m_NormCubeMapArray);
    577.  
    578.         for (int iFaceIdx = 0; iFaceIdx < 6; iFaceIdx++) {
    579.  
    580.             // Pointer to the start of the given face in m_NormCubeMapArray
    581.             startFacePtr = a_Size*a_Size*iFaceIdx;
    582.  
    583.             for (int y = 0; y < a_Size; y++) {
    584.                 for (int x = 0; x < a_Size; x++) {
    585.                     // read normalCube pixel
    586.                     Vector4 m_NormCubeMap_pixel = m_NormCubeMapArray[startFacePtr + y*a_Size + x];
    587.  
    588.                     // read normalvector and pass it to EvalSHBasis to get SHdir
    589.                     Vector3 texelVect;
    590.                     texelVect.x = m_NormCubeMap_pixel[0];
    591.                     texelVect.y = m_NormCubeMap_pixel[1];
    592.                     texelVect.z = m_NormCubeMap_pixel[2];
    593.                     //texelVect = TexelToVect(iFaceIdx, (float)x, (float)y, a_Size);
    594.  
    595.                     EvalSHBasis( texelVect, ref SHdir);
    596.  
    597.                     // set color values
    598.                     double R = 0.0;
    599.                     double G = 0.0;
    600.                     double B = 0.0;
    601.                
    602.                     for (int i = 0; i < 25; ++i)
    603.                     {
    604.                         R += (SHr[i] * SHdir[i] * SHBandFactor[i]);
    605.                         G += (SHg[i] * SHdir[i] * SHBandFactor[i]);
    606.                         B += (SHb[i] * SHdir[i] * SHBandFactor[i]);
    607.                     }
    608.                     // Lux needs alpha!
    609.                     irrCubeMap.SetPixel((CubemapFace)iFaceIdx, x, y, new Color((float)R,(float)G,(float)B, 1.0f ));
    610.                 }
    611.             }
    612.         }
    613.         irrCubeMap.Apply();
    614.     }
    615.  
    616.     //--------------------------------------------------------------------------------------
    617.     // This function return the BaseFilterAngle require by cubemapgen to its FilterExtends
    618.     // It allow to optimize the texel to access base on the specular power.
    619.     static float GetBaseFilterAngle(float cosinePower)
    620.     {
    621.         // We want to find the alpha such that:
    622.         // cos(alpha)^cosinePower = epsilon
    623.         // That's: acos(epsilon^(1/cosinePower))
    624.         const float threshold = 0.000001f;  // Empirical threshold (Work perfectly, didn't check for a more big number, may get some performance and still god approximation)
    625.         float Angle = 180.0f;
    626.         if (Angle != 0.0f)
    627.         {
    628.             Angle = Mathf.Acos(Mathf.Pow(threshold, 1.0f / cosinePower));
    629.             Angle *= 180.0f / CP_PI; // Convert to degree
    630.             Angle *= 2.0f; // * 2.0f because cubemapgen divide by 2 later
    631.         }
    632.  
    633.         return Angle;
    634.     }
    635.  
    636.     //--------------------------------------------------------------------------------------
    637.     // Convert cubemap face texel coordinates and face idx to 3D vector
    638.  
    639.     Vector3 TexelToVect(int a_FaceIdx, float a_U, float a_V, int a_Size) {
    640.         float nvcU, nvcV;
    641.  
    642.         nvcU = (2.0f * ((float)a_U + 0.5f) / (float)a_Size ) - 1.0f;
    643.         nvcV = (2.0f * ((float)a_V + 0.5f) / (float)a_Size ) - 1.0f;
    644.         // U contribution
    645.         Vector3 Dir = sgFace2DMapping[a_FaceIdx, 0] * nvcU;
    646.         // V contribution
    647.         Vector3 tempVec = sgFace2DMapping[a_FaceIdx, 1] * nvcV;
    648.         Dir += tempVec;
    649.         // Add face axis
    650.         Dir += sgFace2DMapping[a_FaceIdx, 2];
    651.         // Normalize vector
    652.         Dir = Vector3.Normalize(Dir);
    653.         return(Dir);
    654.     }
    655.  
    656.     //--------------------------------------------------------------------------------------
    657.     // Convert 3D vector to cubemap face texel coordinates and face idx
    658.  
    659.     private Vector3 VectToTexelCoord(Vector3 a_XYZ, int a_Size) {
    660.         float nvcU, nvcV;
    661.         float maxCoord;
    662.         Vector3 onFaceXYZ;
    663.         int faceIdx;
    664.         float u, v;
    665.             // Get Absolute value
    666.         Vector3 absXYZ = new Vector3(Mathf.Abs(a_XYZ.x), Mathf.Abs(a_XYZ.y), Mathf.Abs(a_XYZ.z));
    667.    
    668.         if( (absXYZ[0] >= absXYZ[1]) && (absXYZ[0] >= absXYZ[2]) )
    669.         {
    670.             maxCoord = absXYZ[0];
    671.             if(a_XYZ[0] >= 0) faceIdx = 0; // face = XPOS -> FACE_X_POS
    672.             else faceIdx = 1; // FACE_X_NEG;                  
    673.         }
    674.         else if ( (absXYZ[1] >= absXYZ[0]) && (absXYZ[1] >= absXYZ[2]) )
    675.         {
    676.             maxCoord = absXYZ[1];
    677.             if(a_XYZ[1] >= 0) faceIdx = 2; // face = XPOS -> FACE_Y_POS
    678.             else faceIdx = 3; // FACE_Y_NEG;                  
    679.         }
    680.         else
    681.         {
    682.             maxCoord = absXYZ[2];
    683.             if(a_XYZ[2] >= 0) faceIdx = 4;  // face = XPOS -> FACE_Z_POS
    684.             else faceIdx = 5; // FACE_Z_NEG;                  
    685.         }
    686.         // Divide through by max coord so face vector lies on cube face
    687.         onFaceXYZ = a_XYZ * 1.0f/maxCoord;
    688.         nvcU = Vector3.Dot(sgFace2DMapping[faceIdx, 0] , onFaceXYZ ); // U-Direction
    689.         nvcV = Vector3.Dot(sgFace2DMapping[faceIdx, 1] , onFaceXYZ ); // V-Direction
    690.         // Modify original AMD code to return value from 0 to Size - 1
    691.     //    As we will sample multiple pixels we skip (int)Mathf.Floor here
    692.         u = (a_Size - 1) * 0.5f * (nvcU + 1.0f);
    693.         v = (a_Size - 1) * 0.5f * (nvcV + 1.0f);
    694.         a_XYZ.x = faceIdx;
    695.         a_XYZ.y = u;
    696.         a_XYZ.z = v;
    697.         return a_XYZ;
    698.     }
    699.  
    700.     //--------------------------------------------------------------------------------------
    701.     //    Compute solid angle of given texel in cubemap face for weighting taps in the
    702.     //    kernel by the area they project to on the unit sphere.
    703.  
    704.     //    Original code from Ignacio Castaño
    705.  
    706.     float TexelCoordSolidAngle(int a_FaceIdx, float a_U, float a_V, int faceSize)
    707.     {
    708.         // Scale up to [-1, 1] range (inclusive), offset by 0.5 to point to texel center.
    709.             float U = (2.0f * ((float)a_U + 0.5f) / (float)faceSize ) - 1.0f;
    710.             float V = (2.0f * ((float)a_V + 0.5f) / (float)faceSize ) - 1.0f;
    711.  
    712.             float InvResolution = 1.0f / faceSize;
    713.             // U and V are the -1..1 texture coordinate on the current face.
    714.         // Get projected area for this texel
    715.         float x0 = U - InvResolution;
    716.         float y0 = V - InvResolution;
    717.         float x1 = U + InvResolution;
    718.         float y1 = V + InvResolution;
    719.         float SolidAngle = AreaElement(x0, y0) - AreaElement(x0, y1) - AreaElement(x1, y0) + AreaElement(x1, y1);
    720.     //    Returns values between 0.001 and 0.009
    721.     //    So lets multiply it by 100.0f
    722.         return SolidAngle * 100.0f;
    723.     }
    724.     static float AreaElement( float x, float y )
    725.     {
    726.         return Mathf.Atan2(x * y, Mathf.Sqrt(x * x + y * y + 1));
    727.     }
    728.  
    729.     //--------------------------------------------------------------------------------------
    730.     // Fixup cube edges
    731.  
    732.     void FixupCubeEdges (Cubemap CubeMap)
    733.     {
    734.         int maxMipLevels = (int)(Mathf.Log((float)CubeMap.width, 2.0f)) + 1;
    735.         int base_Size = CubeMap.width;
    736.    
    737.         // Do not perform any edge fixed for mip level 0
    738.         for (int mipLevel = 1; mipLevel < maxMipLevels; mipLevel++)
    739.         {
    740.             // declare jagged array for all faces and init its child arrays
    741.             Color[][] PixelsOfAllFaces = new Color[6][];
    742.             PixelsOfAllFaces[0] = CubeMap.GetPixels(CubemapFace.PositiveX, mipLevel);
    743.             PixelsOfAllFaces[1] = CubeMap.GetPixels(CubemapFace.NegativeX, mipLevel);
    744.             PixelsOfAllFaces[2] = CubeMap.GetPixels(CubemapFace.PositiveY, mipLevel);
    745.             PixelsOfAllFaces[3] = CubeMap.GetPixels(CubemapFace.NegativeY, mipLevel);
    746.             PixelsOfAllFaces[4] = CubeMap.GetPixels(CubemapFace.PositiveZ, mipLevel);
    747.             PixelsOfAllFaces[5] = CubeMap.GetPixels(CubemapFace.NegativeZ, mipLevel);
    748.  
    749.             int a_Size = base_Size >> mipLevel;
    750.             // As we use a_Size as pointer in our arrays we have to lower it by 1
    751.             a_Size -= 1;
    752.  
    753.  
    754.             int a_FixupWidth = 3;
    755.             int fixupDist = (int)Mathf.Min( a_FixupWidth, a_Size / 2);
    756.  
    757.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[0,0]], PixelsOfAllFaces[sg_CubeCornerList[0,1]], PixelsOfAllFaces[sg_CubeCornerList[0,2]], 0, 0, a_Size, a_Size, a_Size, 0);
    758.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[1,0]], PixelsOfAllFaces[sg_CubeCornerList[1,1]], PixelsOfAllFaces[sg_CubeCornerList[1,2]], a_Size, 0, a_Size, 0, 0, 0);
    759.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[2,0]], PixelsOfAllFaces[sg_CubeCornerList[2,1]], PixelsOfAllFaces[sg_CubeCornerList[2,2]], 0, a_Size, a_Size, 0, a_Size, a_Size);
    760.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[3,0]], PixelsOfAllFaces[sg_CubeCornerList[3,1]], PixelsOfAllFaces[sg_CubeCornerList[3,2]], a_Size, a_Size, a_Size, a_Size, 0, a_Size);
    761.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[4,0]], PixelsOfAllFaces[sg_CubeCornerList[4,1]], PixelsOfAllFaces[sg_CubeCornerList[4,2]], a_Size, 0, 0, a_Size, 0, 0);
    762.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[5,0]], PixelsOfAllFaces[sg_CubeCornerList[5,1]], PixelsOfAllFaces[sg_CubeCornerList[5,2]], 0, 0, 0, 0, a_Size, 0);
    763.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[6,0]], PixelsOfAllFaces[sg_CubeCornerList[6,1]], PixelsOfAllFaces[sg_CubeCornerList[6,2]], a_Size, a_Size, 0, 0, 0, a_Size);
    764.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[7,0]], PixelsOfAllFaces[sg_CubeCornerList[7,1]], PixelsOfAllFaces[sg_CubeCornerList[7,2]], 0, a_Size, 0, a_Size, a_Size, a_Size);
    765.  
    766.             // Perform 2nd iteration in reverse order
    767.  
    768.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[7,0]], PixelsOfAllFaces[sg_CubeCornerList[7,1]], PixelsOfAllFaces[sg_CubeCornerList[7,2]], 0, a_Size, 0, a_Size, a_Size, a_Size);
    769.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[6,0]], PixelsOfAllFaces[sg_CubeCornerList[6,1]], PixelsOfAllFaces[sg_CubeCornerList[6,2]], a_Size, a_Size, 0, 0, 0, a_Size);
    770.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[5,0]], PixelsOfAllFaces[sg_CubeCornerList[5,1]], PixelsOfAllFaces[sg_CubeCornerList[5,2]], 0, 0, 0, 0, a_Size, 0);
    771.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[4,0]], PixelsOfAllFaces[sg_CubeCornerList[4,1]], PixelsOfAllFaces[sg_CubeCornerList[4,2]], a_Size, 0, 0, a_Size, 0, 0);
    772.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[3,0]], PixelsOfAllFaces[sg_CubeCornerList[3,1]], PixelsOfAllFaces[sg_CubeCornerList[3,2]], a_Size, a_Size, a_Size, a_Size, 0, a_Size);
    773.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[2,0]], PixelsOfAllFaces[sg_CubeCornerList[2,1]], PixelsOfAllFaces[sg_CubeCornerList[2,2]], 0, a_Size, a_Size, 0, a_Size, a_Size);
    774.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[1,0]], PixelsOfAllFaces[sg_CubeCornerList[1,1]], PixelsOfAllFaces[sg_CubeCornerList[1,2]], a_Size, 0, a_Size, 0, 0, 0);
    775.             AverageCorner(a_Size, PixelsOfAllFaces[sg_CubeCornerList[0,0]], PixelsOfAllFaces[sg_CubeCornerList[0,1]], PixelsOfAllFaces[sg_CubeCornerList[0,2]], 0, 0, a_Size, a_Size, a_Size, 0);
    776.  
    777.    
    778.  
    779.             // Average Edges
    780.             // Note that this loop does not process the corner texels, since they have already been averaged
    781.             for (int i = 1; i < (a_Size - 1); i++)
    782.             {
    783.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[0,0]], PixelsOfAllFaces[sg_CubeEdgeList[0,1]], i, 0, a_Size, a_Size - i, fixupDist, new Vector4(0, 1, -1, 0) );
    784.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[1,0]], PixelsOfAllFaces[sg_CubeEdgeList[1,1]], i, a_Size, a_Size, i, fixupDist, new Vector4(0, -1, -1, 0) );
    785.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[2,0]], PixelsOfAllFaces[sg_CubeEdgeList[2,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    786.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[3,0]], PixelsOfAllFaces[sg_CubeEdgeList[3,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    787.            
    788.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[4,0]], PixelsOfAllFaces[sg_CubeEdgeList[4,1]], i, 0, 0, i, fixupDist, new Vector4(0, 1, 1, 0) );
    789.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[5,0]], PixelsOfAllFaces[sg_CubeEdgeList[5,1]], i, a_Size, 0, a_Size - i, fixupDist, new Vector4(0, -1, 1, 0) );
    790.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[6,0]], PixelsOfAllFaces[sg_CubeEdgeList[6,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    791.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[7,0]], PixelsOfAllFaces[sg_CubeEdgeList[7,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    792.            
    793.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[8,0]], PixelsOfAllFaces[sg_CubeEdgeList[8,1]], i, a_Size, i, 0, fixupDist, new Vector4(0, -1, 0, 1) );
    794.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[9,0]], PixelsOfAllFaces[sg_CubeEdgeList[9,1]], i, 0, a_Size - i, 0, fixupDist, new Vector4(0, 1, 0, 1) );
    795.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[10,0]], PixelsOfAllFaces[sg_CubeEdgeList[10,1]], i, 0, i, a_Size, fixupDist, new Vector4(0, 1, 0, -1) );
    796.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[11,0]], PixelsOfAllFaces[sg_CubeEdgeList[11,1]], i, a_Size, a_Size - i, a_Size, fixupDist, new Vector4(0, -1, 0, -1) );
    797.        
    798.             }
    799.             // Perform 2nd iteration in reverse order
    800.         /*    for (int i = 0; i < (a_Size); i++)
    801.             {
    802.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[11,0]], PixelsOfAllFaces[sg_CubeEdgeList[11,1]], i, a_Size, a_Size - i, a_Size, fixupDist, new Vector4(0, -1, 0, -1) );
    803.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[10,0]], PixelsOfAllFaces[sg_CubeEdgeList[10,1]], i, 0, i, a_Size, fixupDist, new Vector4(0, 1, 0, -1) );
    804.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[9,0]], PixelsOfAllFaces[sg_CubeEdgeList[9,1]], i, 0, a_Size - i, 0, fixupDist, new Vector4(0, 1, 0, 1) );
    805.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[8,0]], PixelsOfAllFaces[sg_CubeEdgeList[8,1]], i, a_Size, i, 0, fixupDist, new Vector4(0, -1, 0, 1) );
    806.            
    807.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[7,0]], PixelsOfAllFaces[sg_CubeEdgeList[7,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    808.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[6,0]], PixelsOfAllFaces[sg_CubeEdgeList[6,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    809.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[5,0]], PixelsOfAllFaces[sg_CubeEdgeList[5,1]], i, a_Size, 0, a_Size - i, fixupDist, new Vector4(0, -1, 1, 0) );
    810.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[4,0]], PixelsOfAllFaces[sg_CubeEdgeList[4,1]], i, 0, 0, i, fixupDist, new Vector4(0, 1, 1, 0) );  
    811.            
    812.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[3,0]], PixelsOfAllFaces[sg_CubeEdgeList[3,1]], a_Size, i, 0, i, fixupDist, new Vector4(-1, 0, 1, 0) );
    813.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[2,0]], PixelsOfAllFaces[sg_CubeEdgeList[2,1]], 0, i, a_Size, i, fixupDist, new Vector4(1, 0, -1, 0) );
    814.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[1,0]], PixelsOfAllFaces[sg_CubeEdgeList[1,1]], i, a_Size, a_Size, i, fixupDist, new Vector4(0, -1, -1, 0) );
    815.                 AverageEdge(a_Size, PixelsOfAllFaces[sg_CubeEdgeList[0,0]], PixelsOfAllFaces[sg_CubeEdgeList[0,1]], i, 0, a_Size, a_Size - i, fixupDist, new Vector4(0, 1, -1, 0) );
    816.             } */
    817.  
    818.        
    819.  
    820.             // Write Pixel from the jagged array back to the cubemap faces
    821.             for (int writeFace = 0; writeFace < 6; writeFace++ ) {
    822.                 Color[] tempColors = PixelsOfAllFaces[writeFace];
    823.                 CubeMap.SetPixels(tempColors, (CubemapFace)writeFace, mipLevel);
    824.             }
    825.         }
    826.         CubeMap.Apply(false);
    827.     }
    828.  
    829.  
    830.     private void AverageEdge(int a_Size, Color[] face_A, Color[] face_B, int x_A, int y_A, int x_B, int y_B, int fixupDist, Vector4 dir)
    831.     {
    832.         // As a_Size is used as factor we have to increase it by 1
    833.         a_Size += 1;
    834.         Color AverageEdgeColor = face_A[a_Size * y_A + x_A] * 0.5f + face_B[+ a_Size * y_B + x_B] * 0.5f;  
    835.         face_A[a_Size * y_A + x_A] = AverageEdgeColor;
    836.         face_B[a_Size * y_B + x_B] = AverageEdgeColor;
    837.     /*    for (int iFixup = 0; iFixup < fixupDist; iFixup++)
    838.         {
    839.             float fixupFrac = (float)(fixupDist - iFixup) / (float)fixupDist;
    840.             Color AverageEdgeColor_A = face_A[a_Size * y_A + a_Size * (int)dir.y * iFixup + x_A + (int)dir.x * iFixup];
    841.             Color AverageEdgeColor_B = face_B[a_Size * y_B + a_Size * (int)dir.w * iFixup + x_B + (int)dir.z * iFixup];
    842.             // CP_FIXUP_PULL_HERMITE
    843.             float fixupWeight = ((-2.0f * fixupFrac + 3.0f) * fixupFrac * fixupFrac);
    844.        
    845.         //    face_A[a_Size* y_A + a_Size * (int)dir.y * iFixup + x_A + (int)dir.x * iFixup ] = Color.red * (fixupWeight);
    846.         //    face_B[a_Size * y_B + a_Size * (int)dir.w * iFixup + x_B + (int)dir.z * iFixup ] = Color.blue * (fixupWeight);
    847.  
    848.             face_A[a_Size* y_A + a_Size * (int)dir.y * iFixup + x_A + (int)dir.x * iFixup ] = AverageEdgeColor * fixupWeight + AverageEdgeColor_A * (1.0f-fixupWeight) ;
    849.             face_B[a_Size * y_B + a_Size * (int)dir.w * iFixup + x_B + (int)dir.z * iFixup ] = AverageEdgeColor * fixupWeight + AverageEdgeColor_B * (1.0f-fixupWeight) ;
    850.    
    851.  
    852.         } */
    853.     }
    854.  
    855.     private void AverageCorner (int a_Size, Color[] face_A , Color[] face_B, Color [] face_C, int x_A, int y_A, int x_B, int y_B, int x_C, int y_C)
    856.     {
    857.         // As a_Size is used as factor we have to increase it by 1
    858.         a_Size += 1;
    859.         Color AverageCornerColor = face_A[a_Size * y_A + x_A]/3.0f + face_B[a_Size * y_B + x_B]/3.0f + face_C[a_Size * y_C + x_C]/3.0f;
    860.         face_A[ a_Size * y_A + x_A] = AverageCornerColor;
    861.         face_B[a_Size * y_B + x_B] = AverageCornerColor;
    862.         face_C[a_Size * y_C + x_C] = AverageCornerColor;
    863.     }
    864.  
    865.  
    866.     //--------------------------------------------------------------------------------------
    867.     // Builds a normalizer cubemap, with the texels solid angle stored in the fourth component
    868.  
    869.     void BuildNormalizerSolidAngleCubemap(int a_Size, Cubemap a_Surface)
    870.     {
    871.         //a_Size = a_Surface.width;
    872.         int iCubeFace, u, v;
    873.         Vector3 a_XYZ = new Vector3(0,0,0);
    874.         Color[] i_CubeMapColors = new Color[a_Size*a_Size];
    875.         //
    876.         float weight = 0.0f;
    877.         //iterate over cube faces
    878.         for(iCubeFace=0; iCubeFace<6; iCubeFace++)
    879.         {
    880.             for(v=0; v< a_Size; v++)
    881.             {
    882.                 for(u=0; u < a_Size; u++)
    883.                 {
    884.                     // calc TexelToVect in a_XYZ
    885.                     a_XYZ = TexelToVect(iCubeFace, (float)u, (float)v, a_Size);
    886.                     // calc weight
    887.                     weight = TexelCoordSolidAngle(iCubeFace, (float)u, (float)v, a_Size);
    888.                     // Compress a_XYZ to fit into Color
    889.                     i_CubeMapColors[v * a_Size + u] = new Color ((a_XYZ[0]+1.0f)/2.0f, (a_XYZ[1]+1.0f)/2.0f, (a_XYZ[2]+1.0f)/2.0f, weight);
    890.                 }        
    891.             }
    892.             // set CubemapFace
    893.             a_Surface.SetPixels(i_CubeMapColors, (CubemapFace)iCubeFace);
    894.         }
    895.         // set cubeMap
    896.         a_Surface.Apply(true);
    897.         // Debug.Log ("BuildNormalizerSolidAngleCubemap finished");
    898.     }
    899.  
    900.     //--------------------------------------------------------------------------------------
    901.     // Builds a normalizer array, with the texels solid angle stored in the fourth component
    902.  
    903.     void BuildNormalizerSolidAngleArray (int a_Size, ref Vector4[] normSolid)
    904.     {
    905.         int iCubeFace, u, v;
    906.         Vector3 a_XYZ = new Vector3(0,0,0);
    907.         //
    908.         float weight = 0.0f;
    909.         //iterate over cube faces
    910.         for(iCubeFace=0; iCubeFace<6; iCubeFace++)
    911.         {
    912.             for(v=0; v< a_Size; v++)
    913.             {
    914.                 for(u=0; u < a_Size; u++)
    915.                 {
    916.                     // calc TexelToVect in a_XYZ
    917.                     a_XYZ = TexelToVect(iCubeFace, (float)u, (float)v, a_Size);
    918.                     // calc weight
    919.                     weight = TexelCoordSolidAngle(iCubeFace, (float)u, (float)v, a_Size);
    920.                     //
    921.                     normSolid[iCubeFace * a_Size* a_Size + v * a_Size + u] = new Vector4(a_XYZ[0], a_XYZ[1], a_XYZ[2], weight);
    922.                 }        
    923.             }
    924.         }
    925.         // Debug.Log ("BuildNormalizerSolidAngleArray finished");  
    926.     }
    927.  
    928.     ///////////////////////////////////////////////
    929.     // SH order use for approximation of irradiance cubemap is 5, mean 5*5 equals 25 coefficients
    930.     // #define MAX_SH_ORDER 5
    931.     // #define NUM_SH_COEFFICIENT (MAX_SH_ORDER * MAX_SH_ORDER)
    932.  
    933.     void EvalSHBasis(Vector3 dir, ref double[] res )
    934.     {
    935.         double SqrtPi = (double)Mathf.Sqrt(CP_PI);
    936.  
    937.         double xx = dir[0];
    938.         double yy = dir[1];
    939.         double zz = dir[2];
    940.  
    941.         // x[i] == pow(x, i), etc.
    942.         // float64 x[MAX_SH_ORDER+1], y[MAX_SH_ORDER+1], z[MAX_SH_ORDER+1];
    943.         double[] x = new double[26];
    944.         double[] y = new double[26];
    945.         double[] z = new double[26];
    946.         x[0] = 1.0;
    947.         y[0] = 1.0;
    948.         z[0] = 1.0;
    949.         for (int i = 1; i < 25+1; ++i)
    950.         {
    951.             x[i] = xx * x[i-1];
    952.             y[i] = yy * y[i-1];
    953.             z[i] = zz * z[i-1];
    954.         }
    955.  
    956.         res[0]  = (1/(2.0*SqrtPi));
    957.  
    958.         res[1]  = -(Mathf.Sqrt(3/CP_PI)*yy)/2.0;
    959.         res[2]  = (Mathf.Sqrt(3/CP_PI)*zz)/2.0;
    960.         res[3]  = -(Mathf.Sqrt(3/CP_PI)*xx)/2.0;
    961.  
    962.         res[4]  = (Mathf.Sqrt(15/CP_PI)*xx*yy)/2.0;
    963.         res[5]  = -(Mathf.Sqrt(15/CP_PI)*yy*zz)/2.0;
    964.         res[6]  = (Mathf.Sqrt(5/CP_PI)*(-1 + 3*z[2]))/4.0;
    965.         res[7]  = -(Mathf.Sqrt(15/CP_PI)*xx*zz)/2.0;
    966.         res[8]  = Mathf.Sqrt(15/CP_PI)*(x[2] - y[2])/4.0;
    967.  
    968.         res[9]  = (Mathf.Sqrt(35/(2.0f*CP_PI))*(-3*x[2]*yy + y[3]))/4.0;
    969.         res[10] = (Mathf.Sqrt(105/CP_PI)*xx*yy*zz)/2.0;
    970.         res[11] = -(Mathf.Sqrt(21/(2.0f*CP_PI))*yy*(-1 + 5*z[2]))/4.0;
    971.         res[12] = (Mathf.Sqrt(7/CP_PI)*zz*(-3 + 5*z[2]))/4.0;
    972.         res[13] = -(Mathf.Sqrt(21/(2.0f*CP_PI))*xx*(-1 + 5*z[2]))/4.0;
    973.         res[14] = (Mathf.Sqrt(105/CP_PI)*(x[2] - y[2])*zz)/4.0;
    974.         res[15] = -(Mathf.Sqrt(35/(2.0f*CP_PI))*(x[3] - 3*xx*y[2]))/4.0;
    975.  
    976.         res[16] = (3*Mathf.Sqrt(35/CP_PI)*xx*yy*(x[2] - y[2]))/4.0;
    977.         res[17] = (-3*Mathf.Sqrt(35/(2.0f*CP_PI))*(3*x[2]*yy - y[3])*zz)/4.0;
    978.         res[18] = (3*Mathf.Sqrt(5/CP_PI)*xx*yy*(-1 + 7*z[2]))/4.0f;
    979.         res[19] = (-3*Mathf.Sqrt(5/(2.0f*CP_PI))*yy*zz*(-3 + 7*z[2]))/4.0;
    980.         res[20] = (3*(3 - 30*z[2] + 35*z[4]))/(16.0*SqrtPi);
    981.         res[21] = (-3*Mathf.Sqrt(5/(2.0f*CP_PI))*xx*zz*(-3+ 7*z[2]))/4.0;
    982.         res[22] = (3*Mathf.Sqrt(5/CP_PI)*(x[2] - y[2])*(-1 + 7*z[2]))/8.0;
    983.         res[23] = (-3*Mathf.Sqrt(35/(2.0f*CP_PI))*(x[3] - 3*xx*y[2])*zz)/4.0;
    984.         res[24] = (3*Mathf.Sqrt(35/CP_PI)*(x[4] - 6*x[2]*y[2] + y[4]))/16.0;
    985.     }
    986.  
    987.     // See Peter-Pike Sloan paper for these coefficients
    988.     static double[] SHBandFactor = {
    989.         1.0,
    990.         2.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0,
    991.         1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0,
    992.         0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, // The 4 band will be zeroed
    993.         - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0, - 1.0 / 24.0
    994.     };
    995.  
    996.     void FakeHDR (Cubemap CubeMap, bool hasmipLevels) {
    997.         int maxMipLevels = 1;
    998.         if (hasmipLevels) {
    999.             maxMipLevels = (int)(Mathf.Log((float)CubeMap.width, 2.0f)) + 1;
    1000.         }
    1001.         int base_Size = CubeMap.width;
    1002.         Vector4 rgbmColor = new Vector4();
    1003.  
    1004.         for (int mipLevel = 0; mipLevel < maxMipLevels; mipLevel++)
    1005.         {
    1006.             int a_Size = base_Size >> mipLevel;
    1007.             // As we use a_Size as pointer in our arrays we have to lower it by 1
    1008.             //a_Size -= 1;
    1009.  
    1010.  
    1011.             for (int a_FaceIdx = 0; a_FaceIdx < 6; a_FaceIdx++)
    1012.             {
    1013.                 // Get all pixels of the given face
    1014.                 Color[] FaceColors = CubeMap.GetPixels((CubemapFace)a_FaceIdx, mipLevel);
    1015.                 // Iterate over dst cube map face texel
    1016.                 for (int a_V  = 0; a_V < a_Size; a_V++)
    1017.                 {
    1018.                     for (int a_U = 0; a_U < a_Size; a_U++)
    1019.                     {
    1020.                         rgbmColor.x = FaceColors[a_V * a_Size + a_U].r;
    1021.                         rgbmColor.y = FaceColors[a_V * a_Size + a_U].g;
    1022.                         rgbmColor.z = FaceColors[a_V * a_Size + a_U].b;
    1023.                         rgbmColor *= 1.0f/6.0f;
    1024.                         rgbmColor.w = Mathf.Clamp01(Mathf.Max(Mathf.Max(rgbmColor.x, rgbmColor.y), rgbmColor.z));
    1025.                         rgbmColor.w = Mathf.Ceil(rgbmColor.w*255.0f) / 255.0f;
    1026.                         rgbmColor.x = rgbmColor.x / rgbmColor.w;
    1027.                         rgbmColor.y = rgbmColor.y / rgbmColor.w;
    1028.                         rgbmColor.z = rgbmColor.z / rgbmColor.w;
    1029.                         FaceColors[a_V * a_Size + a_U] = rgbmColor;
    1030.                     }
    1031.                 }
    1032.                 CubeMap.SetPixels(FaceColors,(CubemapFace)a_FaceIdx, mipLevel);
    1033.             }
    1034.         }
    1035.         CubeMap.Apply(false);
    1036.     }
    1037.  
    1038.  
    1039. }
    1040. #endif
     
  7. Cherno

    Cherno

    Joined:
    Apr 7, 2013
    Posts:
    515
    You forgot a "}" somewhere. You have to go through your whole script and check if every "{" has a "}". It's probably easier if you comment out whole functions and do it in parts. That way you can see which parts of your script are clean. If that fails, try looking for a missing ";", although that would give a different kind of error message.
     
    Last edited: Mar 13, 2015
    Schneider21 likes this.