Ejemplo n.º 1
0
        public PlantDensityData GetDensity(float longtiude, float latitude)
        {
            const double yspan = Math.PI;

            int y = (int)(((yspan * 0.5 - latitude) / yspan) * Height);
            int x = (int)(((longtiude + Math.PI) / (2 * Math.PI)) * Width);

            if (y < 0)
            {
                y += Height;
            }
            if (y >= Height)
            {
                y -= Height;
            }

            if (x < 0)
            {
                x += Width;
            }
            if (x >= Width)
            {
                x -= Width;
            }

            int idx = y * Width + x;
            PlantDensityData result = new PlantDensityData();

            for (int i = 0; i < TypeCount; i++)
            {
                result.Density[i] = densityTable[i][idx] / 255f;
                //if (result.Density[i] < 0.1f)
                //    result.Density[i] = 0.1f;
            }
            return(result);
        }
Ejemplo n.º 2
0
        protected unsafe override void load()
        {
            resourceSize = 0;

            float radlng = MathEx.Degree2Radian(info.Longitude);
            float radlat = MathEx.Degree2Radian(info.Latitude);
            float radr   = MathEx.Degree2Radian(info.Radius) * 2;

            TreeOrientation = PlanetEarth.GetOrientation(radlng, radlat);
            TreeOrientation.TranslationValue = PlanetEarth.GetPosition(radlng, radlat, PlanetEarth.PlanetRadius);


            int vtxCount   = 0;
            int vtxOffset  = 0;
            int vtxCount2  = 0;
            int vtxOffset2 = 0;

            int plantCount = (int)(info.Amount * 0.05f);



            FastList <byte> vertices2     = new FastList <byte>(plantCount * 2500);
            FastList <int>  indices2      = new FastList <int>();
            int             partVtxCount2 = 0;


            FastList <byte> vertices = new FastList <byte>(plantCount * 2500);
            Dictionary <Material, FastList <int> > indices      = new Dictionary <Material, FastList <int> >();
            Dictionary <Material, int>             partVtxCount = new Dictionary <Material, int>();

            plantCount = 0;

            byte[] vtxBldBuffer = new byte[TreeVertex.Size];

            const float AreaWidth = 0.036f;

            for (float blkLng = radlng - radr; blkLng < radlng + radr; blkLng += AreaWidth)
            {
                for (float blkLat = radlat - radr; blkLat < radlat + radr; blkLat += AreaWidth)
                {
                    float altblk = TerrainData.Instance.QueryHeight(blkLng, blkLat) - 100;

                    if (altblk < 0)
                    {
                        continue;
                    }

                    float density = PlantDensity.Instance.GetPlantDensity(blkLng, blkLat);

                    int count = (int)(density * 2.25f);

                    for (int i = 0; i < count; i++)
                    {
                        float treeLng = blkLng + AreaWidth * Randomizer.GetRandomSingle();
                        float treeLat = blkLat + AreaWidth * Randomizer.GetRandomSingle();

                        float alt = TerrainData.Instance.QueryHeight(treeLng, treeLat);

                        PlantDensityData d = PlantDensity.Instance.GetDensity(treeLng, treeLat);
                        int idx            = Randomizer.Random(d.Density, PlantDensity.TypeCount);

                        TreeModelData[] mdls     = TreeModelLibrary.Instance.Get(idx);
                        TreeModelData   meshData = mdls[Randomizer.GetRandomInt(mdls.Length)];


                        Matrix treeOrientation = PlanetEarth.GetOrientation(treeLng, treeLat);
                        treeOrientation.TranslationValue = PlanetEarth.GetPosition(treeLng, treeLat,
                                                                                   PlanetEarth.PlanetRadius + alt * TerrainMeshManager.PostHeightScale);

                        float instanceData = Randomizer.GetRandomSingle();

                        float theta  = instanceData * MathEx.PIf * 2;
                        float rotCos = (float)Math.Cos(theta);
                        float rotSin = (float)Math.Sin(theta);

                        #region 数据
                        resourceSize += meshData.VertexCount * TreeVertex.Size;
                        vtxCount     += meshData.VertexCount;

                        fixed(byte *src = &meshData.VertexData[0])
                        {
                            VertexPNT1 *ptr = (VertexPNT1 *)src;

                            for (int j = 0; j < meshData.VertexCount; j++)
                            {
                                TreeVertex p;
                                p.pos.X = rotCos * ptr[j].pos.X - rotSin * ptr[j].pos.Z;
                                p.pos.Z = rotSin * ptr[j].pos.X + rotCos * ptr[j].pos.Z;
                                p.pos.Y = ptr[j].pos.Y;

                                p.pos = p.pos * (Game.TreeScale * (instanceData * 0.4f + 0.8f));

                                Vector3 pp;
                                Vector3.TransformSimple(ref p.pos, ref treeOrientation, out pp);
                                p.pos = pp;

                                p.n.X = rotCos * ptr[j].n.X - rotSin * ptr[j].n.Z;
                                p.n.Z = rotSin * ptr[j].n.Z + rotCos * ptr[j].n.Z;
                                p.n.Y = ptr[j].n.Y;

                                p.tex1 = new Vector3(ptr[j].u, ptr[j].v, instanceData);

                                fixed(byte *dst = &vtxBldBuffer[0])
                                {
                                    Memory.Copy(&p, dst, TreeVertex.Size);
                                }

                                p.tc    = new Vector2(treeLng, treeLat);
                                p.tc.X += MathEx.PIf;
                                //p.tc.Y -= MathEx.Degree2Radian(10);

                                p.tc.X = 0.5f * p.tc.X / MathEx.PIf;
                                p.tc.Y = (-p.tc.Y + MathEx.PiOver2) / MathEx.PIf;

                                vertices.Add(vtxBldBuffer);
                            }
                        }

                        Material[] mtrls = meshData.Materials;
                        for (int k = 0; k < mtrls.Length; k++)
                        {
                            Material mtrl = mtrls[k];

                            FastList <int> idxData;
                            if (!indices.TryGetValue(mtrl, out idxData))
                            {
                                idxData = new FastList <int>(plantCount * 120);
                                indices.Add(mtrl, idxData);

                                partVtxCount.Add(mtrl, 0);
                            }

                            partVtxCount[mtrl] += meshData.PartVtxCount[k];

                            int[] meshIdx = meshData.Indices[k];

                            for (int j = 0; j < meshIdx.Length; j++)
                            {
                                idxData.Add(meshIdx[j] + vtxOffset);
                            }
                        }
                        vtxOffset += meshData.VertexCount;
                        #endregion

                        TreeModelData meshData2 = TreeModelLibrary.Instance.GetTrunk();
                        #region 树桩
                        resourceSize += meshData2.VertexCount * TreeVertex.Size;
                        vtxCount2    += meshData2.VertexCount;

                        fixed(byte *src = &meshData2.VertexData[0])
                        {
                            VertexPNT1 *ptr = (VertexPNT1 *)src;

                            for (int j = 0; j < meshData2.VertexCount; j++)
                            {
                                TreeVertex p;
                                p.pos.X = rotCos * ptr[j].pos.X - rotSin * ptr[j].pos.Z;
                                p.pos.Z = rotSin * ptr[j].pos.X + rotCos * ptr[j].pos.Z;
                                p.pos.Y = ptr[j].pos.Y;

                                p.pos = p.pos * (Game.TreeScale * (instanceData * 0.4f + 0.8f));

                                Vector3 pp;
                                Vector3.TransformSimple(ref p.pos, ref treeOrientation, out pp);
                                p.pos = pp;

                                p.n.X = rotCos * ptr[j].n.X - rotSin * ptr[j].n.Z;
                                p.n.Z = rotSin * ptr[j].n.Z + rotCos * ptr[j].n.Z;
                                p.n.Y = ptr[j].n.Y;

                                p.tex1 = new Vector3(ptr[j].u, ptr[j].v, instanceData);

                                fixed(byte *dst = &vtxBldBuffer[0])
                                {
                                    Memory.Copy(&p, dst, TreeVertex.Size);
                                }

                                vertices2.Add(vtxBldBuffer);
                            }
                        }

                        material2      = meshData2.Materials[0];
                        partVtxCount2 += meshData2.PartVtxCount[0];

                        int[] meshIdx2 = meshData2.Indices[0];

                        for (int j = 0; j < meshIdx2.Length; j++)
                        {
                            indices2.Add(meshIdx2[j] + vtxOffset2);
                        }
                        vtxOffset2 += meshData2.VertexCount;
                        #endregion
                        plantCount++;
                    }
                }
            }



            // ============================================================================

            ObjectFactory fac = renderSys.ObjectFactory;
            vtxDecl = fac.CreateVertexDeclaration(TreeVertex.Elements);
            int vtxSize = vtxDecl.GetVertexSize();

            vtxBuffer = fac.CreateVertexBuffer(vtxCount, vtxDecl, BufferUsage.Static);

            vertices.Trim();
            vtxBuffer.SetData <byte>(vertices.Elements);

            vtxBuffer2 = fac.CreateVertexBuffer(vtxCount2, vtxDecl, BufferUsage.Static);
            vertices2.Trim();
            vtxBuffer2.SetData <byte>(vertices2.Elements);

            int partCount = indices.Count;

            idxBuffer = new IndexBuffer[partCount];
            materials = new Material[partCount];
            opBuf     = new RenderOperation[partCount];

            int index = 0;

            foreach (KeyValuePair <Material, FastList <int> > e in indices)
            {
                FastList <int> list = e.Value;
                list.Trim();

                materials[index] = e.Key;
                idxBuffer[index] = fac.CreateIndexBuffer(IndexBufferType.Bit32, list.Count, BufferUsage.Static);

                idxBuffer[index].SetData <int>(list.Elements);

                resourceSize += sizeof(int) * list.Count;

                // ==============================================================================================

                opBuf[index].Material  = e.Key;
                opBuf[index].Geomentry = new GeomentryData();
                opBuf[index].Geomentry.BaseIndexStart    = 0;
                opBuf[index].Geomentry.BaseVertex        = 0;
                opBuf[index].Geomentry.IndexBuffer       = idxBuffer[index];
                opBuf[index].Geomentry.PrimCount         = idxBuffer[index].IndexCount / 3;
                opBuf[index].Geomentry.PrimitiveType     = RenderPrimitiveType.TriangleList;
                opBuf[index].Geomentry.VertexBuffer      = vtxBuffer;
                opBuf[index].Geomentry.VertexCount       = partVtxCount[e.Key];
                opBuf[index].Geomentry.VertexDeclaration = vtxDecl;
                opBuf[index].Geomentry.VertexSize        = vtxSize;
                opBuf[index].Sender = this;
                index++;
            }

            indices2.Trim();

            idxBuffer2 = fac.CreateIndexBuffer(IndexBufferType.Bit32, indices2.Count, BufferUsage.Static);
            idxBuffer2.SetData <int>(indices2.Elements);
            opbuf2              = new RenderOperation[1];
            opbuf2[0].Material  = material2;
            opbuf2[0].Geomentry = new GeomentryData();
            opbuf2[0].Geomentry.BaseIndexStart    = 0;
            opbuf2[0].Geomentry.BaseVertex        = 0;
            opbuf2[0].Geomentry.IndexBuffer       = idxBuffer2;
            opbuf2[0].Geomentry.PrimCount         = idxBuffer2.IndexCount / 3;
            opbuf2[0].Geomentry.PrimitiveType     = RenderPrimitiveType.TriangleList;
            opbuf2[0].Geomentry.VertexBuffer      = vtxBuffer2;
            opbuf2[0].Geomentry.VertexCount       = partVtxCount2;
            opbuf2[0].Geomentry.VertexDeclaration = vtxDecl;
            opbuf2[0].Geomentry.VertexSize        = vtxSize;
            opbuf2[0].Sender = this;
        }
Ejemplo n.º 3
0
        public PlantDensityData GetDensity(float longtiude, float latitude)
        {
            const double yspan = Math.PI;

            int y = (int)(((yspan * 0.5 - latitude) / yspan) * Height);
            int x = (int)(((longtiude + Math.PI) / (2 * Math.PI)) * Width);

            if (y < 0) y += Height;
            if (y >= Height) y -= Height;

            if (x < 0) x += Width;
            if (x >= Width) x -= Width;

            int idx = y * Width + x;
            PlantDensityData result = new PlantDensityData();
            for (int i = 0; i < TypeCount; i++)
            {
                result.Density[i] = densityTable[i][idx] / 255f;
                //if (result.Density[i] < 0.1f)
                //    result.Density[i] = 0.1f;
            }
            return result;
        }