/// <summary> /// Reads in scene object from files. No other logic. /// </summary> /// <param name="contentManager">An instance of the content manager that the program is using.</param> /// <param name="defaultMaterial">A model cannot render without a material, so assigning a default material to it is mandatory.<</param> public void PopulateScene(ContentManager contentManager, Material defaultMaterial) { // NOTE: This logic is currently hard-coded for simplicity. If at some point in time the scene gets more complex, // then all this code will change to reading an XML scene file, or there will be an external class that specializes in scene // building that populates the scene graph for us. try { ModelGraph = new List<ModelNode>(); for (int i = 0; i < 4; i++) { ModelGraph.Add(new ModelNode()); ModelGraph[i].LoadContent(contentManager, "Models\\teapot"); ModelGraph[i].Name = "Teapot " + (i+1).ToString(); ModelGraph[i].Material = defaultMaterial; } this.ModelGraph[0].Position = new Vector3(3.5f, 0f, -3.5f); this.ModelGraph[1].Position = new Vector3(-3.5f, 0f, -3.5f); this.ModelGraph[2].Position = new Vector3(-3.5f, 0f, 3.5f); this.ModelGraph[3].Position = new Vector3(3.5f, 0f, 3.5f); } catch (Exception e) { MessageBox.Show("Loading model failed with message:" + e.Message); throw; } }
public void AssignNewMaterial(string objectName, Material material) { foreach (ModelNode modelNode in ModelGraph) { modelNode.AssignNewMaterial(objectName, material); } }
public void AssignNewMaterial(int objectId, Material material) { foreach (ModelNode modelNode in ModelGraph) { modelNode.AssignNewMaterial(objectId, material); } }
public void AssignNewMaterial(int objectId, Material material) { if (this.NodeId == objectId) { this.Material = material; } foreach (ModelNode modelNode in this.SubNodes) { modelNode.AssignNewMaterial(objectId, material); } }
public void AssignNewMaterial(string objectName, Material material) { if (this.Name.Equals(objectName)) { this.Material = material; } foreach (ModelNode modelNode in this.SubNodes) { modelNode.AssignNewMaterial(objectName, material); } }
private void UpdateMaterialChart(Material material) { SpectralData data = material.ReflectanceDistribution; Series series = MaterialChart.Series[0]; series.Points.Clear(); for (int wavelength = data.LowestWavelength, i = 0; wavelength <= data.HighestWavelength; wavelength += data.StepSize, i++) { series.Points.Add(new DataPoint((float)wavelength, data.WaveData[i])); } }
/// <summary> /// Read in all the materials from the given file. /// </summary> /// <param name="fileName">Path to the data file.</param> protected void ReadInMaterials(string fileName) { XmlDocument materialsXML = new XmlDocument(); materialsXML.Load(fileName); foreach (XmlElement materialXML in materialsXML.GetElementsByTagName(XMLDataConstants.Material)) { Material material = new Material(); material.Initialize(materialXML); this.Materials.Add(material); } }
public void UpdateSelectedObjectMaterial(string objectName, Material material) { this.SceneGraph.AssignNewMaterial(objectName, material); }
/// <summary> /// Calculate the tristimulus values for the given combination of light source, material and observer. /// </summary> /// <returns>A float array of size 3 containing X, Y and Z in each cell respectively.</returns> public static Vector3 CalculateTristimulusValues(LightSource lightSource, Material material, Observer observer, bool clipInvisible = false) { // TODO: This may not be the most efficient of all approaches, make sure you change this to be more streamlined. // Normalize spectra. // List<SpectralData> spectraBank = new List<SpectralData>(); spectraBank.Add(lightSource.SpectralPowerDistribution); spectraBank.Add(material.ReflectanceDistribution); spectraBank.Add(observer.ResponseSpectra[0]); spectraBank.Add(observer.ResponseSpectra[1]); spectraBank.Add(observer.ResponseSpectra[2]); Utilities.NormalizeSpectra(spectraBank); // Calculate the normalizing constant for tristimulus integration // float K = Utilities.TristimulusNormalizingConstant(lightSource, observer); float summation; int stepSize = lightSource.SpectralPowerDistribution.StepSize; // The wave data we need is nested deep inside objects. So grab it into local arrays // for convenience of coding. // float[] lightSourceData, materialData, observerXData, observerYData, observerZData; if (clipInvisible) { // Find out what indexes correspond to wavelengths between 380 and 780 nm. // Since the data is normalized, calculating based on 1 source should be enough. int startIndex = (380 - lightSource.SpectralPowerDistribution.LowestWavelength) / lightSource.SpectralPowerDistribution.StepSize; int count = (780 - 380) / lightSource.SpectralPowerDistribution.StepSize + 1; // Sanity check if (startIndex < 0) { throw new ArgumentException("wavelength data provided started after 380 nm"); } lightSourceData = lightSource.SpectralPowerDistribution.WaveData.GetRange(startIndex, count).ToArray(); materialData = material.ReflectanceDistribution.WaveData.GetRange(startIndex, count).ToArray(); observerXData = observer.ResponseSpectra[0].WaveData.GetRange(startIndex, count).ToArray(); observerYData = observer.ResponseSpectra[1].WaveData.GetRange(startIndex, count).ToArray(); observerZData = observer.ResponseSpectra[2].WaveData.GetRange(startIndex, count).ToArray(); } else { lightSourceData = lightSource.SpectralPowerDistribution.WaveData.ToArray(); materialData = material.ReflectanceDistribution.WaveData.ToArray(); observerXData = observer.ResponseSpectra[0].WaveData.ToArray(); observerYData = observer.ResponseSpectra[1].WaveData.ToArray(); observerZData = observer.ResponseSpectra[2].WaveData.ToArray(); } // Calculate the L*M product array. This reduces the repeated multiplication operations that would otherwise be // required. // float[] lmProductArray = Utilities.ComputeLMProductArray(lightSourceData, materialData); Vector3 tristimulusValues = new Vector3(); // Calculate X // summation = Utilities.ComputeSummationTerm(lmProductArray, observerXData); tristimulusValues.X = K * summation * (float)stepSize; // Calculate Y // summation = Utilities.ComputeSummationTerm(lmProductArray, observerYData); tristimulusValues.Y = K * summation * (float)stepSize; // Calculate Z // summation = Utilities.ComputeSummationTerm(lmProductArray, observerZData); tristimulusValues.Z = K * summation * (float)stepSize; return tristimulusValues; }
public static Vector4 GetEquivalentRGB(Material material) { Vector3 materialXYZ = Utilities.CalculateTristimulusValues( TheDataManager.GetLightSourceByPartialName("D65"), material, TheDataManager.GetObserverByPartialName("1964"), true); return Utilities.CalculateRGBfromXYZ(materialXYZ); }