示例#1
0
		public void Append (MeshWrapper addMesh, Vector3 offset, int type)
		{
			//verts
			for (int v=0; v<addMesh.verts.Length; v++) verts[vertCounter+v] = addMesh.verts[v] + offset;
			if (normals != null) for (int v=0; v<addMesh.verts.Length; v++) verts[vertCounter+v] = addMesh.normals[v];
			if (tangents != null) for (int v=0; v<addMesh.verts.Length; v++) tangents[vertCounter+v] = addMesh.tangents[v];
			if (uvs != null) for (int v=0; v<addMesh.verts.Length; v++) uvs[vertCounter+v] = addMesh.uvs[v];
			if (uv1 != null) for (int v=0; v<addMesh.verts.Length; v++) uv1[vertCounter+v] = addMesh.uv1[v];
			if (colors != null) for (int v=0; v<addMesh.verts.Length; v++) colors[vertCounter+v] = addMesh.colors[v];

			//tris
		//	for (int t=0; t<addMesh.triangles[0].Length; t++) 
		//		triangles[type][triCounters[type] + t] = addMesh.triangles[0][t] + vertCounter;

			for (int t=0; t<addMesh.tris.Length; t++) 
				triangles[type][triCounters[type] + t] = addMesh.tris[t] + vertCounter;
			triCounters[type] += addMesh.tris.Length;
			
			//increment counters	
		//	triCounters[type] += addMesh.triangles[0].Length;
			vertCounter += addMesh.verts.Length;
		}
示例#2
0
		public void Build ()
		{
			if (land.profile) Profiler.BeginSample("Build Far");
			
			if (land.farMesh == null) { filter.sharedMesh.Clear(); return; }
			
			//round coordinates to prevent jitter
			int step = (int)(land.farSize / 5f);
			x = Mathf.RoundToInt( 1f*x/step ) * step;
			z = Mathf.RoundToInt( 1f*z/step ) * step;
			
			//creating wrapper
			MeshWrapper wrapper = new MeshWrapper(land.farMesh);
			wrapper.uvs = new Vector2[wrapper.verts.Length]; //do not load arrays from mesh, but create them
			wrapper.uv1 = new Vector2[wrapper.verts.Length];
			if (land.rtpCompatible) wrapper.colors = new Color[wrapper.verts.Length];

			//calculating array of types
			//TODO bring this fn somewhere (to VoxelTerrain) to avoid calculation 2 types per chunk
			int[] typeToChannel = new int[land.types.Length]; //[0,1,2,3,4,0,0,0]
			int counter = 0; 
			for (int t=0; t<land.types.Length; t++) 
			{
				if (land.types[t].filledTerrain) { typeToChannel[t]=counter; counter++; }
				else typeToChannel[t] = -1;
			}

			//gathering ref array
			bool[] refExist = new bool[land.types.Length];
			for (int i=0; i<land.types.Length; i++) refExist[i] = land.types[i].filledTerrain;

			//setting mesh constant arrays
			if (filter.sharedMesh==null || filter.sharedMesh.vertexCount != wrapper.verts.Length)
			{
				if (filter.sharedMesh==null) filter.sharedMesh = new Mesh();
				filter.sharedMesh.Clear();
				filter.sharedMesh.vertices = new Vector3[wrapper.verts.Length]; //to equalize number of verts with wrapper
				//filter.sharedMesh.tangents = new Vector4[wrapper.verts.Length];
			}

			#region Setting Verts

				for (int v=0; v<wrapper.verts.Length; v++)
				{
					//vert position
					float vertX = wrapper.verts[v].x * land.farSize;
					float vertZ = wrapper.verts[v].z * land.farSize;
					wrapper.verts[v] = new Vector3(vertX, land.data.GetTopPoint((int)vertX+x, (int)vertZ+z), vertZ); //there could be GetTopPoint with refExist, but this is faster

					//vert type
					int type = land.data.GetTopType((int)vertX+x, (int)vertZ+z, refExist);
					if (type>=typeToChannel.Length) type=0;
					int textureNum = typeToChannel[type];

					if (!land.rtpCompatible)
					{
						switch (textureNum)
						{
							case 0: wrapper.uvs[v] = new Vector2(1,0); break;
							case 1: wrapper.uvs[v] = new Vector2(0,1); break;
							case 2: wrapper.uv1[v] = new Vector2(1,0); break;
							case 3: wrapper.uv1[v] = new Vector2(0,1); break;
						}
					}
					else
					{
						switch (textureNum)
						{
							case 0: wrapper.colors[v] = new Color(1,0,0,0); break;
							case 1: wrapper.colors[v] = new Color(0,1,0,0); break;
							case 2: wrapper.colors[v] = new Color(0,0,1,0); break;
							case 3: wrapper.colors[v] = new Color(0,0,0,1); break;
						}
					}
				}
			#endregion

			#region Calculating normals

				wrapper.ApplyTo(filter.sharedMesh);
				filter.sharedMesh.RecalculateNormals();
				wrapper.normals = filter.sharedMesh.normals;

			#endregion

			#region Adjust (lower verts and disable tris)

				//calculating already built area
				int minX = 2147483000;
				int maxX = -2147483000;
				int minZ = 2147483000;
				int maxZ = -2147483000;

				for (int i=0; i<land.chunks.array.Length; i++)
				{
					Chunk chunk = land.chunks.array[i];
					if (chunk == null) continue;
					if (chunk.stage != Chunk.Stage.complete) continue;
					if (chunk.faces == null || chunk.faces.Length == 0) continue;

					if (chunk.offsetX < minX) minX = chunk.offsetX;
					if (chunk.offsetZ < minZ) minZ = chunk.offsetZ;
					if (chunk.offsetX + land.chunkSize > maxX) maxX = chunk.offsetX + land.chunkSize;
					if (chunk.offsetZ + land.chunkSize > maxZ) maxZ = chunk.offsetZ + land.chunkSize;
				}

				//finding verts that are intersecting already built chunks
				bool[] vertInChunk = new bool[wrapper.verts.Length];
				for (int i=0; i<wrapper.verts.Length; i++)
				{
					Vector3 vert = wrapper.verts[i];

					vertInChunk[i] = true;

					if (vert.x+x < minX || vert.z+z < minZ || vert.x+x > maxX || vert.z+z > maxZ) { vertInChunk[i] = false; continue; }

					int vertChunkX = Mathf.FloorToInt(1f*(vert.x+x)/land.chunkSize);
					int vertChunkZ = Mathf.FloorToInt(1f*(vert.z+z)/land.chunkSize);

					if (!land.chunks.CheckInRange(vertChunkX, vertChunkZ)) { vertInChunk[i] = false; continue; }

					Chunk chunk = land.chunks[vertChunkX, vertChunkZ];
					if (chunk == null || chunk.stage != Chunk.Stage.complete) vertInChunk[i] = false;

					//flooring vert a bit
					wrapper.verts[i] -= wrapper.normals[i]*0.5f;
				}

				//if all of the triangle verts are in chunk or at floor - disable triangle
				int[] tris = wrapper.triangles[0];
				for (int t=0; t<tris.Length; t+=3)
				{
					if ((vertInChunk[ tris[t] ] && vertInChunk[ tris[t+1] ] && vertInChunk[ tris[t+2] ]) ||
						(wrapper.verts[ tris[t] ].y<0.01f && wrapper.verts[ tris[t+1] ].y<0.01f && wrapper.verts[ tris[t+2]].y<0.01f) )
						{ tris[t]=0; tris[t+1]=0; tris[t+2]=0; }
				}

			#endregion

			//applying wrapper
			wrapper.ApplyTo(filter.sharedMesh);

			//resetting vertex colors
			if (!land.rtpCompatible)
			{
				Color[] colors = new Color[wrapper.verts.Length];
				for (int v=0; v<wrapper.verts.Length; v++) colors[v] = new Color(0.5f, 0.5f, 0.5f, 1f);
				filter.sharedMesh.colors = colors;
			}

			#region Material

				GetComponent<Renderer>().sharedMaterial = land.terrainMaterial;
				//MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();

				//int defaultType = 0;
				//	for(int i=0; i<typeToChannel.Length; i++) 
				//		if (typeToChannel[i] != 0) defaultType = i;
				
				//for(int i=0; i<4; i++)
				//	{
				//		string propPostfix = i==0 ? "" : (i+1).ToString();
						
				//		int type = defaultType;
				//		for (int j=0; j<typeToChannel.Length; j++) 
				//			if (typeToChannel[j]==i) type = j;

				//		//if (land.types[type].texture != null) materialPropertyBlock.AddTexture("_MainTex" + propPostfix, land.types[type].texture);
				//		//if (land.types[type].bumpTexture != null)materialPropertyBlock.AddTexture("_BumpMap" + propPostfix, land.types[type].bumpTexture);
				//	}

				//materialPropertyBlock.SetFloat("_Tile", 0.1f);
				//GetComponent<Renderer>().SetPropertyBlock(materialPropertyBlock);

			#endregion

			//moving object
			transform.localPosition = new Vector3(x,0,z);

			//shrinking bounds so that they do not exceed build dist
			//filter.sharedMesh.bounds = new Bounds(Vector3.zero, new Vector3(land.removeDistance, filter.sharedMesh.bounds.extents.y, land.removeDistance));

			if (land.profile) Profiler.EndSample();
		}
示例#3
0
		public void AppendWithFFD (MeshWrapper addMesh, int type, Vector3 cornerA, Vector3 cornerB, Vector3 cornerC, Vector3 cornerD, Vector3 normal)
		{
			//verts
			for (int v=0; v < addMesh.verts.Length; v++) 
			{
				float xPercent = addMesh.verts[v].x + 0.5f;
				float zPercent = addMesh.verts[v].z + 0.5f;
				
				Vector3 vertX1 = cornerB*xPercent + cornerA*(1-xPercent);
				Vector3 vertX2 = cornerC*xPercent + cornerD*(1-xPercent);
				
				verts[vertCounter+v] = vertX1*zPercent + vertX2*(1-zPercent) + new Vector3(0, addMesh.verts[v].y, 0); 
			}

			if (normals != null) 
			{
				if (normal.sqrMagnitude > 0.01f) for (int v=0; v<addMesh.verts.Length; v++) normals[vertCounter+v] = normal;
				else for (int v=0; v<addMesh.verts.Length; v++) normals[vertCounter+v] = addMesh.normals[v];
			}

			if (tangents != null) for (int v=0; v<addMesh.verts.Length; v++) tangents[vertCounter+v] = addMesh.tangents[v];
			if (uvs != null) for (int v=0; v<addMesh.verts.Length; v++) uvs[vertCounter+v] = addMesh.uvs[v];
			if (uv1 != null) for (int v=0; v<addMesh.verts.Length; v++) uv1[vertCounter+v] = addMesh.uv1[v];
			if (colors != null) for (int v=0; v<addMesh.verts.Length; v++) colors[vertCounter+v] = addMesh.colors[v];

			//tris
		//	for (int t=0; t<addMesh.triangles[0].Length; t++) 
		//		triangles[type][triCounters[type] + t] = addMesh.triangles[0][t] + vertCounter;

			for (int t=0; t<addMesh.tris.Length; t++) 
				triangles[type][triCounters[type] + t] = addMesh.tris[t] + vertCounter;
			triCounters[type] += addMesh.tris.Length;
			
			//increment counters	
		//	triCounters[type] += addMesh.triangles[0].Length;
			vertCounter += addMesh.verts.Length;
		}
示例#4
0
		//operators
		public void Append (MeshWrapper addMesh, Vector3 offset) { Append(addMesh, offset, 0); }
示例#5
0
		public void Append (MeshWrapper addMesh, float x,float y,float z, int type) //shift xyz. Type is submesh id that should be added to
		{
			//verts
			for (int v=0; v < addMesh.verts.Length; v++) 
			{
				int vBase = v+vertNum;
				
				verts[vBase] = new Vector3(addMesh.verts[v].x+x, addMesh.verts[v].y+y, addMesh.verts[v].z+z);
				normals[vBase] = addMesh.normals[v];
				tangents[vBase] = addMesh.tangents[v];
				uvs[vBase] = addMesh.uvs[v];
				uv1[vBase] = addMesh.uv1[v];
				colors[vBase] = addMesh.colors[v];
			}

			//tris
			for (int t=0; t<addMesh.subs[0].tris.Length; t++) 
				subs[type].tris[t+subs[type].triNum] = addMesh.subs[0].tris[t] + vertNum;
				
			subs[type].triNum += addMesh.subs[0].tris.Length;
				
			vertNum += addMesh.verts.Length;
		}
示例#6
0
		public void AppendToFace (MeshWrapper addMesh, Chunk.Face face, Vector3[] terrainVerts, int type, float height=1f, float incline=0f, float random=0f, bool takeNormals=true)
		{
			//verts
			for (int v=0; v < addMesh.verts.Length; v++) 
			{
				int vBase = v+vertNum;
				
				//random
				int randomNum = (int)Mathf.Repeat(face.x*20 + face.y*10 + face.z*5 + face.dir + v, 990);
				
				float xPercent = addMesh.verts[v].x + 0.5f;
				float zPercent = addMesh.verts[v].z + 0.5f;
				
				Vector3 vertX1 = terrainVerts[face.cornerNums.b]*xPercent + terrainVerts[face.cornerNums.a]*(1-xPercent);
				Vector3 vertX2 = terrainVerts[face.cornerNums.c]*xPercent + terrainVerts[face.cornerNums.d]*(1-xPercent);
				Vector3 vert = vertX1*zPercent + vertX2*(1-zPercent); 

				verts[vBase] = new Vector3(
					vert.x + face.normal.x*incline + (VoxelTerrain.random[randomNum]-0.5f)*random, 
					vert.y + addMesh.verts[v].y*height + (VoxelTerrain.random[randomNum+1]-0.5f)*random, 
					vert.z + face.normal.z*incline + (VoxelTerrain.random[randomNum+2]-0.5f)*random);
				
				if (takeNormals) normals[vBase] = face.normal;
				else normals[vBase] = addMesh.normals[v];
				
				tangents[vBase] = addMesh.tangents[v];
				uvs[vBase] = addMesh.uvs[v];
				uv1[vBase] = addMesh.uv1[v];
				
				colors[vBase] = addMesh.colors[v];
			}
			
			//tris
		//	for (int t=0; t<addMesh.triangles[0].Length; t++) 
		//		triangles[type][triCounters[type] + t] = addMesh.triangles[0][t] + vertCounter;

			for (int t=0; t<addMesh.tris.Length; t++) 
				triangles[type][triCounters[type] + t] = addMesh.tris[t] + vertCounter;
			triCounters[type] += addMesh.tris.Length;
			
			//increment counters	
		//	triCounters[type] += addMesh.triangles[0].Length;
			vertCounter += addMesh.verts.Length;
		}