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