/// <summary> /// Processes a <see cref="LODTerrain"/> in a <see cref="MAPTerrainMoHAA"/>. /// For MoHAA forks only. /// </summary> /// <param name="lodTerrain">The <see cref="LODTerrain"/> object to process.</param> /// <returns>A <see cref="MAPTerrainMoHAA"/> object to be added to a <see cref="MAPBrush"/> object.</returns> private MAPTerrainMoHAA ProcessTerrainMoHAA(LODTerrain lodTerrain) { string shader = _bsp.textures[lodTerrain.texture].name; MAPTerrainMoHAA.Partition partition = new MAPTerrainMoHAA.Partition() { shader = shader, textureScale = new double[] { 1, 1 }, }; MAPTerrainMoHAA terrain = new MAPTerrainMoHAA() { size = new Vector2d(9, 9), flags = ((lodTerrain.flags & (1 << 6)) > 0) ? 1 : 0, origin = new Vector3d(lodTerrain.x * 64, lodTerrain.y * 64, lodTerrain.baseZ), }; terrain.partitions.Add(partition); terrain.partitions.Add(partition); terrain.partitions.Add(partition); terrain.partitions.Add(partition); for (int i = 0; i < 9; ++i) { for (int j = 0; j < 9; ++j) { MAPTerrainMoHAA.Vertex vertex = new MAPTerrainMoHAA.Vertex() { height = lodTerrain.heightmap[i, j] * 2, }; terrain.vertices.Add(vertex); } } return(terrain); }
/// <summary> /// 烘焙环境信息到指定RenderTextrue /// </summary> /// <param name="terrain"></param> /// <param name="size"></param> /// <returns></returns> public static int Bake(LODTerrain terrain, int size = 512) { RenderTexture renderTexture = null; int num = -1; for (int i = 0; i < Terrainmapping.mapIndex.Count; i++) { if (Terrainmapping.mapIndex[i] < 0) { num = i; renderTexture = Terrainmapping.maps[i]; Terrainmapping.mapIndex[i] = num; break; } } if (renderTexture != null) { Terrainmapping.CreateObjects(); Terrainmapping.UpdateCameraModes(); Terrainmapping.rttCamera.gameObject.SetActive(true); Terrainmapping.rttCamera.enabled = true; Terrainmapping.sntMat = terrain.matrial; Terrainmapping.quad.renderer.lightmapIndex = terrain.renderer.lightmapIndex; Terrainmapping.quad.renderer.lightmapTilingOffset = terrain.renderer.lightmapTilingOffset; Terrainmapping.quad.renderer.material = Terrainmapping.sntMat; Terrainmapping.rttCamera.targetTexture = renderTexture; RenderTexture.active = renderTexture; Terrainmapping.rttCamera.Render(); Terrainmapping.rttCamera.gameObject.SetActive(false); RenderTexture.active = null; Terrainmapping.quad.renderer.material = null; Terrainmapping.sntMat = null; } return(num); }
/// <summary> /// Processes a <see cref="LODTerrain"/> in a <see cref="MAPTerrainMoHAA"/>. /// For MoHAA forks only. /// </summary> /// <param name="lodTerrain">The <see cref="LODTerrain"/> object to process.</param> /// <returns>A <see cref="MAPTerrainMoHAA"/> object to be added to a <see cref="MAPBrush"/> object.</returns> private MAPTerrainMoHAA ProcessTerrainMoHAA(LODTerrain lodTerrain) { string shader = _bsp.textures[lodTerrain.TextureIndex].Name; MAPTerrainMoHAA.Partition partition = new MAPTerrainMoHAA.Partition() { shader = shader, textureScale = new float[] { 1, 1 }, }; MAPTerrainMoHAA terrain = new MAPTerrainMoHAA() { size = new Vector2(9, 9), flags = ((lodTerrain.Flags & (1 << 6)) > 0) ? 1 : 0, origin = new Vector3(lodTerrain.X * 64, lodTerrain.Y * 64, lodTerrain.BaseZ), }; terrain.partitions.Add(partition); terrain.partitions.Add(partition); terrain.partitions.Add(partition); terrain.partitions.Add(partition); for (int i = 0; i < 9; ++i) { for (int j = 0; j < 9; ++j) { MAPTerrainMoHAA.Vertex vertex = new MAPTerrainMoHAA.Vertex() { height = lodTerrain.Heightmap[i, j] * 2, }; terrain.vertices.Add(vertex); } } return(terrain); }
/// <summary> /// Creates a <see cref="Mesh"/> appropriate for <paramref name="lodTerrain"/>. /// </summary> /// <param name="lodTerrain">The <see cref="LODTerrain"/> to create a <see cref="Mesh"/> for.</param> /// <param name="textureName">The name of the texture/shader applied to the <see cref="LODTerrain"/>.</param> /// <returns>The <see cref="Mesh"/> generated for <paramref name="lodTerrain"/>.</returns> protected Mesh CreateLoDTerrainMesh(LODTerrain lodTerrain, string textureName) { if (!materialDirectory.ContainsKey(textureName)) { LoadMaterial(textureName); } return(MeshUtils.CreateMoHAATerrainMesh(bsp, lodTerrain)); }
/// <summary> /// 创建网格UV坐标数据数据 /// </summary> public void BuildUVs() { if (LODTerrain.shareUVS == null) { LODTerrain.BuildShareUVS(); } this.mesh.uv = LODTerrain.shareUVS; this.uvs = LODTerrain.shareUVS; }
/// <summary> /// 创建网格三角形索引数组数据 /// </summary> public void BuildTriangles() { if (LODTerrain.shareTriangles == null) { LODTerrain.BuildShareTriangles(); } this.triangles = LODTerrain.shareTriangles; this.mesh.triangles = this.triangles; }
/// <summary> /// Builds a <see cref="Mesh"/> from the passed <see cref="LODTerrain"/> and returns it. /// </summary> /// <param name="bsp">The <see cref="BSP"/> which <paramref name="lodTerrain"/> came from.</param> /// <param name="lodTerrain">The <see cref="LODTerrain"/> to generate a <see cref="Mesh"/> from.</param> /// <returns>The <see cref="Mesh"/> created from the <see cref="LODTerrain"/>.</returns> public static Mesh CreateMoHAATerrainMesh(BSP bsp, LODTerrain lodTerrain) { Vector3 origin = new Vector3(lodTerrain.x * 64, lodTerrain.y * 64, lodTerrain.baseZ); Vector3[] corners = GetCornersForTerrain(origin, 512, (lodTerrain.flags & (1 << 6)) > 0); Vector3[] offsets = new Vector3[81]; for (int y = 0; y < 9; ++y) { for (int x = 0; x < 9; ++x) { if ((lodTerrain.flags & (1 << 6)) > 0) { offsets[(x * 9) + y] = (Vector3.up * lodTerrain.heightmap[y, x] * 2 * inch2MeterScale); } else { offsets[(y * 9) + x] = (Vector3.up * lodTerrain.heightmap[y, x] * 2 * inch2MeterScale); } } } Vector2[] uv = new Vector2[] { new Vector2(lodTerrain.textureCoords[0], lodTerrain.textureCoords[1]), new Vector2(lodTerrain.textureCoords[2], lodTerrain.textureCoords[3]), new Vector2(lodTerrain.textureCoords[4], lodTerrain.textureCoords[5]), new Vector2(lodTerrain.textureCoords[6], lodTerrain.textureCoords[7]), }; Vector2[] uv2 = new Vector2[4]; //Vector3[] textureAxes = TextureInfo.TextureAxisFromPlane(new Plane(corners[0], corners[1], corners[2])); //TextureInfo info = new TextureInfo(textureAxes[0].SwizzleYZ(), -textureAxes[1].SwizzleYZ(), Vector2.zero, Vector2.one / 2f, 0, 0, 0); Mesh mesh = new Mesh(); mesh.Clear(); mesh.vertices = corners; mesh.uv = uv; mesh.uv2 = uv2; mesh.CalculateTerrainVertices(offsets, 8); mesh.triangles = BuildDisplacementTriangles(8); mesh.NegateVs(); mesh.RecalculateNormals(); mesh.RecalculateBounds(); return(mesh); }
/// <summary> /// 地形资源加载完成,开始显示地形 /// </summary> /// <param name="asset"></param> private void OnTerrainLoadCompate(Asset asset) { if (asset.loaded) //资源加载的直接显示 { this.terrain = asset.terrain; this.terrain.name = this.key; this.terrain.transform.position = new Vector3(this.position.x, 0f, this.position.z); this.terrain.gameObject.layer = GameLayer.Layer_Ground; if (this._lightmapPrototype.lightmapIndex >= 0) { this.terrain.GetComponent <Renderer>().lightmapIndex = this._lightmapPrototype.lightmapIndex; this.terrain.GetComponent <Renderer>().lightmapTilingOffset = this._lightmapPrototype.lightmapTilingOffset; } this.terrain.splatsMapPath = string.Concat(new object[] { "Scenes/", this.region.scene.sceneID, "/", this.region.regionX, "_", this.region.regionY, "/", this.tileX, "_", this.tileY, "Splats" }); if (!GameScene.isPlaying) { this.terrain.BuildMaterial(null); } } else //不是加载的,创建一个基础的地形 { LODTerrainData terrainData = new LODTerrainData(); this.terrain = LODTerrain.CreateTerrainGameObject(terrainData, false); this.terrain.name = this.key; this.terrain.transform.position = new Vector3(this.position.x, 0f, this.position.z); this.terrain.gameObject.layer = GameLayer.Layer_Ground; this.terrain.Init(); } if (!GameScene.isPlaying && this.terrain != null) //给地形添加网格碰撞器 { this.terrain.gameObject.AddComponent <MeshCollider>(); } }
/// <summary> /// 使用地形数据信息创建地形游戏对象 /// </summary> /// <param name="terrainData">属性数据</param> /// <param name="useTrrainData"></param> /// <returns></returns> public static LODTerrain CreateTerrainGameObject(LODTerrainData terrainData, bool useTrrainData = false) { GameObject gameObject = new GameObject(); LODTerrain lODTerrain = gameObject.AddComponent <LODTerrain>(); gameObject.isStatic = true; lODTerrain.terrainData = terrainData; lODTerrain.terrainConfig = GameScene.mainScene.terrainConfig; lODTerrain.mesh = new Mesh(); if (GameScene.isPlaying) { lODTerrain.mesh.vertices = terrainData.vertices; } else { if (LODTerrain.shareVertices == null) { LODTerrain.BuildShareVertices(); } if (terrainData.vertices != null) { lODTerrain.vertices = terrainData.vertices; } else { lODTerrain.vertices = LODTerrain.shareVertices; } lODTerrain.normals = terrainData.normals; lODTerrain.tangents = terrainData.tangents; lODTerrain.mesh.vertices = lODTerrain.vertices; lODTerrain.BuildUVs(); lODTerrain.mesh.normals = lODTerrain.normals; lODTerrain.mesh.tangents = lODTerrain.tangents; lODTerrain.BuildTriangles(); } gameObject.AddComponent <MeshFilter>().mesh = lODTerrain.mesh; lODTerrain.terrainRenderer = gameObject.AddComponent <MeshRenderer>(); if (GameScene.isPlaying) { lODTerrain.terrainRenderer.enabled = false; lODTerrain.terrainRenderer.receiveShadows = true; lODTerrain.terrainRenderer.castShadows = false; } return(lODTerrain); }
/// <summary> /// 销毁回收 /// </summary> public void Destroy() { if (GameScene.isPlaying) { if (this.waterData != null) { this.waterData.Release(); } if (this.terrain != null) { this.terrain.Destroy(); DelegateProxy.GameDestory(this.terrain); DelegateProxy.GameDestory(this.terrain.gameObject); this.terrain = null; } if (this.water != null) { this.water.Destroy(); DelegateProxy.GameDestory(this.water); DelegateProxy.GameDestory(this.water.gameObject); this.water = null; } } else { if (this.terrain != null) { DelegateProxy.DestroyObjectImmediate(this.terrain.gameObject); } if (this.water != null) { DelegateProxy.DestroyObjectImmediate(this.water.gameObject); } } //同时销毁tile上的(静态)unit if (this.units != null) { while (this.units.Count > 0) { GameObjectUnit gameObjectUnit = this.units[0]; //进行destory,放入cache待重用 if (this.scene.ContainUnit(gameObjectUnit)) { this.scene.RemoveUnit(gameObjectUnit, true, true); } else { //场景不包含的unit,销毁,并加入静态缓存待重用 gameObjectUnit.Destroy(); this.scene.RemoveEmptyUnit(gameObjectUnit); } } this.units.Clear(); this.units = null; this.unitsMap.Clear(); this.unitsMap = null; } this.left = null; this.right = null; this.top = null; this.bot = null; this.top_left = null; this.top_right = null; this.bot_left = null; this.bot_right = null; this.region = null; this.scene = null; this._lightmapPrototype = null; this.waterData = null; this.heights = new float[0, 0]; this.grids = new int[0, 0]; this.heights = null; this.grids = null; }
public void PaintSplatsmap(LODTerrain terrain, Vector3 worldPos, Splat splat, int insertIndex = -1) { this.terrain = terrain; int num = -1; for (int i = 0; i < this.terrain.terrainData.splats.Length; i++) { if (this.terrain.terrainData.splats[i] == null) { this.terrain.terrainData.splats[i] = splat; num = i; break; } if (this.terrain.terrainData.splats[i].key == splat.key) { this.terrain.terrainData.splats[i] = splat; num = i; break; } } if (num < 0 && insertIndex >= 0) { if (insertIndex > this.terrain.terrainData.splats.Length - 1) { insertIndex = this.terrain.terrainData.splats.Length - 1; } this.terrain.terrainData.splats[insertIndex] = splat; } if (num < 0) { return; } if (num < this.terrain.terrainData.spaltsmapLayers) { int num2 = (int)(terrain.transform.position.x - worldPos.x) + 16; int num3 = (int)(terrain.transform.position.z - worldPos.z) + 16; int num4 = this.size / 2; float[,,] splatsmap = this.terrain.terrainData.splatsmap; for (int j = 0; j < 32; j++) { for (int k = 0; k < 32; k++) { int num5 = num2 - (31 - k) + num4; int num6 = num3 - j + num4; if (num5 >= 0 && num5 < this.size) { if (num6 >= 0 && num6 < this.size) { float num7 = this.GetStrength(num5, num6); float num8 = this.ApplyBrush(splatsmap[j, k, num], num7 * this.strengthen); splatsmap[j, k, num] = num8; this.Normalize(k, j, num, splatsmap); } } } } this.terrain.terrainData.SetSplasmap(0, 0, splatsmap); } else { LogSystem.Log(new object[] { "超出纹理层级。" }); } }