// ********************************************************************** // void Awake() { particleLauncher = gameObject.GetComponent(typeof(ParticleLauncher)) as ParticleLauncher; tintColor = new Color(); meanColor = new Color(); savingTimer = new Timer(); recorder = camera.GetComponent<ScreenRecorder>(); shapeSampleStats = new ShapeSamplingStatistics(); particleSampleStats = new ParticleSamplingStatistics(); colourSampleStats = new ColourSamplingStatistics(); // Our sampling settings datasetForm = "hierarchy"; // "flat", "singlefeature", "hierarchy" numPlanets = 8 * 210; // how many planets to generate in this simulation featureorder = new int[] {0, 1, 2, 3, 4, 5, 6}; //featureorder = RandomPermutation(featureorder); // the random ordering of features in the hierarchy // Read in the existing record of planet details recordFilePath = filePath + "stimulusLookup.json"; if (File.Exists(recordFilePath)) { Debug.Log("Opening record of generated planets."); LoadExistingPlanets(recordFilePath); } else { allExistingPlanets.allPlanetData = new List<PlanetData>(); allExistingPlanets.planetColours = new Color[allExistingPlanets.nLevels]; } }
// ********************************************************************** // public void UpdateSettings(ShapeSettings settings, bool reset, ShapeSamplingStatistics shapeSampleStats) { this.settings = reset ? RandomizeShapeSettings(settings, shapeSampleStats) : settings; // generate a new random planet noiseFilters = new INoiseFilter[settings.noiseLayers.Length]; for (int i = 0; i < noiseFilters.Length; i++) { noiseFilters[i] = NoiseFilterFactory.CreateNoiseFilter(settings.noiseLayers[i].noiseSettings); } elevationMinMax = new MinMax(); }
// ********************************************************************** // void LoadNextSettings(int count) { Debug.Log("planet index: " + count); int colourindex; int heightindex; int roughnessindex; int ringindex; int mooninessindex; int atmosphereindex; int sunindex; const int LOW_LEVEL = 0; const int NULL_LEVEL = 1; const int HIGH_LEVEL = 2; switch (datasetForm) { case "flat": // for generating a full data set (non hierarchical, all combinations) colourindex = count % 3; heightindex = (int)(Math.Floor(count / 3f) % 3); roughnessindex = (int)(Math.Floor(count / (3f * 3f)) % 3); ringindex = (int)(Math.Floor(count / (3f * 3f * 3f)) % 3); mooninessindex = (int)(Math.Floor(count / (3f * 3f * 3f * 3f)) % 3); atmosphereindex = (int)(Math.Floor(count / (3f * 3f * 3f * 3f * 3f)) % 3); sunindex = (int)(Math.Floor(count / (3f * 3f * 3f * 3f * 3f * 3f)) % 3); break; case "singlefeature": // for testing perception of individual levels while keeping all other parameters constant. Whichever one you want to alter, make =(count%3) colourindex = 0; heightindex = 0; roughnessindex = 0; ringindex = count % 3; mooninessindex = 0; atmosphereindex = 0; sunindex = 0; break; case "heirarchy": // for generating a single hierarchical dataset of level 3 (8 planets) // note that the -1, 0 and +1 levels in the RSA matrix correspond to 0, 1 and 2 index levels of each feature respectively. // the numbers 0-6 here correspond to the ordering: // [0] colourindex // [1] roughnessindex // [2] heightindex // [3] ringindex // [4] mooninessindex // [5] atmosphereindex // [6] sunindex // such that e.g. for featureorder = { 6, 0, 1, 2, 3, 4, 5 }; the 6th element of featureorder is always the sunindex, with takes the position of feature 5 in the hierarchy // e.g. the 0th element of featureorder corresponds to the colourindex, which takes the position of the 6th feature in the hierarchy //int[] featureorder = { 0, 1, 2, 3, 4, 5, 6 }; // HRS can also make a function that uses a random permutation but keep fixed for now int[] featureindex = new int[featureorder.Length]; // Populate the feature index array to be equal to the null level so that it makes setting the hierarchy easier for (int i = 0; i < featureindex.Length; i++) { featureindex[i] = NULL_LEVEL; } // set the hierarchy logic - yes this could be simplified for better coding practice HRS if (numPlanets % 8 != 0) { Debug.Log("Warning: generating a number of planets that will not correctly fill the 3 level hierarchy. Check numPlanets."); } float x = 8f; count = count % 8; float rightsidecount = count; featureindex[0] = LessThanHalfOfX((float)count, x) ? LOW_LEVEL: HIGH_LEVEL; if (featureindex[0] == LOW_LEVEL) // fill in the left side of the tree from root, N0 { x = x / 2f; featureindex[1] = LessThanHalfOfX((float)count, x) ? LOW_LEVEL : HIGH_LEVEL; if (featureindex[1] == LOW_LEVEL) // left side of tree from N1 { x = x / 2f; featureindex[3] = LessThanHalfOfX((float)count, x) ? LOW_LEVEL : HIGH_LEVEL; } else // right side of tree from N1 { x = x / 2f; rightsidecount = rightsidecount - x; featureindex[4] = LessThanHalfOfX(rightsidecount, x) ? LOW_LEVEL : HIGH_LEVEL; } } else // right side of tree from root, N0 { x = x / 2f; rightsidecount = rightsidecount - x; featureindex[2] = LessThanHalfOfX(rightsidecount, x) ? LOW_LEVEL : HIGH_LEVEL; if (featureindex[2] == LOW_LEVEL) // left side of tree from N2 { x = x / 2f; featureindex[5] = LessThanHalfOfX(rightsidecount, x) ? LOW_LEVEL : HIGH_LEVEL; } else // right side of tree from N2 { x = x / 2f; rightsidecount = rightsidecount - x; featureindex[6] = LessThanHalfOfX(rightsidecount, x) ? LOW_LEVEL : HIGH_LEVEL; } } // print these out to check its working properly for (int i = 0; i < featureindex.Length; i++) { Debug.Log("feature index [" + i + "]: " + featureindex[i]); } colourindex = featureindex[featureorder[0]]; // 0th element on feature order says which feature this is the RSA matrix roughnessindex = featureindex[featureorder[1]]; // 1 heightindex = featureindex[featureorder[2]]; // 2 ringindex = featureindex[featureorder[3]]; // 3 mooninessindex = featureindex[featureorder[4]]; // 4 atmosphereindex = featureindex[featureorder[5]]; // 5 sunindex = featureindex[featureorder[6]]; // 6 break; default: colourindex = 0; roughnessindex = 0; heightindex = 0; ringindex = 0; mooninessindex = 0; atmosphereindex = 0; sunindex = 0; break; } Color colour = allExistingPlanets.planetColours[colourindex]; GaussianSummaryStats height = allExistingPlanets.mountainHeights[heightindex]; GaussianSummaryStats roughness = allExistingPlanets.mountainRoughnesses[roughnessindex]; GaussianSummaryStats ringradius = allExistingPlanets.ringRadii[ringindex]; GaussianSummaryStats mooniness = allExistingPlanets.mooninesses[mooninessindex]; GaussianSummaryStats atmosphere = allExistingPlanets.atmosphereLevels[atmosphereindex]; GaussianSummaryStats sunradius = allExistingPlanets.sunRadii[sunindex]; GaussianSummaryStats coloursaturation = allExistingPlanets.saturationLevels[colourindex]; colourSampleStats = new ColourSamplingStatistics(); colourSampleStats.setMean = true; colourSampleStats.colourLevel = colourindex; // try using this as a key for saturation level rather than colour colourSampleStats.meanColour = colour; colourSampleStats.stdev = allExistingPlanets.colourStd; colourSampleStats.meanSaturation = coloursaturation.mean; shapeSampleStats = new ShapeSamplingStatistics(); shapeSampleStats.setMean = true; shapeSampleStats.mountainRoughnessLevel = roughnessindex; shapeSampleStats.meanBaseRoughness = roughness.mean; shapeSampleStats.stdBaseRoughness = roughness.stdev; shapeSampleStats.mountainHeightLevel = heightindex; shapeSampleStats.meanStrength = height.mean; shapeSampleStats.stdStrength = height.stdev; particleSampleStats = new ParticleSamplingStatistics(); particleSampleStats.setMean = true; particleSampleStats.ringLevel = ringindex; particleSampleStats.meanRingRadius = ringradius.mean; particleSampleStats.stdRingRadius = ringradius.stdev; particleSampleStats.mooninessLevel = mooninessindex; particleSampleStats.meanMooniness = mooniness.mean; particleSampleStats.stdMooniness = mooniness.stdev; particleSampleStats.atmosphereLevel = atmosphereindex; particleSampleStats.meanAtmosphere = atmosphere.mean; particleSampleStats.stdAtmosphere = atmosphere.stdev; particleSampleStats.sunLevel = sunindex; particleSampleStats.meanSunRadius = sunradius.mean; particleSampleStats.stdSunRadius = sunradius.stdev; }
// ********************************************************************** // public ShapeSettings RandomizeShapeSettings(ShapeSettings settings, ShapeSamplingStatistics shapeSampleStats) { // Planet physical shape settings settings.planetRadius = 1f; settings.mountainHeightLevel = shapeSampleStats.mountainHeightLevel; settings.mountainRoughnessLevel = shapeSampleStats.mountainRoughnessLevel; for (int i = 0; i < settings.noiseLayers.Length; i++) { ShapeSettings.NoiseLayer noiseLayer = settings.noiseLayers[i]; noiseLayer.enabled = true; noiseLayer.useFirstLayerAsMask = true; // ***HRS these are for playing with so that we are modifying values in reasonable-looking ranges across the features that we want switch (noiseLayer.noiseSettings.filterType) { case NoiseSettings.FilterType.Simple: // constant feature values noiseLayer.noiseSettings.simpleNoiseSettings.persistence = 0.6f; // keep this fixed around .5f noiseLayer.noiseSettings.simpleNoiseSettings.minValue = 0.95f; // keep this fixed around .95f, because the height-based colours start f*****g up noiseLayer.noiseSettings.simpleNoiseSettings.numLayers = 4; // variable feature values if (shapeSampleStats.setMean) { // note that these will appear weird if they take on negative values, so be aware of that. We dont want to truncate at 0 though because then we effectively limit the variability. mountainHeight = GaussianRandom(shapeSampleStats.meanStrength, shapeSampleStats.stdStrength) * (i + 1); mountainRoughness = GaussianRandom(shapeSampleStats.meanBaseRoughness, shapeSampleStats.stdBaseRoughness) * (i + 1); // we may want to keep this one fixed around 1f noiseLayer.noiseSettings.simpleNoiseSettings.strength = mountainHeight; noiseLayer.noiseSettings.simpleNoiseSettings.baseRoughness = mountainRoughness; } else { noiseLayer.noiseSettings.simpleNoiseSettings.strength = RandomNumberInRange(0.01f, 0.3f) * (i + 1); noiseLayer.noiseSettings.simpleNoiseSettings.baseRoughness = RandomNumberInRange(0.7f, 1.1f) * (i + 1); // we may want to keep this one fixed around 1f } noiseLayer.noiseSettings.simpleNoiseSettings.roughness = 2.2f; // RandomNumberInRange(1f, 3.0f); // looks nice around 2.2f // change the position of the noise on the planet (almost the same as creating new noise object, if we do this for each layer independently its fine noiseLayer.noiseSettings.simpleNoiseSettings.centre.x = RandomNumberInRange(-.5f, .5f); noiseLayer.noiseSettings.simpleNoiseSettings.centre.y = RandomNumberInRange(-.5f, .5f); noiseLayer.noiseSettings.simpleNoiseSettings.centre.z = RandomNumberInRange(-.5f, .5f); break; case NoiseSettings.FilterType.Rigid: // HRS note in generated stimulus set version we dont have any rigid noise filters to keep the stimuli dimensions clearly separable /* * // constant feature values * noiseLayer.noiseSettings.rigidNoiseSettings.persistence = 0.5f; // keep this fixed around .5f * noiseLayer.noiseSettings.rigidNoiseSettings.minValue = 0.95f; // keep this fixed around .95f, because the height-based colours start f*****g up * noiseLayer.noiseSettings.rigidNoiseSettings.numLayers = 4; * * // variable feature values * noiseLayer.noiseSettings.rigidNoiseSettings.strength = RandomNumberInRange(0.05f, 0.4f) * (i + 1); // height of mountains * noiseLayer.noiseSettings.rigidNoiseSettings.baseRoughness = RandomNumberInRange(0.8f, 3f) * (i + 1); // roughness of mountains * noiseLayer.noiseSettings.rigidNoiseSettings.roughness = 2.2f; // RandomNumberInRange(1f, 3.0f); // looks nice around 2.2f * * // change the position of the noise on the planet (almost the same as creating new noise object, if we do this for each layer independently its fine * noiseLayer.noiseSettings.rigidNoiseSettings.centre.x = RandomNumberInRange(-.5f, .5f); * noiseLayer.noiseSettings.rigidNoiseSettings.centre.y = RandomNumberInRange(-.5f, .5f); * noiseLayer.noiseSettings.rigidNoiseSettings.centre.z = RandomNumberInRange(-.5f, .5f); */ break; } settings.noiseLayers[i] = noiseLayer; } return(settings); }