void ReGen() { VoxelGrassMeshComputer.Init(); m_Grasses.Clear(); RaycastHit rch; for (float x = m_StartCoord.x + 0.5f; x < m_StartCoord.x + m_GenAreaSize; ++x) { for (float z = m_StartCoord.z + 0.5f; z < m_StartCoord.z + m_GenAreaSize; ++z) { Vector3 origin = new Vector3(x, 512f, z); if (Physics.Raycast(origin, Vector3.down, out rch, 1024, 1 << Pathea.Layer.VFVoxelTerrain)) { VoxelGrassInstance gi = new VoxelGrassInstance(); gi.Position = rch.point; gi.Density = 1; gi.Normal = rch.normal; gi.ColorF = m_GrassColor; gi.Prototype = m_ProtoType; m_Grasses.Add(gi); } } } VoxelGrassMeshComputer.ComputeMesh(m_Grasses, 0, m_Mesh, m_Density); m_Grasses.Clear(); }
private static int RandomCount(float expectation, VoxelGrassInstance vgi) { float min = (float)((int)(expectation)); float p = expectation - min; return((int)((p == 0f) ? min : ((vgi.RandAttr.x < p) ? min + 1 : min))); }
public void CopyTo(VoxelGrassInstance rgi) { m_Position_x = rgi.m_Position_x; m_Position_y = rgi.m_Position_y; m_Position_z = rgi.m_Position_z; m_Density = rgi.m_Density; m_Normal_x = rgi.m_Normal_x; m_Normal_z = rgi.m_Normal_z; m_Color_r = rgi.m_Color_r; m_Color_g = rgi.m_Color_g; m_Color_b = rgi.m_Color_b; m_Prototype = rgi.m_Prototype; }
public static void ComputeParticleMesh(VoxelGrassInstance[] grass_array, int count) { s_Output.Reset(); // Billboard grasses for (int i = 0; i < count; ++i) { VoxelGrassInstance vgi = grass_array[i]; int a = i * 4; int b = a + 1; int c = a + 2; int d = a + 3; s_Output.Norms[d] = s_Output.Norms[c] = s_Output.Norms[b] = s_Output.Norms[a] = vgi.RandPos(0); Vector3 n = vgi.Normal; s_Output.UVs[d] = s_Output.UVs[c] = s_Output.UVs[b] = s_Output.UVs[a] = new Vector2(n.x, n.z); s_Output.UV2s[d] = s_Output.UV2s[c] = s_Output.UV2s[b] = s_Output.UV2s[a] = new Vector2((float)(vgi.Prototype) / (float)(GrassPrototypeMgr.s_PrototypeCount), 0); s_Output.Color32s[d] = s_Output.Color32s[c] = s_Output.Color32s[b] = s_Output.Color32s[a] = Color.white; } s_Output.BillboardCount = count; s_Output.TriquadCount = 0; s_Output.TotalVertCount = count * 4; }
private void PlantANewGrass(int startX, int startZ, int iX, int iZ, float fDensity, VoxelPaintXML.PlantDescCLS[] pVeges, float[][] tileHeightBuf, List <VoxelGrassInstance> outlstGrassInst) { int ix = iX + VoxelTerrainConstants._numVoxelsPrefix; int iz = iZ + VoxelTerrainConstants._numVoxelsPrefix; float fy = tileHeightBuf[iz][ix]; if (fy < 4.0f) { return; //minHeight } float fHeightXL = tileHeightBuf[iz - 1][ix]; float fHeightXR = tileHeightBuf[iz + 1][ix]; float fHeightZL = tileHeightBuf[iz][ix - 1]; float fHeightZR = tileHeightBuf[iz][ix + 1]; float sx = fHeightZR - fHeightZL; // _iC is x float sz = fHeightXR - fHeightXL; // _iR is z int nVegesTypes = pVeges.Length; int idxVegeType = 0; int rand100 = myRand.Next(100); for (; idxVegeType < nVegesTypes && pVeges[idxVegeType].pct < rand100; idxVegeType++) { ; } if (idxVegeType >= nVegesTypes) { return; } VoxelGrassInstance _grassInst = new VoxelGrassInstance(); _grassInst.Position = new Vector3(startX + iX, fy, startZ + iZ); _grassInst.Density = fDensity; _grassInst.Normal = new Vector3(-sx, 2.0f, sz); // The attribute will normalize this vector _grassInst.ColorDw = new Color32(0xff, 0xff, 0xff, 0xff); _grassInst.Prototype = pVeges[idxVegeType].idx; outlstGrassInst.Add(_grassInst); }
/// <summary> /// Computes the mesh elements info the output /// </summary> /// <param name='grass_list'> /// Grass list. /// </param> /// <param name='density'> /// Global Density. /// </param> public static void ComputeMesh(List <VoxelGrassInstance> grass_list, List <VoxelGrassInstance> tri_grass_list, float density) { s_Output.Reset(); int grass_cnt = 0; int tri_grass_cnt = 0; if (grass_list != null) { grass_cnt = grass_list.Count; } if (tri_grass_list != null) { tri_grass_cnt = tri_grass_list.Count; } Vector3 up = Vector3.up; int quad = 0; float _2pi = Mathf.PI * 2; float _page_interval = _2pi / 3; float angle_randomness = 0.3f; // Billboard grasses for (int i = 0; i < grass_cnt; ++i) { VoxelGrassInstance vgi = grass_list[i]; int randcnt = RandomCount(s_FullDensity * vgi.Density * density, vgi); for (int q = 0; q < randcnt; ++q) { int a = quad * 4; int b = a + 1; int c = a + 2; int d = a + 3; s_Output.Norms[d] = s_Output.Norms[c] = s_Output.Norms[b] = s_Output.Norms[a] = vgi.RandPos(q); Vector3 n = vgi.Normal; Vector3 n1 = (n * 1.25f - up * 0.25f).normalized; Vector3 n2 = (n * 0.5f + up * 0.5f).normalized; s_Output.UVs[a] = new Vector2(n1.x, n1.z); s_Output.UVs[c] = s_Output.UVs[b] = new Vector2(n2.x, n2.z); s_Output.UVs[d] = s_Output.UVs[a]; s_Output.UV2s[d] = s_Output.UV2s[c] = s_Output.UV2s[b] = s_Output.UV2s[a] = new Vector2((float)(vgi.Prototype) / (float)(GrassPrototypeMgr.s_PrototypeCount), 0); s_Output.Color32s[d] = s_Output.Color32s[c] = s_Output.Color32s[b] = s_Output.Color32s[a] = vgi.ColorDw; quad++; } } s_Output.BillboardCount = quad; // Tri-quad grasses for (int i = 0; i < tri_grass_cnt; ++i) { VoxelGrassInstance vgi = tri_grass_list[i]; int randcnt = RandomCount(s_FullDensity * vgi.Density * density * 0.333f, vgi); for (int t = 0; t < randcnt; ++t) { float phase = (float)(vgi.RandAttr.x) * _2pi; Vector3 randpos = vgi.RandPos(t); for (int page = 0; page < 3; ++page) { int a = quad * 4; int b = a + 1; int c = a + 2; int d = a + 3; s_Output.Norms[d] = s_Output.Norms[c] = s_Output.Norms[b] = s_Output.Norms[a] = randpos; Vector3 n = vgi.Normal; Vector3 n1 = (n * 1.1f - up * 0.1f).normalized; Vector3 n2 = (n * 0.5f + up * 0.5f).normalized; s_Output.UVs[a] = new Vector2(n1.x, n1.z); s_Output.UVs[c] = s_Output.UVs[b] = new Vector2(n2.x, n2.z); s_Output.UVs[d] = s_Output.UVs[a]; s_Output.UV2s[d] = s_Output.UV2s[c] = s_Output.UV2s[b] = s_Output.UV2s[a] = new Vector2((float)(vgi.Prototype - 64) / (float)(GrassPrototypeMgr.s_PrototypeCount), page * _page_interval + phase + ((float)(vgi.RandAttrs(page + 1).x) - 0.5f) * angle_randomness); s_Output.Color32s[d] = s_Output.Color32s[c] = s_Output.Color32s[b] = s_Output.Color32s[a] = vgi.ColorDw; quad++; } } } s_Output.TriquadCount = quad - s_Output.BillboardCount; s_Output.TotalVertCount = quad * 4; }