public Grass(SimpleSubrecord <String> EditorID, ObjectBounds ObjectBounds, Model Model, GrassData Data) { this.EditorID = EditorID; this.ObjectBounds = ObjectBounds; this.Model = Model; this.Data = Data; }
void DoUpdateGrassKernelCPU(ref GrassData[] datas, int idx) { GrassData data = datas[idx]; Vector3 expansiveForce = Vector3.zero; for (int i = 0; _obstaclesDataTestCPU != null && i < _obstaclesDataTestCPU.Length; ++i) { Vector3 dirToObstacle = _obstaclesDataTestCPU[i].Position - data.Position; float obstacleRadiusSQ = _obstaclesDataTestCPU[i].Radius * _obstaclesDataTestCPU[i].Radius; float distToObstacleSQ = dirToObstacle.x * dirToObstacle.x + dirToObstacle.y * dirToObstacle.y + dirToObstacle.z * dirToObstacle.z; if (distToObstacleSQ - obstacleRadiusSQ < 0) { float flattening = (1f - smoothstep(0f, 1f, distToObstacleSQ)) * Time.deltaTime * 4f; data.Flattening = Mathf.Max(data.Flattening - flattening, 0.2f); } if (distToObstacleSQ - obstacleRadiusSQ < 4f) { float forceIntensity = 1 - smoothstep(0f, 4f, distToObstacleSQ); expansiveForce += Vector3.Normalize(-dirToObstacle) * _obstaclesDataTestCPU[i].ExpansiveForce * forceIntensity; expansiveForce.y = 0f; data.ExpansiveForce = expansiveForce; } } datas[idx] = data; }
public Grass() { EditorID = new SimpleSubrecord <String>("EDID"); ObjectBounds = new ObjectBounds("OBND"); Model = new Model(); Data = new GrassData("DATA"); }
/*public void GenShadowMap() { * * }*/ /// <summary> /// 预生成草地信息数组,传输给grassMaterial /// </summary> public void PregenerateGrassInfo() { Vector3Int startPosition = Vector3Int.zero; System.Random random = new System.Random(); GrassData[] grassData = new GrassData[pregenerateGrassAmount]; //随机生成草根位置、方向、高度、密度索引 for (int i = 0; i < pregenerateGrassAmount; i++) { float deltaX = (float)random.NextDouble(); float deltaZ = (float)random.NextDouble(); Vector3 root = new Vector3(deltaX * patchSize, 0, deltaZ * patchSize); GrassData data = new GrassData(0.5f + 0.5f * (float)random.NextDouble(), (float)random.NextDouble(), new Vector4(root.x, root.y, root.z, (float)random.NextDouble())); grassData[i] = data; } grassBuffer = new ComputeBuffer(pregenerateGrassAmount, sizeof(float) * 6); grassBuffer.SetData(grassData); //send to gpu grassMaterial.SetInt("_SectionCount", bladeSectionCount); Shader.SetGlobalFloat("_TileSize", patchSize); grassMaterial.SetBuffer("_patchData", grassBuffer); //test Shader.SetGlobalInt("_SectionCount", bladeSectionCount); Shader.SetGlobalBuffer("_patchData", grassBuffer); }
public void SetMapGrassData(GrassData grassData) { GrassDataInfo = grassData; SetTextures(grassData.GrassTextures); _ShowBlockDirty = true; _SubmitInstanceDirty = true; }
private void Spawn() { const float distanceIncrement = (Constants.MaxDist - Constants.MinDist) / Constants.PlayerGrassPoolSize; float distance = Constants.MinDist, angle = 0f; var playerLoc = _playerTransform.position; playerLoc.y = 0f; for (int i = 0; i < Constants.PlayerGrassPoolSize; i++) { var loc = playerLoc + new Vector3(Mathf.Sin(angle), 0f, Mathf.Cos(angle)) * distance; var grassEntity = _entityManager.Instantiate(_templateEntity); _entityManager.SetComponentData(grassEntity, new Translation { Value = loc }); var grassData = new GrassData() { IsDynamic = true, SwayDuration = 0, StaticCullingId = -1, }; _entityManager.AddComponent <GrassData>(grassEntity); _entityManager.SetComponentData(grassEntity, grassData); _entityManager.AddComponentData(grassEntity, new Disabled()); distance += distanceIncrement; angle += Constants.GrassRadialGap / (Mathf.PI * distance); } }
public GrassChunk(GrassData _data) { TipSize = _data.TipSize; OneLinePerChunkTipNum = _data.OneLinePerChunkTipNum; OneChunkTipNum = OneLinePerChunkTipNum * OneLinePerChunkTipNum; OneChunkSize = TipSize * OneLinePerChunkTipNum; DummyPointElements = _data.TerrainSize / TipSize; MaptipIndicesElements = _data.TerrainSize / OneChunkSize; if (_data.ChunkWidth % 2 == 1) { HalfWidth = (_data.ChunkWidth - 1) / 2; } else { HalfWidth = _data.ChunkWidth / 2; } if (_data.ChunkDepth % 2 == 1) { HalfDepth = (_data.ChunkDepth - 1) / 2; } else { HalfDepth = _data.ChunkDepth / 2; } }
protected override void OnUpdate() { float deltaTime = Time.DeltaTime; //赋给类的成员变量 if (mJobStarted) { //mJobHandle.Complete(); //Debug.Log(mGrassData.Length); // if(mGrassArray == null) // mGrassArray = mGrassData.ToArray(); //Debug.Log(" 1mTempGrassData.Length: " + mTempGrassData.Length); if (positionBuffer == null) { //Debug.Log("mTempGrassData.Length: " + mTempGrassData.Length); positionBuffer = new ComputeBuffer(mTempGrassData.Length, 16); positionBuffer.SetData(mTempGrassData.AsArray()); } mTempGrassData.Dispose(); } NativeList <GrassData> tempList = new NativeList <GrassData>(0, Allocator.TempJob); mTempGrassData = tempList; //mGrassData.Clear(); //1. culling. Entities .WithName("GrassSystem") .WithStoreEntityQueryInField(ref query) .ForEach((in Unity.Transforms.Translation position, in GrassInstanceComponent grassInstance) => { // rotation.Value = math.mul( // math.normalize(rotation.Value), // quaternion.AxisAngle(math.up(), rotationSpeed.RadiansPerSecond * deltaTime)); //testArray.Append(grassInstance.InstanceID); uint test = grassInstance.InstanceID; GrassData d = new GrassData() { Position = position.Value, InstanceID = grassInstance.InstanceID, }; tempList.Add(d); })
public override void ReadData(ESPReader reader, long dataEnd) { while (reader.BaseStream.Position < dataEnd) { string subTag = reader.PeekTag(); switch (subTag) { case "EDID": if (EditorID == null) { EditorID = new SimpleSubrecord <String>(); } EditorID.ReadBinary(reader); break; case "OBND": if (ObjectBounds == null) { ObjectBounds = new ObjectBounds(); } ObjectBounds.ReadBinary(reader); break; case "MODL": if (Model == null) { Model = new Model(); } Model.ReadBinary(reader); break; case "DATA": if (Data == null) { Data = new GrassData(); } Data.ReadBinary(reader); break; default: throw new Exception(); } } }
public void Save() { int xMax = Mathf.CeilToInt((1.0f * MapSize.x / GrassInstance.BlockSize.x)); int yMax = Mathf.CeilToInt((1.0f * MapSize.y / GrassInstance.BlockSize.y)); GrassData grassData = ScriptableObject.CreateInstance <GrassData>(); for (int i = 0; i < xMax * yMax; i++) { grassData.BlockList.Add(new GrassData.GrassBlock()); } grassData.BlockXMax = xMax; grassData.BlockYMax = yMax; var grassRoot = transform; var msehFilters = grassRoot.GetComponentsInChildren <MeshFilter>(); HashSet <Texture2D> textures = new HashSet <Texture2D>(); foreach (var msehFilter in msehFilters) { var blockX = Mathf.FloorToInt(1.0f * msehFilter.transform.position.x / GrassInstance.BlockSize.x); var blockY = Mathf.FloorToInt(1.0f * msehFilter.transform.position.z / GrassInstance.BlockSize.y); var index = blockY * xMax + blockX; var grassItem = new GrassData.GrassItem(); grassData.BlockList[index].GrassItems.Add(grassItem); grassItem.TransformMatrix = msehFilter.transform.localToWorldMatrix; grassItem.UV0Offset = new Vector4(1f, 1f, 0f, 0f); foreach (var uvInfo in msehFilter.sharedMesh.uv) { grassItem.UV0Offset.x = Mathf.Min(grassItem.UV0Offset.x, uvInfo.x); grassItem.UV0Offset.y = Mathf.Min(grassItem.UV0Offset.y, uvInfo.y); grassItem.UV0Offset.z = Mathf.Max(grassItem.UV0Offset.z, uvInfo.x); grassItem.UV0Offset.w = Mathf.Max(grassItem.UV0Offset.w, uvInfo.y); } var grassEditorDataCache = msehFilter.GetComponent <GrassEditorDataCache>(); grassItem.ColorInfo = grassEditorDataCache.GrassColor; var texture = grassEditorDataCache.GrassTexture; var assetName = texture.name; grassItem.TextureName = assetName; textures.Add(texture as Texture2D); } grassData.GrassTextures = textures.ToList(); if (!Directory.Exists(GrassDataDir)) { Directory.CreateDirectory(GrassDataDir); AssetDatabase.Refresh(); } AssetDatabase.CreateAsset(grassData, GrassDataDir + "/" + GrassDataFileName + ".asset"); }
void AddGrassTexturesToTerrain(GrassData TerrainGrassData, ChunkData chunkData, int detailLayer) { Texture2D grassTexture = TerrainGrassData.GrassTexture; //Set detail texture DetailPrototype[] detailPrototype = chunkData.detailPrototype; detailPrototype[detailLayer] = new DetailPrototype(); detailPrototype[detailLayer].prototypeTexture = grassTexture; //Set grass colour detailPrototype[detailLayer].healthyColor = TerrainGrassData.GrassColour; detailPrototype[detailLayer].dryColor = TerrainGrassData.GrassColourDry; detailPrototype[detailLayer].renderMode = DetailRenderMode.GrassBillboard; detailPrototype[detailLayer].maxHeight = TerrainGrassData.GrassMaxHeight; detailPrototype[detailLayer].minHeight = TerrainGrassData.GrassMinHeight; detailPrototype[detailLayer].maxWidth = TerrainGrassData.GrassMaxWidth; detailPrototype[detailLayer].minWidth = TerrainGrassData.GrassMinWidth; }
public override void ReadDataXML(XElement ele, ElderScrollsPlugin master) { XElement subEle; if (ele.TryPathTo("EditorID", false, out subEle)) { if (EditorID == null) { EditorID = new SimpleSubrecord <String>(); } EditorID.ReadXML(subEle, master); } if (ele.TryPathTo("ObjectBounds", false, out subEle)) { if (ObjectBounds == null) { ObjectBounds = new ObjectBounds(); } ObjectBounds.ReadXML(subEle, master); } if (ele.TryPathTo("Model", false, out subEle)) { if (Model == null) { Model = new Model(); } Model.ReadXML(subEle, master); } if (ele.TryPathTo("Data", false, out subEle)) { if (Data == null) { Data = new GrassData(); } Data.ReadXML(subEle, master); } }
/// <summary> /// Initializes fields to default values if they were null /// post serialization. /// </summary> void OnEnable() { _instance = this; IsInitialized = true; if (Generator == null) { Generator = new GenerationData(); } if (ShaderData == null) { ShaderData = new ShaderData(); } if (BiomesData == null) { BiomesData = new List <BiomeData>(); } if (Details == null) { Details = new List <DetailData>(); } if (HeightMapData == null) { HeightMapData = new TileMapData { Name = "Height Map" } } ; if (TemperatureMapData == null) { TemperatureMapData = new TileMapData { Name = "Temperature Map", RampColor1 = Color.red, RampColor2 = Color.blue } } ; if (MoistureMapData == null) { MoistureMapData = new TileMapData { Name = "Moisture Map", RampColor1 = Color.cyan, RampColor2 = Color.white } } ; if (Tessellation == null) { Tessellation = new TessellationData(); } if (Grass == null) { Grass = new GrassData(); } if (EditorState == null) { EditorState = new EditorStateData(); } } void Start() { CreateMTD(); if (Generator.GenerateOnStart) { Generate(); } } void Update() { if (!IsInitialized) { return; } if (Application.isPlaying && Generator.Pool != null && Generator.GenerateOnStart) { //Generator.Pool.ResetQueue(); Generator.Pool.Update(); } } void Reset() { OnEnable(); //Initialize default values }
void SpawnGrass(GrassData TerrainGrassData, ChunkData chunkData, int detailLayer) { MapGenerator mapGenerator = new MapGenerator(); TerrainData terrainData = chunkData.terrainData; Terrain terrain = chunkData.terrain; const int resolutionMultipier = 2; const int grassResolution = TerrainResolution * resolutionMultipier; int[,] grassMap = new int[grassResolution, grassResolution]; float[,] fGrassMap = mapGenerator.GenerateNoiseMap(TerrainGrassData.GrassNoiseData, grassResolution, chunkData.position); int incremement = 1;// (int)(1 / TerrainGrassData.GrassSpawnDensity); System.Random rand = new System.Random(); int spawnDensity = TerrainGrassData.GrassSpawnDensity; for (int i = 0; i < grassResolution; i += incremement) { for (int j = 0; j < grassResolution; j += incremement) { float terrainHeight = terrain.terrainData.GetHeight((int)(j / resolutionMultipier), (int)(i / resolutionMultipier)) / (float)ProceduralTerrain.Current.TerrainMapData.TerrainHeight; //Get alpha map at this location (inverted) float[,,] localAlphaMap = terrainData.GetAlphamaps(j / resolutionMultipier, i / resolutionMultipier, 1, 1); //Get the strength of the terrain grass texture at this point on the terrain float grassStrength = localAlphaMap[0, 0, 2]; //2 being the grass texture on the terrain if (grassStrength >= TerrainGrassData.GrassSpawnGroundTextureThreshold) { grassMap[i, j] = spawnDensity; } else { grassMap[i, j] = 0; continue; } //Compare against generated noise if (fGrassMap[i, j] >= TerrainGrassData.GrassSpawnNoiseThreshold) { grassMap[i, j] = spawnDensity; } else { grassMap[i, j] = 0; continue; } //Compare against spawn rate chance, skip if grass spawn chance is 1 as it will always spawn if (TerrainGrassData.GrassSpawnChance < 1) { if (rand.Next(0, 100) <= TerrainGrassData.GrassSpawnChance * 100) { grassMap[i, j] = spawnDensity; } else { grassMap[i, j] = 0; continue; } } //If grass is not within min and max height if (!(terrainHeight >= TerrainGrassData.MinGrassSpawnHeight && terrainHeight <= TerrainGrassData.MaxGrassSpawnHeight)) { grassMap[i, j] = 0; } } } //Remove grass already in this area in other detail maps for (int i = 1; i <= TerrainGrassDataArray.Length; i++) { if (detailLayer < i) { break; } //Get grass map of layer below int[,] tempGrassMap = terrain.terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, detailLayer - i); //Take grass map away from temp grass map for (int x = 0; x < tempGrassMap.GetLength(0); x++) { for (int y = 0; y < tempGrassMap.GetLength(1); y++) { //If grass here, remove grass from temp grass map if (grassMap[x, y] > 0) { tempGrassMap[x, y] = 0; } } } //Assign updated temp grass map back to terrain terrain.terrainData.SetDetailLayer(0, 0, detailLayer - i, tempGrassMap); } terrain.terrainData.SetDetailLayer(0, 0, detailLayer, grassMap); terrain.Flush(); }
void DoUpdateGrassKernelCPU(ref GrassData[] datas, int idx) { GrassData data = datas[idx]; Vector3 expansiveForce = Vector3.zero; for(int i = 0; _obstaclesDataTestCPU != null && i < _obstaclesDataTestCPU.Length; ++i) { Vector3 dirToObstacle = _obstaclesDataTestCPU[i].Position - data.Position; float obstacleRadiusSQ = _obstaclesDataTestCPU[i].Radius*_obstaclesDataTestCPU[i].Radius; float distToObstacleSQ = dirToObstacle.x*dirToObstacle.x + dirToObstacle.y*dirToObstacle.y + dirToObstacle.z*dirToObstacle.z; if(distToObstacleSQ-obstacleRadiusSQ < 0) { float flattening = (1f-smoothstep(0f, 1f, distToObstacleSQ)) * Time.deltaTime * 4f; data.Flattening = Mathf.Max(data.Flattening - flattening, 0.2f); } if(distToObstacleSQ-obstacleRadiusSQ < 4f) { float forceIntensity = 1-smoothstep(0f, 4f, distToObstacleSQ); expansiveForce += Vector3.Normalize(-dirToObstacle) * _obstaclesDataTestCPU[i].ExpansiveForce * forceIntensity; expansiveForce.y = 0f; data.ExpansiveForce = expansiveForce; } } datas[idx] = data; }