public NormalMappedWall(GraphicsDevice graphicsDevice, Vector3 corner1, Vector3 corner2,
            Vector3 corner3, Vector3 corner4, Vector3 normal)
        {
            Vector3[] wallCorners = new Vector3[4];
            wallCorners[0] = corner1;//near left
            wallCorners[1] = corner2;//near  right
            wallCorners[2] = corner3;//far right
            wallCorners[3] = corner4;//far left
            float size = Vector3.Distance(corner1, corner3);
            size /= 100;
            Vector2[] wallTexCoords =
            {
                new Vector2(0.0f, 0.0f),                            // top left corner
                new Vector2(GameConstants.FLOOR_TILE_FACTOR_NORMAL*size, 0.0f),               // top right corner
                new Vector2(GameConstants.FLOOR_TILE_FACTOR_NORMAL*size, GameConstants.FLOOR_TILE_FACTOR_NORMAL*size),  // bottom right corner
                new Vector2(0.0f, GameConstants.FLOOR_TILE_FACTOR_NORMAL*size)                // bottom left corner
            };

            int offset = 0;
            vertices = new NormalMappedVertex[6];
            vertices[offset++] = new NormalMappedVertex(wallCorners[3], wallTexCoords[0], Vector3.Up, Vector4.Zero);//btm left
            vertices[offset++] = new NormalMappedVertex(wallCorners[2], wallTexCoords[1], Vector3.Up, Vector4.Zero);//btm rigth
            vertices[offset++] = new NormalMappedVertex(wallCorners[1], wallTexCoords[2], Vector3.Up, Vector4.Zero);//top right
            vertices[offset++] = new NormalMappedVertex(wallCorners[1], wallTexCoords[2], Vector3.Up, Vector4.Zero);//top right
            vertices[offset++] = new NormalMappedVertex(wallCorners[0], wallTexCoords[3], Vector3.Up, Vector4.Zero);//top left
            vertices[offset++] = new NormalMappedVertex(wallCorners[3], wallTexCoords[0], Vector3.Up, Vector4.Zero);//btm left

            CalcTangent(graphicsDevice);
        }
        private void GenerateRoomGeometry(float floorSize,float wallHeight,
            float floorTileFactor,float ceilingTileFactor,
            float wallTileFactorX,float wallTileFactorY)
        {
            #region wrapyourbrainarroundthis
            /* 5--------6
             * |\      /|
             * | 4----7 |
             * | |    | |
             * | |    | |
             * | 0----3 |
             * |/      \|
             * 1--------2
             *
             * +z wall: 6512 tri1: 651 tri2: 126
             * -z wall: 4730 tri1: 473 tri2: 304
             * +x wall: 7623 tri1: 762 tri2: 237
             * -x wall: 5401 tri1: 540 tri2: 015
             *
             * +y ceiling: 5674 tri1: 567 tri2: 745
             * -y floor:   0321 tri1: 032 tri2: 210
             */
            #endregion

            int offset = 0;
            float halfSize = floorSize * 0.5f;
               #region vertexcoords
            Vector3[] corners =
            {
                new Vector3(-halfSize, 0.0f, -halfSize),            // 0
                new Vector3(-halfSize, 0.0f,  halfSize),            // 1
                new Vector3( halfSize, 0.0f,  halfSize),            // 2
                new Vector3( halfSize, 0.0f, -halfSize),            // 3

                new Vector3(-halfSize, wallHeight, -halfSize),      // 4
                new Vector3(-halfSize, wallHeight,  halfSize),      // 5
                new Vector3( halfSize, wallHeight,  halfSize),      // 6
                new Vector3( halfSize, wallHeight, -halfSize),      // 7
            };

            Vector2[] wallTexCoords =
            {
                new Vector2(0.0f, 0.0f),                            // top left corner
                new Vector2(wallTileFactorX, 0.0f),                 // top right corner
                new Vector2(wallTileFactorX, wallTileFactorY),      // bottom right corner
                new Vector2(0.0f, wallTileFactorY)                  // bottom left corner
            };

            Vector2[] floorTexCoords =
            {
                new Vector2(0.0f, 0.0f),                            // top left corner
                new Vector2(floorTileFactor, 0.0f),                 // top right corner
                new Vector2(floorTileFactor, floorTileFactor),      // bottom right corner
                new Vector2(0.0f, floorTileFactor)                  // bottom left corner
            };

            Vector2[] ceilingTexCoords =
            {
                new Vector2(0.0f, 0.0f),                            // top left corner
                new Vector2(ceilingTileFactor, 0.0f),               // top right corner
                new Vector2(ceilingTileFactor, ceilingTileFactor),  // bottom right corner
                new Vector2(0.0f, ceilingTileFactor)                // bottom left corner
            };
            #endregion
            wallsIndex = offset;

            // -z wall: 4730 tri1: 473 tri2: 304
            vertices[offset++] = new NormalMappedVertex(corners[4], wallTexCoords[0], Vector3.Backward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[7], wallTexCoords[1], Vector3.Backward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[3], wallTexCoords[2], Vector3.Backward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[3], wallTexCoords[2], Vector3.Backward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[0], wallTexCoords[3], Vector3.Backward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[4], wallTexCoords[0], Vector3.Backward, Vector4.Zero);

            // +z wall: 6512 tri1: 651 tri2: 126
            vertices[offset++] = new NormalMappedVertex(corners[6], wallTexCoords[0], Vector3.Forward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[5], wallTexCoords[1], Vector3.Forward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[1], wallTexCoords[2], Vector3.Forward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[1], wallTexCoords[2], Vector3.Forward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[2], wallTexCoords[3], Vector3.Forward, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[6], wallTexCoords[0], Vector3.Forward, Vector4.Zero);

            // -x wall: 5401 tri1: 540 tri2: 015
            vertices[offset++] = new NormalMappedVertex(corners[5], wallTexCoords[0], Vector3.Right, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[4], wallTexCoords[1], Vector3.Right, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[0], wallTexCoords[2], Vector3.Right, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[0], wallTexCoords[2], Vector3.Right, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[1], wallTexCoords[3], Vector3.Right, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[5], wallTexCoords[0], Vector3.Right, Vector4.Zero);

            // +x wall: 7623 tri1: 762 tri2: 237
            vertices[offset++] = new NormalMappedVertex(corners[7], wallTexCoords[0], Vector3.Left, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[6], wallTexCoords[1], Vector3.Left, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[2], wallTexCoords[2], Vector3.Left, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[2], wallTexCoords[2], Vector3.Left, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[3], wallTexCoords[3], Vector3.Left, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[7], wallTexCoords[0], Vector3.Left, Vector4.Zero);

            // +y ceiling: 5674 tri1: 567 tri2: 745
            ceilingIndex = offset;
            vertices[offset++] = new NormalMappedVertex(corners[5], ceilingTexCoords[0], Vector3.Down, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[6], ceilingTexCoords[1], Vector3.Down, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[7], ceilingTexCoords[2], Vector3.Down, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[7], ceilingTexCoords[2], Vector3.Down, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[4], ceilingTexCoords[3], Vector3.Down, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[5], ceilingTexCoords[0], Vector3.Down, Vector4.Zero);

            //// -y floor: 0321 tri1: 032 tri2: 210
            floorIndex = offset;
            vertices[offset++] = new NormalMappedVertex(corners[0], floorTexCoords[0], Vector3.Up, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[3], floorTexCoords[1], Vector3.Up, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[2], floorTexCoords[2], Vector3.Up, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[2], floorTexCoords[2], Vector3.Up, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[1], floorTexCoords[3], Vector3.Up, Vector4.Zero);
            vertices[offset++] = new NormalMappedVertex(corners[0], floorTexCoords[0], Vector3.Up, Vector4.Zero);
        }
        /// <summary>
        /// Generates a wall from the starting position, using the innVector
        /// as the normal of the surface and doing the wall perpendicularly 
        /// towards the length
        /// </summary>
        /// <param name="startPos"></param>
        /// <param name="innVec">The normal of the wall. If the wall should point up positive
        /// z axis, 90 degrees on the x axis, the vector would be (0, 0, 1)</param>
        /// <param name="lenght"></param>
        private void GenerateWall(Vector3 startPos, Vector3 endPos, Vector3 innVec, 
            float height, GraphicsDevice graphicsDevice)
        {
            float length = Vector3.Distance(startPos, endPos);
            length /= 100;
            Vector2[] wallTexCoords =
            {
                new Vector2(0.0f, 0.0f),                                        // top left corner
                new Vector2(GameConstants.WallTileFactorNormalX*length, 0.0f),         // top right corner
                new Vector2(GameConstants.WallTileFactorNormalX*length, GameConstants.WallTileFactorNormalY),// bottom right corner
                new Vector2(0.0f, GameConstants.WallTileFactorNormalY)          // bottom left corner
            };

            int offset = 0;
            vertices = new NormalMappedVertex[6];

            Vector3[] wallCorners = new Vector3[4];
            wallCorners[0] = startPos; //Starting point, bottom left corner when facing wall
            wallCorners[1] = endPos; //Bottom right corner when facing wall
            wallCorners[2] = new Vector3(endPos.X, height, endPos.Z);//top right
            wallCorners[3] = new Vector3(startPos.X, height, startPos.Z);//top left
            vertices[offset++] = new NormalMappedVertex(wallCorners[0], wallTexCoords[0], innVec, Vector4.Zero);//btm left
            vertices[offset++] = new NormalMappedVertex(wallCorners[1], wallTexCoords[1], innVec, Vector4.Zero);//btm rigth
            vertices[offset++] = new NormalMappedVertex(wallCorners[2], wallTexCoords[2], innVec, Vector4.Zero);//top right
            vertices[offset++] = new NormalMappedVertex(wallCorners[2], wallTexCoords[2], innVec, Vector4.Zero);//top right
            vertices[offset++] = new NormalMappedVertex(wallCorners[3], wallTexCoords[3], innVec, Vector4.Zero);//top left
            vertices[offset++] = new NormalMappedVertex(wallCorners[0], wallTexCoords[0], innVec, Vector4.Zero);//btm left

            CalcTangent(graphicsDevice);
        }
        /// <summary>
        /// Generates a ceiling from the 4 given corners
        /// </summary>
        /// <param name="graphicsDevice"></param>
        /// <param name="corner1"></param>
        /// <param name="corner2"></param>
        /// <param name="corner3"></param>
        /// <param name="corner4"></param>
        /// <param name="normal"></param>
        private void GenerateCeiling(GraphicsDevice graphicsDevice, Vector3 corner1, Vector3 corner2,
            Vector3 corner3, Vector3 corner4, Vector3 normal)
        {
            Vector3[] wallCorners = new Vector3[4];
            wallCorners[0] = corner1;//near left
            wallCorners[1] = corner2;//near  right
            wallCorners[2] = corner3;//far right
            wallCorners[3] = corner4;//far left
            float size = Vector3.Distance(corner1, corner3);
            size /= 100;
            Vector2[] wallTexCoords =
            {
                new Vector2(0.0f, 0.0f),                            // top left corner
                new Vector2(GameConstants.FLOOR_TILE_FACTOR_NORMAL*size, 0.0f),               // top right corner
                new Vector2(GameConstants.FLOOR_TILE_FACTOR_NORMAL*size, GameConstants.FLOOR_TILE_FACTOR_NORMAL*size),  // bottom right corner
                new Vector2(0.0f, GameConstants.FLOOR_TILE_FACTOR_NORMAL*size)                // bottom left corner
            };

            int offset = 0;
            vertices = new NormalMappedVertex[6];
            vertices[offset++] = new NormalMappedVertex(wallCorners[0], wallTexCoords[0], normal, Vector4.Zero);//btm left
            vertices[offset++] = new NormalMappedVertex(wallCorners[1], wallTexCoords[1], normal, Vector4.Zero);//btm rigth
            vertices[offset++] = new NormalMappedVertex(wallCorners[2], wallTexCoords[2], normal, Vector4.Zero);//top right
            vertices[offset++] = new NormalMappedVertex(wallCorners[2], wallTexCoords[2], normal, Vector4.Zero);//top right
            vertices[offset++] = new NormalMappedVertex(wallCorners[3], wallTexCoords[3], normal, Vector4.Zero);//top left
            vertices[offset++] = new NormalMappedVertex(wallCorners[0], wallTexCoords[0], normal, Vector4.Zero);//btm left

            Vector4 tangent;

            for (int i = 0; i < vertices.Length; i += 3)
            {
                NormalMappedVertex.CalcTangent(
                    ref vertices[i].Position,
                    ref vertices[i + 1].Position,
                    ref vertices[i + 2].Position,
                    ref vertices[i].TexCoord,
                    ref vertices[i + 1].TexCoord,
                    ref vertices[i + 2].TexCoord,
                    ref vertices[i].Normal,
                    out tangent);

                vertices[i].Tangent = tangent;
                vertices[i + 1].Tangent = tangent;
                vertices[i + 2].Tangent = tangent;
            }

            vertexBuffer = new VertexBuffer(graphicsDevice, typeof(NormalMappedVertex),
                vertices.Length, BufferUsage.WriteOnly);
            vertexBuffer.SetData(vertices);
        }