Esempio n. 1
0
        /// <summary>
        /// Génère un modèle 3D à partir d'une heightmap.
        /// Range : [0, 1]
        /// </summary>
        /// <param name="heightmap"></param>
        /// <returns></returns>
        public static void GenerateVertexBufferWithTransformFlat(float[,] heightmap, out SlimDX.Direct3D11.Buffer vBuffer,
            out SlimDX.Direct3D11.Buffer iBuffer, Matrix transform, Vector2 initialGridPos, float gridLevelScale)
        {
            // Taille du buffer.
            int size = heightmap.GetLength(0) * heightmap.GetLength(1);

            // Création du vertex buffer contenant tous les vertex à dessiner.
            Vertex[] vertexBuffer = new Vertex[size];
            Noise.RidgedMultifractalNoise noise = new Noise.RidgedMultifractalNoise()
            {
                Frequency = 0.00400f,
                Lacunarity = 2.4f,
                OctaveCount = 2,
                Persistence = 0.9f,
                Quality = Noise.NoiseBase.NoiseQuality.QUALITY_FAST,
                Seed = 56549970
            };

            for (int y = 0; y < heightmap.GetLength(1); y++)
            {
                for (int x = 0; x < heightmap.GetLength(0); x++)
                {
                    Vector2 pos2D = new Vector2(x / ((float)heightmap.GetLength(0) - 1),
                                    (y / ((float)heightmap.GetLength(1) - 1)));

                    Vector4 pos = Vector4.Transform(new Vector4(pos2D.X, pos2D.Y, heightmap[x, y], 1.0f), transform);

                    vertexBuffer[(x + y * heightmap.GetLength(0))].Position = pos;
                    vertexBuffer[(x + y * heightmap.GetLength(0))].Texture = new Vector2(pos.X, pos.Y);
                    float texGen = noise.GetValue(pos.X, pos.Y, 0);
                    vertexBuffer[(x + y * heightmap.GetLength(0))].TextureId = texGen;

                }

            }
            //Thread.Sleep(1);
            // Index buffer contenant l'ordre dans lequel dessiner les vertex. (sous forme de carrés).
            int iBufferSize = (heightmap.GetLength(0) - 1) * (heightmap.GetLength(1) - 1) * 6;
            int[] indexBuffer = new int[iBufferSize];
            int sizeX = heightmap.GetLength(0);
            int sizeY = heightmap.GetLength(1);
            int startIndex = 0;
            for (int x = 0; x < sizeX - 1; x++)
            {
                for (int y = 0; y < sizeY - 1; y++)
                {
                    int firstIndex = x + y * (sizeX);
                    int topLeft = firstIndex;
                    int topRight = firstIndex + 1;
                    int lowerLeft = topLeft + sizeX;
                    int lowerRight = lowerLeft + 1;
                    // Triangle 1 (up right)
                    indexBuffer[startIndex++] = topLeft;
                    indexBuffer[startIndex++] = lowerRight;
                    indexBuffer[startIndex++] = lowerLeft;

                    // Triangle 2 (bottom left)
                    indexBuffer[startIndex++] = topLeft;
                    indexBuffer[startIndex++] = topRight;
                    indexBuffer[startIndex++] = lowerRight;
                }
            }
            //Thread.Sleep(1);
            // Calcule les normales aux surfaces.
            // Merci Riemer's XNA Tutorial :D
            for (int i = 0; i < vertexBuffer.Length; i++)
                vertexBuffer[i].Normal = new Vector4(0, 0, 0, 0);
            //Thread.Sleep(1);
            for (int i = 0; i < indexBuffer.Length / 3; i++)
            {
                Vector4 firstvec = vertexBuffer[indexBuffer[i * 3 + 1]].Position - vertexBuffer[indexBuffer[i * 3]].Position;
                Vector4 secondvec = vertexBuffer[indexBuffer[i * 3]].Position - vertexBuffer[indexBuffer[i * 3 + 2]].Position;
                Vector4 normal = new Vector4(Vector3.Cross(
                    new Vector3(firstvec.X, firstvec.Y, firstvec.Z),
                    new Vector3(secondvec.X, secondvec.Y, secondvec.Z)), 1.0f);
                normal.Normalize();
                vertexBuffer[indexBuffer[(i * 3)]].Normal += normal;
                vertexBuffer[indexBuffer[(i * 3 + 1)]].Normal += normal;
                vertexBuffer[indexBuffer[(i * 3 + 2)]].Normal += normal;
            }
            //Thread.Sleep(1);
            for (int i = 0; i < vertexBuffer.Length; i++)
            {
                vertexBuffer[i].Normal.Z = vertexBuffer[i].Normal.Z;

                var v = Util.MathHelper.ReduceXYZ(vertexBuffer[i].Normal);
                v.Normalize();
                vertexBuffer[i].Normal = new Vector4(v, 1.0f);

            }
            //Thread.Sleep(1);

            DataStream vBuffStream = new DataStream(size * Vertex.Stride, true, true);
            vBuffStream.WriteRange<Vertex>(vertexBuffer);
            vBuffStream.Position = 0;
            //Thread.Sleep(1);
            DataStream iBuffStream = new DataStream(iBufferSize * sizeof(int), true, true);
            iBuffStream.WriteRange<int>(indexBuffer);
            iBuffStream.Position = 0;
            //Thread.Sleep(1);
            vBuffer = new SlimDX.Direct3D11.Buffer(Scene.GetGraphicsDevice(), vBuffStream, new BufferDescription()
            {
                BindFlags = BindFlags.VertexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None,
                SizeInBytes = (int)vBuffStream.Length,
                Usage = ResourceUsage.Default
            });

            iBuffer = new SlimDX.Direct3D11.Buffer(Scene.GetGraphicsDevice(), iBuffStream, new BufferDescription()
            {
                BindFlags = BindFlags.IndexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None,
                SizeInBytes = (int)iBuffStream.Length,
                Usage = ResourceUsage.Default
            });

            vBuffStream.Dispose();
            iBuffStream.Dispose();
        }
Esempio n. 2
0
        /// <summary>
        /// Génère un modèle 3D à partir d'une heightmap.
        /// Range : [0, 1]
        /// </summary>
        /// <param name="heightmap"></param>
        /// <returns></returns>
        public static void GenerateVertexBufferWithTransformFlat(float[,] heightmap, out SlimDX.Direct3D11.Buffer vBuffer,
                                                                 out SlimDX.Direct3D11.Buffer iBuffer, Matrix transform, Vector2 initialGridPos, float gridLevelScale)
        {
            // Taille du buffer.
            int size = heightmap.GetLength(0) * heightmap.GetLength(1);


            // Création du vertex buffer contenant tous les vertex à dessiner.
            Vertex[] vertexBuffer = new Vertex[size];
            Noise.RidgedMultifractalNoise noise = new Noise.RidgedMultifractalNoise()
            {
                Frequency   = 0.00400f,
                Lacunarity  = 2.4f,
                OctaveCount = 2,
                Persistence = 0.9f,
                Quality     = Noise.NoiseBase.NoiseQuality.QUALITY_FAST,
                Seed        = 56549970
            };

            for (int y = 0; y < heightmap.GetLength(1); y++)
            {
                for (int x = 0; x < heightmap.GetLength(0); x++)
                {
                    Vector2 pos2D = new Vector2(x / ((float)heightmap.GetLength(0) - 1),
                                                (y / ((float)heightmap.GetLength(1) - 1)));


                    Vector4 pos = Vector4.Transform(new Vector4(pos2D.X, pos2D.Y, heightmap[x, y], 1.0f), transform);



                    vertexBuffer[(x + y * heightmap.GetLength(0))].Position = pos;
                    vertexBuffer[(x + y * heightmap.GetLength(0))].Texture  = new Vector2(pos.X, pos.Y);
                    float texGen = noise.GetValue(pos.X, pos.Y, 0);
                    vertexBuffer[(x + y * heightmap.GetLength(0))].TextureId = texGen;
                }
            }
            //Thread.Sleep(1);
            // Index buffer contenant l'ordre dans lequel dessiner les vertex. (sous forme de carrés).
            int iBufferSize = (heightmap.GetLength(0) - 1) * (heightmap.GetLength(1) - 1) * 6;

            int[] indexBuffer = new int[iBufferSize];
            int   sizeX       = heightmap.GetLength(0);
            int   sizeY       = heightmap.GetLength(1);
            int   startIndex  = 0;

            for (int x = 0; x < sizeX - 1; x++)
            {
                for (int y = 0; y < sizeY - 1; y++)
                {
                    int firstIndex = x + y * (sizeX);
                    int topLeft    = firstIndex;
                    int topRight   = firstIndex + 1;
                    int lowerLeft  = topLeft + sizeX;
                    int lowerRight = lowerLeft + 1;
                    // Triangle 1 (up right)
                    indexBuffer[startIndex++] = topLeft;
                    indexBuffer[startIndex++] = lowerRight;
                    indexBuffer[startIndex++] = lowerLeft;

                    // Triangle 2 (bottom left)
                    indexBuffer[startIndex++] = topLeft;
                    indexBuffer[startIndex++] = topRight;
                    indexBuffer[startIndex++] = lowerRight;
                }
            }
            //Thread.Sleep(1);
            // Calcule les normales aux surfaces.
            // Merci Riemer's XNA Tutorial :D
            for (int i = 0; i < vertexBuffer.Length; i++)
            {
                vertexBuffer[i].Normal = new Vector4(0, 0, 0, 0);
            }
            //Thread.Sleep(1);
            for (int i = 0; i < indexBuffer.Length / 3; i++)
            {
                Vector4 firstvec  = vertexBuffer[indexBuffer[i * 3 + 1]].Position - vertexBuffer[indexBuffer[i * 3]].Position;
                Vector4 secondvec = vertexBuffer[indexBuffer[i * 3]].Position - vertexBuffer[indexBuffer[i * 3 + 2]].Position;
                Vector4 normal    = new Vector4(Vector3.Cross(
                                                    new Vector3(firstvec.X, firstvec.Y, firstvec.Z),
                                                    new Vector3(secondvec.X, secondvec.Y, secondvec.Z)), 1.0f);
                normal.Normalize();
                vertexBuffer[indexBuffer[(i * 3)]].Normal     += normal;
                vertexBuffer[indexBuffer[(i * 3 + 1)]].Normal += normal;
                vertexBuffer[indexBuffer[(i * 3 + 2)]].Normal += normal;
            }
            //Thread.Sleep(1);
            for (int i = 0; i < vertexBuffer.Length; i++)
            {
                vertexBuffer[i].Normal.Z = vertexBuffer[i].Normal.Z;

                var v = Util.MathHelper.ReduceXYZ(vertexBuffer[i].Normal);
                v.Normalize();
                vertexBuffer[i].Normal = new Vector4(v, 1.0f);
            }
            //Thread.Sleep(1);


            DataStream vBuffStream = new DataStream(size * Vertex.Stride, true, true);

            vBuffStream.WriteRange <Vertex>(vertexBuffer);
            vBuffStream.Position = 0;
            //Thread.Sleep(1);
            DataStream iBuffStream = new DataStream(iBufferSize * sizeof(int), true, true);

            iBuffStream.WriteRange <int>(indexBuffer);
            iBuffStream.Position = 0;
            //Thread.Sleep(1);
            vBuffer = new SlimDX.Direct3D11.Buffer(Scene.GetGraphicsDevice(), vBuffStream, new BufferDescription()
            {
                BindFlags      = BindFlags.VertexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags    = ResourceOptionFlags.None,
                SizeInBytes    = (int)vBuffStream.Length,
                Usage          = ResourceUsage.Default
            });

            iBuffer = new SlimDX.Direct3D11.Buffer(Scene.GetGraphicsDevice(), iBuffStream, new BufferDescription()
            {
                BindFlags      = BindFlags.IndexBuffer,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags    = ResourceOptionFlags.None,
                SizeInBytes    = (int)iBuffStream.Length,
                Usage          = ResourceUsage.Default
            });

            vBuffStream.Dispose();
            iBuffStream.Dispose();
        }