Exemple #1
0
        public Interfaces.Rendering.Radiosity.RadiosityIntersection Intersection(Vector3 direction, Vector3 origin)
        {
            if (bounds.RayAABBIntersect(origin, direction))
            {
                EnhancedMesh[] mesh;
                if (meshes.Length > (int)LevelOfDetail.SuperHigh)
                {
                    mesh = meshes[(int)LevelOfDetail.SuperHigh];
                }
                else
                {
                    mesh = null;
                }
                if (mesh == null)
                {
                    for (int x = (int)LevelOfDetail.SuperHigh; x >= 0; x--)
                    {
                        if ((meshes.Length > x) && (meshes[x] != null))
                        {
                            mesh = meshes[x];
                            break;
                        }
                    }
                }

                Intersection closest   = Wrappers.Intersection.None;
                float        distSq    = float.MaxValue;
                int          meshIndex = -1;
                for (int x = 0; x < mesh.Length; x++)
                {
                    Intersection regularIntersect = mesh[x].IntersectRay(origin, direction);
                    if (!regularIntersect.NoIntersection)
                    {
                        float dist2 = (regularIntersect.Position - origin).LengthSq();
                        if (dist2 < distSq)
                        {
                            closest   = regularIntersect;
                            distSq    = dist2;
                            meshIndex = x;
                        }
                    }
                }
                if (!closest.NoIntersection)
                {
                    int    f = closest.FaceIndex * 3;
                    Vertex a = mesh[meshIndex].Vertices[mesh[meshIndex].Indices[f]];
                    Vertex b = mesh[meshIndex].Vertices[mesh[meshIndex].Indices[f + 1]];
                    Vertex c = mesh[meshIndex].Vertices[mesh[meshIndex].Indices[f + 2]];

                    RadiosityIntersection radIntersect = RadiosityHelper.ProcessIntersection(direction, a, b, c, closest, null, false);

                    return(radIntersect);
                }
            }
            return(RadiosityIntersection.None);
        }
        private Interfaces.Rendering.Radiosity.RadiosityIntersection RadiosityIntersect(Vector3 origin, Vector3 direction)
        {
            if (direction.Length() != 1)
            {
                direction.Normalize();
            }
            // TODO: Check bounding box for model, then for each node, then for each bsp.

            Interfaces.Rendering.Radiosity.RadiosityIntersection closest = RadiosityIntersection.None;

            // if (ax + by + cz == -D) then COLLISION
            foreach (NodeBlock node in modelCollisionGeometryValues._nodesList)
            {
                foreach (BspBlock bsp in node.Bsps)
                {
                    //cosAlpha = DotProduct(
                    //         vnRayVector ,  vnPlaneNormal );
                    // if (cosAlpha==0) return -1.0f;
                    // deltaD = planeD -
                    //         DotProduct(vRayOrigin,vnPlaneNormal);
                    //     return (deltaD/cosAlpha);
                    int surfaceIndex = 0;
                    foreach (SurfaceBlock surface in bsp.Surfaces)
                    {
                        RadiosityIntersection tempIntersect = Ray.IntersectRayOnPlane(new Ray(origin, direction), new Plane(bsp.Planes[surface.Plane.Value].Plane.I, bsp.Planes[surface.Plane.Value].Plane.J, bsp.Planes[surface.Plane.Value].Plane.K, bsp.Planes[surface.Plane.Value].Plane.D));

                        if ((bool)tempIntersect)
                        {
                            if (closest != RadiosityIntersection.None)
                            {
                                if (closest.Distance < tempIntersect.Distance)
                                {
                                    continue;
                                }
                            }

                            closest = tempIntersect;
                        }
                    }
                }
            }
            return(closest);
        }
Exemple #3
0
        public bool[,] CreateImportanceMap(Vector3 lightDirection, int photonCount, WorldBounds bounds, out int importanceMapIntersectCount)
        {
            bool[,] hiresMap;

            importanceMapIntersectCount = 0;
            float width     = bounds.X.Difference;
            float height    = bounds.Y.Difference;
            float countRoot = (float)Math.Sqrt(photonCount);
            int   countX    = (int)Math.Ceiling((countRoot * height) / width);
            int   countY    = (int)Math.Ceiling((countRoot * width) / height);
            float distanceX = width / (float)countX;
            float distanceY = height / (float)countY;

            hiresMap = new bool[countX, countY];

            //lightDirection *= -1; // back to original;
            float xPos, yPos;

            yPos = bounds.Y.Lower;
            for (int y = 0; y < countY; y++)
            {
                xPos = bounds.X.Lower;
                for (int x = 0; x < countX; x++)
                {
                    RadiosityIntersection intersect = m_bsp[0].RadiosityIntersect(new Vector3(xPos, yPos, bounds.Z.Upper), lightDirection);
                    // DeMorgan's Theorem FTW!
                    hiresMap[x, y] = !(intersect.NoIntersection || intersect.WrongSide);
                    if (hiresMap[x, y])
                    {
                        importanceMapIntersectCount++;
                    }
                    xPos += distanceX;
                    IncrementProgress();
                }
                yPos += distanceY;
            }
            //importanceMap = hiresMap;
            return(hiresMap);
        }
Exemple #4
0
        /// <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;
        }
Exemple #5
0
        private void CreateRender()
        {
            int   screenWidth  = MdxRender.Device.Viewport.Width;
            int   screenHeight = MdxRender.Device.Viewport.Height;
            float dist2        = RadiosityHelper.GatherDistance * RadiosityHelper.GatherDistance;

            Bitmap renderBitm;// = new Bitmap(screenWidth, screenHeight);

            float[,,] hdr = new float[screenWidth, screenHeight, 3];
            ChangeStage(RadiosityStage.TextureGeneration, screenWidth * screenHeight);
            SetOperation("Rendering...");
            int tenPercent = screenWidth / 10;
            int left       = screenWidth / 2 - tenPercent;
            int right      = screenWidth / 2 + tenPercent;

            for (int y = 0; y < screenHeight; y++)
            {
                for (int x = 0; x < screenWidth; x++)
                {
                    Vector3 direction, origin;
                    MdxRender.CalculatePickRayWorld(x, y, out direction, out origin);
                    //AddDebugRay(origin, direction);

                    RadiosityIntersection intersect = m_bsp[0].RadiosityIntersect(origin, direction);
                    //AddDebugPoint(intersect.Position);

                    if (!intersect.NoIntersection)
                    {
                        Vector3 normal = m_bsp[0].GetFaceNormal(intersect.LightmapIndex, intersect.MaterialIndex, intersect.FaceIndex);
                        List <CompressedPhoton> photons = photonMap.RetrieveNearestNeighbors((PhotonVector3)intersect.Position, dist2, 10000);
                        RealColor sum = RealColor.Black.Copy();//new RealColor(photons.Count, photons.Count, photons.Count);

                        if (photons.Count == 0)
                        {
                            System.Diagnostics.Debugger.Break();
                        }
                        foreach (CompressedPhoton phot in photons)
                        {
                            float dotP = Vector3.Dot(-phot.Direction, normal);
                            if (dotP < 0)
                            {
                                dotP = 0;
                            }

                            sum.Add(phot.Power.Copy().Multiply(dotP));
                        }
                        if ((sum.G > sum.B) && (sum.G > sum.R))
                        {
                            if (x >= left)
                            {
                                if (x <= right)
                                {
                                    if (photons.Count > 100)
                                    {
                                        AddDebugRay(origin, direction);
                                        AddDebugPoint(origin);

                                        foreach (var photon in photons)
                                        {
                                            AddDebugPoint(photon.position.ToVector3());
                                        }
                                    }
                                }
                            }
                            //System.Diagnostics.Debugger.Break();
                        }
                        //sum.Multiply(1 / (dist2 * (float)Math.PI));
                        //sum.Multiply(intersect.Material.AmbientLight);
                        for (int c = 0; c < 3; c++)
                        {
                            hdr[x, y, c] = sum[c];
                        }
                    }
                    else
                    {
                        hdr[x, y, 0] = 0;
                        hdr[x, y, 1] = 0;
                        hdr[x, y, 2] = 0;
                    }
                    IncrementProgress();
                }
            }
            //renderBitm = LinearTonemap(hdr);
            Bitmap tempBitmap = new Bitmap(screenWidth, screenHeight);

            //Graphics g = Graphics.FromImage(tempBitmap);
            //g.DrawImage(renderBitm, 0, 0);
            //g.Dispose();
            //renderBitm.Dispose();
            tempBitmap.Save(@"C:\Users\David\render.bmp");
            return;
        }