예제 #1
0
 public Grass(SimpleSubrecord <String> EditorID, ObjectBounds ObjectBounds, Model Model, GrassData Data)
 {
     this.EditorID     = EditorID;
     this.ObjectBounds = ObjectBounds;
     this.Model        = Model;
     this.Data         = Data;
 }
예제 #2
0
    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;
    }
예제 #3
0
 public Grass()
 {
     EditorID     = new SimpleSubrecord <String>("EDID");
     ObjectBounds = new ObjectBounds("OBND");
     Model        = new Model();
     Data         = new GrassData("DATA");
 }
예제 #4
0
    /*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);
    }
예제 #5
0
 public void SetMapGrassData(GrassData grassData)
 {
     GrassDataInfo = grassData;
     SetTextures(grassData.GrassTextures);
     _ShowBlockDirty      = true;
     _SubmitInstanceDirty = true;
 }
예제 #6
0
        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);
            }
        }
예제 #7
0
    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;
        }
    }
예제 #8
0
    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);
        })
예제 #9
0
        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();
                }
            }
        }
예제 #10
0
    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;
    }
예제 #12
0
        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();
    }
예제 #15
0
    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;
    }