//TODO: why is this called try place ground if you can specify the anchor type? /// <summary> /// Tries to place object on the ground. /// </summary> /// <returns><c>true</c>, if location to spawn object is found, <c>false</c> otherwise.</returns> /// <param name="bounds">Bounds.</param> /// <param name="anchorType">Anchor type, can be Ground, Ceiling, or Wall.</param> /// <param name="finalX">x coord where object should spawn.</param> /// <param name="finalY">y coord where object should spawn.</param> /// <param name="modScale">Modified scale.</param> /// <seealso cref="PrefabDatabase.GetSceneScale">modScale is retrieved via this method.</seealso> /// <param name="whichPlane">Which height plane the object should spawn on.</param> /// private bool TryPlaceGroundObject(Bounds bounds, float modScale, GeneratablePrefab.AttachAnchor anchorType, out int finalX, out int finalY, out HeightPlane whichPlane) { finalX = 0; finalY = 0; whichPlane = null; /* modScale = 1.0f; if (shouldUseStandardizedSize) { modScale = Mathf.Min( standardizedSize.x / bounds.extents.x, standardizedSize.y / bounds.extents.y, standardizedSize.z / bounds.extents.z); } */ Bounds testBounds = new Bounds(bounds.center, modScale * 2f * bounds.extents); int boundsWidth = Mathf.CeilToInt(2 * testBounds.extents.x / gridDim); int boundsLength = Mathf.CeilToInt(2 * testBounds.extents.z / gridDim); float boundsHeight = testBounds.extents.y; List<int> randomPlanesOrder = new List<int>(); int randomOrderValue = _rand.Next(0, int.MaxValue); for(int i = 0; i < _allHeightPlanes.Count; ++i) randomPlanesOrder.Insert(randomOrderValue % (randomPlanesOrder.Count + 1), i); if (_forceStackObject) randomPlanesOrder.Remove(0); bool foundValid = false; foreach(int planeNum in randomPlanesOrder) { HeightPlane curHeightPlane = _allHeightPlanes[planeNum]; // Make sure we aren't hitting the ceiling if (boundsHeight >= curHeightPlane.planeHeight || curHeightPlane.cornerPos.y + boundsHeight >= _curRoomHeight) continue; // Only get grid squares which are valid to place on. List<GridInfo> validValues = curHeightPlane.myGridSpots.FindAll((GridInfo info)=>{return info.rightSquares >= (boundsWidth-1) && info.downSquares > (boundsLength-1) && !info.inUse;}); while(validValues.Count > 0 && !foundValid) { int randIndex = _rand.Next(0, validValues.Count); GridInfo testInfo = validValues[randIndex]; validValues.RemoveAt(randIndex); if (curHeightPlane.TestGrid(testInfo, boundsWidth, boundsLength)) { Vector3 centerPos = curHeightPlane.cornerPos + new Vector3(gridDim * (testInfo.x + (0.5f * boundsWidth)), 0.1f+boundsHeight, gridDim * (testInfo.y + (0.5f * boundsLength))); if (anchorType == GeneratablePrefab.AttachAnchor.Ceiling) centerPos.y = _roomCornerPos.y + _curRoomHeight - (0.1f+boundsHeight); if (Physics.CheckBox(centerPos, testBounds.extents)) { // Found another object here, let the plane know that there's something above messing with some of the squares string debugText = ""; Collider[] hitObjs = Physics.OverlapBox(centerPos, testBounds.extents); HashSet<string> hitObjNames = new HashSet<string>(); foreach(Collider col in hitObjs) { if (col.attachedRigidbody != null) hitObjNames.Add(col.attachedRigidbody.name); else hitObjNames.Add(col.gameObject.name ); curHeightPlane.RestrictBounds(col.bounds); } foreach(string hitName in hitObjNames) debugText += hitName + ", "; if (showProcGenDebug) Debug.LogFormat("Unexpected objects: ({0}) at ({1},{2}) on plane {3} with test {5} ext: {4}", debugText, testInfo.x, testInfo.y, curHeightPlane.name, testBounds.extents, centerPos); } else { // Debug.LogFormat("Selecting ({0},{1}) which has ({2},{3}) to place ({4},{5})", testInfo.x, testInfo.y, testInfo.rightSquares, testInfo.downSquares, boundsWidth, boundsLength); finalX = testInfo.x; finalY = testInfo.y; whichPlane = curHeightPlane; foundValid = true; return foundValid; } } } } return foundValid; }
private void DrawTestGrid(HeightPlane plane) { // Create debug test grid on the floor if (DEBUG_testGridPrefab != null) { GameObject child = new GameObject("TEST GRIDS " + plane.name); child.transform.SetParent(_curRoom); foreach(GridInfo g in plane.myGridSpots) { TextMesh test = GameObject.Instantiate<TextMesh>(DEBUG_testGridPrefab); test.transform.SetParent(child.transform); // test.text = string.Format(" {0}\n{2} {1}\n {3}", g.upSquares, g.leftSquares, g.rightSquares, g.downSquares); test.text = string.Format("{0},{1}", g.x, g.y); test.color = g.inUse ? Color.red: Color.cyan; test.transform.position = plane.GridToWorld(new Point2(g.x, g.y)); test.name = string.Format("{0}: ({1},{2})", DEBUG_testGridPrefab.name, g.x, g.y); test.transform.localScale = gridDim * Vector3.one; } } }
public void CreateRoom(Vector3 roomDimensions, Vector3 roomCenter) { Debug.Log ("Create 1."); _curRoom = new GameObject("New Room").transform; _roomCornerPos = (roomCenter - (0.5f *roomDimensions)) + (gridDim * 0.5f * Vector3.one); _roomCornerPos.y = 0f; Debug.Log ("Create 2."); // Create floor and ceiling Vector3 floorSize = new Vector3(roomDimensions.x, WALL_WIDTH, roomDimensions.z); Vector3 floorStart = roomCenter + new Vector3(-0.5f * roomDimensions.x, -WALL_WIDTH, -0.5f * roomDimensions.z); Vector3 ceilingStart = floorStart + (roomDimensions.y + WALL_WIDTH) * Vector3.up; Debug.Log ("Create 3."); GameObject floor = WallInfo.CreateBoxMesh(floorStart, floorSize, floorMaterial, "Floor", _curRoom); floor.AddComponent<SemanticObjectSimple>(); floor.GetComponent<Rigidbody>().isKinematic = true; Debug.Log ("Create 4."); Renderer[] RendererList = floor.GetComponentsInChildren<Renderer>(); foreach (Renderer _rend in RendererList) { foreach (Material _mat in _rend.materials) { _mat.SetColor("_idval", new Color(0f,0f,1f/256f)); } } Debug.Log ("Create 5."); //{ // _rend.material.SetInt("_idval", 1); //} //floor.GetComponent<Renderer>().material.SetInt("_idval", 1); GameObject borktest = Resources.Load<GameObject> ("Prefabs/PointSpawn"); Debug.Log ("borktest"); if (borktest == null) { Debug.Log ("its null"); } Debug.Log(borktest.name); // Make a spawn plane SpawnArea floorSpawn = GameObject.Instantiate<SpawnArea>(Resources.Load<SpawnArea>("Prefabs/PlaneSpawn")); Debug.Log ("Create 6."); floorSpawn.gameObject.transform.position = roomCenter; Debug.Log ("Create 7."); //retrieve ratio between spawn plane and floor float xRatio = floorSize.x / floorSpawn.gameObject.GetComponent<Collider>().bounds.size.x; float zRatio = floorSize.z / floorSpawn.gameObject.GetComponent<Collider>().bounds.size.z; Debug.Log ("Create 8."); floorSpawn.gameObject.transform.localScale = new Vector3 (xRatio * floorSpawn.gameObject.transform.localScale.x, 0, zRatio * floorSpawn.gameObject.transform.localScale.z); Debug.Log ("Create 9."); Debug.LogFormat ("Created floor: {0}", floorSpawn.name); Debug.Log ("Create 10."); GameObject top = WallInfo.CreateBoxMesh(ceilingStart, floorSize, ceilingMaterial, "Ceiling", _curRoom); Debug.Log ("Create 11."); top.AddComponent<SemanticObjectSimple>(); Debug.Log ("Create 12."); top.GetComponent<Rigidbody>().isKinematic = true; Debug.Log ("Create 13."); RendererList = top.GetComponentsInChildren<Renderer>(); foreach (Renderer _rend in RendererList) { foreach (Material _mat in _rend.materials) { _mat.SetColor("_idval", new Color(0f,0f,2f/256f)); } } Debug.Log ("Create 14."); //{ // _rend.material.SetInt("_idval", 2); //} //top.GetComponent<Renderer>().material.SetInt("_idval", 2); // Setup floor plane _allHeightPlanes.Clear(); HeightPlane basePlane = new HeightPlane(); basePlane.gridDim = gridDim; basePlane.planeHeight = roomDim.y; basePlane.name = "Plane Floor"; _allHeightPlanes.Add(basePlane); _curRoomWidth = Mathf.FloorToInt(roomDim.x / gridDim); _curRoomLength = Mathf.FloorToInt(roomDim.z / gridDim); _curRoomHeight = roomDim.y; basePlane.cornerPos = _roomCornerPos; basePlane.Clear(_curRoomWidth, _curRoomLength); Debug.Log ("Create 15."); // Create walls SubdivideRoom(); Debug.Log ("Create 16."); }
private bool AddObjects(List<PrefabDatabase.PrefabInfo> prefabList) { if (prefabList.Count == 0) { _failures++; return false; } // Randomly add next one? int temp_rand_index = _rand.Next(0, prefabList.Count); PrefabDatabase.PrefabInfo info = prefabList[temp_rand_index]; if (info.loaded==0) { // Load it now Debug.Log("From http loaded!"); var www = WWW.LoadFromCacheOrDownload (info.fileName, 0); var loadedAssetBundle = www.assetBundle; string[] assetList = loadedAssetBundle.GetAllAssetNames (); foreach (string asset in assetList) { GameObject gObj = loadedAssetBundle.LoadAsset<GameObject> (asset); GeneratablePrefab[] prefab = gObj.GetComponents<GeneratablePrefab> (); if (prefab.GetLength (0) == 0) { Debug.LogFormat ("Cannot load GeneratablePrefab component on {0}", gObj); continue; } GeneratablePrefab prefab_temp = prefab [0]; info.loaded = 1; info.complexity = prefab_temp.myComplexity; info.bounds = prefab_temp.myBounds; info.isLight = prefab_temp.isLight; info.anchorType = prefab_temp.attachMethod; foreach (GeneratablePrefab.StackableInfo stackRegion in prefab_temp.stackableAreas) info.stackableAreas.Add (stackRegion); prefabList[temp_rand_index] = info; } loadedAssetBundle.Unload (false); } // Check for excess complexity int maxComplexity = (complexityLevelToCreate - _curComplexity); if (info.complexity > maxComplexity) { // Change for lazy loading /* prefabList.RemoveAll((PrefabDatabase.PrefabInfo testInfo)=>{ return (testInfo.complexity > maxComplexity) | (testInfo.complexity == 0); }); if (showProcGenDebug) Debug.LogFormat("Filtering for complexity {0} > {1} leaving {2} objects ", info.complexity, maxComplexity, prefabList.Count); if (prefabList.Count == 0) return false; */ prefabList.Remove(info); return true; //info = prefabList[_rand.Next(0, prefabList.Count)]; } // Find a spot to place this object int spawnX, spawnZ; //float modScale = prefabDatabase.GetSceneScale (info); float modScale = 1.0f; // For option "Multi_size" if (info.option_scale=="Multi_size") { modScale = modScale*info.dynamic_scale; } // For option "Absol_size" if (info.option_scale=="Absol_size") { float longest_axis = info.bounds.size.magnitude; Debug.Log("Longest axis: " + longest_axis.ToString()); modScale = info.dynamic_scale/longest_axis; } HeightPlane targetHeightPlane; Quaternion modifiedRotation = Quaternion.identity; if (info.stackableAreas.Count == 0) modifiedRotation = Quaternion.Euler(new Vector3(0, (float) _rand.NextDouble() * 360f,0)); Bounds modifiedBounds = info.bounds.Rotate(modifiedRotation); if (TryPlaceGroundObject(modifiedBounds, modScale, info.anchorType, out spawnX, out spawnZ, out targetHeightPlane)) { int boundsWidth = Mathf.CeilToInt(modScale* 2f * modifiedBounds.extents.x / gridDim) - 1; int boundsLength = Mathf.CeilToInt(modScale* 2f * modifiedBounds.extents.z / gridDim) - 1; float modHeight = 0.1f+(modifiedBounds.extents.y * modScale); Vector3 centerPos = targetHeightPlane.cornerPos + new Vector3(gridDim * (spawnX + (0.5f * boundsWidth)), modHeight, gridDim * (spawnZ + (0.5f * boundsLength))); if (info.anchorType == GeneratablePrefab.AttachAnchor.Ceiling) centerPos.y = _roomCornerPos.y + _curRoomHeight - modHeight; // GameObject newPrefab = Resources.Load<GameObject>(info. GameObject newPrefab; if (info.fileName.ToLowerInvariant().Contains("http://")) { Debug.Log("From http"); newPrefab = PrefabDatabase.LoadAssetFromBundleWWW(info.fileName); } else { newPrefab = PrefabDatabase.LoadAssetFromBundle(info.fileName); } // TODO: Factor in complexity to the arrangement algorithm? _curComplexity += info.complexity; GameObject newInstance = UnityEngine.Object.Instantiate<GameObject>(newPrefab.gameObject); newInstance.transform.position = centerPos - (modifiedBounds.center * modScale); newInstance.transform.localScale = newInstance.transform.localScale * modScale; newInstance.transform.rotation = modifiedRotation * newInstance.transform.rotation; //newInstance.name = string.Format("{0} #{1} on {2}", newPrefab.name, (_curRoom != null) ? _curRoom.childCount.ToString() : "?", targetHeightPlane.name); newInstance.name = string.Format("{0}, {1}, {2}", info.fileName, newPrefab.name, (_curRoom != null) ? _curRoom.childCount.ToString() : "?"); Renderer[] RendererList = newInstance.GetComponentsInChildren<Renderer>(); Color colorID = getNewUIDColor (); foreach (Renderer _rend in RendererList) { foreach (Material _mat in _rend.materials) { _mat.SetColor("_idval", colorID); } } // Create test cube if (DEBUG_testCubePrefab != null) { GameObject testCube = UnityEngine.Object.Instantiate<GameObject>(DEBUG_testCubePrefab); testCube.transform.localScale = modScale * 2f * modifiedBounds.extents; testCube.transform.position = centerPos; testCube.name = string.Format("Cube {0}", newInstance.name); testCube.transform.SetParent(_curRoom); } if (showProcGenDebug) Debug.LogFormat("{0}: @{1} R:{2} G:{3} BC:{4} MS:{5}", info.fileName, newInstance.transform.position, targetHeightPlane.cornerPos, new Vector3(gridDim * spawnX, info.bounds.extents.y, gridDim * spawnZ), info.bounds.center, modScale); if (_curRoom != null) newInstance.transform.SetParent(_curRoom); // For stackable objects, create a new height plane to stack if (info.anchorType == GeneratablePrefab.AttachAnchor.Ground) { targetHeightPlane.UpdateGrid(spawnX, spawnZ, boundsWidth, boundsLength); foreach(GeneratablePrefab.StackableInfo stackInfo in info.stackableAreas) { int width = Mathf.FloorToInt(stackInfo.dimensions.x / gridDim); int length = Mathf.FloorToInt(stackInfo.dimensions.z / gridDim); if (width <= 0 || length <= 0) continue; HeightPlane newPlane = new HeightPlane(); newPlane.gridDim = gridDim; // TODO: Set rotation matrix for new plane? newPlane.rotMat = modifiedRotation; newPlane.cornerPos = newInstance.transform.position + (modifiedRotation * (stackInfo.bottomCenter + info.bounds.center)); newPlane.cornerPos = newPlane.GridToWorld(new Vector2((width-1) * -0.5f, (length-1) * -0.5f)); newPlane.planeHeight = stackInfo.dimensions.y; if (stackInfo.dimensions.y <= 0) newPlane.planeHeight = _curRoomHeight - newPlane.cornerPos.y; newPlane.Clear(width, length); newPlane.name = string.Format("Plane for {0}", newInstance.name); _allHeightPlanes.Add(newPlane); } } } else { // TODO: Mark item as unplaceable and continue with smaller objects? if (showProcGenDebug) Debug.LogFormat("Couldn't place: {0}. {1} object types, {2} complexity left", info.fileName, prefabList.Count, complexityLevelToCreate - _curComplexity); prefabList.Remove(info); ++_failures; } return true; }
private bool AddObjects(List<PrefabDatabase.PrefabInfo> prefabList) { if (prefabList.Count == 0) { _failures++; return false; } // Randomly add next one? int temp_rand_index = _rand.Next(0, prefabList.Count); PrefabDatabase.PrefabInfo info = prefabList[temp_rand_index]; // Deprecated if (info.loaded==0) { // Load it now Debug.Log("From http loaded!"); Debug.Log(info.fileName); var www = WWW.LoadFromCacheOrDownload (info.fileName, 0); var loadedAssetBundle = www.assetBundle; string[] assetList = loadedAssetBundle.GetAllAssetNames (); foreach (string asset in assetList) { GameObject gObj = loadedAssetBundle.LoadAsset<GameObject> (asset); GeneratablePrefab[] prefab = gObj.GetComponents<GeneratablePrefab> (); if (prefab.GetLength (0) == 0) { Debug.LogFormat ("Cannot load GeneratablePrefab component on {0}", gObj); continue; } GeneratablePrefab prefab_temp = prefab [0]; info.loaded = 1; info.complexity = prefab_temp.myComplexity; info.bounds = prefab_temp.myBounds; info.isLight = prefab_temp.isLight; info.anchorType = prefab_temp.attachMethod; foreach (GeneratablePrefab.StackableInfo stackRegion in prefab_temp.stackableAreas) info.stackableAreas.Add (stackRegion); prefabList[temp_rand_index] = info; } loadedAssetBundle.Unload (false); } // Check for excess complexity int maxComplexity = (complexityLevelToCreate - _curComplexity); if (info.complexity > maxComplexity) { // Change for lazy loading /* prefabList.RemoveAll((PrefabDatabase.PrefabInfo testInfo)=>{ return (testInfo.complexity > maxComplexity) | (testInfo.complexity == 0); }); if (showProcGenDebug) Debug.LogFormat("Filtering for complexity {0} > {1} leaving {2} objects ", info.complexity, maxComplexity, prefabList.Count); if (prefabList.Count == 0) return false; */ prefabList.Remove(info); return true; //info = prefabList[_rand.Next(0, prefabList.Count)]; } // Find a spot to place this object int spawnX, spawnZ; //float modScale = prefabDatabase.GetSceneScale (info); float modScale = 1.0f; float offset_y = 0.1f; // For global setting if (enable_global_unit_scale==1){ float longest_axis = info.bounds.size.magnitude; //Debug.Log("Longest axis: " + longest_axis.ToString()); modScale = 1/longest_axis; } //TODO Verify that we want to scale by the longest_axis here first (DOSCH very big otherwise) if (scene_scale_con=="Multi_size") { float longest_axis = info.bounds.size.magnitude; modScale = list_rands[0].Next_Gaussian(scene_scale_mean, scene_scale_var); modScale = modScale/longest_axis; } if (scene_scale_con=="Absol_size"){ float longest_axis = info.bounds.size.magnitude; modScale = list_rands[0].Next_Gaussian(scene_scale_mean, scene_scale_var)/longest_axis; } // For option "Multi_size" if (info.option_scale=="Multi_size"){ if (info.apply_to_inst) modScale = list_rands[info.rand_index].Next_Gaussian(info.dynamic_scale, info.scale_var); else modScale = info.first_rand; } // For option "Absol_size" if (info.option_scale=="Absol_size"){ float longest_axis = info.bounds.size.magnitude; if (info.apply_to_inst) modScale = list_rands[info.rand_index].Next_Gaussian(info.dynamic_scale, info.scale_var)/longest_axis; else modScale = info.first_rand/longest_axis; } HeightPlane targetHeightPlane; Quaternion modifiedRotation = Quaternion.identity; if (info.stackableAreas.Count == 0) modifiedRotation = Quaternion.Euler(new Vector3(0, (float) _rand.NextDouble() * 360f,0)); Bounds modifiedBounds = info.bounds.Rotate(modifiedRotation); if (TryPlaceGroundObject(modifiedBounds, modScale, info.anchorType, out spawnX, out spawnZ, out targetHeightPlane, out offset_y)) { int boundsWidth = Mathf.CeilToInt(modScale* 2f * modifiedBounds.extents.x / gridDim) - 1; int boundsLength = Mathf.CeilToInt(modScale* 2f * modifiedBounds.extents.z / gridDim) - 1; //float modHeight = 0.1f+(modifiedBounds.extents.y * modScale); float modHeight = offset_y+(modifiedBounds.extents.y * modScale); Vector3 centerPos = targetHeightPlane.cornerPos + new Vector3(gridDim * (spawnX + (0.5f * boundsWidth)), modHeight, gridDim * (spawnZ + (0.5f * boundsLength))); if (info.anchorType == GeneratablePrefab.AttachAnchor.Ceiling) centerPos.y = _roomCornerPos.y + _curRoomHeight - modHeight; // GameObject newPrefab = Resources.Load<GameObject>(info. GameObject newPrefab; if (info.fileName.ToLowerInvariant().Contains("http://")) { if (use_cache_self==1) { //Debug.Log("From cache!"); //StartCoroutine(PrefabDatabase.LoadAssetFromBundleWWW_cached_self(info.fileName)); //newPrefab = PrefabDatabase.LoadAssetFromBundleWWW(info.fileName); //newPrefab = PrefabDatabase.LoadAssetFromBundleWWW_cache_in_file(info.fileName, info._id_str, info.aws_version, cache_folder); // // //I need to do this here becuase StartCoroutine can not be correctly used in PrefabDatabase string cache_fileName = cache_folder + info._id_str + "_" + info.aws_version + ".bundle"; newPrefab = PrefabDatabase.LoadAssetFromBundle(cache_fileName); if (newPrefab==null){ // Loading it twice now, might influence the efficiency, TODO: load only once // Currently the WWW can not be wrote when used for assetbundle //Debug.Log("Build the cache!"); StartCoroutine(PrefabDatabase.LoadAssetFromBundleWWW_cached_self(info.fileName, cache_fileName)); newPrefab = PrefabDatabase.LoadAssetFromBundleWWW(info.fileName); } } else { //Debug.Log("From http"); newPrefab = PrefabDatabase.LoadAssetFromBundleWWW(info.fileName); } } else { newPrefab = PrefabDatabase.LoadAssetFromBundle(info.fileName); } // TODO: Factor in complexity to the arrangement algorithm? _curComplexity += info.complexity; GameObject newInstance = UnityEngine.Object.Instantiate<GameObject>(newPrefab.gameObject); newInstance.transform.position = centerPos - (modifiedBounds.center * modScale); newInstance.transform.localScale = newInstance.transform.localScale * modScale; newInstance.transform.rotation = modifiedRotation * newInstance.transform.rotation; //newInstance.name = string.Format("{0} #{1} on {2}", newPrefab.name, (_curRoom != null) ? _curRoom.childCount.ToString() : "?", targetHeightPlane.name); newInstance.name = string.Format("{0}, {1}, {2}", info.fileName, newPrefab.name, (_curRoom != null) ? _curRoom.childCount.ToString() : "?"); newInstance.GetComponent<SemanticObject>().isStatic = false; Renderer[] RendererList = newInstance.GetComponentsInChildren<Renderer>(); Color colorID = getNewUIDColor (); foreach (Renderer _rend in RendererList) { foreach (Material _mat in _rend.materials) { // Always use standard shader if(useStandardShader) _mat.shader = Shader.Find("Standard"); // Set glossiness and metallic randomly if(randomMaterials) { float GLOSS_MEAN = 0.588270935961f; float GLOSS_STD = 0.265175303096f; float METALLIC_MEAN = 0.145517241379f; float METALLIC_STD = 0.271416832554f; // Set glossiness using statistical properties derived from a test set Random_help random_gloss = new Random_help(_rand.Next()); float glossiness = GLOSS_MEAN; if(_mat.HasProperty("_Glossiness")) glossiness = _mat.GetFloat("_Glossiness"); //glossiness = glossiness + Convert.ToSingle(_rand.NextDouble()) * GLOSS_STD * 2 - GLOSS_STD; glossiness = random_gloss.Next_Gaussian(glossiness, GLOSS_STD); glossiness = Mathf.Min(glossiness, 1.0f); glossiness = Mathf.Max(glossiness, 0.0f); _mat.SetFloat("_Glossiness", glossiness); // Set metallic using statistical properties derived from a test set Random_help random_metallic = new Random_help(_rand.Next()); float metallic = METALLIC_MEAN; if(_mat.HasProperty("_Metallic")) metallic = _mat.GetFloat("_Metallic"); //metallic = metallic + Convert.ToSingle(_rand.NextDouble()) * METALLIC_STD * 2 - METALLIC_STD; metallic = random_metallic.Next_Gaussian(metallic, METALLIC_STD); metallic = Mathf.Min(metallic, 1.0f); metallic = Mathf.Max(metallic, 0.0f); _mat.SetFloat("_Metallic", metallic); } // Add idval to shader _mat.SetColor("_idval", colorID); } } // Create test cube if (DEBUG_testCubePrefab != null) { GameObject testCube = UnityEngine.Object.Instantiate<GameObject>(DEBUG_testCubePrefab); testCube.transform.localScale = modScale * 2f * modifiedBounds.extents; testCube.transform.position = centerPos; testCube.name = string.Format("Cube {0}", newInstance.name); testCube.transform.SetParent(_curRoom); } if (showProcGenDebug) Debug.LogFormat("{0}: @{1} R:{2} G:{3} BC:{4} MS:{5}", info.fileName, newInstance.transform.position, targetHeightPlane.cornerPos, new Vector3(gridDim * spawnX, info.bounds.extents.y, gridDim * spawnZ), info.bounds.center, modScale); if (_curRoom != null) newInstance.transform.SetParent(_curRoom); // For stackable objects, create a new height plane to stack if (info.anchorType == GeneratablePrefab.AttachAnchor.Ground) { if (disable_rand_stacking==1) { targetHeightPlane.UpdateGrid(spawnX, spawnZ, boundsWidth, boundsLength); } foreach(GeneratablePrefab.StackableInfo stackInfo in info.stackableAreas) { int width = Mathf.FloorToInt(stackInfo.dimensions.x / gridDim); int length = Mathf.FloorToInt(stackInfo.dimensions.z / gridDim); if (width <= 0 || length <= 0) continue; HeightPlane newPlane = new HeightPlane(); newPlane.gridDim = gridDim; // TODO: Set rotation matrix for new plane? newPlane.rotMat = modifiedRotation; newPlane.cornerPos = newInstance.transform.position + (modifiedRotation * (stackInfo.bottomCenter + info.bounds.center)); newPlane.cornerPos = newPlane.GridToWorld(new Vector2((width-1) * -0.5f, (length-1) * -0.5f)); newPlane.planeHeight = stackInfo.dimensions.y; if (stackInfo.dimensions.y <= 0) newPlane.planeHeight = _curRoomHeight - newPlane.cornerPos.y; newPlane.Clear(width, length); newPlane.name = string.Format("Plane for {0}", newInstance.name); _allHeightPlanes.Add(newPlane); } } } else { // TODO: Mark item as unplaceable and continue with smaller objects? if (showProcGenDebug) Debug.LogFormat("Couldn't place: {0}. {1} object types, {2} complexity left", info.fileName, prefabList.Count, complexityLevelToCreate - _curComplexity); prefabList.Remove(info); ++_failures; } return true; }