Ejemplo n.º 1
0
        public override void Render()
        {
            VideoDriver driver = _mgr.VideoDriver;
            CameraSceneNode camera = _mgr.ActiveCamera;

            if (camera == null || driver == null)
                return;

            if (!redrawnextloop)
            {
                driver.SetTransform(TransformationState.World, AbsoluteTransformation);
                driver.SetMaterial(_material);
                driver.DrawIndexedTriangleList(Vertices, lastdrawcount * 4,
                                               Indices, lastdrawcount * 4);
            }
            else
            {
                ReallocateBuffers();

                Vector3D campos = camera.AbsolutePosition;
                Box3D cbox = camera.ViewFrustum.BoundingBox;

                Vector3D pos = Position;
                int drawcount = 0;
                int max = (Particles.Length < MaxDensity) ? Particles.Length : MaxDensity;

                double d = pos.DistanceFrom(campos) / GRASS_PATCH_SIZE;
                if (d > 1.0)
                    max = (int)(max / d);

                //Matrix4 m = new Matrix4();

                for (int i = 0; i < max; i++)
                {
                    int idx = drawcount * 4;

                    GrassParticle particle = Particles[i];
                    Vector3D gpos = particle.pos + pos;

                    double dist = campos.DistanceFromSQ(gpos);
                    if (dist > NewMath.Sqr(DrawDistance))
                        continue;

                    if (!cbox.IsPointInside(gpos))
                        continue;

                    if (dist > NewMath.Sqr(DrawDistance * 0.5))
                    {
                        if (particle.sprite.Height == 0)
                        {
                            float i1 = ((float)i) / ((float)max);
                            float i2 = ((float)(dist / DrawDistance)) / 2f;

                            if (i1 < i2)
                                continue;
                        }
                    }

                    int igridsize = GRASS_PATCH_SIZE / (int)WindRes;
                    int ihalfres = (int)WindRes / 2;

                    int xgrid = (int)(particle.pos.X / (igridsize) + ihalfres);
                    int zgrid = (int)(particle.pos.Z / (igridsize) + ihalfres);

                    float xnext = particle.pos.X / ((float)GRASS_PATCH_SIZE / (float)WindRes) + (WindRes / 2f) - xgrid;
                    float znext = particle.pos.Z / ((float)GRASS_PATCH_SIZE / (float)WindRes) + (WindRes / 2f) - zgrid;

                    Vector2D wind1 = WindGrid[xgrid * WindRes + zgrid];
                    Vector2D wind2 = WindGrid[(xgrid + 1) * WindRes + zgrid];
                    Vector2D wind3 = WindGrid[xgrid * (WindRes + 1) + zgrid];
                    Vector2D wind4 = WindGrid[(xgrid + 1) * (WindRes + 1) + zgrid];
                    Vector2D wind2d = wind1 * (1.0f - xnext) * (1.0f - znext) +
                                      wind2 * xnext * (1.0f - znext) +
                                      wind3 * (1.0f - xnext) * znext +
                                      wind4 * xnext * znext;

                    wind2d *= particle.flex;
                    Vector3D wind = new Vector3D(wind2d.X, 0f, wind2d.Y);

                    Color gcol = new Color(particle.color.A,
                                           (int)(particle.color.R * 0.8f),
                                           (int)(particle.color.G * 0.8f),
                                           (int)(particle.color.B * 0.8f));

                    Vertices[0 + idx].Position = particle.points[0];
                    Vertices[0 + idx].Color = gcol;

                    Vertices[1 + idx].Position = particle.points[1] + wind;
                    Vertices[1 + idx].Color = particle.color;

                    Vertices[2 + idx].Position = particle.points[2] + wind;
                    Vertices[2 + idx].Color = particle.color;

                    Vertices[3 + idx].Position = particle.points[3];
                    Vertices[3 + idx].Color = gcol;

                    int arrpos = (_imagecount.Width * particle.sprite.Height) + particle.sprite.Width;
                    Vertices[0 + idx].TCoords = new Vector2D(v1[arrpos], v2[arrpos]);
                    Vertices[1 + idx].TCoords = new Vector2D(v1[arrpos], v3[arrpos]);
                    Vertices[2 + idx].TCoords = new Vector2D(v4[arrpos], v3[arrpos]);
                    Vertices[3 + idx].TCoords = new Vector2D(v4[arrpos], v2[arrpos]);

                    drawcount++;
                }
                driver.SetTransform(TransformationState.World, AbsoluteTransformation);
                driver.SetMaterial(_material);

                driver.DrawIndexedTriangleList(Vertices, drawcount * 4,
                                               Indices, drawcount * 4);
                lastdrawcount = drawcount;
            }

            if (DebugDataVisible == DebugSceneType.BoundingBox)
            {
                driver.SetTransform(TransformationState.World, AbsoluteTransformation);
                Material m = new Material();
                m.Lighting = false;
                driver.SetMaterial(m);
                driver.Draw3DBox(BoundingBox, Color.From(0, 255, 255, 255));
                Box3D b2 = new Box3D();

                b2.AddInternalPoint(BoundingBox.MaxEdge * 0.01f);
                driver.Draw3DBox(b2, Color.From(0, 255, 255, 255));
            }
        }
Ejemplo n.º 2
0
        bool Create(bool save)
        {
            Random rand = new Random((int)((100 * gridpos.X) + gridpos.Z));
            int count = rand.Next(3000, 3200);

            _bbox = new Box3D();

            Particles = new GrassParticle[count];

            /*Matrix4 m = new Matrix4();
            m.RotationDegrees = Terrain.Rotation;
            m.Translation = Terrain.AbsolutePosition;
            m.MakeInverse();*/

            Color[,] TGMRetrieve = TerrainGrassMap.Retrieve();
            Color[,] TCMRetrieve = TerrainColourMap.Retrieve();
            Color[,] THMRetrieve = TerrainHeightMap.Retrieve();
            System.Collections.ArrayList tosave = new System.Collections.ArrayList();

            for (int i = 0; i < count; i++)
            {
                Particles[i].points = new Vector3D[4];

                float x = rand.Next(0, GRASS_PATCH_SIZE * 10) / 10f;
                float z = rand.Next(0, GRASS_PATCH_SIZE * 10) / 10f;

                x -= GRASS_PATCH_SIZE / 2f;
                z -= GRASS_PATCH_SIZE / 2f;

                Particles[i].pos.X = x;
                Particles[i].pos.Z = z;

                Particles[i].flex = rand.Next(0, 100) / 100f;
                Particles[i].sprite.Width = rand.Next(0, _imagecount.Width);

                if (i < 30)
                    Particles[i].sprite.Height = rand.Next(0, _imagecount.Height);
                else
                    Particles[i].sprite.Height = 0;

                Vector3D p = Position + Particles[i].pos;

                Vector3D xz = new Vector3D(p.X / Terrain.Scale.X, 0f, p.Z / Terrain.Scale.Z);

                int x1 = (int)Math.Floor(xz.X);
                int z1 = (int)Math.Floor(xz.Z);

                if (x1 < 1 ||
                   z1 < 1 ||
                   x1 > TerrainHeightMap.OriginalSize.Width - 1 ||
                   z1 > TerrainHeightMap.OriginalSize.Height - 1)
                    continue;

                Color cDensity = TGMRetrieve[x1, z1];
                if (rand.Next(0, 255) > cDensity.A || cDensity.A < 1)
                    continue;

                float ay = THMRetrieve[x1, z1].B * Terrain.Scale.Y;
                float by = THMRetrieve[x1 + 1, z1].B * Terrain.Scale.Y;
                float cy = THMRetrieve[x1, z1 + 1].B * Terrain.Scale.Y;
                float dy = THMRetrieve[x1 + 1, z1 + 1].B * Terrain.Scale.Y;
                float u1 = xz.X - x1;
                float v1 = xz.Z - z1;
                float height = ay * (1.0f - u1) * (1.0f - v1) + by * u1 * (1.0f - v1) + cy * (1.0f - u1) * v1 + dy * u1 * v1;

                Dimension2Df size = new Dimension2Df(rand.Next(40, 70), 100);
                size.Height *= cDensity.B / 200f;

                Particles[i].pos.Y = height + (size.Height * 0.5f);

                Particles[i].color = TCMRetrieve[x1, z1];
                Particles[i].startColor = TCMRetrieve[x1, z1];

                _bbox.AddInternalPoint(Particles[i].pos);

                Vector3D dimensions = new Vector3D(0.5f * size.Width,
                                                   -0.5f * size.Height,
                                                   0);

                /*float rotation = rand.Next(0, 3600) / 10f;
                Matrix4 m2 = new Matrix4();
                m2.RotationDegrees = new Vector3D(0, rotation, 0);
                m2.RotateVect(dimensions);*/

                //Vector3D h = new Vector3D(dimensions.X,0.0f,dimensions.Z);
                //Vector3D v = new Vector3D(0.0f,dimensions.Y,0.0f);
                Particles[i].points[0] = Particles[i].pos + new Vector3D(dimensions.X, dimensions.Y, dimensions.Z);
                Particles[i].points[1] = Particles[i].pos + new Vector3D(dimensions.X, -dimensions.Y, dimensions.Z);
                Particles[i].points[2] = Particles[i].pos - new Vector3D(dimensions.X, dimensions.Y, dimensions.Z);
                Particles[i].points[3] = Particles[i].pos - new Vector3D(dimensions.X, -dimensions.Y, dimensions.Z);
                tosave.Add(Particles[i]);
            }

            Particles = (GrassParticle[])tosave.ToArray(typeof(GrassParticle));
            tosave.Clear();
            if (save)
                return Save();

            return true;
        }