// Use this for initialization void Start() { crop = new Crop(); if(PlayerPrefs.GetString("FieldName") == ""){ crop.setType(PlayerPrefs.GetInt("CropType")); FieldName = PlayerPrefs.GetString("NFName"); alphatext = new float[terrain.GetComponent<Terrain>().terrainData.alphamapWidth,terrain.GetComponent<Terrain>().terrainData.alphamapHeight,2]; for(int i = 0; i < terrain.GetComponent<Terrain>().terrainData.alphamapWidth; i++){ for(int j = 0; j < terrain.GetComponent<Terrain>().terrainData.alphamapHeight; j++){ alphatext[i,j,0] = 1; alphatext[i,j,1] = 0; } } Vector3 localPos = new Vector3(50,0,50) - terrain.transform.position; Vector3 normalPos = new Vector3((localPos.x/terrain.GetComponent<Terrain>().terrainData.size.x) * terrain.GetComponent<Terrain>().terrainData.alphamapWidth, 0, (localPos.z/terrain.GetComponent<Terrain>().terrainData.size.z) * terrain.GetComponent<Terrain>().terrainData.alphamapHeight); alphatext[(int)normalPos.z,(int)normalPos.x,0] = 0; alphatext[(int)normalPos.z,(int)normalPos.x,1] = 1; terrain.GetComponent<Terrain>().terrainData.SetAlphamaps(0,0,alphatext); } else{ FieldName = PlayerPrefs.GetString("FieldName"); byte[] load = sf.Load (PlayerPrefs.GetString("FieldName")); UnitySerializer.DeserializeInto(load,sf); crop.setField(sf.getCrops()); terrain.GetComponent<Terrain>().terrainData.SetHeights(0,0,sf.getHM ()); terrain.GetComponent<Terrain>().terrainData.SetAlphamaps(0,0,sf.getAM()); alphatext = sf.getAM(); terrain.GetComponent<Terrain>().terrainData.SetAlphamaps(0,0,alphatext); loaded = true; } }
private void ExpandSplatMaps(int delta) { var splatmapSizeModifier = (int) (Math.Pow(2, delta)); var newFirstCount = (SplatMaps.GetUpperBound(0) + 1) * splatmapSizeModifier; var newSecondCount = (SplatMaps.GetUpperBound(1) + 1) * splatmapSizeModifier; var thirdCount = SplatMaps.GetUpperBound(2) + 1; var newSplatMaps = new float[newFirstCount, newSecondCount, thirdCount]; for (var x = 0; x < newFirstCount; x++) { for (var z = 0; z < newSecondCount; z++) { // ReSharper disable SuggestUseVarKeywordEverywhere -- we want to be clear this is an integer division and we want a compile error if that changes. int origX = x / splatmapSizeModifier; int origZ = z / splatmapSizeModifier; // ReSharper restore SuggestUseVarKeywordEverywhere for (var i = 0; i < thirdCount; i++) { newSplatMaps[x, z, i] = SplatMaps[origX, origZ, i]; } } } SplatMaps = newSplatMaps; }
// Use this for initialization void Start() { hmWidth = terr.terrainData.heightmapWidth; hmHeight = terr.terrainData.heightmapHeight; if (Debug.isDebugBuild) { heightMapBackup = terr.terrainData.GetHeights(0, 0, hmWidth, hmHeight); alphaMapBackup = terr.terrainData.GetAlphamaps(0, 0, alphaMapWidth, alphaMapHeight); } }
public void PlaceTrees(ProgressDelegate progressDelegate) { if (!Validate()) return; instances = new ArrayList(); TreesPosition = new List<TreePosition>(); //get alpha map width and height of terrain int alphamapWidth = terrainData.alphamapWidth; int alphamapHeight = terrainData.alphamapHeight; //get splat map of terrain splatmap = terrainData.GetAlphamaps(0,0,alphamapWidth,alphamapHeight); //dimension of splatmaps int xDim = splatmap.GetUpperBound(0); int yDim = splatmap.GetUpperBound(1); //how big is one unit in real world xUnit = (float)terrainData.size.x / (float)(xDim + 1); yUnit = (float)terrainData.size.z / (float)(yDim + 1); float percentPosition = 0.1f; progressDelegate("Placing trees", "Determining basic position", percentPosition); float calculation = 0.4f / xDim; for(int x = 0; x <= xDim; x ++) { for(int y = 0; y <= yDim; y ++) { foreach(TreeTextureSettings treeTexture in TreeTextures) { //this texture is not used for planting trees if (treeTexture.IsUsed == false) continue; float alphaMap = splatmap[x,y,treeTexture.Index]; //this texture is not where we are currently in if (alphaMap < treeTexture.AlphamapValue) continue; //check distance from the nearest tree if (IsTreePositionClose(x, y, treeTexture.TreeDistance, treeTexture.Index)) continue; TreePosition position = new TreePosition(); position.PosX = x; position.PosY = y; position.TreeIndex = treeTexture.DetermineTreePrototype; position.TextureIndex = treeTexture.Index; TreesPosition.Add(position); } } percentPosition += calculation; progressDelegate("Placing trees", "Determining basic position", percentPosition); } Place(progressDelegate); }
void Start() { terrain=gameObject.GetComponent<Terrain>(); heightmapSize = new TextureSize(terrain.terrainData.heightmapWidth,terrain.terrainData.heightmapHeight); alphamapSize = new TextureSize(terrain.terrainData.alphamapWidth,terrain.terrainData.alphamapHeight); numberOfAlphaLayers = terrain.terrainData.alphamapLayers; if (Debug.isDebugBuild){ heightmapBackup = terrain.terrainData.GetHeights(0, 0, heightmapSize.width, heightmapSize.height); alphamapBackup = terrain.terrainData.GetAlphamaps(0, 0, alphamapSize.width, alphamapSize.height); } }
public void loadChunk(float xVal, float yVal, float zVal) { x = xVal; z = zVal; x = x - x % (chunkSize); z = z - z % (chunkSize); y = y - y % (chunkSize); Vector3 position = new Vector3(x, 0, z); maxHeight = terrainScript.mountainHeight; loadVoxels = terrainScript.generateTerrain2(position, true); }
public void OnEnable() { if (wp8) return; //var b = gameObject.activeSelf; //Debug.LogWarning("OnEnable "+b); //if (b) //{ oldHeights = td.GetHeights(0, 0, td.heightmapWidth, td.heightmapHeight); oldalphamaps = td.GetAlphamaps(0, 0, td.alphamapWidth, td.alphamapHeight); for (int i = 0; i < td.detailPrototypes.Length; i++) olddetails.Add(td.GetDetailLayer(0, 0, td.detailWidth, td.detailHeight, i)); oldtrees = td.treeInstances; //} }
public Chunk(float x, float y, float z, int size, int height, float surfaceCrossValue, float noiseScaleFactor, Material material) { size ++; this.size = size; this.height = height; data = new float[size, height, size]; this.xOrigin = x; this.yOrigin = y; this.zOrigin = z; this.surfaceCrossValue = surfaceCrossValue; this.noiseScaleFactor = noiseScaleFactor; meshGameObject = new GameObject("Chunk" + x + "," + y + "," + z, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider)); meshGameObject.transform.position = new Vector3(x, y, z); mesh = new Mesh(); FillData(); TerrainMeshGenerator.FillMesh(ref mesh, data, size, height, surfaceCrossValue); data = null; meshGameObject.GetComponent<MeshFilter>().mesh = mesh; meshGameObject.GetComponent<MeshCollider>().sharedMesh = mesh; meshGameObject.GetComponent<MeshRenderer>().material = material; }
/// <summary> /// 创建地形分块 /// </summary> public void TerrainTileCreate(Vector2 rOffset) { if (mTerrainData == null) { return; } var rSplatMaps = mTerrainData.splatPrototypes; Scene rScene = EditorSceneManager.GetActiveScene(); LargeScene rLargeScene = ScriptableObject.CreateInstance <LargeScene>(); rLargeScene.ID = rScene.name; rLargeScene.Size = mTerrainData.size; rLargeScene.TileRows = mTileNumHeight; rLargeScene.TileCols = mTileNumWidth; rLargeScene.Offset = rOffset; // 保存大场景数据 string rLargeSceneConfigPath = string.Format(MultiSceneDir + "MultiScene/{0}.asset", rScene.name); AssetDatabase.CreateAsset(rLargeScene, rLargeSceneConfigPath); AssetDatabase.Refresh(); int k = 0; List <Terrain> rTerrains = new List <Terrain>(); for (int i = 0; i < mTileNumHeight; i++) { for (int j = 0; j < mTileNumWidth; j++) { TerrainData rTerrainData = new TerrainData(); rTerrainData.heightmapResolution = mTileSize; rTerrainData.baseMapResolution = mTerrainData.baseMapResolution; rTerrainData.SetDetailResolution(mTerrainData.detailResolution, 8); float[,] rHeights = mTerrainData.GetHeights((mTileSize - 1) * i, (mTileSize - 1) * j, mTileSize, mTileSize); rTerrainData.SetHeights(0, 0, rHeights); rTerrainData.size = new Vector3(mTerrainData.size.x / mTileNumWidth, mTerrainData.size.y, mTerrainData.size.z / mTileNumHeight); rTerrainData.splatPrototypes = CreateSplatPrototypes(rSplatMaps, mTerrainData.baseMapResolution, i, j); float[,,] rAlphaMaps = mTerrainData.GetAlphamaps((mTileSize - 1) * i, (mTileSize - 1) * j, mTileSize - 1, mTileSize - 1); string rTerrainPath = string.Format(MultiSceneDir + "{0}/tile_{1}_{2}.asset", rScene.name, i, j); string rTerrainConfigPath = string.Format(MultiSceneDir + "{0}/tile_{1}_{2}_config.asset", rScene.name, i, j); if (!Directory.Exists(Path.GetDirectoryName(rTerrainPath))) { Directory.CreateDirectory(Path.GetDirectoryName(rTerrainPath)); } SceneTile rTile = ScriptableObject.CreateInstance <SceneTile>(); rTile.ID = k; rTile.Row = i; rTile.Col = j; rTile.ParentID = rLargeScene.ID; rTile.Size = mTileSize; rTile.Offset = new Vector2(rTerrainData.size.x * i, rTerrainData.size.z * j); AssetDatabase.CreateAsset(rTerrainData, rTerrainPath); AssetDatabase.CreateAsset(rTile, rTerrainConfigPath); AssetDatabase.Refresh(); rTerrainData = AssetDatabase.LoadAssetAtPath(rTerrainPath, typeof(TerrainData)) as TerrainData; var rTerrainObj = Terrain.CreateTerrainGameObject(rTerrainData); rTerrainObj.name = string.Format("tile_{0}_{1}", i, j); rTerrainObj.transform.position = new Vector3(rTile.Offset.x + rOffset.x, 0, rTile.Offset.y + rOffset.y); Terrain rTerrain = rTerrainObj.GetComponent <Terrain>(); rTerrain.materialType = Terrain.MaterialType.BuiltInLegacyDiffuse; rTerrain.terrainData.alphamapResolution = mTileSize - 1; rTerrain.terrainData.SetAlphamaps(0, 0, rAlphaMaps); rTerrains.Add(rTerrain); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); k++; } } }
private SplatPrototype[] oldTerrainTextures; //the old textures that were used for the old texturing //Given the parameters, visualizes the map on the terrain public void visualizeMap(){ //in this case we wish to remember the old texturing if(oldShowPop == false && oldShowGrowth == false){ oldAlphaMap = CityGenerator.terrain.terrainData.GetAlphamaps (0, 0, CityGenerator.terrain.terrainData.alphamapWidth, CityGenerator.terrain.terrainData.alphamapHeight); oldTerrainTextures = CityGenerator.terrain.terrainData.splatPrototypes; } float popFrac; //the fraction in how much the pop map adds to the final texture float growthFrac; //the fraction in how much the growth map adds to the final texture //we wish to show the old alpha maps again if (CityGenerator.showPop == false && CityGenerator.showGrowth == false) { //set up old textures CityGenerator.terrain.terrainData.splatPrototypes = oldTerrainTextures; //set up old texturing CityGenerator.terrain.terrainData.SetAlphamaps (0, 0, oldAlphaMap); //store and restore the old values oldShowPop = CityGenerator.showPop; oldShowGrowth = CityGenerator.showGrowth; return; } else if (CityGenerator.showPop == true && CityGenerator.showGrowth == false) { //we are painting only the pop map popFrac = 1f; growthFrac = 0f; } else if (CityGenerator.showPop == false && CityGenerator.showGrowth == true) { //we are painting only the growth map popFrac = 0f; growthFrac = 1f; } else { //we are painting both popFrac = 0.5f; growthFrac = 0.5f; } if (CityGeneratorUI.DebugMode) { Debug.Log("popFrac:" + popFrac); Debug.Log("growthFrac:" + growthFrac); } // this makes sure that we can use the textures we need // to paint the pop/growth maps setUpTextures (); //float[y, x, nr of textures] textureData = new float[CityGenerator.terrain.terrainData.alphamapWidth, CityGenerator.terrain.terrainData.alphamapHeight, CityGenerator.terrain.terrainData.alphamapLayers]; //now check if the map size equals the terrain size.. this should be the case //if(terrainData.alphamapWidth != map.GetLength(0) || terrainData.alphamapHeight != map.GetLength(1)){ // Debug.LogError ("Map size does not match terrain size"); //} for (int y = 0; y < CityGenerator.terrain.terrainData.alphamapHeight; y++) { for (int x = 0; x < CityGenerator.terrain.terrainData.alphamapWidth; x++) { float popMapValue = (CityGenerator.popMap == null) ? 0 : CityGenerator.popMap[x, y]; float growthMapValue = (CityGenerator.growthMap == null) ? -1 : CityGenerator.growthMap[x, y]; textureData[y, x, 0] = popMapValue * popFrac; //white textureData[y, x, 1] = (1 - popMapValue) * popFrac; //black //if the current coordinate is red if (growthMapValue == 0) { textureData[y, x, 2] = 1 * growthFrac; //red } else { textureData[y, x, 2] = 0; //red } //if the current coordinate is green if (growthMapValue == 1) { textureData[y, x, 3] = 1 * growthFrac; //green } else { textureData[y, x, 3] = 0; //green } //if the current coordiante is blue if (growthMapValue == 2) { textureData[y, x, 4] = 1 * growthFrac; //blue } else { textureData[y, x, 4] = 0; //blue } } } //apply the new textures CityGenerator.terrain.terrainData.SetAlphamaps (0, 0, textureData); //store and restore the old values oldShowPop = CityGenerator.showPop; oldShowGrowth = CityGenerator.showGrowth; }
extern private void Internal_SetAlphamaps(int x, int y, int width, int height, float[,,] map);
/// <summary> /// Processes all of the images in the file specified. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { // Image data variables float[,,] data = imageData.GetData(); double max = imageData.GetMaximum(); double min = imageData.GetMinimum(); int lambdaCount = imageData.GetLambdaCount(); int width = imageData.GetWidth(); int height = imageData.GetHeight(); // Initialize the writeable bitmaps WriteableBitmap[] bitmaps = new WriteableBitmap[lambdaCount]; // Go through each image in the image data for (int lambda = 0; lambda < lambdaCount; lambda++) { // Instantiate a new writeable bitmap to store this image's pixel data. bitmaps[lambda] = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, null); // Reserve the back buffer for updates. bitmaps[lambda].Lock(); // Iterate through the pixels along the x & y axis in the currently loaded image for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { double n = data[lambda, y, x]; byte pixelValue = (byte)(((n - min) / (max - min)) * MAXIMUM_INTENSITY); unsafe { // Get a pointer to the back buffer. int pBackBuffer = (int)bitmaps[lambda].BackBuffer; // Find the address of the pixel to draw. pBackBuffer += y * bitmaps[lambda].BackBufferStride; pBackBuffer += x * 4; // Compute the pixel's color. int color_data = pixelValue << 16; // R color_data |= pixelValue << 8; // G color_data |= pixelValue << 0; // B // Assign the color data to the pixel. *((int *)pBackBuffer) = color_data; } // Specify the area of the bitmap that changed. bitmaps[lambda].AddDirtyRect(new Int32Rect(x, y, 1, 1)); } } // Release the back buffer and make it available for display. bitmaps[lambda].Unlock(); // Make this bitmap unmodifiable so that any thread can access it. bitmaps[lambda].Freeze(); // Report progress to background worker float quotient = ((lambda + 1) * 1.0f) / (lambdaCount * 1.0f); float percentage = quotient * 100.0f; (sender as BackgroundWorker).ReportProgress((int)percentage); } // Pass the images to the main thread via the result e.Result = bitmaps; }
float[,,] hollowOut(float[,,] arr) //i think arr is passed as a reference so im pretty sure modifying it in this method as a void would be fine but im being careful. Test this later, making this a void and just modifying arr!!!!!!!! { //doesn't work List <Vector3> modPoints = new List <Vector3>(); //all the points we change, any point in this list was hollowed so set it to 0 int hollowCount = 0; int totalCount = 0; for (int x = 0; x < chunkSizeBlocks; x++) { for (int y = 0; y < chunkSizeBlocks; y++) { for (int z = 0; z < chunkSizeBlocks; z++) { if (arr[x, y, z] == 1) { totalCount++; } int startPosX = (x - 1 < 0) ? x : x - 1; int startPosY = (y - 1 < 0) ? y : y - 1; int startPosZ = (z - 1 < 0) ? z : z - 1; int endPosX = (x + 1 > chunkSizeBlocks - 1) ? x : x + 1; int endPosY = (y + 1 > chunkSizeBlocks - 1) ? y : y + 1; int endPosZ = (z + 1 > chunkSizeBlocks - 1) ? z : z + 1; int numAlive = 0; int numAround = 6; //(endPosX - startPosX + 1)*(endPosY - startPosY + 1)*(endPosZ - startPosZ + 1) - 1; //if it's verticies, I think numaround will be 26, to be same, and I'll check probably using loops (or something exhaustive, like the if statements but like 26 of them for all combinations of x +/- 1, y +/- 1, and z +/- 1) if (startPosX == x || startPosY == y || startPosZ == z || endPosX == x || endPosY == y || endPosZ == z) //ignore edge cases entirely { continue; } /*for (int i = startPosX; i <= endPosX; i++) * if (arr[i, y, z] == 1 && i != x) * numAlive++; * * for (int i = startPosY; i <= endPosY; i++) * if (arr[x, i, z] == 1 && i != y) * numAlive++; * * for (int i = startPosZ; i <= endPosZ; i++) * if (arr[x, y, i] == 1 && i != z) * numAlive++;*/ if (arr[x + 1, y, z] == 1) { numAlive++; } if (arr[x - 1, y, z] == 1) { numAlive++; } if (arr[x, y + 1, z] == 1) { numAlive++; } if (arr[x, y - 1, z] == 1) { numAlive++; } if (arr[x, y, z + 1] == 1) { numAlive++; } if (arr[x, y, z - 1] == 1) { numAlive++; } if (numAround > 0 && numAlive >= numAround) { //Debug.Log("here"); modPoints.Add(new Vector3(x, y, z)); hollowCount++; } } } } foreach (Vector3 v in modPoints) { arr[(int)v.x, (int)v.y, (int)v.z] = 0; } //Debug.Log(hollowCount); //Debug.Log(totalCount); return(arr); }
public void rechargerCacheAlphaMap() { cacheAlphamap = data.GetAlphamaps(0, 0, data.alphamapWidth, data.alphamapHeight); }
/// <summary> /// Store Alpha map data from the terrain /// </summary> private void GetAlphaMap() { //Access map size var w = _terrain.terrainData.alphamapWidth; var h = _terrain.terrainData.alphamapHeight; //store the data _alphamapData = _terrain.terrainData.GetAlphamaps(0, 0, w, h); }
public TerrainThreadInfo(Action <float[, , ]> callback, float[,,] parameter) { this.callback = callback; this.calculatedInfo = parameter; }
public BiomeMapResult(float[,,] values, float min, float max) { Values = values; Min = min; Max = max; }
Terrain populateGround(Terrain t) { float[,,] maps = t.terrainData.GetAlphamaps(0, 0, size, size); int unitsForest = 0; int[,] grassMap1 = new int[size, size]; int[,] grassMap2 = new int[size, size]; int[,] grassMap3 = new int[size, size]; int[,] grassMap4 = new int[size, size]; //apply grass for (int z = 0; z < size; z++) { for (int x = 0; x < size; x++) { if (maps[z, x, plainsIndex] != 0f) { grassMap1[z, x] = 3; grassMap2[z, x] = 0; grassMap3[z, x] = 3; grassMap4[z, x] = 2; unitsForest++; } else if (maps[z, x, forestIndex] != 0f) { grassMap1[z, x] = 2; grassMap2[z, x] = 4; grassMap3[z, x] = 2; grassMap4[z, x] = 1; unitsForest++; } else { grassMap1[z, x] = 0; grassMap2[z, x] = 0; grassMap3[z, x] = 0; grassMap4[z, x] = 0; } } if (debug_DrawGrass) { t.terrainData.SetDetailLayer(0, 0, 0, grassMap1); t.terrainData.SetDetailLayer(0, 0, 1, grassMap2); t.terrainData.SetDetailLayer(0, 0, 2, grassMap3); t.terrainData.SetDetailLayer(0, 0, 3, grassMap4); } } if (debug_drawTrees) { //apply trees bool[,] placement = new bool[size, size]; //true=tree there float mountainTreeChance = 1f; float beachTreeChance = .25f; float plainsTreeChance = 1f; int numTrees = 0; float realDensity = ((float)unitsForest / ((float)size * (float)size)) * (float)treeDensity; //print("Input Density: "+treeDensity+" realDensity: "+realDensity+" unitsForest: "+unitsForest+" size"+size); while (numTrees < realDensity) { int x = Random.Range(0, size - 1); int z = Random.Range(0, size - 1); if (!placement[x, z]) { float chance = Random.value; bool canPlace = (maps[z, x, forestIndex] != 0f) || (maps[z, x, plainsIndex] != 0f && chance < plainsTreeChance) || (maps[z, x, beachIndex] != 0f && chance < beachTreeChance) || (maps[z, x, mountainIndex] != 0f && chance < mountainTreeChance); if (canPlace) { TreeInstance tree = createTree(x, z, t); placement[x, z] = true; numTrees++; t.AddTreeInstance(tree); } } } } return(t); }
// Start is called before the first frame update void Start() { //also from youtube for (int x = 0; x < chunkSizeVerts; x++) { for (int y = 0; y < chunkSizeVerts; y++) { for (int z = 0; z < chunkSizeVerts; z++) { float noise = Perlin3D(x * noiseScale, y * noiseScale, z * noiseScale); if (noise >= threshold) //here we pass floats instead so that Perlin behaves { //sampling unity's perlin noise with an integer returns the same value, which was less than the threshold //Instantiate(blockPrefab, new Vector3(x, y, z), Quaternion.identity);//not rotated is what quaternion.identity says //^^ this is if you treat each point as a cube. I will treat each point as a vertex instead. /*bool xSafe = false; * bool ySafe = false; * bool zSafe = false; * if (x == chunkSize - 1) * { * //check edges (x - 1) * } * else * { * //check edges (x + 1) * } * if (y == chunkSize - 1) * { * //check y edges accordingly * } * else * { * //check edges (y + 1) * } * if (z == chunkSize - 1) * { * //check z edges accordingly * } * else * { * //check edges (z + 1) * } * if (xSafe && ySafe && zSafe) { //make sure that we have checked edges, if all edges are filled, then it is safe to set to 0; we are checking if a cube is like covered or not * chunkData[chunkSize - x - 1, chunkSize - y - 1, z] = 0; * } * else * { * chunkData[chunkSize - x - 1, chunkSize - y - 1, z] = 1; * }*/ chunkData[chunkSizeVerts - x - 1, chunkSizeVerts - y - 1, z] = 1; } else { chunkData[chunkSizeVerts - x - 1, chunkSizeVerts - y - 1, z] = 0;//idk if it instantiates to all 0's } } } } chunkData = hollowOut(chunkData); //now that we have our verticies, lets march some cubes? //some for loop logic to get to one cube //now that we are at a cube: //check each of the 8 verticies to see if it is on or off //index = 0; //for all of the 8 //index += (vertex value [1 or 0]) * 2^(vertex index) //lookup, then make triangle CombineInstance[] wholeMesh = new CombineInstance[(int)Mathf.Pow(chunkSizeBlocks, 3)]; Mesh mesh = GetComponent <MeshFilter>().mesh; mesh.Clear(); int[] initialVoxels = { (int)chunkData[0, 0, 0], (int)chunkData[1, 0, 0], (int)chunkData[1, 0, 1], (int)chunkData[0, 0, 1], (int)chunkData[0, 1, 0], (int)chunkData[1, 1, 0], (int)chunkData[1, 1, 1], (int)chunkData[0, 1, 1] }; Mesh temp = MarchingCubes3.perCube(new Vector3(0, 0, 0), initialVoxels, 0); //foreach (int i in initialVoxels) // Debug.Log(i); //mesh.triangles = temp.triangles; //mesh.vertices = temp.vertices; //mesh.RecalculateBounds(); //mesh.RecalculateNormals(); wholeMesh[0] = new CombineInstance(); wholeMesh[0].mesh = temp; //per chunk for (int x = 0; x < chunkSizeVerts - 1; x++) //or x < chunkSizeBlocks { for (int y = 0; y < chunkSizeVerts - 1; y++) { for (int z = 0; z < chunkSizeVerts - 1; z++) { if (x == 0 && y == 0 && z == 0) { continue; } //set blockNum somehow int blockNum = (int)(z + y * (Mathf.Pow(chunkSizeBlocks, 1)) + x * (Mathf.Pow(chunkSizeBlocks, 2))); //percube int[] voxels = { (int)chunkData[x, y, z], (int)chunkData[x + 1, y, z], (int)chunkData[x + 1, y, z + 1], (int)chunkData[x, y, z + 1], (int)chunkData[x, y + 1, z], (int)chunkData[x + 1, y + 1, z], (int)chunkData[x + 1, y + 1, z + 1], (int)chunkData[x, y + 1, z + 1] }; //this is a line worth checking, I made it match up with MarchingCubes3.localVerticies Mesh m = MarchingCubes3Clean.perCube(new Vector3(0, 0, 0), voxels, blockNum); //^^ this causes unity to freeze up //if combineInstance has too many verts: //IMPLEMENT THIS LOGIC LATER, MAYBE IF COMBINING CHUNKS??? //save the current combineInstance to a mesh //make a new one //Debug.Log(wholeMesh[blockNum]); wholeMesh[blockNum] = new CombineInstance(); wholeMesh[blockNum].mesh = m; //Debug.Log(wholeMesh[blockNum]); //wholeMesh[blockNum].transform. = MarchingCubes3Clean.beginningCoordinates(new Vector3(0, 0, 0), blockNum);//comes with the mesh??? //merge meshes } } } /*mesh.Clear(); * * mesh.CombineMeshes(wholeMesh); * * mesh.RecalculateBounds(); * mesh.RecalculateNormals();*/ //Mesh mesh = GetComponent<MeshFilter>().mesh; mesh = GetComponent <MeshFilter>().mesh; //mesh is invisible now. mesh.Clear(); mesh.CombineMeshes(wholeMesh); //mesh.Optimize(); //MeshCollider meshCollider = GetComponent<MeshCollider>(); //meshCollider.sharedMesh = GetComponent<MeshFilter>().mesh; //this won't work but i want it to :(, also it shows up as black and unlit??? //I think the mesh is centered but idk... mesh.RecalculateBounds(); mesh.RecalculateNormals(); }
private void ComputeOutflow(float[,] waterMap, float[,,] outFlow, float[] heightMap, int width, int height) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int xn1 = (x == 0) ? 0 : x - 1; int xp1 = (x == width - 1) ? width - 1 : x + 1; int yn1 = (y == 0) ? 0 : y - 1; int yp1 = (y == height - 1) ? height - 1 : y + 1; float waterHt = waterMap[x, y]; float waterHts0 = waterMap[xn1, y]; float waterHts1 = waterMap[xp1, y]; float waterHts2 = waterMap[x, yn1]; float waterHts3 = waterMap[x, yp1]; float landHt = heightMap[x + y * width]; float landHts0 = heightMap[xn1 + y * width]; float landHts1 = heightMap[xp1 + y * width]; float landHts2 = heightMap[x + yn1 * width]; float landHts3 = heightMap[x + yp1 * width]; float diff0 = (waterHt + landHt) - (waterHts0 + landHts0); float diff1 = (waterHt + landHt) - (waterHts1 + landHts1); float diff2 = (waterHt + landHt) - (waterHts2 + landHts2); float diff3 = (waterHt + landHt) - (waterHts3 + landHts3); //out flow is previous flow plus flow for this time step. float flow0 = Mathf.Max(0, outFlow[x, y, 0] + diff0); float flow1 = Mathf.Max(0, outFlow[x, y, 1] + diff1); float flow2 = Mathf.Max(0, outFlow[x, y, 2] + diff2); float flow3 = Mathf.Max(0, outFlow[x, y, 3] + diff3); float sum = flow0 + flow1 + flow2 + flow3; if (sum > 0.0f) { //If the sum of the outflow flux exceeds the amount in the cell //flow value will be scaled down by a factor K to avoid negative update. float K = waterHt / (sum * TIME); if (K > 1.0f) { K = 1.0f; } if (K < 0.0f) { K = 0.0f; } outFlow[x, y, 0] = flow0 * K; outFlow[x, y, 1] = flow1 * K; outFlow[x, y, 2] = flow2 * K; outFlow[x, y, 3] = flow3 * K; } else { outFlow[x, y, 0] = 0.0f; outFlow[x, y, 1] = 0.0f; outFlow[x, y, 2] = 0.0f; outFlow[x, y, 3] = 0.0f; } } } }
public void InitData() { dataDist = new float[cx + 1, cy + 1, cz + 1]; dataDistPPP = new float[cx + 1, cy + 1, cz + 1]; dataDistPPM = new float[cx + 1, cy + 1, cz + 1]; dataDistPMP = new float[cx + 1, cy + 1, cz + 1]; dataDistPMM = new float[cx + 1, cy + 1, cz + 1]; dataDistMPP = new float[cx + 1, cy + 1, cz + 1]; dataDistMPM = new float[cx + 1, cy + 1, cz + 1]; dataDistMMP = new float[cx + 1, cy + 1, cz + 1]; dataDistMMM = new float[cx + 1, cy + 1, cz + 1]; dataType = new IMaterial[cx + 1, cy + 1, cz + 1]; dataNormal = new Vector[cx + 1, cy + 1, cz + 1]; float cellSizeX = (maxX - minX - 1) / cx; float cellSizeY = (maxY - minY - 1) / cy; float cellSizeZ = (maxZ - minZ - 1) / cz; diag = (float)Math.Sqrt(cellSizeX * cellSizeX + cellSizeY * cellSizeY + cellSizeZ * cellSizeZ); for (int i = 0; i < cx; i++) { for (int j = 0; j < cy + 1; j++) { for (int k = 0; k < cz + 1; k++) { float worldX = minX + i * (maxX - minX - 1) / cx; float worldY = minY + j * (maxY - minY - 1) / cy; float worldZ = minZ + k * (maxZ - minZ - 1) / cz; Vector hitPos = new Vector(worldX, worldY, worldZ); float d = scene.QueryDatabase(hitPos, out var hitObj); dataDist[i, j, k] = d; dataType[i, j, k] = hitObj.Material; dataNormal[i, j, k] = scene.QueryDatabaseNorm(hitPos, d, hitObj); if (float.IsNaN(dataNormal[i, j, k].x)) { dataNormal[i, j, k] = new Vector(0, 0, 1); } } } } float diagXYZ = (float)Math.Sqrt(cellSizeX * cellSizeX + cellSizeY * cellSizeY + cellSizeZ * cellSizeZ); float diagXY = (float)Math.Sqrt(cellSizeX * cellSizeX + cellSizeY * cellSizeY); float diagXZ = (float)Math.Sqrt(cellSizeX * cellSizeX + cellSizeZ * cellSizeZ); float diagYZ = (float)Math.Sqrt(cellSizeY * cellSizeY + cellSizeZ * cellSizeZ); for (int x = 1; x < cx; x++) { for (int y = 1; y < cy; y++) { for (int z = 1; z < cz; z++) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x <= 0 && normal.y <= 0 && normal.z <= 0)) { startMin = float.MaxValue; } dataDistMMM[x, y, z] = min(startMin, dataDistMMM[x - 1, y, z] + cellSizeX, dataDistMMM[x, y - 1, z] + cellSizeY, dataDistMMM[x, y, z - 1] + cellSizeZ, dataDistMMM[x - 1, y - 1, z] + diagXY, dataDistMMM[x, y - 1, z - 1] + diagYZ, dataDistMMM[x - 1, y, z - 1] + diagXZ, dataDistMMM[x - 1, y - 1, z - 1] + diagXYZ); } } } for (int x = 1; x < cx; x++) { for (int y = 1; y < cy; y++) { for (int z = cz - 1; z >= 0; z--) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x <= 0 && normal.y <= 0 && normal.z >= 0)) { startMin = float.MaxValue; } dataDistMMP[x, y, z] = min(startMin, dataDistMMP[x - 1, y, z] + cellSizeX, dataDistMMP[x, y - 1, z] + cellSizeY, dataDistMMP[x, y, z + 1] + cellSizeZ, dataDistMMP[x - 1, y - 1, z] + diagXY, dataDistMMP[x, y - 1, z + 1] + diagYZ, dataDistMMP[x - 1, y, z + 1] + diagXZ, dataDistMMP[x - 1, y - 1, z + 1] + diagXYZ); } } } for (int x = 1; x < cx; x++) { for (int y = cy - 1; y >= 0; y--) { for (int z = 1; z < cz; z++) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x <= 0 && normal.y >= 0 && normal.z <= 0)) { startMin = float.MaxValue; } dataDistMPM[x, y, z] = min(startMin, dataDistMPM[x - 1, y, z] + cellSizeX, dataDistMPM[x, y + 1, z] + cellSizeY, dataDistMPM[x, y, z - 1] + cellSizeZ, dataDistMPM[x - 1, y + 1, z] + diagXY, dataDistMPM[x, y + 1, z - 1] + diagYZ, dataDistMPM[x - 1, y, z - 1] + diagXZ, dataDistMPM[x - 1, y + 1, z - 1] + diagXYZ); } } } for (int x = 1; x < cx; x++) { for (int y = cy - 1; y >= 0; y--) { for (int z = cz - 1; z >= 0; z--) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x <= 0 && normal.y >= 0 && normal.z >= 0)) { startMin = float.MaxValue; } dataDistMPP[x, y, z] = min(startMin, dataDistMPP[x - 1, y, z] + cellSizeX, dataDistMPP[x, y + 1, z] + cellSizeY, dataDistMPP[x, y, z + 1] + cellSizeZ, dataDistMPP[x - 1, y + 1, z] + diagXY, dataDistMPP[x, y + 1, z + 1] + diagYZ, dataDistMPP[x - 1, y, z + 1] + diagXZ, dataDistMPP[x - 1, y + 1, z + 1] + diagXYZ); } } } for (int x = cx - 1; x >= 0; x--) { for (int y = 1; y < cy; y++) { for (int z = 1; z < cz; z++) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x >= 0 && normal.y <= 0 && normal.z <= 0)) { startMin = float.MaxValue; } dataDistPMM[x, y, z] = min(startMin, dataDistPMM[x + 1, y, z] + cellSizeX, dataDistPMM[x, y - 1, z] + cellSizeY, dataDistPMM[x, y, z - 1] + cellSizeZ, dataDistPMM[x + 1, y - 1, z] + diagXY, dataDistPMM[x, y - 1, z - 1] + diagYZ, dataDistPMM[x + 1, y, z - 1] + diagXZ, dataDistPMM[x + 1, y - 1, z - 1] + diagXYZ); } } } for (int x = cx - 1; x >= 0; x--) { for (int y = 1; y < cy; y++) { for (int z = cz - 1; z >= 0; z--) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x >= 0 && normal.y <= 0 && normal.z >= 0)) { startMin = float.MaxValue; } dataDistPMP[x, y, z] = min(startMin, dataDistPMP[x + 1, y, z] + cellSizeX, dataDistPMP[x, y - 1, z] + cellSizeY, dataDistPMP[x, y, z + 1] + cellSizeZ, dataDistPMP[x + 1, y - 1, z] + diagXY, dataDistPMP[x, y - 1, z + 1] + diagYZ, dataDistPMP[x + 1, y, z + 1] + diagXZ, dataDistPMP[x + 1, y - 1, z + 1] + diagXYZ); } } } for (int x = cx - 1; x >= 0; x--) { for (int y = cy - 1; y >= 0; y--) { for (int z = 1; z < cz; z++) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x >= 0 && normal.y >= 0 && normal.z <= 0)) { startMin = float.MaxValue; } dataDistPPM[x, y, z] = min(startMin, dataDistPPM[x + 1, y, z] + cellSizeX, dataDistPPM[x, y + 1, z] + cellSizeY, dataDistPPM[x, y, z - 1] + cellSizeZ, dataDistPPM[x + 1, y + 1, z] + diagXY, dataDistPPM[x, y + 1, z - 1] + diagYZ, dataDistPPM[x + 1, y, z - 1] + diagXZ, dataDistPPM[x + 1, y + 1, z - 1] + diagXYZ); } } } for (int x = cx - 1; x >= 0; x--) { for (int y = cy - 1; y >= 0; y--) { for (int z = cz - 1; z >= 0; z--) { float startMin = dataDist[x, y, z]; Vector normal = dataNormal[x, y, z]; if (startMin >= diagXYZ / 2 || (normal.x >= 0 && normal.y >= 0 && normal.z >= 0)) { startMin = float.MaxValue; } dataDistPPP[x, y, z] = min(startMin, dataDistPPP[x + 1, y, z] + cellSizeX, dataDistPPP[x, y + 1, z] + cellSizeY, dataDistPPP[x, y, z + 1] + cellSizeZ, dataDistPPP[x + 1, y + 1, z] + diagXY, dataDistPPP[x, y + 1, z + 1] + diagYZ, dataDistPPP[x + 1, y, z + 1] + diagXZ, dataDistPPP[x + 1, y + 1, z + 1] + diagXYZ); } } } }
/// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL /// if not using OpenCL/GL interop.</summary> /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param> public MarchingCubes(float[, ,] FuncValues) { InitMarchingCubes(FuncValues, null, null, null); }
/// <summary> /// Generate chunk map data based on perlin noise and interpolation /// </summary> /// <param name="colCoord">Column coordinate to sample</param> /// <returns>Chunk block data</returns> public ChunkColumn.MapDataInfo GenerateNoiseMap(ColumnCoord colCoord) { int size = ChunkColumn.chunkSize; int amountOfVerticalChunks = ChunkColumn.worldHeight; ChunkColumn.MapDataInfo mapData = new ChunkColumn.MapDataInfo(); mapData.SetAllEmpty(); byte[,,] chunkBlockData = new byte[size, size *amountOfVerticalChunks, size]; // Sampling all points using perlin noise within chunk float[,,] sampleNoiseMap = SamplePoints(colCoord); // 0 = differences, 1 = all non-solid, 2 = all solid int allSolidIndex; for (int x = 0; x < sampleNoiseMap.GetLength(0) - 1; x++) { for (int y = 0; y < sampleNoiseMap.GetLength(1) - 1; y++) { for (int z = 0; z < sampleNoiseMap.GetLength(2) - 1; z++) { allSolidIndex = GetAllSolidIndex(ref sampleNoiseMap, x, y, z); if (allSolidIndex == 0) { InterpolatePoints(ref sampleNoiseMap, ref chunkBlockData, x, y, z, colCoord); // Any interpolation means the is atleast 1 solid block mapData.isEmpty[(y * verticalNoiseScale + verticalNoiseScale / 2) / ChunkColumn.chunkSize] = false; } else { float noiseVal; int blockX, blockY, blockZ; if (allSolidIndex == 2) { mapData.isEmpty[(y * verticalNoiseScale + verticalNoiseScale / 2) / ChunkColumn.chunkSize] = false; } // All points the same, skip interpolation for (int k = 0; k < horizontalNoiseScale; k++) { for (int j = 0; j < verticalNoiseScale; j++) { for (int i = 0; i < horizontalNoiseScale; i++) { blockX = x * horizontalNoiseScale + k; blockY = y * verticalNoiseScale + j; blockZ = z * horizontalNoiseScale + i; noiseVal = allSolidIndex == 1 ? 0 : 1; byte blockId = GetBlockIdFromNoise(blockX, blockY, blockZ, noiseVal, colCoord); chunkBlockData[blockX, blockY, blockZ] = blockId; // Add grass to the top layer if (y == 0) { continue; } if (blockId == 0 && chunkBlockData[blockX, blockY - 1, blockZ] == 2) { // Spawn grass chunkBlockData[blockX, blockY - 1, blockZ] = 3; } } } } } } } } mapData.voxelData = chunkBlockData; return(mapData); }
/// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL /// if not using OpenCL/GL interop.</summary> /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param> /// <param name="CLEdgeCoords">OpenCL variable (float) to hold edge coordinates. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLEdgeNormals">OpenCL variable (float) to hold edge normals. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLElementArrayIndex">OpenCL variable (int) to hold element array index. Dimension has to be 5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)</param> public MarchingCubes(float[, ,] FuncValues, CLCalc.Program.Variable CLEdgeCoords, CLCalc.Program.Variable CLEdgeNormals, CLCalc.Program.Variable CLElementArrayIndex) { InitMarchingCubes(FuncValues, CLEdgeCoords, CLEdgeNormals, CLElementArrayIndex); }
public void applyTexture() { splatmapData = thisTerrain.terrainData.GetAlphamaps(0, 0, thisTerrain.terrainData.alphamapWidth, thisTerrain.terrainData.alphamapHeight); for (int x = 0; x < thisTerrain.terrainData.alphamapWidth; x++) { for (int z = 0; z < thisTerrain.terrainData.alphamapHeight; z++) { // Normalise x/y coordinates to range 0-1 float z_01 = (float)z / (float)thisTerrain.terrainData.alphamapHeight; float x_01 = (float)x / (float)thisTerrain.terrainData.alphamapWidth; // Calculate the normal //Vector3 normal = thisTerrain.terrainData.GetInterpolatedNormal (z_01, x_01); float steepness = thisTerrain.terrainData.GetSteepness (z_01, x_01); // Declare a list of floats to hold the array of alpha values float[] splatVals = new float[thisTerrain.terrainData.alphamapLayers]; // splatVals[0] (Soil) represents the base texture splatVals [0] = 0.5f; splatVals [1] = Mathf.Clamp01 (steepness * steepness / (thisTerrain.terrainData.heightmapHeight / 0.05f)); splatVals [2] = 1.0f - Mathf.Clamp01 (steepness * steepness / (thisTerrain.terrainData.heightmapHeight / 5.0f)); // Sum of all splat date must = 1 float n = splatVals.Sum (); // Each layer gets normalized so the sum = 1 for (int i = 0; i<thisTerrain.terrainData.alphamapLayers; i++) { // Normalize so that sum of all texture weights = 1 splatVals [i] /= n; // Assign this point to the splatmap array splatmapData [x, z, i] = splatVals [i]; } } } // And finally assign the new splatmap to the terrainData: thisTerrain.terrainData.SetAlphamaps(0, 0, splatmapData); }
/// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL /// if not using OpenCL/GL interop.</summary> /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param> /// <param name="CLEdgeCoords">OpenCL variable (float) to hold edge coordinates. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLEdgeNormals">OpenCL variable (float) to hold edge normals. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLElementArrayIndex">OpenCL variable (int) to hold element array index. Dimension has to be 5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)</param> private void InitMarchingCubes(float[, ,] FuncValues, CLCalc.Program.Variable CLEdgeCoords, CLCalc.Program.Variable CLEdgeNormals, CLCalc.Program.Variable CLElementArrayIndex) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { CLCalc.InitCL(); } if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { //Reads maximum lengths int maxX = FuncValues.GetLength(0); int maxY = FuncValues.GetLength(1); int maxZ = FuncValues.GetLength(2); max = new int[] { maxX, maxY, maxZ }; #region Creating variables //Isolevel isoLevel = new float[1] { 1.32746E-5f }; varIsoLevel = new CLCalc.Program.Variable(isoLevel); //Step size and x0,y0,z0 varStep = new CLCalc.Program.Variable(step); varInitVals = new CLCalc.Program.Variable(initVals); //Create and copy function values funcVals = new float[maxX * maxY * maxZ]; CLFuncVals = new CLCalc.Program.Variable(funcVals); SetFuncVals(FuncValues); //Edge coordinates - 3 coords * 3 possible directions * number of points edgeCoords = new float[9 * maxX * maxY * maxZ]; if (CLEdgeCoords != null) { varEdgeCoords = CLEdgeCoords; varEdgeCoords.WriteToDevice(edgeCoords); } else { varEdgeCoords = new CLCalc.Program.Variable(edgeCoords); } //4 preliminary normals per edge - has to be averaged afterwards edgePrelimNormals = new float[36 * maxX * maxY * maxZ]; varEdgePrelimNormals = new CLCalc.Program.Variable(edgePrelimNormals); //Edge normals edgeNormals = new float[9 * maxX * maxY * maxZ]; if (CLEdgeNormals != null) { varEdgeNormals = CLEdgeNormals; varEdgeNormals.WriteToDevice(edgeNormals); } else { varEdgeNormals = new CLCalc.Program.Variable(edgeNormals); } //Number of cubes: (maxX-1)*(maxY-1)*(maxZ-1) //Marching cube algorithm: each cube can have 5 triangles drawn, 3 vertexes per triangle //q-th vertex of p-th triangle of the ijk-th cube: [(5*(i+(maxX-1)*j+k*(maxX-1)*(maxY-1))+p)*3+q] elementIndex = new int[5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)]; if (CLElementArrayIndex != null) { varElemIndex = CLElementArrayIndex; varElemIndex.WriteToDevice(elementIndex); } else { varElemIndex = new CLCalc.Program.Variable(elementIndex); } //Edge remapping to build output edges = new int[edgeCoords.Length / 3]; for (int i = 0; i < edges.Length; i++) { edges[i] = -1; } #endregion #region Compile code and create kernels CLMarchingCubesSrc cmsrc = new CLMarchingCubesSrc(); CLCalc.Program.Compile(new string[] { cmsrc.definitions, cmsrc.src }); kernelInterpPts = new CLCalc.Program.Kernel("interpPts"); kernelPolygonize = new CLCalc.Program.Kernel("Polygonize"); kernelSmoothNormals = new CLCalc.Program.Kernel("SmoothNormals"); kernelPolygonizeNoNormals = new CLCalc.Program.Kernel("PolygonizeNoNormals"); #endregion } else { throw new Exception("OpenCL not available"); } }
void Start() { xResolution = myTerrain.terrainData.heightmapWidth; zResolution = myTerrain.terrainData.heightmapHeight; alphaMapWidth = myTerrain.terrainData.alphamapWidth; alphaMapHeight = myTerrain.terrainData.alphamapHeight; numOfAlphaLayers = myTerrain.terrainData.alphamapLayers; if (Debug.isDebugBuild) { heights = myTerrain.terrainData.GetHeights (0, 0, xResolution, zResolution); heightMapBackup = myTerrain.terrainData.GetHeights(0, 0, xResolution, zResolution); alphaMapBackup = myTerrain.terrainData.GetAlphamaps(0, 0, alphaMapWidth, alphaMapHeight); } for(int index = 0; index <picPointPlayer.Length; index++){ picPointPlayer [index]=NULL_VECTOR3; } }
public void GenerateTerrainWithAlphamaps(HEU_SessionBase session, HEU_HoudiniAsset houdiniAsset, bool bRebuild) { if(_layers == null || _layers.Count == 0) { Debug.LogError("Unable to generate terrain due to lack of heightfield layers!"); return; } HEU_VolumeLayer heightLayer = _layers[0]; HAPI_VolumeInfo heightVolumeInfo = new HAPI_VolumeInfo(); bool bResult = session.GetVolumeInfo(_ownerNode.GeoID, heightLayer._part.PartID, ref heightVolumeInfo); if (!bResult) { Debug.LogErrorFormat("Unable to get volume info for height layer: {0}!", heightLayer._layerName); return; } // Special handling of volume cache presets. It is applied here (if exists) because it might pertain to TerrainData that exists // in the AssetDatabase. If we don't apply here but rather create a new one, the existing file will get overwritten. // Applying the preset here for terrain ensures the TerrainData is reused. // Get the volume preset for this part HEU_VolumeCachePreset volumeCachePreset = houdiniAsset.GetVolumeCachePreset(_ownerNode.ObjectNode.ObjectName, _ownerNode.GeoName, TileIndex); if (volumeCachePreset != null) { ApplyPreset(volumeCachePreset); // Remove it so that it doesn't get applied when doing the recook step houdiniAsset.RemoveVolumeCachePreset(volumeCachePreset); } // The TerrainData and TerrainLayer files needs to be saved out if we create them. This creates the relative folder // path from the Asset's cache folder: {assetCache}/{geo name}/Terrain/Tile{tileIndex}/... string relativeFolderPath = HEU_Platform.BuildPath(_ownerNode.GeoName, HEU_Defines.HEU_FOLDER_TERRAIN, HEU_Defines.HEU_FOLDER_TILE + TileIndex); if (bRebuild) { // For full rebuild, re-create the TerrainData instead of using previous _terrainData = null; } //Debug.Log("Generating Terrain with AlphaMaps: " + (_terrainData != null ? _terrainData.name : "NONE")); TerrainData terrainData = _terrainData; Vector3 terrainOffsetPosition = Vector3.zero; // Look up TerrainData file via attribute if user has set it string terrainDataFile = HEU_GeneralUtility.GetAttributeStringValueSingle(session, _ownerNode.GeoID, heightLayer._part.PartID, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TERRAINDATA_FILE_ATTR, HAPI_AttributeOwner.HAPI_ATTROWNER_PRIM); if (!string.IsNullOrEmpty(terrainDataFile)) { TerrainData loadedTerrainData = HEU_AssetDatabase.LoadAssetAtPath(terrainDataFile, typeof(TerrainData)) as TerrainData; if (loadedTerrainData == null) { Debug.LogWarningFormat("TerrainData, set via attribute, not found at: {0}", terrainDataFile); } else { // In the case that the specified TerrainData belongs to another Terrain (i.e. input Terrain), // make a copy of it and store it in our cache. Note that this overwrites existing TerrainData in our cache // because the workflow is such that attributes will always override local setting. string bakedTerrainPath = houdiniAsset.GetValidAssetCacheFolderPath(); bakedTerrainPath = HEU_Platform.BuildPath(bakedTerrainPath, relativeFolderPath); terrainData = HEU_AssetDatabase.CopyAndLoadAssetAtAnyPath(loadedTerrainData, bakedTerrainPath, typeof(TerrainData), true) as TerrainData; if (terrainData == null) { Debug.LogErrorFormat("Unable to copy TerrainData from {0} for generating Terrain.", terrainDataFile); } } } // Generate the terrain and terrain data from the height layer. This applies height values. bResult = HEU_TerrainUtility.GenerateTerrainFromVolume(session, ref heightVolumeInfo, heightLayer._part.ParentGeoNode.GeoID, heightLayer._part.PartID, heightLayer._part.OutputGameObject, ref terrainData, out terrainOffsetPosition); if (!bResult || terrainData == null) { return; } if (_terrainData != terrainData) { _terrainData = terrainData; heightLayer._part.SetTerrainData(terrainData, relativeFolderPath); } heightLayer._part.SetTerrainOffsetPosition(terrainOffsetPosition); int terrainSize = terrainData.heightmapResolution; // Now process TerrainLayers and alpha maps // First, preprocess all layers to get heightfield arrays, converted to proper size List<float[]> heightFields = new List<float[]>(); // Corresponding list of HF volume layers to process as splatmaps List<HEU_VolumeLayer> volumeLayersToProcess = new List<HEU_VolumeLayer>(); int numLayers = _layers.Count; float minHeight = 0; float maxHeight = 0; float heightRange = 0; // This skips the height layer, and processes all other layers. // Note that mask shouldn't be part of _layers at this point. for(int i = 1; i < numLayers; ++i) { float[] normalizedHF = HEU_TerrainUtility.GetNormalizedHeightmapFromPartWithMinMax(session, _ownerNode.GeoID, _layers[i]._part.PartID, _layers[i]._xLength, _layers[i]._yLength, ref minHeight, ref maxHeight, ref heightRange); if (normalizedHF != null && normalizedHF.Length > 0) { heightFields.Add(normalizedHF); volumeLayersToProcess.Add(_layers[i]); } } int numVolumeLayers = volumeLayersToProcess.Count; HAPI_NodeId geoID; HAPI_PartId partID; Texture2D defaultTexture = LoadDefaultSplatTexture(); #if UNITY_2018_3_OR_NEWER // Create or update the terrain layers based on heightfield layers. // Keep existing TerrainLayers, and either update or append to them TerrainLayer[] existingTerrainLayers = terrainData.terrainLayers; // Total layers are existing layers + new alpha maps List<TerrainLayer> finalTerrainLayers = new List<TerrainLayer>(existingTerrainLayers); // This holds the alpha map indices for each layer that will be added to the TerrainData. // The alpha maps could be a mix of existing and new values, so need to know which to use // Initially set to use existing alpha maps, then override later on if specified via HF layers List<int> alphaMapIndices = new List<int>(); for (int a = 0; a < existingTerrainLayers.Length; ++a) { // Negative indices for existing alpha map (offset by -1) alphaMapIndices.Add(-a - 1); } bool bNewTerrainLayer = false; HEU_VolumeLayer layer = null; TerrainLayer terrainLayer = null; bool bSetTerrainLayerProperties = true; for (int m = 0; m < numVolumeLayers; ++m) { bNewTerrainLayer = false; bSetTerrainLayerProperties = true; layer = volumeLayersToProcess[m]; geoID = _ownerNode.GeoID; partID = layer._part.PartID; terrainLayer = null; int terrainLayerIndex = -1; // The TerrainLayer attribute overrides existing TerrainLayer. So if its set, load and use it. string terrainLayerFile = HEU_GeneralUtility.GetAttributeStringValueSingle(session, geoID, partID, HEU_Defines.DEFAULT_UNITY_HEIGHTFIELD_TERRAINLAYER_FILE_ATTR, HAPI_AttributeOwner.HAPI_ATTROWNER_PRIM); if (!string.IsNullOrEmpty(terrainLayerFile)) { terrainLayer = HEU_AssetDatabase.LoadAssetAtPath(terrainLayerFile, typeof(TerrainLayer)) as TerrainLayer; if (terrainLayer == null) { Debug.LogWarningFormat("TerrainLayer, set via attribute, not found at: {0}", terrainLayerFile); // Not earlying out or skipping this layer due to error because we want to keep proper indexing // by creating a new TerrainLayer. } else { // TerrainLayer loaded from attribute. // It could be an existing TerrainLayer that is already part of finalTerrainLayers // or could be a new one which needs to be added. // If its a different TerrainLayer than existing, update the finalTerrainLayers, and index. if (layer._terrainLayer != null && layer._terrainLayer != terrainLayer) { terrainLayerIndex = HEU_TerrainUtility.GetTerrainLayerIndex(layer._terrainLayer, existingTerrainLayers); if (terrainLayerIndex >= 0) { finalTerrainLayers[terrainLayerIndex] = terrainLayer; } } if (terrainLayerIndex == -1) { // Always check if its part of existing list so as not to add it again terrainLayerIndex = HEU_TerrainUtility.GetTerrainLayerIndex(terrainLayer, existingTerrainLayers); } } } // No terrain layer specified, so try using existing if we have it if (terrainLayer == null) { terrainLayerIndex = HEU_TerrainUtility.GetTerrainLayerIndex(layer._terrainLayer, existingTerrainLayers); if (terrainLayerIndex >= 0) { // Note the terrainLayerIndex is same for finalTerrainLayers as existingTerrainLayers terrainLayer = existingTerrainLayers[terrainLayerIndex]; } } // Still not found, so just create a new one if (terrainLayer == null) { terrainLayer = new TerrainLayer(); terrainLayer.name = layer._layerName; //Debug.LogFormat("Created new TerrainLayer with name: {0} ", terrainLayer.name); bNewTerrainLayer = true; } if (terrainLayerIndex == -1) { // Adding to the finalTerrainLayers if this is indeed a newly created or loaded TerrainLayer // (i.e. isn't already part of the TerrainLayers for this Terrain). // Save this layer's index for later on if we make a copy. terrainLayerIndex = finalTerrainLayers.Count; finalTerrainLayers.Add(terrainLayer); // Positive index for alpha map from heightfield (starting at 1) alphaMapIndices.Add(m + 1); } else { // Positive index for alpha map from heightfield (starting at 1) alphaMapIndices[terrainLayerIndex] = m + 1; } // For existing TerrainLayer, make a copy of it if it has custom layer attributes // because we don't want to change the original TerrainLayer. if (!bNewTerrainLayer && layer._hasLayerAttributes) { string bakedTerrainPath = houdiniAsset.GetValidAssetCacheFolderPath(); bakedTerrainPath = HEU_Platform.BuildPath(bakedTerrainPath, relativeFolderPath); TerrainLayer prevTerrainLayer = terrainLayer; terrainLayer = HEU_AssetDatabase.CopyAndLoadAssetAtAnyPath(terrainLayer, bakedTerrainPath, typeof(TerrainLayer), true) as TerrainLayer; if (terrainLayer != null) { // Update the TerrainLayer reference in the list with this copy finalTerrainLayers[terrainLayerIndex] = terrainLayer; } else { Debug.LogErrorFormat("Unable to copy TerrainLayer '{0}' for generating Terrain. " + "Using original TerrainLayer. Will not be able to set any TerrainLayer properties.", layer._layerName); terrainLayer = prevTerrainLayer; bSetTerrainLayerProperties = false; // Again, continuing on to keep proper indexing. } } // Now override layer properties if they have been set via attributes if (bSetTerrainLayerProperties) { LoadLayerPropertiesFromAttributes(session, geoID, partID, terrainLayer, bNewTerrainLayer, defaultTexture); } if (bNewTerrainLayer) { // In order to retain the new TerrainLayer, it must be saved to the AssetDatabase. Object savedObject = null; string layerFileNameWithExt = terrainLayer.name; if (!layerFileNameWithExt.EndsWith(HEU_Defines.HEU_EXT_TERRAINLAYER)) { layerFileNameWithExt += HEU_Defines.HEU_EXT_TERRAINLAYER; } houdiniAsset.AddToAssetDBCache(layerFileNameWithExt, terrainLayer, relativeFolderPath, ref savedObject); } // Store reference layer._terrainLayer = terrainLayer; } // Get existing alpha maps so we can reuse the values if needed float[,,] existingAlphaMaps = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight); terrainData.terrainLayers = finalTerrainLayers.ToArray(); int numTotalAlphaMaps = finalTerrainLayers.Count; #else // Create or update the SplatPrototype based on heightfield layers. // Need to create or reuse SplatPrototype for each layer in heightfield, representing the textures. SplatPrototype[] existingSplats = terrainData.splatPrototypes; // A full rebuild clears out existing splats, but a regular cook keeps them. List<SplatPrototype> finalSplats = new List<SplatPrototype>(existingSplats); // This holds the alpha map indices for each layer that will be added to the TerrainData // The alpha maps could be a mix of existing and new values, so need to know which to use List<int> alphaMapIndices = new List<int>(); // Initially set to use existing alpha maps, then override later on if specified via HF layers. for (int a = 0; a < existingSplats.Length; ++a) { // Negative indices for existing alpha map (offset by -1) alphaMapIndices.Add(-a - 1); } bool bNewSplat = false; HEU_VolumeLayer layer = null; SplatPrototype splatPrototype = null; for (int m = 0; m < numVolumeLayers; ++m) { bNewSplat = false; layer = volumeLayersToProcess[m]; geoID = _ownerNode.GeoID; partID = layer._part.PartID; // Try to find existing SplatPrototype for reuse. But not for full rebuild. splatPrototype = null; if (layer._splatPrototypeIndex >= 0 && layer._splatPrototypeIndex < existingSplats.Length) { splatPrototype = existingSplats[layer._splatPrototypeIndex]; // Positive index for alpha map from heightfield (starting at 1) alphaMapIndices[layer._splatPrototypeIndex] = m + 1; } if (splatPrototype == null) { splatPrototype = new SplatPrototype(); layer._splatPrototypeIndex = finalSplats.Count; finalSplats.Add(splatPrototype); // Positive index for alpha map from heightfield (starting at 1) alphaMapIndices.Add(m + 1); } // Now override splat properties if they have been set via attributes LoadLayerPropertiesFromAttributes(session, geoID, partID, splatPrototype, bNewSplat, defaultTexture); } // On regular cook, get existing alpha maps so we can reuse the values if needed. float[,,] existingAlphaMaps = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight); terrainData.splatPrototypes = finalSplats.ToArray(); int numTotalAlphaMaps = finalSplats.Count; #endif // Set alpha maps by combining with existing alpha maps, and appending new heightfields float[,,] alphamap = null; if (numTotalAlphaMaps > 0 && volumeLayersToProcess.Count > 0) { // Convert the heightfields into alpha maps with layer strengths float[] strengths = new float[volumeLayersToProcess.Count]; for (int m = 0; m < volumeLayersToProcess.Count; ++m) { strengths[m] = volumeLayersToProcess[m]._strength; } alphamap = HEU_TerrainUtility.AppendConvertedHeightFieldToAlphaMap( volumeLayersToProcess[0]._xLength, volumeLayersToProcess[0]._yLength, existingAlphaMaps, heightFields, strengths, alphaMapIndices); // Update the alphamap resolution to the actual size of the first // heightfield layer used for the alphamaps. // Setting the size before setting the alphamas applies proper scaling. int alphamapResolution = volumeLayersToProcess[0]._xLength; terrainData.alphamapResolution = alphamapResolution; terrainData.SetAlphamaps(0, 0, alphamap); } // Tree instances for scattering HEU_TerrainUtility.ApplyScatter(terrainData, _scatterTrees); // If the layers were writen out, this saves the asset DB. Otherwise user has to save it themselves. // Not 100% sure this is needed, but without this the editor doesn't know the terrain asset has been updated // and therefore doesn't import and show the terrain layer. HEU_AssetDatabase.SaveAssetDatabase(); }
/* * This is ran during the start up of the scene. * This set the terrain to dug up when driven over. * */ void Start() { crop = new Crop(); waypoints = new WaypointFPT(terrain); waypoints.genPointsStr(new Vector3(50,0,50),true); tractorAI = (GameObject)Instantiate(objPre,new Vector3(50,.3f,50),Quaternion.identity); tractorAI.name = "AI Tractor FP"; if(PlayerPrefs.GetString("FieldName") == ""){ crop.setType(PlayerPrefs.GetInt("CropType")); FieldName = PlayerPrefs.GetString("NFName"); alphatext = new float[terrain.GetComponent<Terrain>().terrainData.alphamapWidth,terrain.GetComponent<Terrain>().terrainData.alphamapHeight,2]; for(int i = 0; i < terrain.GetComponent<Terrain>().terrainData.alphamapWidth; i++){ for(int j = 0; j < terrain.GetComponent<Terrain>().terrainData.alphamapHeight; j++){ alphatext[i,j,0] = 1; alphatext[i,j,1] = 0; } } Vector3 localPos = new Vector3(50,0,50) - terrain.transform.position; Vector3 normalPos = new Vector3((localPos.x/terrain.GetComponent<Terrain>().terrainData.size.x) * terrain.GetComponent<Terrain>().terrainData.alphamapWidth, 0, (localPos.z/terrain.GetComponent<Terrain>().terrainData.size.z) * terrain.GetComponent<Terrain>().terrainData.alphamapHeight); alphatext[(int)normalPos.z,(int)normalPos.x,0] = 0; alphatext[(int)normalPos.z,(int)normalPos.x,1] = 1; terrain.GetComponent<Terrain>().terrainData.SetAlphamaps(0,0,alphatext); // fieldData = new SFFD(terrain.GetComponent<Terrain>().terrainData.alphamapWidth,terrain.GetComponent<Terrain>().terrainData.alphamapHeight,2, // terrain.GetComponent<Terrain>().terrainData.detailWidth,terrain.GetComponent<Terrain>().terrainData.detailHeight,terrain.GetComponent<Terrain>().terrainData.detailPrototypes.Length, // terrain.GetComponent<Terrain>().terrainData.heightmapWidth,terrain.GetComponent<Terrain>().terrainData.heightmapHeight); // fieldData.setHM (terrain.GetComponent<Terrain>().terrainData.GetHeights(0,0,terrain.GetComponent<Terrain>().terrainData.heightmapWidth,terrain.GetComponent<Terrain>().terrainData.heightmapHeight)); // fieldData.setAM (terrain.GetComponent<Terrain>().terrainData.GetAlphamaps(0,0,terrain.GetComponent<Terrain>().terrainData.alphamapWidth,terrain.GetComponent<Terrain>().terrainData.alphamapHeight)); // fieldData.setDM (terrain.GetComponent<Terrain>().terrainData.GetDetailLayer(0,0,terrain.GetComponent<Terrain>().terrainData.detailWidth,terrain.GetComponent<Terrain>().terrainData.detailHeight,1)); // fieldData.save(); } else{ FieldName = PlayerPrefs.GetString("FieldName"); byte[] load = sf.Load (PlayerPrefs.GetString("FieldName")); UnitySerializer.DeserializeInto(load,sf); crop.setField(sf.getCrops()); tractorAI.transform.position += new Vector3(0,15,0); terrain.GetComponent<Terrain>().terrainData.SetHeights(0,0,sf.getHM ()); terrain.GetComponent<Terrain>().terrainData.SetAlphamaps(0,0,sf.getAM()); alphatext = sf.getAM(); terrain.GetComponent<Terrain>().terrainData.SetAlphamaps(0,0,alphatext); loaded = true; } }
void GenerateViaMesh(int size, bool generate_density = true) { meshData = new MeshData(); meshData.useRenderDataForCol = true; print("Generating mesh"); if (generate_density) { Noise generator = new Noise(Seed); density = new float[size + 1, size + 1, size + 1]; positions = new Vector3Int[size + 1, size + 1, size + 1]; print("Generating density"); for (int x = 0; x < size + 1; x++) { for (int y = 0; y < size + 1; y++) { for (int z = 0; z < size + 1; z++) { Vector3Int pos = new Vector3Int(x, y, z) + ChunkPosition * size; positions[x, y, z] = pos; float top = (size - pos.y); density[x, y, z] = generator.Evaluate(new Vector3(pos.x / ((float)(size * 4)), pos.y / ((float)(size * 4)), pos.z / ((float)(size * 4)))) + 2.0f * top * top * top * top / (size * size * size * size); } } } } for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { for (int z = 0; z < size; z++) { if (isSquare(x, y, z)) { var pos = positions[x, y, z]; if (!isSquare(x, y + 1, z)) { meshData = FaceDataUp(pos.x, pos.y, pos.z, meshData); } if (!isSquare(x, y - 1, z)) { meshData = FaceDataDown(pos.x, pos.y, pos.z, meshData); } if (!isSquare(x, y, z + 1)) { meshData = FaceDataNorth(pos.x, pos.y, pos.z, meshData); } if (!isSquare(x, y, z - 1)) { meshData = FaceDataSouth(pos.x, pos.y, pos.z, meshData); } if (!isSquare(x + 1, y, z)) { meshData = FaceDataEast(pos.x, pos.y, pos.z, meshData); } if (!isSquare(x - 1, y, z)) { meshData = FaceDataWest(pos.x, pos.y, pos.z, meshData); } } } } } initialized = State.ReadyToLoad; // mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; /* * foreach (Vector3 square in squares) { * GameObject obj = new GameObject(); * obj.transform.parent = this.transform; * var collider = obj.AddComponent<BoxCollider>(); * collider.size = Vector3.one; * collider.transform.position = square; * } */ }
/// <summary> /// Highlights all values above a certain threshold as red /// </summary> /// <param name="value"></param> public void HighlightThreshold(int threshold, HighlightCondition highlightCondition = HighlightCondition.ABOVE) { this.highlightCondition = highlightCondition; double max = imageData.GetMaximum(); double min = imageData.GetMinimum(); int width = imageData.GetWidth(); int height = imageData.GetHeight(); float[,,] data = imageData.GetData(); WriteableBitmap highlightedImage = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, null); highlightedImage.Lock(); // Go through each pixel in each image for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { double n = data[imageIndex, y, x]; byte pixelValue = (byte)(((n - min) / (max - min)) * MAXIMUM_INTENSITY); unsafe { // Get a pointer to the back buffer. int pBackBuffer = (int)highlightedImage.BackBuffer; // Find the address of the pixel to draw. pBackBuffer += y * highlightedImage.BackBufferStride; pBackBuffer += x * 4; // Compute the pixel's color. int color_data; if (highlightCondition == HighlightCondition.ABOVE) { if (n > threshold) { color_data = pixelValue << 16; // R color_data |= 0; // G color_data |= 0; // B } else { color_data = pixelValue << 16; // R color_data |= pixelValue << 8; // G color_data |= pixelValue << 0; // B } } else { if (n < threshold) { color_data = pixelValue << 16; // R color_data |= 0; // G color_data |= 0; // B } else { color_data = pixelValue << 16; // R color_data |= pixelValue << 8; // G color_data |= pixelValue << 0; // B } } // Assign the color data to the pixel. *((int *)pBackBuffer) = color_data; } // Specify the area of the bitmap that changed. highlightedImage.AddDirtyRect(new Int32Rect(x, y, 1, 1)); } } // Release the back buffer and make it available for display. highlightedImage.Unlock(); mainWindow.ImageViewer.Source = highlightedImage; }
void Start() { Screen.showCursor = false; terrain = this.GetComponent<Terrain>(); foreach (AnimationState state in thelight.animation) { state.time = 1.5f; state.speed *= 1/120.0f; } alphas = terrain.terrainData.GetAlphamaps(0,0,512,512); restoreTerrain(); original_alphas = terrain.terrainData.GetAlphamaps(0,0,512,512); doDetails(); terrain.Flush(); }
void Awake() { terrain = GetComponent <Terrain>(); terrainData = terrain.terrainData; // Generation of heads Transform headsFolder = GameObject.Find("Heads").transform; int numberOfCollectibleHeads = Random.Range(minCollectibleHeads, maxCollectibleHeads); for (int i = 0; i < numberOfCollectibleHeads; i++) { //Transform head = Instantiate(headPrefab, new Vector3(Random.Range(boundsSize, terrainData.size.x - boundsSize), spawnHeight, Random.Range(boundsSize, terrainData.size.z - boundsSize)), Quaternion.identity, headsFolder); //head.tag = "CollectibleHead"; } // Generation of links Transform linksFolder = GameObject.Find("Links").transform; int numberOfCollectibleLinks = Random.Range(minCollectibleLinks, maxCollectibleLinks); for (int i = 0; i < numberOfCollectibleLinks; i++) { Transform link = Instantiate(collectibleLinkPrefab, new Vector3(Random.Range(boundsSize, terrainData.size.x - boundsSize), spawnHeight, Random.Range(boundsSize, terrainData.size.z - boundsSize)), Quaternion.identity, linksFolder); link.name = "link" + i; } Vector2 orig = new Vector2(Random.value * 100f, Random.value * 100f); // Generation of terrain float[,] heights = terrainData.GetHeights(0, 0, terrainData.heightmapWidth, terrainData.heightmapHeight); for (int i = 0; i < terrainData.heightmapWidth; i++) { for (int j = 0; j < terrainData.heightmapHeight; j++) { heights[i, j] = Mathf.PerlinNoise(orig.x + i / groundNoiseFactor, orig.y + j / groundNoiseFactor); } } terrainData.SetHeights(0, 0, heights); // Generation of details and paint bool isGrass = false; float height = 0f, heightMargin = 0; float minRockHeight = (rockHeight - rockHeightMargin) / terrainData.size.y, maxRockHeight = (rockHeight + rockHeightMargin) / terrainData.size.y, minGrassHeight = (grassHeight - grassHeightMargin) / terrainData.size.y, maxGrassHeight = (grassHeight + grassHeightMargin) / terrainData.size.y; float heightmapRes = terrainData.heightmapResolution / (float)terrainData.detailResolution, alphamapRes = terrainData.alphamapResolution / (float)terrainData.detailResolution; int alphamapI = 0, alphamapJ = 0; orig = new Vector2(Random.value * 220f, Random.value * 220f); int[,] details = terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, 0); float[,,] alphamaps = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight); for (int i = 0; i < terrainData.detailWidth; i++) { for (int j = 0; j < terrainData.detailHeight; j++) { height = heights[Mathf.FloorToInt(heightmapRes * i), Mathf.FloorToInt(heightmapRes * j)]; alphamapI = Mathf.FloorToInt(alphamapRes * i); alphamapJ = Mathf.FloorToInt(alphamapRes * j); // Determine whether there is grass or not here isGrass = false; if (height < maxGrassHeight) { isGrass = true; } // Ground and rock painting if (height >= minRockHeight && height <= maxRockHeight) { heightMargin = (height - minRockHeight) / (maxRockHeight - minRockHeight); alphamaps[alphamapI, alphamapJ, 0] = 1f - heightMargin; alphamaps[alphamapI, alphamapJ, 1] = 0; alphamaps[alphamapI, alphamapJ, 2] = heightMargin; } else if (height < minRockHeight) { alphamaps[alphamapI, alphamapJ, 0] = 1; alphamaps[alphamapI, alphamapJ, 1] = 0; alphamaps[alphamapI, alphamapJ, 2] = 0; } else if (height > maxRockHeight) { alphamaps[alphamapI, alphamapJ, 0] = 0; alphamaps[alphamapI, alphamapJ, 1] = 0; alphamaps[alphamapI, alphamapJ, 2] = 1; } // Grass details if (isGrass) { if (height < Random.Range(minGrassHeight - grassBorder, minGrassHeight)) { details[i, j] = 1; } else { details[i, j] = 0; } // Grass painting if (height >= minGrassHeight && height <= maxGrassHeight) { heightMargin = (height - minGrassHeight) / (maxGrassHeight - minGrassHeight); alphamaps[alphamapI, alphamapJ, 0] = heightMargin; alphamaps[alphamapI, alphamapJ, 1] = 1f - heightMargin; alphamaps[alphamapI, alphamapJ, 2] = 0; } else if (height < minGrassHeight) { alphamaps[alphamapI, alphamapJ, 0] = 0; alphamaps[alphamapI, alphamapJ, 1] = 1; } else if (height > maxGrassHeight) { alphamaps[alphamapI, alphamapJ, 1] = 0; } } else { details[i, j] = 0; } } } terrainData.SetDetailLayer(0, 0, 0, details); terrainData.SetAlphamaps(0, 0, alphamaps); }
//private GUI myGUI; void Start() { //myGUI = GUI(); terr = this.GetComponent<Terrain>(); hmWidth = terr.terrainData.heightmapWidth; hmHeight = terr.terrainData.heightmapHeight; alphaMapWidth = terr.terrainData.alphamapWidth; alphaMapHeight = terr.terrainData.alphamapHeight; numOfAlphaLayers = terr.terrainData.alphamapLayers; if (Debug.isDebugBuild) { heightMapBackup = terr.terrainData.GetHeights(0, 0, hmWidth, hmHeight); alphaMapBackup = terr.terrainData.GetAlphamaps(0, 0, alphaMapWidth, alphaMapHeight); } }
/*private IEnumerator GetPrefabs(WorldSerialization blob) * { * for (int i = 0; i < blob.world.prefabs.Count; i++) { * yield return null; * if ((blob.world.prefabs[i].category.ToLower().Contains("monument") || blob.world.prefabs[i].category.ToLower().Contains("river")) || blob.world.prefabs[i].category.ToLower().Contains("decor")) { * Debug.Log(blob.world.prefabs[i].id + "-" + blob.world.prefabs[i].category); * FileSystem.Operation g2 = FileSystem.LoadAsync(StringPool.Get((blob.world.prefabs[i].id))); * /*yield return new WaitUntil(() => { * return g2.isDone; * });* * while (!g2.isDone) { * yield return null; * } * * GameObject g3 = g2.Load<GameObject>(); * * GameObject g = Instantiate(g3, blob.world.prefabs[i].position, blob.world.prefabs[i].rotation); * g.transform.localScale = blob.world.prefabs[i].scale; * g.SetActive(true); * g.AddComponent<EditableObject>(); * g.AddComponent<BoxCollider>(); * yield return null; * Debug.Log("Loaded " + i + "/" + blob.world.prefabs.Count); * } * else * { * yield return null; * Debug.Log("Skipping " + i + "/" + blob.world.prefabs.Count); * } * } * }*/ private void SaveMap(WorldSerialization blob) { // Resolution of the terrain height and water maps var meshResolution = Mathf.NextPowerOfTwo((int)(blob.world.size * 0.50f)) + 1; // Resolution of the terrain splat, topology, biome and alpha maps var textureResolution = Mathf.NextPowerOfTwo((int)(blob.world.size * 0.50f)); // The dimensions of the terrain object, Y always goes from -500 to +500, X and Z from -extents to +extents var terrainSize = new Vector3(blob.world.size, 1000, blob.world.size); // The position of the terrain object, chosen so world origin is always at the center of the terrain bounds var terrainPosition = -0.5f * terrainSize; // Terrain mesh height values (16 bit) // Indexed [z, x] var terrainMap = new TerrainMap <short>(blob.GetMap("terrain").data, 1); // World height values (16 bit) // Indexed [z, x] // Used to sample the height at which to spawn grass and decor at // Can include both terrain and other meshes like for example cliffs var heightMap = new TerrainMap <short>(blob.GetMap("height").data, 1); // Water map (16 bit) // Indexed [z, x] // Includes both the ocean plane at zero level and any rivers var waterMap = new TerrainMap <short>(blob.GetMap("water").data, 1); // Alpha map (8 bit) // Indexed [z, x] // Zero to render parts of the terrain invisible var alphaMap = new TerrainMap <byte>(blob.GetMap("alpha").data, 1); // Splat map (8 bit, 8 channels) // Indexed [c, z, x] (see TerrainSplat class) // Sum of all channels should be normalized to 255 var splatMap = new TerrainMap <byte>(blob.GetMap("splat").data, 8); // Biome map (8 bit, 4 channels) // Indexed [c, z, x] (see TerrainBiome class) // Sum of all channels should be normalized to 255 var biomeMap = new TerrainMap <byte>(blob.GetMap("biome").data, 4); // Topology map (32 bit) // Indexed [z, x] (see TerrainTopology class) // Used as a bit mask, multiple topologies can be set in one location var topologyMap = new TerrainMap <int>(blob.GetMap("topology").data, 1); float[,] terrainMap2 = data.GetHeights(0, 0, meshResolution, meshResolution); for (int y = 0; y < meshResolution; y++) { for (int x = 0; x < meshResolution; x++) { terrainMap[y, x] = BitUtility.Float2Short(terrainMap2[y, x]); } } int t = 0; for (; t < blob.world.maps.Count; t++) { if (blob.world.maps[t].name == "terrain") { break; } } blob.world.maps[t].data = terrainMap.ToByteArray(); int wh = 0; for (; wh < blob.world.maps.Count; wh++) { if (blob.world.maps[wh].name == "height") { break; } } blob.world.maps[wh].data = terrainMap.ToByteArray(); float[,,] splatMap2 = data.GetAlphamaps(0, 0, textureResolution, textureResolution); for (int y = 0; y < textureResolution; y++) { for (int x = 0; x < textureResolution; x++) { splatMap[0, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 0]); splatMap[1, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 1]); splatMap[2, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 2]); splatMap[3, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 3]); splatMap[4, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 4]); splatMap[5, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 5]); splatMap[6, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 6]); splatMap[7, y, x] = BitUtility.Float2Byte(splatMap2[y, x, 7]); } } int s = 0; for (; s < blob.world.maps.Count; s++) { if (blob.world.maps[s].name == "splat") { break; } } blob.world.maps[s].data = splatMap.ToByteArray(); float[,] waterMap2 = data2.GetHeights(0, 0, meshResolution, meshResolution); for (int y = 0; y < meshResolution; y++) { for (int x = 0; x < meshResolution; x++) { waterMap[y, x] = BitUtility.Float2Short(waterMap2[y, x]); } } int w = 0; for (; w < blob.world.maps.Count; w++) { if (blob.world.maps[w].name == "water") { break; } } blob.world.maps[w].data = waterMap.ToByteArray(); //blob.world.prefabs.Clear(); for (int i = 0; i < blob.world.prefabs.Count; i++) { for (int j = 0; j < spawnedPrefabs.Count; j++) { if (spawnedPrefabs[j].GetComponent <PrefabData>().idInList == i) { blob.world.prefabs[i].position = spawnedPrefabs[j].transform.position; blob.world.prefabs[i].rotation = spawnedPrefabs[j].transform.rotation.eulerAngles; blob.world.prefabs[i].scale = spawnedPrefabs[j].transform.localScale; } } } blob.Save(filename + ".new"); }
public void UpdateAlphamaps() { terrainAlphamap = terDat.GetAlphamaps(0, 0, terDat.alphamapWidth, terDat.alphamapHeight); }
public bool ReadData(string fileName) { m_hdfOperator.Close(); m_L1file = fileName; m_hdfOperator.Open(fileName); m_EVInfo = m_hdfOperator.GetDatasetInfo("EV_RefSB", "/"); m_EV = ReadEV(); m_lonInfo = m_hdfOperator.GetDatasetInfo("Longitude", "/"); m_lon = ReadLon(); m_latInfo = m_hdfOperator.GetDatasetInfo("Latitude", "/"); m_lat = ReadLat(); m_calcoef = ReadCalcoefAttr(); this.Update(); return true; }
void StartMakingTerrain() { mainTerrain = terr; hmWidth = terr.terrainData.heightmapWidth; hmHeight = terr.terrainData.heightmapHeight; if (Debug.isDebugBuild) { heightMapBackup = terr.terrainData.GetHeights(0, 0, hmWidth, hmHeight); alphaMapBackup = terr.terrainData.GetAlphamaps(0, 0, alphaMapWidth, alphaMapHeight); } gameManager = GameObject.FindGameObjectWithTag("Game Manager"); if (gameManager != null) roughness = gameManager.GetComponent<GameManager>().GetSliderValue(); GroupTerrains(); }
IEnumerator Coroutine() { Utils.ClearMemory(); if (terrainData == null || terrain == null) { CreateTerrain(); yield return(null); } heights = terrainData.GetHeights(0, 0, terrainData.heightmapWidth, terrainData.heightmapHeight); alphas = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight); Vector3 position = terrain.transform.position; float waterRelativeHeight = water.position.y / size.y; //Generate heights terrainGenerator.SetupConfig(); bool terrainHeights1 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateHeights(heights, 0, 4); terrainHeights1 = false; }); bool terrainHeights2 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateHeights(heights, 1, 4); terrainHeights2 = false; }); bool terrainHeights3 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateHeights(heights, 2, 4); terrainHeights3 = false; }); bool terrainHeights4 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateHeights(heights, 3, 4); terrainHeights4 = false; }); while (terrainHeights1 || terrainHeights2 || terrainHeights3 || terrainHeights4) { yield return(null); } //create roads bool road = true; ThreadPool.QueueUserWorkItem((o) => { roadGenerator.Generate(heights, size, position, waterRelativeHeight); road = false; }); //paint textures bool terrainTextures = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.PrepareTextures(heights, waterRelativeHeight); terrainTextures = false; }); while (terrainTextures) { yield return(null); } bool terrainTextures1 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateTextures(heights, alphas, 0, 4); terrainTextures1 = false; }); bool terrainTextures2 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateTextures(heights, alphas, 1, 4); terrainTextures2 = false; }); bool terrainTextures3 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateTextures(heights, alphas, 2, 4); terrainTextures3 = false; }); bool terrainTextures4 = true; ThreadPool.QueueUserWorkItem((o) => { terrainGenerator.GenerateTextures(heights, alphas, 3, 4); terrainTextures4 = false; }); //level roads while (road) { yield return(null); } bool roadHeights = true; ThreadPool.QueueUserWorkItem((o) => { roadGenerator.DrawRoadHeights(heights, size, position, alphas.GetLength(0)); roadHeights = false; }); //paint roads while (road || terrainTextures1 || terrainTextures2 || terrainTextures3 || terrainTextures4) { yield return(null); } bool roadTextures = true; ThreadPool.QueueUserWorkItem((o) => { roadGenerator.DrawRoadTextures(alphas, size, position); roadTextures = false; }); while (roadTextures || roadHeights) { yield return(null); } terrainData.SetHeights(0, 0, heights); terrainData.SetAlphamaps(0, 0, alphas); terrain.Flush(); yield return(null); reflection.RenderProbe(); Utils.ClearMemory(); if (onGenerated != null) { onGenerated(); } }
// Start is called before the first frame update void Start() { //also from youtube for (int x = 0; x < chunkSizeBlocks; x++) { for (int y = 0; y < chunkSizeBlocks; y++) { for (int z = 0; z < chunkSizeBlocks; z++) { float noise = Perlin3D(x * noiseScale, y * noiseScale, z * noiseScale); if (noise >= threshold) //here we pass floats instead so that Perlin behaves { //sampling unity's perlin noise with an integer returns the same value, which was less than the threshold //Instantiate(blockPrefab, new Vector3(x, y, z), Quaternion.identity);//not rotated is what quaternion.identity says ogChunkData[chunkSizeBlocks - x - 1, chunkSizeBlocks - y - 1, z] = 1; } else { ogChunkData[chunkSizeBlocks - x - 1, chunkSizeBlocks - y - 1, z] = 0;//idk if it instantiates to all 0's } } } } hollowedChunkData = hollowOut(ogChunkData); //now that we have our verticies, lets march some cubes? //some for loop logic to get to one cube //now that we are at a cube: //check each of the 8 verticies to see if it is on or off //index = 0; //for all of the 8 //index += (vertex value [1 or 0]) * 2^(vertex index) //lookup, then make triangle /*CombineInstance[] wholeMesh = new CombineInstance[(int)Mathf.Pow(chunkSizeBlocks, 3)]; * * Mesh mesh = GetComponent<MeshFilter>().mesh; * * mesh.Clear(); * * //int[] initialVoxels = { (int) hollowedChunkData[0, 0, 0], (int) hollowedChunkData[1, 0, 0], (int) hollowedChunkData[1, 0, 1], (int) hollowedChunkData[0, 0, 1], (int) hollowedChunkData[0, 1, 0], (int) hollowedChunkData[1, 1, 0], (int) hollowedChunkData[1, 1, 1], (int) hollowedChunkData[0, 1, 1] }; * * Mesh temp = prefab.GetComponent<MeshFilter>().sharedMesh;//MarchingCubes3.perCube(new Vector3(0, 0, 0), initialVoxels, 0); * * ////foreach (int i in initialVoxels) * //// Debug.Log(i); * * ////mesh.triangles = temp.triangles; * ////mesh.vertices = temp.vertices; * * ////mesh.RecalculateBounds(); * ////mesh.RecalculateNormals(); * * wholeMesh[0] = new CombineInstance(); * wholeMesh[0].mesh = temp; * * //Debug.Log(chunkSizeBlocks);*/ //per chunk for (int x = 0; x < chunkSizeBlocks; x++) { for (int y = 0; y < chunkSizeBlocks; y++) { for (int z = 0; z < chunkSizeBlocks; z++) { /*if (x == 0 && y == 0 && z == 0) * { * continue; * }*/ /*//set blockNum somehow * int blockNum = (int)(z + y * (Mathf.Pow(chunkSizeBlocks, 1)) + x * (Mathf.Pow(chunkSizeBlocks, 2))); * //percube * int[] voxels = { (int)chunkData[x, y, z], (int)chunkData[x + 1, y, z], (int)chunkData[x + 1, y, z + 1], (int)chunkData[x, y, z + 1], (int)chunkData[x, y + 1, z], (int)chunkData[x + 1, y + 1, z], (int)chunkData[x + 1, y + 1, z + 1], (int)chunkData[x, y + 1, z + 1] }; //this is a line worth checking, I made it match up with MarchingCubes3.localVerticies * Mesh m = MarchingCubes3Clean.perCube(new Vector3(0, 0, 0), voxels, blockNum); * //^^ this causes unity to freeze up * * //if combineInstance has too many verts: //IMPLEMENT THIS LOGIC LATER, MAYBE IF COMBINING CHUNKS??? * //save the current combineInstance to a mesh * //make a new one * //Debug.Log(wholeMesh[blockNum]); * wholeMesh[blockNum] = new CombineInstance(); * wholeMesh[blockNum].mesh = m; * //Debug.Log(wholeMesh[blockNum]); * //wholeMesh[blockNum].transform. = MarchingCubes3Clean.beginningCoordinates(new Vector3(0, 0, 0), blockNum);//comes with the mesh??? * //merge meshes*/ int blockNum = (int)(z + y * (Mathf.Pow(chunkSizeBlocks, 1)) + x * (Mathf.Pow(chunkSizeBlocks, 2))); //int voxel = (int)chunkData[x, y, z]; //Debug.Log("Block #:" + blockNum + ", isOn: " + chunkData[x, y, z]); if ((int)hollowedChunkData[x, y, z] > 0) { Instantiate(prefab, MarchingCubes3Clean.beginningCoordinates(new Vector3(0, 0, 0), blockNum, chunkSizeBlocks), Quaternion.identity); /*wholeMesh[blockNum] = new CombineInstance(); * wholeMesh[blockNum].mesh = prefab.GetComponent<MeshFilter>().sharedMesh; * Debug.Log(prefab.GetComponent<MeshFilter>().mesh.vertices.Length); * wholeMesh[blockNum].mesh.vertices = new Vector3[] { new Vector3(wholeMesh[blockNum].mesh.vertices[0].x + x, wholeMesh[blockNum].mesh.vertices[0].y + y, wholeMesh[blockNum].mesh.vertices[0].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[1].x + x, wholeMesh[blockNum].mesh.vertices[1].y + y, wholeMesh[blockNum].mesh.vertices[1].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[2].x + x, wholeMesh[blockNum].mesh.vertices[2].y + y, wholeMesh[blockNum].mesh.vertices[2].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[3].x + x, wholeMesh[blockNum].mesh.vertices[3].y + y, wholeMesh[blockNum].mesh.vertices[3].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[4].x + x, wholeMesh[blockNum].mesh.vertices[4].y + y, wholeMesh[blockNum].mesh.vertices[4].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[5].x + x, wholeMesh[blockNum].mesh.vertices[5].y + y, wholeMesh[blockNum].mesh.vertices[5].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[7].x + x, wholeMesh[blockNum].mesh.vertices[7].y + y, wholeMesh[blockNum].mesh.vertices[7].z + z), * new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z), new Vector3(wholeMesh[blockNum].mesh.vertices[6].x + x, wholeMesh[blockNum].mesh.vertices[6].y + y, wholeMesh[blockNum].mesh.vertices[6].z + z),}; */ } } } } /*mesh = GetComponent<MeshFilter>().mesh; //mesh is invisible now. * * mesh.Clear(); * * mesh.CombineMeshes(wholeMesh); * * //mesh.Optimize(); * * //MeshCollider meshCollider = GetComponent<MeshCollider>(); * * //meshCollider.sharedMesh = GetComponent<MeshFilter>().mesh; //this won't work but i want it to :(, also it shows up as black and unlit??? * //I think the mesh is centered but idk... * * mesh.RecalculateBounds(); * mesh.RecalculateNormals(); * /*mesh.Clear(); * * mesh.CombineMeshes(wholeMesh); * * mesh.RecalculateBounds(); * mesh.RecalculateNormals();* * * //Mesh mesh = GetComponent<MeshFilter>().mesh; * * mesh = GetComponent<MeshFilter>().mesh; //mesh is invisible now. * * mesh.Clear(); * * mesh.CombineMeshes(wholeMesh); * * //mesh.Optimize(); * * //MeshCollider meshCollider = GetComponent<MeshCollider>(); * * //meshCollider.sharedMesh = GetComponent<MeshFilter>().mesh; //this won't work but i want it to :(, also it shows up as black and unlit??? * //I think the mesh is centered but idk... * * mesh.RecalculateBounds(); * mesh.RecalculateNormals();*/ }
public UndoStep(float[,] heights, float[,,] splats, int x, int z) { this.x = x; this.z = z; this.heights = heights.Clone() as float[,]; if (splats!=null) this.splats = splats.Clone() as float[,,]; else this.splats = null; }
protected override void GenerateLayout(out bool[,] accessible, out bool[,,] corridorLayout, out float[,,] corridorWidths) { corridorLayout = SceneGenUtils.GenerateCorridorLayout(size, size, out accessible); corridorWidths = new float[size, size, 4]; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { for (int t = 0; t < 4; t++) { if (corridorLayout[x, y, t]) { corridorWidths[x, y, t] = 10f; } } } } }
public UndoStep(float[,] heights, float[,,] splats, int heightsOffsetX, int heightsOffsetZ, int splatsOffsetX, int splatsOffsetZ) { this.heightsOffsetX = heightsOffsetX; this.heightsOffsetZ = heightsOffsetZ; this.splatsOffsetX = splatsOffsetX; this.splatsOffsetZ = splatsOffsetZ; this.heights = heights.Clone() as float[,]; if (splats!=null) this.splats = splats.Clone() as float[,,]; else this.splats = null; }
void Start() { terrain = GetComponent<Terrain>(); RefreshTerrainMapVars(); if (Debug.isDebugBuild){ heightmapBackup = terrain.terrainData.GetHeights(0, 0, heightMap.width, heightMap.height); alphamapBackup = terrain.terrainData.GetAlphamaps(0, 0, alphaMap.width, alphaMap.height); //backupTreeInstances = terrain.terrainData.treeInstances; } GenerateTerrain(); }
private void CleanUp() { _worldData = null; if (_chunks != null) { foreach (var chunk in _chunks) { chunk.Dispose(); } } }
public static void draw() { List <int> fpsCounter = new List <int>(); for (int i = 0; i < 10; i++) { fpsCounter.Add(0); } frame = new int[width, height, 3]; lock (nextFrameLock) { nextFrame = new float[width, height, 3]; lastFrame = frame; } if (ConsoleSettings.screenAutoSize) { int w = 0; int h = 0; new ConsoleGameEngine.ConsoleEngine(20, 20, 8, 8); for (int i = 20; i <= 1000; i += 10) { try { new ConsoleGameEngine.ConsoleEngine(i, 20, 8, 8); } catch (System.ArgumentOutOfRangeException) { break; } w = i - 2; } for (int i = 20; i <= 1000; i += 10) { try { new ConsoleGameEngine.ConsoleEngine(20, i, 8, 8); } catch (System.ArgumentOutOfRangeException) { break; } h = i - 2; } ConsoleSettings.screenHeight = h - 2; ConsoleSettings.screenWidth = w - 2; } Engine = new ConsoleGameEngine.ConsoleEngine((int)ConsoleSettings.screenWidth + 1, (int)ConsoleSettings.screenHeight + 1, 8, 8); ConsoleGameEngine.Color[] colors = new ConsoleGameEngine.Color[16]; var handle = GetStdHandle(-11); uint mode; GetConsoleMode(handle, out mode); mode |= 4; SetConsoleMode(handle, mode); for (int i = 0; i < 16; i++) { colors[i] = new ConsoleGameEngine.Color(i * 16, i * 16, i * 16); } for (int i = 0; i < 256; i++) { colorsText[i] = $"\u001b[38;2;{i};{i};{i}m█"; } Engine.SetPalette(colors); Stopwatch frameClock = new Stopwatch(); while (true) { sw.Restart(); //frameClock.Restart(); lock (nextFrameLock) { if (frameReady) { lastFrame = frame; frame = new int[nextFrame.GetLength(0), nextFrame.GetLength(1), 3]; width = nextFrame.GetLength(0); height = nextFrame.GetLength(1); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if ((nextFrame[x, y, 0]) <= 0) { frame[x, y, 0] = 0; } else if ((nextFrame[x, y, 0]) >= 255) { frame[x, y, 0] = 255; } else { frame[x, y, 0] = (int)(nextFrame[x, y, 0]); } if ((nextFrame[x, y, 1]) <= 0) { frame[x, y, 1] = 0; } else if ((nextFrame[x, y, 1]) >= 255) { frame[x, y, 1] = 255; } else { frame[x, y, 1] = (int)(nextFrame[x, y, 1]); } if ((nextFrame[x, y, 2]) <= 0) { frame[x, y, 2] = 0; } else if ((nextFrame[x, y, 2]) >= 255) { frame[x, y, 2] = 255; } else { frame[x, y, 2] = (int)(nextFrame[x, y, 2]); } } } frameReady = false; } else { continue; } } if (lastScreenMode != (int)ConsoleSettings.screenMode) { screenWriteAll(); lastScreenMode = (int)ConsoleSettings.screenMode; lastFrame = new int[width, height, 3]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { lastFrame[x, y, 0] = -1; lastFrame[x, y, 1] = -1; lastFrame[x, y, 2] = -1; } } lastR = -1; lastG = -1; lastB = -1; } switch (ConsoleSettings.screenMode) { case ConsoleSettings.screenModes.trueColor: screenWriteChanges(); break; case ConsoleSettings.screenModes.graySpeed: for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float br = (frame[x, y, 0] + frame[x, y, 1] + frame[x, y, 2]) / 3; ConsoleGameEngine.ConsoleCharacter cc = ConsoleGameEngine.ConsoleCharacter.Full; if (br < 64) { cc = ConsoleGameEngine.ConsoleCharacter.Light; } if (br >= 64 && br < 128) { cc = ConsoleGameEngine.ConsoleCharacter.Medium; } if (br >= 128 && br < 192) { cc = ConsoleGameEngine.ConsoleCharacter.Dark; } if (br >= 192) { cc = ConsoleGameEngine.ConsoleCharacter.Full; } Engine.SetPixel(new ConsoleGameEngine.Point(x - 1, y - 1), frame[x, y, 0] / 16, cc); } } Engine.DisplayBuffer(); break; } /* * frameClock.Stop(); * * if (frameClock.ElapsedMilliseconds < 14) * { * Thread.Sleep((int)(15 - frameClock.ElapsedMilliseconds)); * }*/ sw.Stop(); if (sw.ElapsedMilliseconds > 0) { int fps = 0; for (int i = 0; i < fpsCounter.Count; i++) { fps += fpsCounter[i]; } fps /= fpsCounter.Count; Console.Title = "screen: " + fps + " fps | render: " + Renderer.fps + " fps | triangles: " + Renderer.lastTriCount; fpsCounter.Insert(0, (int)(1000 / sw.ElapsedMilliseconds)); fpsCounter.RemoveAt(fpsCounter.Count - 1); } } }
public UndoStep(float[,] heights, float[,,] splats, int heightsOffsetX, int heightsOffsetZ, int splatsOffsetX, int splatsOffsetZ) { //clamping offset low (no need to clamp high as float[,] already has proper size) if (heightsOffsetX<0) heightsOffsetX=0; if (heightsOffsetZ<0) heightsOffsetZ=0; if (splatsOffsetX<0) splatsOffsetX=0; if (splatsOffsetZ<0) splatsOffsetZ=0; this.heightsOffsetX = heightsOffsetX; this.heightsOffsetZ = heightsOffsetZ; this.splatsOffsetX = splatsOffsetX; this.splatsOffsetZ = splatsOffsetZ; this.heights = heights.Clone() as float[,]; if (splats!=null) this.splats = splats.Clone() as float[,,]; else this.splats = null; }
public void ReadFile(TextReader sr, Vector3 offset) { DateTime temps = DateTime.Now; string line = "#"; // decalage jusqu'a la taille de la grille while (line[0] == '#') { line = sr.ReadLine(); // lecture de la taille de la grille } string[] size = line.Split(' '); // string[] size = allline[4].Split(' '); // grille plate (GP) X = int.Parse(size[5]); Y = int.Parse(size[6]); Z = int.Parse(size[7]); // int nScalar; // nScalar = X*Y*Z; DateTime temps1 = DateTime.Now; Debug.Log(" taille de la grille : " + X + " " + Y + " " + Z); line = sr.ReadLine(); // lecture de l'origine string[] origs = line.Split(' '); // string[] origs = allline[5].Split(' '); //GP float oX = float.Parse(origs[1]); float oY = float.Parse(origs[2]); float oZ = float.Parse(origs[3]); DateTime temps2 = DateTime.Now; // lecture du delta float dX, dY, dZ; line = sr.ReadLine(); string[] delt = line.Split(' '); // string[] delt = allline[6].Split(' '); // GP dX = float.Parse(delt[1]); line = sr.ReadLine(); delt = line.Split(' '); // delt = allline[7].Split(' '); // GP dY = float.Parse(delt[2]); line = sr.ReadLine(); delt = line.Split(' '); // delt = allline[8].Split(' '); // GP dZ = float.Parse(delt[3]); DateTime temps3 = DateTime.Now; //lecture des commentaire line = sr.ReadLine(); line = sr.ReadLine(); DateTime temps4 = DateTime.Now; // test du nScalaile a faire pour plus de securité // int test_nScalar; // test_nScalar = 0; // line = sr.ReadLine(); // declaration de la grille _dim = new int[3]; _dim[0] = X; _dim[1] = Y; _dim[2] = Z; _grid = new float[X, Y, Z]; // _gridplate = new float[X*Y*Z]; GP // for(int i=0; i<X; i++) // { // for(int j=0; j<Y; j++) // { // for(int k=0; k<Z; k++) // { // _grid[i,j,k] = 0.0f; // } // } // } _delta = new Vector3(); _delta.x = dX; _delta.y = dY; _delta.z = dZ; Debug.Log("ReadDX :: Delta DX - " + _delta); _origin = new Vector3(); _origin.x = oX - offset.x; _origin.y = oY + offset.y; _origin.z = oZ + offset.z; Debug.Log("ReadDX :: Origin DX - " + _origin); Debug.Log("ReadDX :: Offset DX - " + offset); // line = sr.ReadLine(); string[] vals = line.Split(' '); Debug.Log(line); float val; int l = 10; // int nbline = 11; // GP // string[] vals = allline[nbline].Split(' '); int test_compteur = 0; for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { for (int k = 0; k < Z; k++) { if (l < 3) { if (test_compteur < (X * Y * Z) - 1) { val = float.Parse(vals[l]); _grid[i, j, k] = val; //// if (i==50 && j==50) //// if (val < 1.75) //// Debug.Log(" ijk" +i +" "+j+" "+k+" valeur dans la grille : "+ _grid[i,j,k]+" vals: "+ vals[l] + " val: " + val); // l++; } } else { line = sr.ReadLine(); test_compteur += 3; vals = line.Split(' '); val = float.Parse(vals[0]); _grid[i, j, k] = val; l = 1; } } } } Debug.Log("ReadDX :: test compteur - " + test_compteur); // lecture sur grille plate avec _gridplate // for (int i = 0 ;i < X*Y*Z/3;i++){ // vals = allline[nbline++].Split(' '); // _gridplate[i*3] = float.Parse(vals[0]); // _gridplate[i*3+1]= float.Parse(vals[1]); // _gridplate[i*3+2] = float.Parse(vals[2]); // } // DateTime temps5 = DateTime.Now; Debug.Log("ReadDX :: taille - " + (temps1 - temps)); Debug.Log("ReadDX :: lecture origine - " + (temps2 - temps1)); Debug.Log("ReadDX :: lecture de delta - " + (temps3 - temps2)); Debug.Log("ReadDX :: ligne vide - " + (temps4 - temps3)); Debug.Log("ReadDX :: grille lu - " + (temps5 - temps4)); loaded = true; }
void Start() { xResolution = myTerrain.terrainData.heightmapWidth; zResolution = myTerrain.terrainData.heightmapHeight; alphaMapWidth = myTerrain.terrainData.alphamapWidth; alphaMapHeight = myTerrain.terrainData.alphamapHeight; numOfAlphaLayers = myTerrain.terrainData.alphamapLayers; if (Debug.isDebugBuild) { heights = myTerrain.terrainData.GetHeights (0, 0, xResolution, zResolution); heightMapBackup = myTerrain.terrainData.GetHeights(0, 0, xResolution, zResolution); alphaMapBackup = myTerrain.terrainData.GetAlphamaps(0, 0, alphaMapWidth, alphaMapHeight); } }
private static void UnifyPrototypes(ref TerrainLayer[] basePrototypes, ref float[,,] baseData, ref TerrainLayer[] addPrototypes, ref float[,,] addData) /// Makes both datas prototypes arrays equal, and the layers arrays relevant to prototypes (empty arrays) /// Safe per-channel blend could be performed after this operation { //guard if prototypes have not been changed if (ArrayTools.MatchExactly(basePrototypes, addPrototypes)) { return; } //creating array of unified prototypes List <TerrainLayer> unifiedPrototypes = new List <TerrainLayer>(); unifiedPrototypes.AddRange(basePrototypes); //do not change the base prototypes order for (int p = 0; p < addPrototypes.Length; p++) { if (!unifiedPrototypes.Contains(addPrototypes[p])) { unifiedPrototypes.Add(addPrototypes[p]); } } //lut to convert prototypes indexes Dictionary <int, int> baseToUnifiedIndex = new Dictionary <int, int>(); Dictionary <int, int> addToUnifiedIndex = new Dictionary <int, int>(); for (int p = 0; p < basePrototypes.Length; p++) { baseToUnifiedIndex.Add(p, unifiedPrototypes.IndexOf(basePrototypes[p])); //should be 1,2,3,4,5, but doing this in case unified prototypes gather will be optimized } for (int p = 0; p < addPrototypes.Length; p++) { addToUnifiedIndex.Add(p, unifiedPrototypes.IndexOf(addPrototypes[p])); } //re-creating base data { float[,,] newBaseData = new float[baseData.GetLength(0), baseData.GetLength(1), unifiedPrototypes.Count]; int baseDataLayers = baseData.GetLength(2); for (int i = 0; i < baseDataLayers; i++) { ArrayTools.CopyLayer(baseData, newBaseData, i, baseToUnifiedIndex[i]); } baseData = newBaseData; } //re-creating add data { float[,,] newAddData = new float[addData.GetLength(0), addData.GetLength(1), unifiedPrototypes.Count]; int addDataLayers = addData.GetLength(2); for (int i = 0; i < addDataLayers; i++) { ArrayTools.CopyLayer(addData, newAddData, i, addToUnifiedIndex[i]); } addData = newAddData; } //saving prototypes basePrototypes = unifiedPrototypes.ToArray(); addPrototypes = unifiedPrototypes.ToArray(); }
public void GenerateChunk(float seed) { chunkTerrainObjectGenerator.DeleteAllChunkObjects(); _seed = seed; map = new int[_maxX + 1, _maxY + 1, _maxZ + 1]; fillValueMap = new float[_maxX + 1, _maxY + 1, _maxZ + 1]; int blocksAboveMidHeight = _maxY - (int)_midHeight; int blocksBelowMidHeight = (int)_midHeight; List <Vector3> verticies = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <int> triangles = new List <int>(); List <Vector2> uvs = new List <Vector2>(); perlinNoise = new FastNoiseLite(); List <Color> ColorList = new List <Color>(); perlinNoise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2); for (int i = 0; i < _maxX + 1; i++) { for (int k = 0; k < _maxZ + 1; k++) { float tempHeight = Noise.GenerateCoordHeights(i + _position.x, k + _position.z, _heightCurve, _skylandDropCurve, _skylandDeclinePrecent, _skylandRadius, _mapScale, _heightScale, _seed, _cutOut); for (int j = 0; j < _maxY + 1; j++) { if (j == 0 || j == _maxY) { map[i, j, k] = 0; continue; } float fillMultiplier = 0; if (j <= _midHeight) { float reversedCurrentPrecentOfTheWayUp = (((float)blocksBelowMidHeight - (float)j) / _midHeight); if (reversedCurrentPrecentOfTheWayUp > 1) { fillValueMap[i, j, k] = -0.5f; } else if (tempHeight > reversedCurrentPrecentOfTheWayUp) { fillValueMap[i, j, k] = 0.6f; } else { fillValueMap[i, j, k] = -0.5f; } fillMultiplier = Mathf.Clamp(1 / (Mathf.Abs(tempHeight - reversedCurrentPrecentOfTheWayUp) * 2), -1, 1); } if (j > _midHeight) { float currentPrecentOfWayUp = (((float)j - blocksBelowMidHeight) / blocksAboveMidHeight); if (currentPrecentOfWayUp > 1) { fillValueMap[i, j, k] = -0.5f; } else if (tempHeight > currentPrecentOfWayUp) { fillValueMap[i, j, k] = 0.6f; } else { fillValueMap[i, j, k] = -0.5f; } fillMultiplier = Mathf.Clamp(1 / (Mathf.Abs(tempHeight - currentPrecentOfWayUp) * 5), -1, 1); } if (tempHeight > -0.4f) { fillValueMap[i, j, k] += Noise.GenerateOverhangsAndCaves(i + _position.x, j + _position.y, k + _position.z, _seed) * fillMultiplier * _3dNoiseMultiplier; } if (fillValueMap[i, j, k] > 0) { map[i, j, k] = 1; } else { map[i, j, k] = 0; } } } } for (int x = 0; x < _maxX; x++) { for (int y = 0; y < _maxY; y++) { for (int z = 0; z < _maxZ; z++) { int triangleLookUpValue = 0; if (map[x, y, z] == 1) { triangleLookUpValue += 1; } if (map[x + 1, y, z] == 1) { triangleLookUpValue += 2; } if (map[x + 1, y, z + 1] == 1) { triangleLookUpValue += 4; } if (map[x, y, z + 1] == 1) { triangleLookUpValue += 8; } if (map[x, y + 1, z] == 1) { triangleLookUpValue += 16; } if (map[x + 1, y + 1, z] == 1) { triangleLookUpValue += 32; } if (map[x + 1, y + 1, z + 1] == 1) { triangleLookUpValue += 64; } if (map[x, y + 1, z + 1] == 1) { triangleLookUpValue += 128; } int edgeIndecies = Constants.edgeTable[triangleLookUpValue]; for (int i = 0; i < 16; i += 3) { Vector3[] cubeCorners = { new Vector3(x, y, z), new Vector3(x + 1, y, z), new Vector3(x + 1, y, z + 1), new Vector3(x, y, z + 1), new Vector3(x, y + 1, z), new Vector3(x + 1, y + 1, z), new Vector3(x + 1, y + 1, z + 1), new Vector3(x, y + 1, z + 1) }; if (Constants.triTable[triangleLookUpValue, i] == -1) { break; } int a0 = Constants.cornerIndexAFromEdge[Constants.triTable[triangleLookUpValue, i]]; int a1 = Constants.cornerIndexBFromEdge[Constants.triTable[triangleLookUpValue, i]]; int b0 = Constants.cornerIndexAFromEdge[Constants.triTable[triangleLookUpValue, i + 1]]; int b1 = Constants.cornerIndexBFromEdge[Constants.triTable[triangleLookUpValue, i + 1]]; int c0 = Constants.cornerIndexAFromEdge[Constants.triTable[triangleLookUpValue, i + 2]]; int c1 = Constants.cornerIndexBFromEdge[Constants.triTable[triangleLookUpValue, i + 2]]; triangles.Add(verticies.Count); triangles.Add(verticies.Count + 1); triangles.Add(verticies.Count + 2); Vector3 vertexPos1 = (cubeCorners[a0] + cubeCorners[a1]) / 2; Vector3 vertexPos2 = (cubeCorners[b0] + cubeCorners[b1]) / 2; Vector3 vertexPos3 = (cubeCorners[c0] + cubeCorners[c1]) / 2; vertexPos1.y += fillValueMap[(int)cubeCorners[a0].x, (int)cubeCorners[a0].y, (int)cubeCorners[a0].z] + fillValueMap[(int)cubeCorners[a1].x, (int)cubeCorners[a1].y, (int)cubeCorners[a1].z]; vertexPos2.y += fillValueMap[(int)cubeCorners[b0].x, (int)cubeCorners[b0].y, (int)cubeCorners[b0].z] + fillValueMap[(int)cubeCorners[b1].x, (int)cubeCorners[b1].y, (int)cubeCorners[b1].z]; vertexPos3.y += fillValueMap[(int)cubeCorners[c0].x, (int)cubeCorners[c0].y, (int)cubeCorners[c0].z] + fillValueMap[(int)cubeCorners[c1].x, (int)cubeCorners[c1].y, (int)cubeCorners[c1].z]; verticies.Add(vertexPos1); verticies.Add(vertexPos2); verticies.Add(vertexPos3); var normal = Vector3.Cross(vertexPos2 - vertexPos1, vertexPos3 - vertexPos1); for (int t = 0; t < 3; t++) { ColorList.Add(_colorGradient.Evaluate((normal.y + 1) / 2)); normals.Add(normal); uvs.Add(Vector3.zero); } } } } } chunkTerrainObjectGenerator.GenerateNewChunkObjects(_position, verticies, normals, _treeList); Mesh mesh = new Mesh(); mesh.vertices = verticies.ToArray(); mesh.normals = normals.ToArray(); mesh.triangles = triangles.ToArray(); mesh.uv = uvs.ToArray(); mesh.colors = ColorList.ToArray(); if (chunk != null) { Object.Destroy(chunk); } chunk = InstantiateChunk(mesh); chunkTerrainObjectGenerator.ChildAllObjectsToParent(chunk); }
// Use this for initialization private void Start() { m_CharacterController = GetComponent<CharacterController>(); m_Camera = Camera.main; m_OriginalCameraPosition = m_Camera.transform.localPosition; m_FovKick.Setup(m_Camera); m_HeadBob.Setup(m_Camera, m_StepInterval); m_StepCycle = 0f; m_NextStep = m_StepCycle/2f; m_Jumping = false; m_AudioSource = GetComponent<AudioSource>(); m_MouseLook.Init(transform , m_Camera.transform); mTerrainData = Terrain.activeTerrain.terrainData; alphamapWidth = mTerrainData.alphamapWidth; alphamapHeight = mTerrainData.alphamapHeight; mSplatmapData = mTerrainData.GetAlphamaps (0, 0, alphamapWidth, alphamapHeight); mNumTextures = mSplatmapData.Length / (alphamapWidth * alphamapHeight); }
public static void SmoothTerrain(TerrainExtension ext) { Terrain t = ext.GetComponent <Terrain>(); if (t == null) { return; } int heightMapWidth = t.terrainData.heightmapWidth; float[,] masterData = t.terrainData.GetHeights(0, 0, heightMapWidth, heightMapWidth); int asize = t.terrainData.alphamapWidth; float[,,] alphaData = t.terrainData.GetAlphamaps(0, 0, asize, asize); float tx = 0; float tz = 0; Vector3 pos = Vector3.zero; for (int x = 0; x < heightMapWidth; x++) { tx = (float)x / (float)(heightMapWidth - 1); for (int y = 0; y < heightMapWidth; y++) { tz = (float)y / (float)(heightMapWidth - 1); float blend = 0; if (t.terrainData.alphamapLayers >= ext.AutoSettings.SmoothBlendPerSplat.Length) { int atx = Mathf.FloorToInt(tx * (asize - 1)); int aty = Mathf.FloorToInt(tz * (asize - 1)); for (int ic = 0; ic < ext.AutoSettings.SmoothBlendPerSplat.Length; ic++) { blend += alphaData[atx, aty, ic] * ext.AutoSettings.SmoothBlendPerSplat[ic]; } } else { blend = ext.AutoSettings.SmoothBlend; //Debug.Log("Mismatch in layers"); } List <float> accumulated = new List <float>(); List <int> xshifts = new List <int>(); List <int> yshifts = new List <int>(); if (x > 0) { xshifts.Add(-1); } xshifts.Add(0); if (x < heightMapWidth - 1) { xshifts.Add(1); } if (y > 0) { yshifts.Add(-1); } yshifts.Add(0); if (y < heightMapWidth - 1) { yshifts.Add(1); } float accumHeight = 0; float numSamples = 0; for (int ii = 0; ii < xshifts.Count; ii++) { for (int jj = 0; jj < yshifts.Count; jj++) { float h = masterData[x + xshifts[ii], y + yshifts[jj]]; accumulated.Add(h); accumHeight += h; numSamples += 1; } } masterData[x, y] = Mathf.Lerp(masterData[x, y], accumHeight / numSamples, blend); } } t.terrainData.SetHeights(0, 0, masterData); }
void Start() { craterWidth = crater.width; craterHeight = crater.height; terrain = GetComponent<Terrain> (); data = terrain.terrainData; heightRestore = data.GetHeights (0, 0, data.heightmapWidth, data.heightmapHeight); alphaRestore = data.GetAlphamaps (0, 0, data.alphamapHeight, data.alphamapWidth); template = crater.GetPixels (); worker = new Thread (WorkerMethod); worker.Start (); StartCoroutine (ApplyDamage ()); }
public static void Normalize(float[,,] map) { Normalize(map, 0, 1); }
public void SmoothVoxels() { //float startTime = Time.realtimeSinceStartup; //This averages a voxel with all its neighbours. int w = m_voxels.GetLength(0); int h = m_voxels.GetLength(1); int l = m_voxels.GetLength(2); float[,,] smothedVoxels = new float[w,h,l]; for(int x = 1; x < w-1; x++) { for(int y = 1; y < h-1; y++) { for(int z = 1; z < l-1; z++) { float ht = 0.0f; for(int i = 0; i < 27; i++) ht += m_voxels[x + m_sampler[i,0], y + m_sampler[i,1], z + m_sampler[i,2]]; smothedVoxels[x,y,z] = ht/27.0f; } } } m_voxels = smothedVoxels; //Debug.Log("Smooth voxels time = " + (Time.realtimeSinceStartup-startTime).ToString() ); }
public void OnEnable() { if (_LeftDataSerialized != null) _LeftData = _LeftDataSerialized.GetHRIRData(); if (_RightDataSerialized != null) _RightData = _RightDataSerialized.GetHRIRData(); }