static RadiosityRenderer() { _renderer = new RadiosityRenderer(null); }
/// <summary> /// Main photon processing algorithm. /// </summary> private void ProcessCollisions() { ChangeStage(RadiosityStage.PhotonBouncing, m_maxPhotons); photonsComplete = 0; // Loop through all the lights. for (int _currentLightIndex = 0; _currentLightIndex < this.m_lights.Count; _currentLightIndex++) { lightIndex = _currentLightIndex; if (m_lights[_currentLightIndex] is DiffuseLight) { DiffuseLight light = m_lights[_currentLightIndex] as DiffuseLight; //AddDebugRay(light.Center, light.Normal); AddDebugRay(light.Center, light.Normal, RadiosityDebugLineListID.LightDirections); } if (m_lights[_currentLightIndex] is RadiosityLight) { (m_lights[_currentLightIndex] as RadiosityLight).pointCount = m_maxPhotons; } int retryCount = 20; photonMap.BeginLight(); // Loop through the number of photons per light. Parallel.For(0, m_lights[lightIndex].PhotonCount, delegate(int _currentPhotonIndex) { if (stopRequested) { return; } if (!updateInProgress) { SetOperation("Bouncing photons..."); } photonIndex = _currentPhotonIndex; int _collisionCount = 0; IPhoton _photon; lock (this.m_lights[_currentLightIndex]) { // Generate a photon from the current light. _photon = this.m_lights[_currentLightIndex].GeneratePhoton(); AddDebugPoint(_photon.Position, RadiosityDebugPointListID.PhotonSpawn); AddDebugRay(_photon.Position, _photon.Direction, RadiosityDebugLineListID.DirectOnly); } //_photon.Color.Multiply(m_lights[_currentLightIndex].Power * m_lights.Count); // Bounce the photon around for the maximum permitted bounces. while (true)//_collisionCount < this.m_maxBounces) { RadiosityIntersection closest = RadiosityIntersection.None; float distSq = float.MaxValue; if (collideModels) { for (int x = 0; x < m_models.Count; x++) { RadiosityIntersection intersect = m_models[x].Intersection(_photon.Direction, _photon.Position); if (intersect != RadiosityIntersection.None) { //AddDebugPoint(intersect.Position); float dist = (intersect.Position - _photon.Position).LengthSq(); if (dist < distSq) { distSq = dist; closest = intersect; } } } } for (int x = 0; x < m_bsp.Count; x++) { // TODO: Test radiosity model to see if changes fixed the issues. RadiosityIntersection intersect = m_bsp[x].RadiosityIntersect(_photon.Position, _photon.Direction); if ((intersect.NoIntersection) || (intersect.WrongSide)) { continue; } float dist = float.MaxValue; if ((dist = (intersect.Position - _photon.Position).LengthSq()) < distSq) { closest = intersect; distSq = dist; } } // If the diffuse light never collided, it will randomly generate another. if ((closest == RadiosityIntersection.None)) { if (m_lights[_currentLightIndex] is DiffuseLight) { if (_collisionCount < 1) { if (retryCount > 0) { retryCount--; _currentPhotonIndex--; break; } } } retryCount = 5; break; } retryCount = 5; if (_collisionCount == 0) { AddDebugPoint(closest.Position, RadiosityDebugPointListID.DirectOnly); } else { AddDebugPoint(closest.Position, RadiosityDebugPointListID.IndirectOnly); } Photon phot = new Photon { LightmapIndex = (short)closest.LightmapIndex, MaterialIndex = (short)closest.MaterialIndex, Direction = (PhotonVector3)_photon.Direction, position = (PhotonVector3)closest.Position, Power = _photon.Color.Copy() }; AddDebugRay(closest.Position, closest.NewDirection, RadiosityDebugLineListID.IndirectOnly); _photon.Position = closest.Position; _photon.Direction = closest.NewDirection; lock (photonMap) { photonMap.Store(phot); } _photon.Color.Tint(closest.Material.ReflectionTint); _collisionCount++; if ((closest.Absorbed) || (_collisionCount >= m_maxBounces)) { break; } } photonsComplete++; IncrementProgress(); }); //photonMap.EndLight(); } Interfaces.Output.Write(Interfaces.OutputTypes.Information, "Finished processing photons..."); ChangeStage(RadiosityStage.TreeBalancing, 100); SetOperation("Balancing the photon map..."); photonMap.Balance(); RadiosityRenderer.SavePhotonMap(); Interfaces.Output.Write(Interfaces.OutputTypes.Information, "Saved the photon map!"); SetOperation("Updating viewport..."); try { //UpdateBspLightmaps(); CreateLightmaps(); } catch (Exception a) { SetOperation("Error!.. " + a.Message); Interfaces.Output.Write(Interfaces.OutputTypes.Error, "Error!.. " + a.Message, a.StackTrace); } try { UpdateViewportLightmaps(); } catch (System.Threading.AggregateException a) { Interfaces.Output.Write(Interfaces.OutputTypes.Error, "Error of type AggregateException thrown."); foreach (Exception exc in a.InnerExceptions) { Interfaces.Output.Write(Interfaces.OutputTypes.Error, "Error: " + exc.Message, exc.StackTrace); } } #region Debug #if DEBUG Console.WriteLine("Done!"); #endif #endregion stopRequested = false; }