public bool TerrainLoaded(UnityEngine.Terrain setting, float detailDistance) { var data = setting.terrainData; var detailResolution = data.detailResolution; var heightMapResolution = data.heightmapResolution; var prototypes = data.detailPrototypes; var detailCount = prototypes.Length; var division = Mathf.CeilToInt(detailResolution / (float)_detailNodeSize); if (!Helper.AlmostEqual(detailResolution, division * _detailNodeSize)) { return(false); } var detailData = new List <int[, ]>(); if (_instancingDraw == null) { _instancingDraw = new DetailInstancingDraw[detailCount]; } List <DividedDetailProperty> detailProps = new List <DividedDetailProperty>(); for (int i = 0; i < detailCount; ++i) { detailData.Add(data.GetDetailLayer(0, 0, detailResolution, detailResolution, i)); detailProps.Add(new DividedDetailProperty(data, prototypes[i], _detailNodeSize, i)); if (_instancingDraw[i] == null) { var renderer = new InstancingRenderer(prototypes[i]); _instancingDraw[i] = new DetailInstancingDraw(renderer, VisibilityShader, setting, data); } } var nodeSize = new Vector2(data.size.x / division, data.size.z / division); var cluster = new GpuInstancingNodeCluster <GpuInstancingDetailNode>(); cluster.InitDivision(setting.transform.position, nodeSize, division, division, detailDistance); cluster.InitHeightMap(data.GetHeights(0, 0, heightMapResolution, heightMapResolution), data.size.y); cluster.TerrainName = setting.name; _data.SetGridParam(data.size.x, detailDistance, nodeSize); _terrainProperty = new TerrainProperty(setting, data, detailDistance); for (int x = 0; x < division; ++x) { for (int z = 0; z < division; ++z) { var node = new GpuInstancingDetailNode(); node.TerrainName = setting.name; node.X = x; node.Z = z; node.SetInstantiationShader(_instantiationShader); node.SetShaderProperty(_terrainProperty, detailProps); node.InitCountInUnit(detailData, x, z, _detailNodeSize); cluster.AddNode(x, z, node); cluster.UpdateMaxCountInLayer(node); } } _data.AddCluster(cluster); return(true); }
public bool TerrainLoaded(UnityEngine.Terrain setting, float detailDistance, Vector3 basePos, float[,] heightMap) { var data = setting.terrainData; var detailResolution = data.detailResolution; var prototypes = data.detailPrototypes; var detailCount = prototypes.Length; var division = Mathf.CeilToInt(detailResolution / (float)_nodeSize); if (!Helper.AlmostEqual(detailResolution, division * _nodeSize)) { _logger.WarnFormat("unmatch param in detail: detailResolution -> {0}, unitSize -> {1}, division -> {2}", detailResolution, _nodeSize, division); return(false); } if (detailCount == 0) { _logger.Warn("no grass prototypes exists"); return(false); } var detailData = new List <int[, ]>(); if (_instancingDraw == null) { _instancingDraw = new DetailInstancingDraw[detailCount]; } List <DividedDetailProperty> detailProps = new List <DividedDetailProperty>(); float nodeMargin = float.MinValue; for (int i = 0; i < detailCount; ++i) { detailData.Add(data.GetDetailLayer(0, 0, detailResolution, detailResolution, i)); detailProps.Add(new DividedDetailProperty(prototypes[i], _nodeSize, i)); if (_instancingDraw[i] == null) { var renderer = new InstancingRenderer(prototypes[i]); nodeMargin = Mathf.Max(nodeMargin, renderer.SphereRadius); _instancingDraw[i] = new DetailInstancingDraw(renderer, VisibilityShader, SortShader, setting, data, basePos); } } var nodeSize = new Vector2(data.size.x / division, data.size.z / division); var cluster = new GpuInstancingNodeCluster <GpuInstancingDetailNode>(); cluster.InitDivision(basePos, nodeSize, division, division, detailDistance); cluster.InitHeightMap(heightMap, data.size.y, nodeMargin); cluster.TerrainName = setting.name; _data.SetGridParam(data.size.x, detailDistance, nodeSize); _terrainProperty = new TerrainProperty(); _terrainProperty.InitForDetail(setting, data, detailDistance, basePos); for (int x = 0; x < division; ++x) { for (int z = 0; z < division; ++z) { var node = new GpuInstancingDetailNode(); node.TerrainName = setting.name; node.X = x; node.Z = z; node.SetInstantiationShader(_instantiationShader); node.SetShaderProperty(_terrainProperty, detailProps); node.InitCountInUnit(detailData, x, z, _nodeSize); cluster.AddNode(x, z, node); cluster.UpdateMaxCountInLayer(node); } } _data.AddCluster(cluster); return(true); }