unsafe void BuildTrunk(RenderSystem rs) { FileLocation fl = FileSystem.Instance.Locate("shuzhuang.mesh", GameFileLocs.Model); ModelMemoryData mdlData2 = new ModelMemoryData(rs, fl); loadedModels.Add(mdlData2); MeshData[] dataArr2 = mdlData2.Entities; if (dataArr2.Length == 1) { TreeModelData mdl; MeshData data = dataArr2[0]; Material[][] mtrls = data.Materials; int partCount = mtrls.Length; FastList<int>[] indices = new FastList<int>[partCount]; for (int i = 0; i < partCount; i++) indices[i] = new FastList<int>(); mdl.Materials = new Material[partCount]; mdl.Indices = new int[partCount][]; mdl.PartVtxCount = new int[partCount]; MeshFace[] faces = data.Faces; for (int i = 0; i < faces.Length; i++) { int matId = faces[i].MaterialIndex; indices[matId].Add(faces[i].IndexA); indices[matId].Add(faces[i].IndexB); indices[matId].Add(faces[i].IndexC); } for (int i = 0; i < partCount; i++) { Material mtrl = mtrls[i][0]; mdl.Materials[i] = mtrl; indices[i].Trim(); mdl.Indices[i] = indices[i].Elements; int partVtxCount = 0; bool[] passed = new bool[data.VertexCount]; for (int j = 0; j < mdl.Indices[i].Length; j++) { passed[indices[i][j]] = true; } for (int j = 0; j < data.VertexCount; j++) if (passed[j]) partVtxCount++; mdl.PartVtxCount[i] = partVtxCount; } mdl.VertexCount = data.VertexCount; mdl.VertexData = new byte[data.VertexCount * data.VertexSize]; fixed (byte* dst = &mdl.VertexData[0]) { Memory.Copy(data.Data.ToPointer(), dst, mdl.VertexData.Length); } trunk = mdl; } }
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; }
unsafe void BuildTrunk(RenderSystem rs) { FileLocation fl = FileSystem.Instance.Locate("shuzhuang.mesh", GameFileLocs.Model); ModelMemoryData mdlData2 = new ModelMemoryData(rs, fl); loadedModels.Add(mdlData2); MeshData[] dataArr2 = mdlData2.Entities; if (dataArr2.Length == 1) { TreeModelData mdl; MeshData data = dataArr2[0]; Material[][] mtrls = data.Materials; int partCount = mtrls.Length; FastList <int>[] indices = new FastList <int> [partCount]; for (int i = 0; i < partCount; i++) { indices[i] = new FastList <int>(); } mdl.Materials = new Material[partCount]; mdl.Indices = new int[partCount][]; mdl.PartVtxCount = new int[partCount]; MeshFace[] faces = data.Faces; for (int i = 0; i < faces.Length; i++) { int matId = faces[i].MaterialIndex; indices[matId].Add(faces[i].IndexA); indices[matId].Add(faces[i].IndexB); indices[matId].Add(faces[i].IndexC); } for (int i = 0; i < partCount; i++) { Material mtrl = mtrls[i][0]; mdl.Materials[i] = mtrl; indices[i].Trim(); mdl.Indices[i] = indices[i].Elements; int partVtxCount = 0; bool[] passed = new bool[data.VertexCount]; for (int j = 0; j < mdl.Indices[i].Length; j++) { passed[indices[i][j]] = true; } for (int j = 0; j < data.VertexCount; j++) { if (passed[j]) { partVtxCount++; } } mdl.PartVtxCount[i] = partVtxCount; } mdl.VertexCount = data.VertexCount; mdl.VertexData = new byte[data.VertexCount * data.VertexSize]; fixed(byte *dst = &mdl.VertexData[0]) { Memory.Copy(data.Data.ToPointer(), dst, mdl.VertexData.Length); } trunk = mdl; } }