Exemple #1
0
        public void rotate(float angle)
        {
            heading = Vector4.Transform(heading, Matrix4.CreateRotationZ(angle));
            heading.Normalize();
            transformation = Matrix4.CreateRotationZ(angle) * transformation;

            notifyCameras();
        }
        private List<ISectData> TestHitTest(int X, int Y)
        {
            String mess = "";
            mess = "Screen X,Y = (" + X.ToString() + "," + Y.ToString() + ")\r\n";

            /*
            (Note that most window systems place the mouse coordinate origin in the upper left of the window instead of the lower left.
            That's why window_y is calculated the way it is in the above code. When using a glViewport() that doesn't match the window height,
            the viewport height and viewport Y are used to determine the values for window_y and norm_y.)

            The variables norm_x and norm_y are scaled between -1.0 and 1.0. Use them to find the mouse location on your zNear clipping plane like so:

            float y = near_height * norm_y;
            float x = near_height * aspect * norm_x;
            Now your pick ray vector is (x, y, -zNear).
             */
            int w = glControl1.Width;
            int h = glControl1.Height;
            mess += "Screen Width/Height = " + w.ToString() + "," + h.ToString() + "\r\n";
            float aspect = ((float)glControl1.Width) / ((float)glControl1.Height);
            //mess += "Screen Aspect = " + aspect.ToString() + "\r\n";

            int window_y = (h - Y) - h/2;
            double norm_y = (double)(window_y)/(double)(h/2);
            int window_x = X - w/2;
            double norm_x = (double)(window_x)/(double)(w/2);
            float near_height = .2825f; // no detectable error

            float y = (float)(near_height * norm_y);
            float x = (float)(near_height * aspect * norm_x);

            /*
            To transform this eye coordinate pick ray into object coordinates, multiply it by the inverse of the ModelView matrix in use
            when the scene was rendered. When performing this multiplication, remember that the pick ray is made up of a vector and a point,
            and that vectors and points transform differently. You can translate and rotate points, but vectors only rotate.
            The way to guarantee that this is working correctly is to define your point and vector as four-element arrays,
            as the following pseudo-code shows:

            float ray_pnt[4] = {0.f, 0.f, 0.f, 1.f};
            float ray_vec[4] = {x, y, -near_distance, 0.f};
            The one and zero in the last element determines whether an array transforms as a point or a vector when multiplied by the
            inverse of the ModelView matrix.*/
            Vector4 ray_pnt = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
            //Vector4 ray_vec = new Vector4((float)norm_x, (float)norm_y, -1.0f, 0);
            Vector4 ray_vec = new Vector4((float)x, (float)y, -1f, 0);
            ray_vec.Normalize();

            //mess += "Eye Pick Vec =  (" + String.Format("{0:0.00}", ray_vec.X) + ", " + String.Format("{0:0.00}", ray_vec.Y) + "," + String.Format("{0:0.00}", ray_vec.Z) + ")\r\n";

            Matrix4 modelViewMatrix;
            GL.GetFloat(GetPName.ModelviewMatrix, out modelViewMatrix);
            Matrix4 viewInv = Matrix4.Invert(modelViewMatrix);

            Vector4 t_ray_pnt = new Vector4();
            Vector4 t_ray_vec = new Vector4();

            Vector4.Transform(ref ray_vec, ref viewInv, out t_ray_vec);
            Vector4.Transform(ref ray_pnt, ref viewInv, out t_ray_pnt);
            //mess += "World Pick Vec =  (" + String.Format("{0:0.00}", t_ray_vec.X) + ", " + String.Format("{0:0.00}", t_ray_vec.Y) + "," + String.Format("{0:0.00}", t_ray_vec.Z) + ")\r\n";
            //mess += "World Pick Pnt =  (" + String.Format("{0:0.00}", t_ray_pnt.X) + ", " + String.Format("{0:0.00}", t_ray_pnt.Y) + "," + String.Format("{0:0.00}", t_ray_pnt.Z) + ")\r\n";

            Point3d origin = new Point3d();
            Point3d intersect = new Point3d();
            Engine3D.Vector3d dir = new Engine3D.Vector3d();

            origin.Set(t_ray_pnt.X, t_ray_pnt.Y, t_ray_pnt.Z);
            dir.Set(t_ray_vec.X, t_ray_vec.Y, t_ray_vec.Z); // should this be scaled?

            List<ISectData> isects = RTUtils.IntersectObjects(dir, origin, UVDLPApp.Instance().Engine3D.m_objects, true);
            if (isects.Count > 0)
            {
                ISectData isect = (ISectData)isects[0]; // get the first
                ix = (float)isect.intersect.x; // show the closest
                iy = (float)isect.intersect.y;
                iz = (float)isect.intersect.z;
            }

            return isects;
        }
        private void Spiral(float k, float acc, ref Vector4 center, ref Vector4 input, ref Vector4 output)
        {
            var tmp = input - center;
            var dist = tmp.Xy.Length;

            if(dist < 0.1)
                return;

            var d = new Vector4(
                tmp.Y,
                -tmp.X,
                0,
                0);
            d.Normalize();

            d *= 1f/(float)Math.Max(Math.Pow(dist, k), 0.1);
            output += acc * d;
        }
        private void Spiral(float k, float acc, ref Vector4 center, ref Vector4 input, ref Vector4 output)
        {
            var tmp = input - center;
            var dist = tmp.Length;

            for(int i = 0; i < 3; i++)
            {
                if(float.IsNaN(tmp.X) || float.IsNaN(tmp.Y))
                    break;

                var x_n = k * tmp.Y;// + tmp.X;
                var y_n = -k * tmp.X;// + tmp.Y;
                var z_n = 1;

                var d = new Vector4(x_n, y_n, z_n, 0);
                d.Normalize();

                d *= 1f/Math.Max((float)Math.Sqrt(dist), 0.1f);
                output += acc * d;
                tmp = new Vector4(tmp.Z, tmp.X, tmp.Y,0);
                output = new Vector4(output .Z, output .X, output .Y,0);
            }
        }
Exemple #5
0
 private Vector4 GetWeights(float altitude)
 {
     Vector4 weights = new Vector4(1);
     weights.X = MathUtil.Clamp((-altitude + 40)/20, 0, 1);
     weights.Y = MathUtil.Clamp(Math.Abs(altitude-75)/40,0,1);
     weights.Z = MathUtil.Clamp(Math.Abs(altitude - 175)/80, 0, 1);
     weights.W = MathUtil.Clamp((altitude - 350)/50, 0, 1);
     weights.Normalize();
     return weights;
 }
Exemple #6
0
 public void SwingSword(World W)
 {
     if (_swingFrame >= SWING_FRAMES) {
         _swingFrame = 0;
         Vector3 off = new Vector3(0.5f, 1.5f, 0.5f);
         Vector3 moff = new Vector3(0.5f, 1, 0.5f);
         Vector3 rpos = _pos + off;
         Vector4 rdir = new Vector4(-Vector4.UnitZ);
         Matrix4 trans = Matrix4.Mult(
                      Matrix4.CreateFromAxisAngle(Vector3.UnitX, Pitch),
                      Matrix4.CreateFromAxisAngle(Vector3.UnitY, -Yaw)
         );
         rdir = Vector4.Transform(rdir, trans);
         rdir.Normalize();
         double min = 10;
         Enemy dmg = null;
         foreach (IEntity ent in W.Ents) {
             Enemy e = ent as Enemy;
             if (e != null) {
                 Enemy.BS.Pos = e.Pos + moff;
                 double d = Enemy.BS.RayIntersection(rpos, rdir.Xyz);
                 if (!Double.IsNaN(d) && d > 0 && d < min) {
                     min = d;
                     dmg = e;
                 }
             }
         }
         if (dmg != null) {
             dmg.Hurt(10);
             dmg.ApplyForce(new Vector3(
                 (float)-Math.Sin(-Yaw) * KNOCKBACK,
                 0,
                 (float)-Math.Cos(-Yaw) * KNOCKBACK
             )
             );
         }
     }
 }
Exemple #7
0
        /// <summary>
        /// This is the frustum.
        /// </summary>
        /// <param name="normalize">Normalize the vectors</param>
        /// <returns>0-3 is left,right,top,bottom, 4-5 is the near/far plane</returns>
        public static Vector4[] GetFrustum(bool normalize)
        {
            // Get bounds of view.
            float[] viewport = new float[4];
            float[] projectiofM = new float[16];
            float[] modelviewfM = new float[16];
            Matrix4 projectionM = new Matrix4();
            Matrix4 modelviewM = new Matrix4();
            Matrix4 projMultimodel;// = new Matrix4();
            Matrix4 ScreenFrustum = new Matrix4(); // all 4 used
            Vector4[] NearFarFrustum = new Vector4[2]; // only 0-1 used, 2-3 is zero
            Vector4[] RetArr = new Vector4[6]; // only 0-1 used, 2-3 is zero
            GL.GetFloat(GetPName.Viewport, viewport);
            GL.GetFloat(GetPName.ProjectionMatrix, out projectionM);
            GL.GetFloat(GetPName.ModelviewMatrix, out modelviewM);
            projMultimodel = Matrix4.Mult(projectionM, modelviewM);

            // Got the wrong order used columns when it should have been rows.....
            /*Vector4 rPlane = new Vector4(projMultimodel.Column0.W - projMultimodel.Column0.X,
                projMultimodel.Column1.W - projMultimodel.Column1.X,
                projMultimodel.Column2.W - projMultimodel.Column2.X,
                projMultimodel.Column3.W - projMultimodel.Column3.X);*/
            Vector4 rPlane = new Vector4(projMultimodel.Column3.X - projMultimodel.Column0.X,
                projMultimodel.Column3.Y - projMultimodel.Column1.X,
                projMultimodel.Column3.Z - projMultimodel.Column2.X,
                projMultimodel.Column3.W - projMultimodel.Column3.X);
            if (normalize)
            {
                rPlane.Normalize();
            }

            Vector4 rPlaneManual = new Vector4(projMultimodel.M14 - projMultimodel.M11,
                projMultimodel.M24 - projMultimodel.M21,
                projMultimodel.M34 - projMultimodel.M31,
                projMultimodel.M44 - projMultimodel.M41);
            if (normalize)
            {
                rPlaneManual.Normalize();
            }

            /*Vector4 rPlaneManual2;
            unsafe
            {
                float* clip1 = (float*)(&projMultimodel);
                rPlaneManual2 = new Vector4(clip1[3] - clip1[0], clip1[7] - clip1[4], clip1[11] - clip1[8], clip1[15] - clip1[12]);
                rPlaneManual2.Normalize();
            }
            */

            /*Vector4 lPlane = new Vector4(projMultimodel.Column0.W + projMultimodel.Column0.X,
                projMultimodel.Column1.W + projMultimodel.Column1.X,
                projMultimodel.Column2.W + projMultimodel.Column2.X,
                projMultimodel.Column3.W + projMultimodel.Column3.X);*/
            /*
            Vector4 lPlane = new Vector4(projMultimodel.Column3.X + projMultimodel.Column0.X,
                projMultimodel.Column3.Y + projMultimodel.Column1.X,
                projMultimodel.Column3.Z + projMultimodel.Column2.X,
                projMultimodel.Column3.W + projMultimodel.Column3.X);*/
            Vector4 row = projMultimodel.Row0;
            Vector4 lPlane = new Vector4(projMultimodel.Column3.X + row.X,
               projMultimodel.Column3.Y + row.Y,
               projMultimodel.Column3.Z + row.Z,
               projMultimodel.Column3.W + row.W);
            if (normalize)
            {
                lPlane.Normalize();
            }
            /*Vector4 bPlane = new Vector4(projMultimodel.Column0.W - projMultimodel.Column0.Y,
                projMultimodel.Column1.W - projMultimodel.Column1.Y,
                projMultimodel.Column2.W - projMultimodel.Column2.Y,
                projMultimodel.Column3.W - projMultimodel.Column3.Y);*/
            Vector4 bPlane = new Vector4(projMultimodel.Column3.X - projMultimodel.Column0.Y,
                projMultimodel.Column3.Y - projMultimodel.Column1.Y,
                projMultimodel.Column3.Z - projMultimodel.Column2.Y,
                projMultimodel.Column3.W - projMultimodel.Column3.Y);
            if (normalize)
            {
                bPlane.Normalize();
            }
            /*Vector4 tPlane = new Vector4(projMultimodel.Column0.W + projMultimodel.Column0.Y,
                projMultimodel.Column1.W + projMultimodel.Column1.Y,
                projMultimodel.Column2.W + projMultimodel.Column2.Y,
                projMultimodel.Column3.W + projMultimodel.Column3.Y);*/
            Vector4 tPlane = new Vector4(projMultimodel.Column3.X + projMultimodel.Column0.Y,
                projMultimodel.Column3.Y + projMultimodel.Column1.Y,
                projMultimodel.Column3.Z + projMultimodel.Column2.Y,
                projMultimodel.Column3.W + projMultimodel.Column3.Y);
            if (normalize)
            {
                tPlane.Normalize();
            }
            ScreenFrustum = new Matrix4(rPlane, lPlane, bPlane, tPlane);

            /*NearFarFrustum[0] = new Vector4(projMultimodel.Column0.W + projMultimodel.Column0.Z,
                projMultimodel.Column1.W + projMultimodel.Column1.Z,
                projMultimodel.Column2.W + projMultimodel.Column2.Z,
                projMultimodel.Column3.W + projMultimodel.Column3.Z);*/
            NearFarFrustum[0] = new Vector4(projMultimodel.Column3.X + projMultimodel.Column0.Z,
                projMultimodel.Column3.Y + projMultimodel.Column1.Z,
                projMultimodel.Column3.Z + projMultimodel.Column2.Z,
                projMultimodel.Column3.W + projMultimodel.Column3.Z);
            if (normalize)
            {
                NearFarFrustum[0].Normalize();
            }
            /*NearFarFrustum[1] = new Vector4(projMultimodel.Column0.W - projMultimodel.Column0.Z,
                projMultimodel.Column1.W - projMultimodel.Column1.Z,
                projMultimodel.Column2.W - projMultimodel.Column2.Z,
                projMultimodel.Column3.W - projMultimodel.Column3.Z);*/
            NearFarFrustum[1] = new Vector4(projMultimodel.Column3.X - projMultimodel.Column0.Z,
                projMultimodel.Column3.Y - projMultimodel.Column1.Z,
                projMultimodel.Column3.Z - projMultimodel.Column2.Z,
                projMultimodel.Column3.W - projMultimodel.Column3.Z);
            if (normalize)
            {
                NearFarFrustum[1].Normalize();
            }

            RetArr[0] = ScreenFrustum.Row0;
            RetArr[1] = ScreenFrustum.Row1;
            RetArr[2] = ScreenFrustum.Row2;
            RetArr[3] = ScreenFrustum.Row3;
            RetArr[4] = NearFarFrustum[0];
            RetArr[5] = NearFarFrustum[1];

            return RetArr;
        }
Exemple #8
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();
        }
Exemple #9
0
        /// <summary>
        /// Génère un modèle 3D en forme de planète à partir de plusieurs bruits.
        /// </summary>
        /// <param name="aabb">Bounding box du morceau de planète généré.</param>
        /// <param name="gridLevelScale">Echelle du morceau de grille à générer. L'échelle est divisée par 2
        /// à chaque étage du quadtree</param>
        /// <param name="gridSize">Taille de la grille à générer.</param>
        /// <param name="highNoise">Bruit "high"</param>
        /// <param name="iBuffer">Index buffer en du mesh créé en sortie.</param>
        /// <param name="initialGridPos">Position du coin supérieur gauche de la grille à générer dans la grille initiale de range [0, 1]</param>
        /// <param name="lowNoise">Bruit "low"</param>
        /// <param name="repNoise">Bruit de répartition</param>
        /// <param name="vBuffer">Vertex buffer en du mesh créé en sortie.</param>
        /// <param name="chunkGeography">Informations de sortie concernant la géographie du morceau généré.</param>
        /// <param name="planetPosition">Position de la planète.</param>
        /// <param name="radius">Rayon de la planète.</param>
        /// <returns></returns>
        public static void GeneratePlanet(Vector3 planetPosition,
            float radius,
            int gridSize, 
            Vector2 initialGridPos,
            float gridLevelScale,
            Noise.NoiseBase lowNoise,
            Noise.NoiseBase highNoise,
            Noise.NoiseBase repNoise,
            out SlimDX.Direct3D11.Buffer vBuffer,
            out BoundingBox aabb,
            out ChunkAltitude geo)
        {
            // Geography
            geo = new ChunkAltitude();

            // Taille du buffer.
            int size = gridSize * gridSize ;
            const bool computeNormals = true;
            Vector3 min = new Vector3(float.MaxValue);
            Vector3 max = new Vector3(float.MinValue);

            // Création du vertex buffer contenant tous les vertex à dessiner.
            VWrapper[] vertexBuffer = new VWrapper[size];

            // Texture noise
            Noise.NoiseMapGenerator.NoiseParameters p = new Noise.NoiseMapGenerator.NoiseParameters()
            {
                Frequency = 128.0f,
                Lacunarity = 2.5f,
                NoiseEnd = new Vector2(initialGridPos.X + gridLevelScale, initialGridPos.Y + gridLevelScale),
                NoiseStart = new Vector2(initialGridPos.X, initialGridPos.Y),
                NoiseType = Noise.NoiseMapGenerator.NoiseParameters.RIDGED_ID,
                Persistence = 0.94f,
                Seed = 456464560
            };
            Noise.NoiseBase texNoise = p.CreateNoise();

            float theta, phi;
            Vector3 transformedPos;
            for (int y = 0; y < gridSize; y++)
            {
                for (int x = 0; x < gridSize; x++)
                {
                    // Cette section a pour but de calculer la normale par rapport au "sol" de la planète, pour cela
                    // Elle calcule les positions des verte
                    Vector2 pos2D = new Vector2(x / ((float)gridSize - 1),
                                    (y / ((float)gridSize - 1)));

                    // Transformation en sphère.
                    float noisePosX = initialGridPos.X + pos2D.X * gridLevelScale;
                    float noisePosY = initialGridPos.Y + pos2D.Y * gridLevelScale;
                    phi = (noisePosX) * (float)Math.PI * 2;
                    theta = (noisePosY) * (float)Math.PI;

                    // TODO : optimiser pour éviter les calculs redondants.
                    transformedPos = Util.SphericalCoords.ToCartesian(theta, phi, radius);//new Vector3(xSph, ySph, zSph);

                    // Création de la normale au sol.
                    Vector3 normal = Vector3.Normalize(transformedPos);

                    // Valeur du bruit
                    float noiseValue = Noise.NoiseMapGenerator.GetMultiNoiseValue(repNoise, highNoise, lowNoise,
                        transformedPos.X / radius, transformedPos.Y / radius, transformedPos.Z / radius);
                    float tNoiseValue = texNoise.GetValue(transformedPos.X / radius, transformedPos.Y / radius, transformedPos.Z / radius);

                    // Création de la position finale
                    Vector3 finalPos = transformedPos + normal * noiseValue;
                    Vector4 pos = new Vector4(finalPos, 1.0f);

                    // Informations de géométrie.
                    min = Util.MathHelper.Min(finalPos, min);
                    max = Util.MathHelper.Max(finalPos, max);
                    geo.MinAltitude = Math.Min(noiseValue, geo.MinAltitude);
                    geo.MaxAltitude = Math.Max(noiseValue, geo.MaxAltitude);

                    // Ajout des données dans le VBuffer.
                    int index = (x + y * gridSize);

                    vertexBuffer[index] = new VWrapper();
                    vertexBuffer[index].SphereNormal = normal;

                    // Position 3D du point avec displacement.
                    vertexBuffer[index].Vertex.Position = pos;
                    // Position 3D du point sans displacement.
                    vertexBuffer[index].Vertex.SpherePosition = new Vector4(transformedPos, 1.0f);
                    vertexBuffer[index].Vertex.SphereNormal = new Vector4(normal, 1.0f);
                    // Coordonnées de texture.
                    vertexBuffer[index].Vertex.Texture = new Vector2(noisePosX, noisePosY);
                    vertexBuffer[index].Vertex.Normal = new Vector4(0);
                    vertexBuffer[index].Vertex.Altitude = noiseValue;

                    // Valeurs additionnelles.
                    vertexBuffer[index].Vertex.TextureId = tNoiseValue;
                }

            }

            // Index buffer contenant l'ordre dans lequel dessiner les vertex. (sous forme de carrés).
            int iBufferSize = (gridSize - 1) * (gridSize - 1) * 6;
            int[] indexBuffer = GetIndexBufferCpu(gridSize);
            if (computeNormals)
            {
                //Thread.Sleep(1);
                for (int i = 0; i < indexBuffer.Length / 3; i++)
                {
                    Vector4 firstvec = vertexBuffer[indexBuffer[i * 3 + 1]].Vertex.Position - vertexBuffer[indexBuffer[i * 3]].Vertex.Position;
                    Vector4 secondvec = vertexBuffer[indexBuffer[i * 3]].Vertex.Position - vertexBuffer[indexBuffer[i * 3 + 2]].Vertex.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)]].Vertex.Normal += normal;
                    vertexBuffer[indexBuffer[(i * 3 + 1)]].Vertex.Normal += normal;
                    vertexBuffer[indexBuffer[(i * 3 + 2)]].Vertex.Normal += normal;
                }
                for (int i = 0; i < vertexBuffer.Length; i++)
                {
                    var v = Util.MathHelper.ReduceXYZ(vertexBuffer[i].Vertex.Normal);
                    v.Normalize();
                    vertexBuffer[i].Vertex.Normal = new Vector4(v, 1.0f);
                    vertexBuffer[i].Vertex.SphereNormal = new Vector4(Util.MathHelper.ReduceXYZ(vertexBuffer[i].Vertex.Normal) - vertexBuffer[i].SphereNormal, 1.0f);

                }
            }

            // Création des buffers.
            DataStream vBuffStream = new DataStream(size * Vertex.Stride, true, true);
            for (int i = 0; i < size; i++)
                vBuffStream.Write<Vertex>(vertexBuffer[i].Vertex);
            vBuffStream.Position = 0;

            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
            });

            vBuffStream.Dispose();

            aabb = new BoundingBox(min, max);
        }
        void ISimulationScheme.Simulate(System3 system, DateTime simulationTime, long simulationStep)
        {
            m_SpeedUpperBound = Math.Max(m_SpeedUpperBound * 0.75f, 0.01f);

            var trailSize = Math.Max(system.TrailSize, 1);
            var trailCount = (system.Position.Length + trailSize - 1) / trailSize;
            var trailBundleSize = Math.Max(TrailBundleSize, 1);
            var trailBundleCount = (trailCount + trailBundleSize - 1) / trailBundleSize;

            var stepsPerFrame = Math.Max(system.StepsPerFrame, 1);
            var fun = system.ChaoticMap.Map;
            var position = system.Position;
            var dimension = system.Dimension;
            var meta = system.Meta;
            var rotation = system.Rotation;
            var attribute1 = system.Color;

            var particleCount = position.Length;
            var particleScale = system.ParticleScaleFactor;
            var dt = (float)system.DT;

            Parallel.For (0, trailBundleCount,
            bundleIndex =>
            {
                var firsttrail = bundleIndex * trailBundleSize * trailSize;
                var lasttrail = Math.Min(firsttrail + trailBundleSize , particleCount);
                var speedBound = m_SpeedUpperBound;
                var dp = Vector4.Zero;
                var dpA = Vector4.Zero;
                var dpB = Vector4.Zero;
                var delta2 = Vector4.Zero;
                var size = 0f;
                var middlepoint = Vector4.Zero;
                var endpoint = Vector4.Zero;

                for (int j = 0; j < stepsPerFrame; j++)
                {
                    for (int i = firsttrail ; i < lasttrail ; i += 1)
                    {
                        //i is the trail's first element
                        var pi = i + meta[i].Leader;
                        var K = dt;

                        size = Math.Max(meta[pi].Size, float.Epsilon);

                        if(MapMode == MapModeType.ForceField)
                        {
                            dp = new Vector4 (meta[i].Velocity, 0);
                            fun (ref position[pi], ref delta2);
                            meta[i].Velocity += delta2.Xyz * dt;
                        }
                        else
                        {
                            fun (ref position[pi], ref dp);
                        }

                        //
                        var b0 = new Vector4( dp.Xyz, 0);
                        var b2 = new Vector4( Vector3.Cross( b0.Xyz, rotation[pi].Row1.Xyz), 0);
                        var b1 = new Vector4( Vector3.Cross( b2.Xyz, b0.Xyz), 0);

                        b0.Normalize();
                        b1.Normalize();
                        b2.Normalize();

                        //
                        if(IntegrationStep == IntegrationStepType.LimitDelta)
                        {
                            K *= Math.Min(1, 10 * (size * particleScale)/ (dp.Length * dt));
                        }

                        if(Interpolation == InterpolationType.Cubic)
                            K *= 0.5f;

                        dp *= K;

                        //
                        var localCount = (float)Math.Ceiling(dp.Length / (size * particleScale));
                        localCount = Math.Min(localCount, trailSize);
                        if(Interpolation == InterpolationType.Cubic)
                        {
                            dpA = 2 * dp;
                            middlepoint = position[pi] + dp;
                            fun (ref middlepoint, ref dpB);
                            dpB *= K;
                            endpoint = middlepoint + dpB;

                            fun (ref endpoint, ref dpB);
                            dpB *= 2 * K;
                        }

                        for(int li = 0; li < localCount; li++)
                        {
                            meta[i].Leader = (meta[i].Leader + trailBundleSize) % (trailSize * trailBundleSize);

                            var ii = i + meta[i].Leader;
                            if (ii >= particleCount)
                            {
                                ii = i;
                                meta[i].Leader = 0;
                            }

                            if(Interpolation == InterpolationType.Cubic)
                            {
                                var t = (1 + li) / localCount;
                                var p1 = 2*t*t*t - 3*t*t + 1;
                                var p2 = t*t*t - 2*t*t + t;
                                var p3 = -p1 + 1;
                                var p4 = p2 + t*t - t;

                                position[ii] =
                                    p1 *  position[pi] +
                                    p2 * dpA +
                                    p3 * endpoint +
                                    p4 * dpB;

                                dimension[ii] = new Vector4 (size, size, size, size);
                                rotation[ii] = new Matrix4(b0, b1, b2, new Vector4(0,0,0,1));
                            }
                            else
                            {
                                position[ii] = position[pi] + ((1 + li) / localCount) * dp;
                                dimension[ii] = new Vector4 (size, size, size, size);
                                rotation[ii] = new Matrix4(b0, b1, b2, new Vector4(0,0,0,1));
                            }

                            switch (ComputeMetadataMode) {
                            case ComputeMetadata.Speed:
                                attribute1[ii] = dp;
                            break;
                            case ComputeMetadata.Tangent:
                                attribute1[ii] = b0;
                            break;
                            default:
                            break;
                            }
                        }
                    }
                }

                var orig = m_SpeedUpperBound;
                var help = orig;
                while(
                    speedBound > orig &&
                    (help = Interlocked.CompareExchange(ref m_SpeedUpperBound, speedBound, orig)) != orig)
                    orig = help;
            });
        }
Exemple #11
0
 internal ShadowLight(Vector3 LightPosition, Vector4 LightColor, float LightPower, float LightFOV, float LightNearDistance, float LightFarDistance, bool LightIsSpotLight)
 {
     _Position = LightPosition;
     _LColor = LightColor;
     _LColor.Normalize();
     _LColor *= LightPower;
     _LColor.W = 1f;
     _FOV = LightFOV;
     _NearDistance = LightNearDistance;
     _FarDistance = LightFarDistance;
     IsSpotLight = LightIsSpotLight;
 }