Ejemplo n.º 1
0
 public PhotonTracer(Scene scene, RenderStrategy renderStrategy, int maxPhotons) : base(scene, renderStrategy)
 {
     this.scene                 = scene;
     this.maxPhotons            = maxPhotons;
     this.indirectEnlightenment = new PhotonMap(maxPhotons);
     this.causticsEnlightenment = new PhotonMap(maxPhotons);
     this.buildPhotonMaps       = true;
     this.scene.Primitives.CollectionChanged += Primitives_CollectionChanged;
     this.scene.Lights.CollectionChanged     += Lights_CollectionChanged;
     this.scene.Materials.CollectionChanged  += Materials_CollectionChanged;
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Begins calculating a light mapping solution.
        /// </summary>
        /// <exception cref="System.ApplicationException">
        /// Thrown when no BSP is in the current scene graph.
        /// </exception>
        public void Begin()
        {
            //      MdxRender.RenderDebug = false;

            SetOperation("Loading scenario...");
            _scenario = Prometheus.Instance.ProjectManager.ScenarioTag as ScenarioBase;

            if (_scenario == null)
            {
                throw new RadiosityException("The current project has no scenario tag or the scenario tag is invalid.");
            }

            if (_scenario.BspList.Count <= 0)
            {
                throw new RadiosityException("The current project's scenario tag does not contain a bsp tag or the bsp tag is invalid.");
            }

            SetOperation("Retrieving lighting information...");
            m_bsp = _scenario.BspList;
            WorldBounds bounds = m_bsp[0].WorldBounds;

            foreach (IBsp bsp in m_bsp)
            {
                bounds &= bsp.WorldBounds;
            }

            // We need to find the six planes of world bounds.
            m_worldBounds = bounds.CalculatePlanes();

            // Try and obtain any lighting information.
            if (Prometheus.Instance.ProjectManager.ScenarioTag != null)
            {
                this.m_lights = _scenario.WorldLighting;
                this.m_models = _scenario.StaticModels;

                if (m_models == null)
                {
                    m_models = new List <IModel>();
                }
            }
            else
            {
                ICamera camera = MdxRender.Camera;
                List <RadiosityLight> lights = new List <RadiosityLight>();
                this.m_lights = new List <ILight>();
                m_lights.Add(new RadiosityLight(camera.Position, new RealColor(1f, 1f, 1.0f), 20f));
            }

            // Get each lightmap from the currently loaded BSP.
            for (int i = 0; i < m_bsp.Count; i++)
            {
                // Add the DirectX texture to the high dynamic range texture collection.
                foreach (BaseTexture _texture in m_bsp[i].Lightmaps)
                {
                    TextureMap _lightmap = new TextureMap(_texture);
                    m_textures.AddTexture(_lightmap);
                }
            }

            // TODO: Figure out the number of photons each light gets. For now, set them all to use the same amount.
            float totalPower = 0f;
            float maxPower   = 0f;

            foreach (ILight light in m_lights)
            {
                totalPower += light.Power;
                maxPower    = Math.Max(light.Power, maxPower);
            }

            int directionalPhotons = 0;

            foreach (ILight light in m_lights)
            {
                int photonCount = (int)((float)m_maxPhotons * light.Power / totalPower);//(int)Math.Round((light.Power / totalPower) * (float)m_maxPhotons);
                light.PhotonCount = photonCount;
                light.Color.Multiply(light.Power);

                if (light is DirectionalLight)
                {
                    directionalPhotons += photonCount;
                }
            }
            bool[,] importance;
            int count;

            ChangeStage(RadiosityStage.CreatingImportanceMap, directionalPhotons);
            SetOperation("Optimizing Pass...");
            for (int l = 0; l < m_lights.Count; l++)
            {
                if (m_lights[l] is DirectionalLight)
                {
                    DirectionalLight light = m_lights[l] as DirectionalLight;
                    if (light.PhotonCount > 0)
                    {
                        importance = CreateImportanceMap(light.Direction, light.PhotonCount, bounds, out count);
                    }
                    else
                    {
                        importance = null; count = 0;
                    }
                    RadiosityHelper.ImportanceMap         = importance;
                    RadiosityHelper.ImportanceMapOnPixels = count;
                }
            }

            //currentOperation = "Saving any unsaved data...";
            //this.SaveAll();
            photonMap = new PhotonMap(m_maxBounces * m_maxPhotons);
            SetOperation("Perform radiosity...");
            // Process collisions.
            this.ProcessCollisions();

            ChangeStage(RadiosityStage.Done, 100);

            Interfaces.Output.Write(Interfaces.OutputTypes.Information, m_photonsLost + " photon(s) lost during radiosity.");
            if (OnComplete != null)
            {
                OnComplete();
            }
        }