/// <summary>
        /// Create plane renderer
        /// </summary>
        /// <param name="setPos">Set position</param>
        /// <param name="setPlane">Set plane</param>
        /// <param name="setMaterial">Set material</param>
        /// <param name="setSize">Set size</param>
        public PlaneRenderer(Vector3 setPos,
			Plane setPlane, Material setMaterial, float setSize)
        {
            pos = setPos;
            plane = setPlane;
            material = setMaterial;
            size = setSize;
        }
        /// <summary>
        /// Load car stuff
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();

            // Load car model
            carModel = new Model("SpeedyRacer");

            // Load landscape
            landscape = new Landscape();

            // Load extra textures
            brakeTrackMaterial = new Material("track");
        }
        /// <summary>
        /// Render
        /// </summary>
        public void Render(Material columnMaterial)
        {
            // We use tangent vertices for everything here
            BaseGame.Device.VertexDeclaration = TangentVertex.VertexDeclaration;
            // Restore the world matrix
            BaseGame.WorldMatrix = Matrix.Identity;

            // Render all columns
            ShaderEffect.normalMapping.Render(
                columnMaterial,
                "Specular20",
                new BaseGame.RenderHandler(RenderColumnVertices));

            // Restore the world matrix
            BaseGame.WorldMatrix = Matrix.Identity;
        }
        /// <summary>
        /// Set parameters, this overload sets all material parameters too.
        /// </summary>
        public virtual void SetParametersOptimized(Material setMat)
        {
            if (setMat == null)
                throw new ArgumentNullException("setMat");

            // No need to set world matrix, will be done later in mesh rendering
            // in the MeshRenderManager. All the rest is set with help of the
            // SetParametersOptimizedGeneral above.

            // Only update ambient, diffuse, specular and the textures, the rest
            // will not change for a material change in MeshRenderManager.
            ambientColor.SetValue(setMat.ambientColor.ToVector4());
            diffuseColor.SetValue(setMat.diffuseColor.ToVector4());
            specularColor.SetValue(setMat.specularColor.ToVector4());
            if (setMat.diffuseTexture != null)
                diffuseTexture.SetValue(setMat.diffuseTexture.XnaTexture);
            if (setMat.normalTexture != null)
                normalTexture.SetValue(setMat.normalTexture.XnaTexture);
        }
        /// <summary>
        /// Render
        /// </summary>
        /// <param name="setMat">Set matrix</param>
        /// <param name="passName">Pass name</param>
        /// <param name="renderDelegate">Render delegate</param>
        public void Render(Material setMat,
			string techniqueName,
			BaseGame.RenderHandler renderCode)
        {
            if (techniqueName == null)
                throw new ArgumentNullException("techniqueName");
            if (renderCode == null)
                throw new ArgumentNullException("renderCode");

            SetParameters(setMat);

            // Can we do the requested technique?
            // For graphic cards not supporting ps2.0, fall back to ps1.1
            if (BaseGame.CanUsePS20 == false &&
                techniqueName.EndsWith("20"))
                // Use same technique without the 20 ending!
                techniqueName = techniqueName.Substring(0, techniqueName.Length - 2);

            // Start shader
            effect.CurrentTechnique = effect.Techniques[techniqueName];
            try
            {
                effect.Begin(SaveStateMode.None);

                // Render all passes (usually just one)
                //foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                for (int num = 0; num < effect.CurrentTechnique.Passes.Count; num++)
                {
                    EffectPass pass = effect.CurrentTechnique.Passes[num];

                    pass.Begin();
                    renderCode();
                    pass.End();
                } // foreach (pass)
            } // try
            finally
            {
                // End shader
                effect.End();
            } // finally
        }
        /// <summary>
        /// Set parameters, this overload sets all material parameters too.
        /// </summary>
        public virtual void SetParameters(Material setMat)
        {
            if (worldViewProj != null)
                worldViewProj.SetValue(BaseGame.WorldViewProjectionMatrix);
            if (viewProj != null)
                viewProj.SetValue(BaseGame.ViewProjectionMatrix);
            if (world != null)
                world.SetValue(BaseGame.WorldMatrix);
            if (viewInverse != null)
                viewInverse.SetValue(BaseGame.InverseViewMatrix);
            if (lightDir != null)
                lightDir.SetValue(BaseGame.LightDirection);

            // Set the reflection cube texture only once
            if (lastUsedReflectionCubeTexture == null &&
                reflectionCubeTexture != null)
            {
                ReflectionCubeTexture = BaseGame.UI.SkyCubeMapTexture;
            } // if (lastUsedReflectionCubeTexture)

            // Set all material properties
            if (setMat != null)
            {
                AmbientColor = setMat.ambientColor;
                DiffuseColor = setMat.diffuseColor;
                SpecularColor = setMat.specularColor;
                SpecularPower = setMat.specularPower;
                DiffuseTexture = setMat.diffuseTexture;
                NormalTexture = setMat.normalTexture;
                HeightTexture = setMat.heightTexture;
                ParallaxAmount = setMat.parallaxAmount;
                DetailTexture = setMat.detailTexture;
            } // if (setMat)
        }
        /// <summary>
        /// Add model mesh part with the used effect to our sortedMeshes list.
        /// Neither the model mesh part nor the effect is directly used,
        /// we will extract all data from the model and only render the
        /// index and vertex buffers later.
        /// The model mesh part must use the TangentVertex format.
        /// </summary>
        /// <param name="vertexBuffer">Vertex buffer</param>
        /// <param name="indexBuffer">Index buffer</param>
        /// <param name="part">Part</param>
        /// <param name="effect">Effect</param>
        /// <returns>Renderable mesh</returns>
        public RenderableMesh Add(VertexBuffer vertexBuffer,
			IndexBuffer indexBuffer, ModelMeshPart part, Effect effect)
        {
            string techniqueName = effect.CurrentTechnique.Name;

            // Does this technique already exists?
            MeshesPerMaterialPerTechniques foundList = null;
            for (int listNum = 0; listNum < sortedMeshes.Count; listNum++)
            {
                MeshesPerMaterialPerTechniques list = sortedMeshes[listNum];

                if (list.technique.Name == techniqueName)
                {
                    foundList = list;
                    break;
                } // if (list.technique.Name)
            } // for (listNum)

            // Did not found list? Create new one
            if (foundList == null)
            {
                foundList = new MeshesPerMaterialPerTechniques(
                    ShaderEffect.normalMapping.GetTechnique(techniqueName));
                sortedMeshes.Add(foundList);
            } // if (foundList)

            // Create new material from the current effect parameters.
            // This will create duplicate materials if the same material is used
            // multiple times, we check this later.
            Material material = new Material(effect);

            // Search for material inside foundList.
            for (int innerListNum = 0; innerListNum <
                foundList.meshesPerMaterials.Count; innerListNum++)
            {
                MeshesPerMaterial innerList =
                    foundList.meshesPerMaterials[innerListNum];

                // Check if this is the same material and we can use it instead.
                // For our purposes it is sufficiant if we check textures and colors.
                if (innerList.material.diffuseTexture == material.diffuseTexture &&
                    innerList.material.normalTexture == material.normalTexture &&
                    innerList.material.ambientColor == material.ambientColor &&
                    innerList.material.diffuseColor == material.diffuseColor &&
                    innerList.material.specularColor == material.specularColor &&
                    innerList.material.specularPower == material.specularPower)
                {
                    // Reuse this material and quit this search
                    material = innerList.material;
                    break;
                } // if (innerList.material.diffuseTexture)
            } // foreach (innerList)

            // Build new RenderableMesh object
            RenderableMesh mesh = new RenderableMesh(
                vertexBuffer, indexBuffer, material, foundList.technique,
                ShaderEffect.normalMapping.WorldParameter,
                part.VertexDeclaration,
                part.StreamOffset, part.VertexStride, part.BaseVertex,
                part.NumVertices, part.StartIndex, part.PrimitiveCount);
            foundList.Add(mesh);
            return mesh;
        }
            /// <summary>
            /// Create renderable mesh
            /// </summary>
            /// <param name="setVertexBuffer">Set vertex buffer</param>
            /// <param name="setIndexBuffer">Set index buffer</param>
            /// <param name="setMaterial">Set material</param>
            /// <param name="setUsedTechnique">Set used technique</param>
            /// <param name="setWorldParameter">Set world parameter</param>
            /// <param name="setVertexDeclaration">Set vertex declaration</param>
            /// <param name="setStreamOffset">Set stream offset</param>
            /// <param name="setVertexStride">Set vertex stride</param>
            /// <param name="setBaseVertex">Set base vertex</param>
            /// <param name="setNumVertices">Set number vertices</param>
            /// <param name="setStartIndex">Set start index</param>
            /// <param name="setPrimitiveCount">Set primitive count</param>
            public RenderableMesh(VertexBuffer setVertexBuffer,
				IndexBuffer setIndexBuffer, Material setMaterial,
				EffectTechnique setUsedTechnique, EffectParameter setWorldParameter,
				VertexDeclaration setVertexDeclaration,
				int setStreamOffset, int setVertexStride, int setBaseVertex,
				int setNumVertices, int setStartIndex, int setPrimitiveCount)
            {
                vertexBuffer = setVertexBuffer;
                indexBuffer = setIndexBuffer;
                material = setMaterial;
                usedTechnique = setUsedTechnique;
                worldParameter = setWorldParameter;
                vertexDeclaration = setVertexDeclaration;
                streamOffset = setStreamOffset;
                vertexStride = setVertexStride;
                baseVertex = setBaseVertex;
                numVertices = setNumVertices;
                startIndex = setStartIndex;
                primitiveCount = setPrimitiveCount;
            }
 /// <summary>
 /// Create meshes per material for the setMaterial.
 /// </summary>
 /// <param name="setMaterial">Set material</param>
 public MeshesPerMaterial(Material setMaterial)
 {
     material = setMaterial;
 }
        /// <summary>
        /// Render
        /// </summary>
        public void Render(Material guardRailMaterial)
        {
            // We use tangent vertices for everything here
            BaseGame.Device.VertexDeclaration = TangentVertex.VertexDeclaration;
            // Restore the world matrix
            BaseGame.WorldMatrix = Matrix.Identity;

            // Render the complete guardrail
            ShaderEffect.normalMapping.Render(
                guardRailMaterial,
                "Specular20",
                new BaseGame.RenderHandler(RenderGuardRailVertices));

            /*done in track class
            // And also render all the holder piles
            foreach (Matrix mat in holderPileMatrices)
            {
                holderModel.Render(mat);
            } // foreach if (Vector3.DistanceSquared)
             */

            // Restore the world matrix
            BaseGame.WorldMatrix = Matrix.Identity;
        }
        /// <summary>
        /// Update parameters
        /// </summary>
        public override void SetParameters(Material setMat)
        {
            // Can't set parameters if loading failed!
            if (effect == null)
                return;

            // If we are in menu mode, use different values for the shader
            // than in the game!
            if (SpeedyRacerManager.InMenu)
            {
                shadowNearPlane = 1.0f;
                shadowFarPlane = 28;
                virtualLightDistance = 24;
                virtualVisibleRange = 23.5f;
                if (BaseGame.CanUsePS20)
                {
                    compareDepthBias = 0.00075f;//0.00025f;
                    shadowMapDepthBiasValue = 0.00075f;//0.00025f;
                } // if (BaseGame.CanUsePS20)
                else
                {
                    // Ps 1.1 isn't as percise!
                    compareDepthBias = 0.0025f;
                    shadowMapDepthBiasValue = 0.002f;
                } // else
            } // if (SpeedyRacerManager.InMenu)
            else
            {
                shadowNearPlane = 1.0f;
                shadowFarPlane = 6.25f * 28 * 1.25f;
                virtualLightDistance = 5.5f * 24 * 1.3f;
                virtualVisibleRange = 5.5f * 23.5f;

                if (BaseGame.CanUsePS20)
                {
                    compareDepthBias = 0.00085f;//0.00025f;
                    shadowMapDepthBiasValue = 0.00085f;// 0.00025f;
                } // if (BaseGame.CanUsePS20)
                else
                {
                    // Ps 1.1 isn't as percise!
                    shadowFarPlane = 4.75f*28;
                    virtualLightDistance = 4.0f*24;
                    virtualVisibleRange = 4.0f*23.5f;
                    compareDepthBias = 0.0065f;//0.0045f;//0.0025f;
                    shadowMapDepthBiasValue = 0.0035f;//0.0025f;
                } // else
            } // else
            #if XBOX360
            // Make it a little more percise on the box.
            compareDepthBias = 0.00065f;//0.00025f;
            shadowMapDepthBiasValue = 0.00065f;// 0.00025f;
            #endif

            base.SetParameters(setMat);

            // Set all extra parameters for this shader
            depthBias.SetValue(compareDepthBias);
            shadowMapDepthBias.SetValue(shadowMapDepthBiasValue);
            shadowMapTexelSize.SetValue(
                new Vector2(texelWidth, texelHeight));
            nearPlane.SetValue(shadowNearPlane);
            farPlane.SetValue(shadowFarPlane);
        }